URDF文件完成后,可以在rviz中显示机器人的模型,如果要在gazebo中进行物理环境仿真,还需要为URDF文件加入一些gazebo相关的标签。既然是仿真,那么机器人应该像真在真实环境中一样,可以通过传感器感知周围环境,还可以根据指令进行运动。
在gazebo中可以通过插入一些插件,来仿真机器人的传感器、执行器的特性,这些插件通过<gazebo>元素中的<plugin>标签描述,使用下边的格式加入到URDF文件中:
<gazebo>
<plugin name="differential_drive_controller" filename="libdiffdrive_plugin.so">
... plugin parameters ...
</plugin>
</gazebo>
当然,这些插件常常需要附着于机器人的某个部分,比如要加入一个激光传感器的插件,那么我们需要将这个插件与机器人模型中的激光传感器link绑定:
<gazebo reference="your_link_name">
<plugin name="your_link_laser_controller" filename="libgazebo_ros_laser.so">
... plugin parameters ...
</plugin>
</gazebo>
gazebo默认支持不少常用的设备,可以找到ros安装目录中的gazebo_plugins功能包,里边就是所有支持的插件。当然,你也可以自己编写需要的gazebo插件。
下边列出一些常用插件的使用方法:
1.差速驱动插件
很多机器人本体都采用差速驱动的方式,gazebo提供差速机器人的仿真插件,可以直接将下边的代码放到URDF文件中,修改相应的参数,指定运动控制需要订阅的主题,让机器人在gazebo中动起来。
<gazebo>
<plugin name="differential_drive_controller" filename="libgazebo_ros_diff_drive.so">
<alwaysOn>true</alwaysOn>
<updateRate>${update_rate}</updateRate>
<leftJoint>base_link_right_wheel_joint</leftJoint>
<rightJoint>base_link_left_wheel_joint</rightJoint>
<wheelSeparation>0.5380</wheelSeparation>
<wheelDiameter>0.2410</wheelDiameter>
<torque>20</torque>
<commandTopic>cmd_vel</commandTopic>
<odometryTopic>odom</odometryTopic>
<odometryFrame>odom</odometryFrame>
<robotBaseFrame>base_footprint</robotBaseFrame>
</plugin>
</gazebo>
2.摄像头
在gazebo中也可以让机器人的摄像头看到虚拟的环境,将下边的代码放到URDF文件中,“reference”修改成机器人的摄像头link,还有一些分辨率、刷新率、发布的图像主题等等参数。把机器人模型在gazebo中运行起来后,用image_view或者rviz就可以看到机器人在虚拟环境中的视野了。
<!-- camera -->
<gazebo reference="camera_link">
<sensor type="camera" name="camera1">
<update_rate>30.0</update_rate>
<camera name="head">
<horizontal_fov>1.3962634</horizontal_fov>
<image>
<width>800</width>
<height>800</height>
<format>R8G8B8</format>
</image>
<clip>
<near>0.02</near>
<far>300</far>
</clip>
<noise>
<type>gaussian</type>
<!-- Noise is sampled independently per pixel on each frame.
That pixel's noise value is added to each of its color
channels, which at that point lie in the range [0,1]. -->
<mean>0.0</mean>
<stddev>0.007</stddev>
</noise>
</camera>
<plugin name="camera_controller" filename="libgazebo_ros_camera.so">
<alwaysOn>true</alwaysOn>
<updateRate>0.0</updateRate>
<cameraName>rrbot/camera1</cameraName>
<imageTopicName>image_raw</imageTopicName>
<cameraInfoTopicName>camera_info</cameraInfoTopicName>
<frameName>camera_link</frameName>
<hackBaseline>0.07</hackBaseline>
<distortionK1>0.0</distortionK1>
<distortionK2>0.0</distortionK2>
<distortionK3>0.0</distortionK3>
<distortionT1>0.0</distortionT1>
<distortionT2>0.0</distortionT2>
</plugin>
</sensor>
</gazebo>
我们来解释一下这个插件中的参数含义:
<gazebo reference="camera_link">
插件都是用来描述link、joint的,是一种虚无的属性描述,需要关联相应的实体,所以首先我们需要通过reference参数来定义关联的link或者joint。这里我们关联的是camera_link。
<sensor type="camera" name="camera1">
然后声明插件的类型,并为该插件取一个唯一的名称。
<update_rate>30.0</update_rate>
设置摄像头数据更新的最大频率。
<horizontal_fov>1.3962634</horizontal_fov>
<image>
<width>800</width>
<height>800</height>
<format>R8G8B8</format>
</image>
<clip>
<near>0.02</near>
<far>300</far>
</clip>
再来设置一些摄像头相关的参数,尽量让这些仿真的参数与实际使用的硬件相同。
<plugin name="camera_controller" filename="libgazebo_ros_camera.so">
关联摄像头插件,该插件已经在gazebo中实现,所以直接关联即可。
<cameraName>rrbot/camera1</cameraName>
<imageTopicName>image_raw</imageTopicName>
<cameraInfoTopicName>camera_info</cameraInfoTopicName>
<frameName>camera_link</frameName>
声明摄像头发布的消息话题,以及数据所在的参考系。
3.Kinect
Kinect在机器人导航中用的也很多,为机器人的kinect link绑定这个kinect插件,我们就可以在gazebo中进行SLAM、导航了,对于一些初学者,就算没有实体机器人,也可以在仿真器中玩转机器人。
<gazebo>
<plugin name="${link_name}_controller" filename="libgazebo_ros_openni_kinect.so">
<baseline>0.2</baseline>
<alwaysOn>true</alwaysOn>
<updateRate>1.0</updateRate>
<cameraName>${camera_name}_ir</cameraName>
<imageTopicName>/${camera_name}/depth/image_raw</imageTopicName>
<cameraInfoTopicName>/${camera_name}/depth/camera_info</cameraInfoTopicName>
<depthImageTopicName>/${camera_name}/depth/image_raw</depthImageTopicName>
<depthImageInfoTopicName>/${camera_name}/depth/camera_info</depthImageInfoTopicName>
<pointCloudTopicName>/${camera_name}/depth/points</pointCloudTopicName>
<frameName>${frame_name}</frameName>
<pointCloudCutoff>0.5</pointCloudCutoff>
<distortionK1>0.00000001</distortionK1>
<distortionK2>0.00000001</distortionK2>
<distortionK3>0.00000001</distortionK3>
<distortionT1>0.00000001</distortionT1>
<distortionT2>0.00000001</distortionT2>
<CxPrime>0</CxPrime>
<Cx>0</Cx>
<Cy>0</Cy>
<focalLength>0</focalLength>
<hackBaseline>0</hackBaseline>
</plugin>
</gazebo>
4.激光
有没有感叹过激光传感器太贵了!现在不要9999,不要999,只要把激光传感器的插件放到URDF模型中,上万的激光传感器在gazebo里随便用,妈妈再也不用担心玩机器人败家了。
<gazebo reference="hokuyo_link">
<sensor type="ray" name="head_hokuyo_sensor">
<pose>0 0 0 0 0 0</pose>
<visualize>false</visualize>
<update_rate>40</update_rate>
<ray>
<scan>
<horizontal>
<samples>720</samples>
<resolution>1</resolution>
<min_angle>-1.570796</min_angle>
<max_angle>1.570796</max_angle>
</horizontal>
</scan>
<range>
<min>0.10</min>
<max>30.0</max>
<resolution>0.01</resolution>
</range>
<noise>
<type>gaussian</type>
<!-- Noise parameters based on published spec for Hokuyo laser
achieving "+-30mm" accuracy at range < 10m. A mean of 0.0m and
stddev of 0.01m will put 99.7% of samples within 0.03m of the true
reading. -->
<mean>0.0</mean>
<stddev>0.01</stddev>
</noise>
</ray>
<plugin name="gazebo_ros_head_hokuyo_controller" filename="libgazebo_ros_laser.so">
<topicName>/rrbot/laser/scan</topicName>
<frameName>hokuyo_link</frameName>
</plugin>
</sensor>
</gazebo>
当然,实践是第一要义,这些插件用起来效果到底怎么样,还得你上手来试试。ROS中的很多机器人也提供了gazebo中仿真的模型和实验的案例,如果你还不太明白,直接运行这些已有的模型,看看别人写的代码,理解会更快。这里,推荐一个husky机器人的案例,可以在gazebo中SLAM和自主导航。
husky机器人的主页是http://wiki.ros.org/Robots/Husky,仿真案例在Demo Applications那里。
参考链接:
http://gazebosim.org/tutorials?tut=ros_gzplugins
http://wiki.ros.org/Robots/Husky