想要在ROS系统中对我们的机器人进行仿真,需要使用gazebo。

gazebo是一种适用于复杂室内多机器人和室外环境的仿真环境。它能够在三维环境中对多个机器人、传感器及物体进行仿真,产生实际传感器反馈和物体之间的物理响应。

在本文中,你会学习如何使用之前创建的机器人模型,如何加载一个激光雷达传感器和摄像头,并使机器人模型像真的机器人一样移动。

一、在 gazebo 中使用 URDF 3D 模型

在 gazebo 工作前,我们需要安装ROS功能包与 gazebo 交互:

  1. $ sudo apt-get install ros-indigo-gazebo-ros-pkgs ros-indigo-ros-control

为了在 gazebo 中导入机器人模型,你需要先完成 URDF 模型。在这里我们将使用.xacro文件,虽然这可能更复杂,但是对于代码开发来说其功能非常强大。你能够在 chapter7_tutorials/robot1_description/urdf/robot1_base_01.xacro 找到修改后的文件:(由于代码过多,所以并未完全贴出,下面只是很少的一部分代码)

  1. <link name="base_link">
  2. <visual>
  3. <geometry>
  4. <box size="0.2 .3 .1"/>
  5. </geometry>
  6. <origin rpy="0 0 1.54" xyz="0 0 0.05"/>
  7. <material name="white">
  8. <color rgba="1 1 1 1"/>
  9. </material>
  10. </visual>
  11. <collision>
  12. <geometry>
  13. <box size="0.2 .3 0.1"/>
  14. </geometry>
  15. </collision>
  16. <xacro:default_inertial mass="10"/>
  17. </link>

这是机器人底盘 base_link 的新代码。请注意 collision 和 inertial 部分对于在 gazebo 中运行模型是必需的,这样才能计算机器人的物理响应。

想要启动这一切,我们创建一个名为 gazebo.launch 的启动文件到 chapter7_tutorials/robot1_gazebo/launch 文件夹下,并添加以下代码:

  1. <?xml version="1.0"?>
  2. <launch>
  3. <!-- these are the arguments you can pass this launch file, for example paused:=true -->
  4. <arg name="paused" default="true"/>
  5. <arg name="use_sim_time" default="false"/>
  6. <arg name="gui" default="true"/>
  7. <arg name="headless" default="false"/>
  8. <arg name="debug" default="true"/>
  9. <!-- We resume the logic in empty_world.launch, changing only the name of the world to be launched -->
  10. <include file="$(find gazebo_ros)/launch/empty_world.launch">
  11. <arg name="world_name" value="$(find robot1_gazebo)/worlds/robot.world"/>
  12. <arg name="debug" value="$(arg debug)" />
  13. <arg name="gui" value="$(arg gui)" />
  14. <arg name="paused" value="$(arg paused)"/>
  15. <arg name="use_sim_time" value="$(arg use_sim_time)"/>
  16. <arg name="headless" value="$(arg headless)"/>
  17. </include>
  18. <!-- Load the URDF into the ROS Parameter Server -->
  19. <arg name="model" />
  20. <param name="robot_description"
  21. command="$(find xacro)/xacro.py $(arg model)" />
  22. <!-- Run a python script to the send a service call to gazebo_ros to spawn a URDF robot -->
  23. <node name="urdf_spawner" pkg="gazebo_ros" type="spawn_model" respawn="false" output="screen"
  24. args="-urdf -model robot1 -param robot_description -z 0.05"/>
  25. </launch>

想要启动文件,需要使用以下命令:

  1. $ roslaunch robot1_gazebo gazebo.launch model:="`rospack find robot1_description`/urdf/robot1_base_01.xacro"

然后可以在 gazebo 中看到机器人。仿真初始状态是暂停的,你可以点击 paly 来运行它。(不过机器人不会移动)

正如你所见,模型并没有任何纹理渲染。在rviz中你能看到在URDF文件中声明的纹理。但是在 gazebo 中,你看不到它们。为了在 gazebo 中添加可见的纹理,需要在你的 .gazebo 模型文件中创建robot.gazebo文件。将 robot1_description/urdf/robot1_base_01.xacro 文件另存为 robot1_base_02.xacro,并添加如下代码,即可创建robot.gazebo文件:

  1. <xacro:include filename="$(find robot1_description)/urdf/robot.gazebo" />

启动这个新文件,你看到的机器人虽然还是同一个,但已经带有纹理了:

  1. $ roslaunch robot1_gazebo gazebo.launch model:="`rospack find robot1_description`/urdf/robot1_base_02.xacro"

你将会看到以下输出:

二、在 gazebo 中添加传感器

在gazebo中,你能够对机器人的物理运动进行仿真。你同样能仿真它的传感器。

在本节中我们将会向模型中添加一个摄像头和激光雷达传感器。

我们会从 gazebo_ros_demos 功能包中调用激光雷达。这是ROS的神奇之处,你能从其他功能包中复用代码从而简化开发。

我们唯一需要做的是向 robot1_base_02.xacro 文件中增加这些行,来为机器人添加 Hokuyo 激光雷达3D模型,并另存为 robot1_base_03.xacro 文件:

  1. <!-- Hokuyo Laser -->
  2. <link name="hokuyo_link">
  3. <collision>
  4. <origin xyz="0 0 0" rpy="0 0 0"/>
  5. <geometry>
  6. <box size="0.1 0.1 0.1"/>
  7. </geometry>
  8. </collision>
  9. <visual>
  10. <origin xyz="0 0 0" rpy="0 0 0"/>
  11. <geometry>
  12. <mesh filename="package://robot1_description/meshes/hokuyo.dae"/>
  13. </geometry>
  14. </visual>
  15. <inertial>
  16. <mass value="1e-5" />
  17. <origin xyz="0 0 0" rpy="0 0 0"/>
  18. <inertia ixx="1e-6" ixy="0" ixz="0" iyy="1e-6" iyz="0" izz="1e-6" />
  19. </inertial>
  20. </link>

在 robot.gazebo 文件里,我们将添加 libgazebo_ros_laser 插件,这样就可以模拟 Hokuyo 激光测距雷达的行为。

  1. <!-- hokuyo -->
  2. <gazebo reference="hokuyo_link">
  3. <sensor type="ray" name="head_hokuyo_sensor">
  4. <pose>0 0 0 0 0 0</pose>
  5. <visualize>false</visualize>
  6. <update_rate>40</update_rate>
  7. <ray>
  8. <scan>
  9. <horizontal>
  10. <samples>720</samples>
  11. <resolution>1</resolution>
  12. <min_angle>-1.570796</min_angle>
  13. <max_angle>1.570796</max_angle>
  14. </horizontal>
  15. </scan>
  16. <range>
  17. <min>0.10</min>
  18. <max>30.0</max>
  19. <resolution>0.01</resolution>
  20. </range>
  21. <noise>
  22. <type>gaussian</type>
  23. <!-- Noise parameters based on published spec for Hokuyo laser
  24. achieving "+-30mm" accuracy at range < 10m. A mean of 0.0m and
  25. stddev of 0.01m will put 99.7% of samples within 0.03m of the true
  26. reading. -->
  27. <mean>0.0</mean>
  28. <stddev>0.01</stddev>
  29. </noise>
  30. </ray>
  31. <plugin name="gazebo_ros_head_hokuyo_controller" filename="libgazebo_ros_laser.so">
  32. <topicName>/scan</topicName>
  33. <frameName>hokuyo_link</frameName>
  34. </plugin>
  35. </sensor>
  36. </gazebo>

使用以下命令启动新的模型:

  1. $ roslaunch robot1_gazebo gazebo.launch model:="`rospack find robot1_description`/urdf/robot1_base_03.xacro"

你将会看到附带激光雷达模块的机器人。

采用同样的方法,我们向 robot.gazebo 和 robot1_base_03.xacro 添加几行代码以增加另一个传感器(一个摄像头)。

再使用以下命令启动添加摄像头后的模型:

  1. $ roslaunch robot1_gazebo gazebo.launch model:="`rospack find robot1_description`/urdf/robot1_base_04.xacro"

注意,这个激光雷达会像真实的雷达一样产生“真实"的传感器数据。你能够通过 rostopic echo 命令看到这些数据:

  1. $ rostopic echo /robot/laser/scan

我们可以向摄像头发出相同命令,但如果你想观察摄像头看到的 gazebo 仿真图像,你可以在终端中写入以下指令:

  1. $ rosrun image_view image_view image:=/robot/camera1/image_raw

下面是点击"play"允许后摄像头拍摄的图像。

三、在 gazebo 中加载和使用地图

在本小节中我们将会使用一张柳树车库公司(Willow Garage)办公室的地图、这张地图在我们的ROS软件中应该默认安装了,保存在 gazebo_worlds 功能包中。

为了检查模型,可以使用以下命令启动 .launch 文件:

  1. $ roslaunch gazebo_ros willowgarage_world.launch

你会在 gazebo 中看到3D的办公室。这个办公室只有墙壁,你可以添加桌子、椅子和其他你想添加的物体。

我们现在要做的是创建一个新的 .launch 文件来同时加载地图和机器人。为实现这个功能,我们在 robot1_gazebo/launch 文件夹下创建一个名为 gazebo_wg.launch 的文件,并添加以下代码:

  1. <?xml version="1.0"?>
  2. <launch>
  3. <include file="$(find gazebo_ros)/launch/willowgarage_world.launch">
  4. </include>
  5. <!-- Load the URDF into the ROS Parameter Server -->
  6. <param name="robot_description"
  7. command="$(find xacro)/xacro.py '$(find robot1_description)/urdf/robot1_base_04.xacro'" />
  8. <node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher" />
  9. <!-- Run a python script to the send a service call to gazebo_ros to spawn a URDF robot -->
  10. <node name="urdf_spawner" pkg="gazebo_ros" type="spawn_model" respawn="false" output="screen"
  11. args="-urdf -model robot1 -param robot_description -z 0.05"/>
  12. </launch>

现在运行带有机器人的地图模型文件(注意:有些时候会出现软件崩溃,多尝试运行几次):

  1. $ roslaunch robot1_gazebo gazebo_wg.launch

你会在 gazebo 中看到机器人和地图。下一步是在仿真虚拟环境中命令机器人移动和接受其传感器的仿真读数。

四、在 gazebo 中移动机器人

滑移转向(skid-steer)机器人是一种对机身两侧轮子分别进行驱动的移动机器人。它通过将两侧轮子控制在不同的转速(所产生的转速差)进行转向,而不需要轮子有任何转向行动。

正如前面所说,在 gazebo 中我们需要对机器人、关节、传感器等设备的行为进行编程。和前面的激光雷达一样,gazeb 也已经有了 skid 驱动的实现,我们能够直接使用它移动机器人。使用此行驶控制器,只需要在模型文件(robot1_base_04.xacro)中增加以下代码:

  1. <!-- Drive controller -->
  2. <gazebo>
  3. <plugin name="skid_steer_drive_controller" filename="libgazebo_ros_skid_steer_drive.so">
  4. <updateRate>100.0</updateRate>
  5. <robotNamespace>/</robotNamespace>
  6. <leftFrontJoint>base_to_wheel1</leftFrontJoint>
  7. <rightFrontJoint>base_to_wheel3</rightFrontJoint>
  8. <leftRearJoint>base_to_wheel2</leftRearJoint>
  9. <rightRearJoint>base_to_wheel4</rightRearJoint>
  10. <wheelSeparation>4</wheelSeparation>
  11. <wheelDiameter>0.1</wheelDiameter>
  12. <robotBaseFrame>base_link</robotBaseFrame>
  13. <torque>1</torque>
  14. <topicName>cmd_vel</topicName>
  15. <broadcastTF>0</broadcastTF>
  16. </plugin>
  17. </gazebo>

你在代码中能够看到的参数都是一些简单的配置,以便这个控制器能够支持4个轮子的机器人工作。例如,我们选择 base_to_wheel1、base_to_wheel2、base_to_wheel3、base_to_wheel4 关节作为机器人的驱动轮。

另外一个有趣的参数是 topicName。我们需要以这个参数为名发布命令来控制机器人。此时,当你发布一个 sensor_msgs/Twist 主题调用 /cmd_vel 时,机器人将会移动。正确配置轮子关节的方向非常重要,按照xacro文件中的当前方向,机器人将上下移动,因此有必要修改四个轮子的初始rpy,如以下代码中的 base link 和 wheel1 关节:

  1. <joint name="base_to_wheel1" type="continuous">
  2. <parent link="base_link"/>
  3. <child link="wheel_1"/>
  4. <origin rpy="-1.5707 0 0" xyz="0.1 0.15 0"/>
  5. <axis xyz="0 0 1" />
  6. </joint>

所有修改都保存在 chapter7_tutorials/robot1_description/urdf/robot1_base_04.xacro 文件中。现在我们使用以下命令启动带有控制器、机器人和地图的模型:

  1. $ roslaunch robot1_gazebo gazebo_wg.launch

你将会在 gazebo 屏幕中看到机器人在地图上。现在我们将使用键盘来移动地图中的机器人。这个节点在 teleop_twist_keyboard 功能包中,发布 /cmd_vel 主题。运行以下命令以按照此功能包:

  1. $ sudo apt-get install ros-indigo-teleop-twist-keyboard
  2. $ rosstack profile
  3. $ rospack profile

然后,运行节点如下:

  1. $ rosrun teleop_twist_keyboard teleop_twist_keyboard.py

现在你会看到一个有很多说明的新命令行窗口,你可以使用(u,i,o,j,k,l,m,“,”,“.”)按键来移动机器人并设置最大速度。(目前已知u键是加速,j键是左转,k键是减速,l键是右转)

如果一切顺利的话,你可以驾驶机器人穿越 Willow Garage 的办公室。你可以观察到激光雷达数据和摄像头显示的图像。

五、小节

在本文中,你学会了如何创建一个属于自己的3D机器人模型。这包括对添加纹理、创建关节和说明如何使用节点来移动机器人等工作的详细解释。

概况来讲,我们已经看到了如何复用其他机器人的部件来设计我们自己的机器人,特别是我们已经包含了抓取器并添加了传感器,例如一个激光雷达和一个摄像头。

因此,在仿真中不需要完全从无到有来建造一个机器人,社区里已经开发了大量的机器人,你可以下载代码并在 ROS 和 gazebo 中运行它们,如有必要也可以修改它们。

ROS学习笔记十二:使用gazebo在ROS中仿真的更多相关文章

  1. python3.4学习笔记(十二) python正则表达式的使用,使用pyspider匹配输出带.html结尾的URL

    python3.4学习笔记(十二) python正则表达式的使用,使用pyspider匹配输出带.html结尾的URL实战例子:使用pyspider匹配输出带.html结尾的URL:@config(a ...

  2. Go语言学习笔记十二: 范围(Range)

    Go语言学习笔记十二: 范围(Range) rang这个关键字主要用来遍历数组,切片,通道或Map.在数组和切片中返回索引值,在Map中返回key. 这个特别像python的方式.不过写法上比较怪异使 ...

  3. java jvm学习笔记十二(访问控制器的栈校验机制)

    欢迎装载请说明出处:http://blog.csdn.net/yfqnihao 本节源码:http://download.csdn.net/detail/yfqnihao/4863854 这一节,我们 ...

  4. ROS学习笔记十:URDF详解

    Unified Robot Description Format,简称为URDF(标准化机器人描述格式),是一种用于描述机器人及其部分结构.关节.自由度等的XML格式文件. 一.URDF语法规范 参见 ...

  5. ROS学习(十二)—— 编写简单的消息发布器和订阅器(C++)

    一.创建发布器节点 1 节点功能: 不断的在ROS网络中广播消息 2 创建节点 (1)打开工作空间目录 cd ~/catkin_ws/src/beginner_tutorials 创建一个发布器节点( ...

  6. (C/C++学习笔记) 十二. 指针

    十二. 指针 ● 基本概念 位系统下为4字节(8位十六进制数),在64位系统下为8字节(16位十六进制数) 进制表示的, 内存地址不占用内存空间 指针本身是一种数据类型, 它可以指向int, char ...

  7. Python学习笔记(十二)—Python3中pip包管理工具的安装【转】

    本文转载自:https://blog.csdn.net/sinat_14849739/article/details/79101529 版权声明:本文为博主原创文章,未经博主允许不得转载. https ...

  8. ROS学习笔记八:基于Qt搭建ROS开发环境

    1 前言 本文介绍一种Qt下进行ROS开发的完美方案,使用的是ros-industrial的Levi-Armstrong在2015年12月开发的一个Qt插件ros_qtc_plugin,这个插件使得Q ...

  9. ROS学习笔记五:创建和使用ROS msg和srv

    1 msg和srv简介 1.1 msg文件 msg文件就是一个简单的text文件,其中每行有一个类型和名称,可用的类型如下: int8, int16, int32, int64 (plus uint* ...

随机推荐

  1. google 上网

    https://chrome.google.com/webstore/detail/%E5%BC%80%E7%9C%BC/kpamljbkjaaljbcgobdealnpalcgicna?hl=zh- ...

  2. js性能优化之函数节流(分流函数)

    函数节流的原理 比如我们在window.onresize事件中要打印当前浏览器窗口的大小,在我们通过拖拽来改变窗口大小时候,打印窗口大小这个工作1s就运行了10次.而实际上我们只需要2次或者3次. 比 ...

  3. HDU 5288(OO’s Sequence-区间互质情况统计)

    OO's Sequence Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) ...

  4. 【Java集合源代码剖析】HashMap源代码剖析

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/36034955 您好,我正在參加CSDN博文大赛,假设您喜欢我的文章.希望您能帮我投一票.谢 ...

  5. 跟面试官讲Binder(零)

    面试的时候,面试官问你说,简单说一下Android的Binder机制,你会怎么回答? 我想,我会这么说. 在Android启动的时候,Zygote进程孵化出第一个子进程叫SystemServer,而在 ...

  6. IIS+Asp.Net Mvc必须知道的事(解决启动/重启/自动回收站点后第一次访问慢问题)

    问题现象: Asp.net Mvc站点部署在IIS上后,第一个用户第一次访问站点,都会比较慢,确切的说是访问站点的Action页面(即非静态页面,因为静态页面直接由IIS处理返回给用户即完成请求,而A ...

  7. 在VC6.0中多线程编程演示样例(带同步信号量)

    直接上代码: #include <windows.h>//必要的头文件,使用Windows API函数 #include <stdio.h> int index = 0; in ...

  8. Mac下Apache+MySQL+PHP安装

    max下是自带有Apache和php的服务器的,不需要另外安装,本文就对相关配置进行介绍. 第一:Apache 在终端中输入,下面指令即可启动Apache服务器: //启动 sudo apachect ...

  9. ios开发--NSDate与NSDateFormatter的相关用法【转】

    原文地址:http://blog.sina.com.cn/s/blog_91ff71c0010188u9.html 1.NSDateFormatter配合NSDate与NSString之间的转化  N ...

  10. UC技术博客开放通知

    国内知名浏览器UC开放技术博客( http://tech.uc.cn/),技术博客所涵盖技术点有: Hadoop Linux MySQL 前端与client技术 图像处理 开发语言和框架 数据存储 数 ...