Turtlebot的描述模型
建立机器人模型应该是进行仿真的第一步工作,因为它将是我们以后开发算法的控制对象。本文中将详细分析Turtlebot的描述模型,以及相关描述文件的组织方式。
在召唤Turtlebot一文中, 会看到我们打招呼的Turtlebot的模型被保存在turtlebot_description中robots子目录下的kobuki_hexagons_kinect.urdf.xacro文件中。
$ roscd turtlebot_description/robots/
$ ls | grep kobuki_hexagons_kinect.urdf.xacro
kobuki_hexagons_kinect.urdf.xacro
这个是一个Xacro文件,内容很简单,首先申明了机器人的名称,并告知使用了xacro技术。
<?xml version="1.0"?>
<robot name="turtlebot" xmlns:xacro="http://ros.org/wiki/xacro">
接着通过xacro引入了机器人的基本配置,以及底盘kobuki、六边形托盘和双目摄像头kinect的模型描述。
<xacro:include filename="$(find turtlebot_description)/urdf/turtlebot_common_library.urdf.xacro" />
<xacro:include filename="$(find kobuki_description)/urdf/kobuki.urdf.xacro" />
<xacro:include filename="$(find turtlebot_description)/urdf/stacks/hexagons.urdf.xacro"/>
<xacro:include filename="$(find turtlebot_description)/urdf/sensors/kinect.urdf.xacro"/>
"turtlebot_common_library.urdf.xacro"并没有什么特别之处,它只是定义了圆周率常量M_PI,和不同颜色的材料属性。"hexagons.urdf.xacro"描述了托盘的结构, 所有的关节都是fixed,没有可以移动的部分也没有传感器。"kobuki.urdf.xacro"描述的是底盘的构造,它有需要控制的轮子,和陀螺仪等传感器。 "kinect.urdf.xacro"则是双目摄像头的模型。在后续的内容中,我们将详细介绍底盘和Kinect的建模方法以及引入的Gazebo插件。
上面的四个文件都用xacro描述的,可以说是底盘、托盘和双目摄像头的定义,下面则是对它们的实例化。其中"stack_hexagons"和"sensor_kinect"都有一个parent的属性, 其值为"base_link",后面我们会看到它指的是kobuki的基座。
<kobuki/>
<stack_hexagons parent="base_link"/>
<sensor_kinect parent="base_link"/>
</robot>
1. kobuki.urdf.xacro

kobuki是Turtlebot默认使用的底盘,它有一套独立的以kobuki_为前缀的技术栈。与turtlebot_description类似,kobuki_description中保存了底盘kobuki的模型描述。 右图是折叠后的kobuki.urdf.xacro,总体上可以分为common_properties, kobuki_gazebo和kobuki三个部分。
首先,通过xacro:include引入了描述文件common_properties.urdf.xacro,它与刚刚提到的turtlebot_common_library.urdf.xacro一样定义了圆周率常量,和各种不同颜色的材料属性,没什么特别之处。
然后,引入了描述文件kobuki_gazebo.urdf.xacro,它是对kobuki的仿真配置,在其中描述了各个关节的摩擦系数、控制率。还添加了碰撞、防跌落、陀螺仪等各种控制器。 关键是添加了控制kobuki的插件。后续将详细讨论这个文件。
最后,定义了kobki的模型,由5个部分构成:基座base_link、左轮wheel_left_link、右轮wheel_right_link、前万向轮caster_front_link、后万向轮caster_front_link。 此外还指定了陀螺仪gyro_link、防跌落传感器cliff_sensor_xxx_link的惯性属性。模型中的各个joint标签则描述了各个link的相对关系,传感器和各种轮子都安装在基座上base_link。 其中由于左右轮需要转动,所以它们的类型是"continuous",其余则都是"fixed"类型的关节。此外,kobuki模型中还定义了一个base_footprint的虚拟部件, 基座通过base_joint连接在这个虚拟部件上。这样做主要是为了方便地表示机器人在仿真世界中的移动。
2. kobuki_gazebo.urdf.xacro

右图是折叠之后的kobuki_gazebo.urdf.xacro文件,它为kobuki中除base_footprint外的所有link都添加了一个gazebo标签。其中左右轮和前后万向轮的内容类似, 定义了摩擦系数,碰撞刚度和阻尼系数,碰撞深度和速度等参数。
<gazebo reference="wheel_left_link">
<mu1>1.0</mu1>
<mu2>1.0</mu2>
<kp>1000000.0</kp>
<kd>100.0</kd>
<minDepth>0.001</minDepth>
<maxVel>1.0</maxVel>
</gazebo>
"base_link"中除了定义了两个摩擦系数外,还添加了一个碰撞传感器,称之为bumper,它用于检测物体之间是否接触上了。
这个传感器使用的是Gazebo原生的传感器模型,
它实际上是Gazebo中的一个SDF标签。这个标签的属性type指定了传感器的类型,这里是contact;
属性name则是为了给传感器一个唯一的名称。其子标签always_on表示传感器是否需要总是按照更新频率更新数据;update_rate子标签则指示了传感器的更新频率;
visualize子标签则说明是否在GUI上显示;contact子标签则是对碰撞传感器类型的设置,其子标签collision指定一个用作碰撞传感器的link。
<gazebo reference="base_link">
<mu1>0.3</mu1>
<mu2>0.3</mu2>
<sensor type="contact" name="bumpers">
<always_on>1</always_on>
<update_rate>50.0</update_rate>
<visualize>true</visualize>
<contact>
<collision>base_footprint_fixed_joint_lump__base_collision</collision>
</contact>
</sensor>
</gazebo>
kobuki有三个防跌落传感器分别位于前、左、右,它们都使用激光传感器ray。
我们已经在用SDF文件模拟激光雷达一文中介绍过这个传感器了,这里不再详细解释。与碰撞传感器类似,
gyro_link关联了一个imu类型的传感器,它也是一个SDF标签。最后引入了一个控制器插件,
这是kobuki_gazebo_plugins包中的一个用C++写的库。
在Kobuki控制插件一文中详细解释之。
3. kinect.urdf.xacro

右图为折叠后的kinect.urdf.xacro文件,它引入了两个xacro文件。其中,turtlebot_gazebo.urdf.xacro为turtlebot添加了深度摄像头的传感器, 并植入了kinect的控制插件。turtlebot_properties.urdf.xacro文件定义了一些关于kinect的参数。此外定义了参数kinect_cam_py和sensor_kinect的模型。
在turtlebot_properties.urdf.xacro中定义了cam_px, cam_pz, cam_or, cam_op, cam_oy定义了传感器的安装位置和方向。在源文件中还注释了cam_py的定义, 取而代之的是在kinect.urdf.xacro中定义的kinect_cam_py。
turtlebot_gazebo.urdf.xacro的内容如下。定义了一个"depth"类型的传感器,并在它的子标签中定义了水平视角horizontal_fov为60°, 图像格式为B8G8R8,640×480的像素,以及远近裁剪面。最后添加kinect控制器插件, libgazebo_ros_openni_kinect.so是gazebo_plugins包中的一个动态库。
<gazebo reference="camera_link">
<sensor type="depth" name="camera">
<always_on>true</always_on>
<update_rate>20.0</update_rate>
<camera>
<horizontal_fov>${60.0*M_PI/180.0}</horizontal_fov>
<image>
<format>B8G8R8</format>
<width>640</width>
<height>480</height>
</image>
<clip>
<near>0.05</near>
<far>8.0</far>
</clip>
</camera>
<plugin name="kinect_camera_controller" filename="libgazebo_ros_openni_kinect.so">
<cameraName>camera</cameraName>
<alwaysOn>true</alwaysOn>
<updateRate>10</updateRate>
<imageTopicName>rgb/image_raw</imageTopicName>
<depthImageTopicName>depth/image_raw</depthImageTopicName>
<pointCloudTopicName>depth/points</pointCloudTopicName>
<cameraInfoTopicName>rgb/camera_info</cameraInfoTopicName>
<depthImageCameraInfoTopicName>depth/camera_info</depthImageCameraInfoTopicName>
<frameName>camera_depth_optical_frame</frameName>
<baseline>0.1</baseline>
<distortion_k1>0.0</distortion_k1>
<distortion_k2>0.0</distortion_k2>
<distortion_k3>0.0</distortion_k3>
<distortion_t1>0.0</distortion_t1>
<distortion_t2>0.0</distortion_t2>
<pointCloudCutoff>0.4</pointCloudCutoff>
</plugin>
</sensor>
</gazebo>
4. 总结
我们所研究的Turtlebot由三个部分构成:底盘、托盘和3D传感器。
其中底盘由基座、左轮、右轮、前万向轮、后万向轮5个部分构成,并且安装了防跌落、防碰撞的传感器。为了方便在ROS环境中获取底盘的状态、控制底盘,引入了一个kobuki_controller的控制插件。
托盘则没有什么特别之处,都是各种固定的连接。3D传感器则选用的是Kinect,同样的也引入了一个kinect_camera_controller的插件。我们将在后续的文章中介绍这两个插件。