Turtlebot眼中的世界
在与Turtlebot打招呼的时候,我们已经通过gmapping_demo.launch和amcl_demo.launch演示了建图和导航的demo, 它们都是turtlebot_gazebo包中的launch文件。gmapping是一种常用的开源SLAM算法, ROS为之提供了一个封装(源码)。 amcl是一种使用自适应蒙特卡洛定位方法的2维导航系统。
本文中我们将详细分析这两个launch文件,瞻仰一下地图构建和定位导航的大门,后续还有专题介绍相关的算法。
1. gmapping_demo.launch
下面是gmapping_demo.launch的内容,十分简单,只是根据3D传感器的类型,选择加载对应的launch文件。
<launch>
<arg name="3d_sensor" default="$(env TURTLEBOT_3D_SENSOR)"/> <!-- r200, kinect, asus_xtion_pro -->
<arg name="custom_gmapping_launch_file" default="$(find turtlebot_navigation)/launch/includes/gmapping/$(arg 3d_sensor)_gmapping.launch.xml"/>
<include file="$(arg custom_gmapping_launch_file)"/>
</launch>
它定义了两个参数,3d_sensor用于指示3D传感器,默认值由环境变量TURTLEBOT_3D_SENSOR,通过如下指令可以查看变量为asus_xtion_pro。 在分析Turtlebot的描述模型的时候我们分明看到装在Turtlebot上的是kinect啊,这里怎么就变成了asus_xtion_pro。
$ env | grep TURTLEBOT_3D_SENSOR
TURTLEBOT_3D_SENSOR=asus_xtion_pro
第二个参数custom_gmapping_launch_file指示了实际运行Gmapping的launch文件,按照默认参数所指的路径我们找到了turtlebot_navigation包中关于gmapping的launch文件目录。 我们看到了将要加载的asus_xtion_pro_gmapping.launch.xml,和kinect配置下的launch文件。经过diff工具对比发现两者完全一样,所以我们也就不再追究为什么是asus_xtion_pro了。
$ roscd turtlebot_navigation/launch/includes/gmapping/
$ ls
astra_gmapping.launch.xml gmapping.launch.xml
asus_xtion_pro_gmapping.launch.xml kinect_gmapping.launch.xml
asus_xtion_pro_offset_gmapping.launch.xml r200_gmapping.launch.xml
在asus_xtion_pro_gmapping.launch.xml文件中首先定义了三个参数scan_topic,base_frame和odom_frame。这三个参数将在未来创建ROS运行节点时用于配置系统运行参数。
<launch>
<arg name="scan_topic" default="scan" />
<arg name="base_frame" default="base_footprint"/>
<arg name="odom_frame" default="odom"/>
在接下来的内容中,只有一个主题,就是运行gmapping包中的slam_gmapping节点。同时还定义了很多运行时的参数param,在下面的代码片段中省略了大部分, 只留下了与launch文件加载时的参数arg相关的三个,体现arg在launch文件中的作用。
<node pkg="gmapping" type="slam_gmapping" name="slam_gmapping" output="screen">
<param name="base_frame" value="$(arg base_frame)"/>
<param name="odom_frame" value="$(arg odom_frame)"/>
<!-- 还有很多参数,因为篇幅关系这里省略之... -->
<remap from="scan" to="$(arg scan_topic)"/>
</node>
</launch>
2. amcl_demo.launch
下面是amcl_demo.launch的内容,一开始先定义了两个参数map_file和3d_sensor。3d_sensor就不用多讲了,跟gmapping_demo.launch的一样。map_file是进行机器人导航的基础, 它指定了机器人运行的地图文件。
<launch>
<arg name="map_file" default="$(env TURTLEBOT_GAZEBO_MAP_FILE)"/>
<arg name="3d_sensor" default="$(env TURTLEBOT_3D_SENSOR)"/> <!-- r200, kinect, asus_xtion_pro -->
接着建立一个地图服务器。map_server是ROS的一个地图服务器工具包,它以Service的形式提供地图数据。并且提供map_saver工具, 用于保存动态建立的地图到指定文件中。这里以输入参数"map_file"作为服务的地图。
<node name="map_server" pkg="map_server" type="map_server" args="$(arg map_file)" />
然后创建了三个参数描述初始位置,并且使用和gmapping_demo.launch类似的套路用一个输入参数来指示实际的导航launch文件。虽然按照代码中的路径描述和参数3d_sensor的设置, 应当使用的是asus_xtion_pro_amcl.launch.xml,但在源代码中这个文件实际上是一个指向amcl.launch.xml的软链接,所以实际加载的是amcl.launch.xml。
<arg name="initial_pose_x" default="0.0"/>
<arg name="initial_pose_y" default="0.0"/>
<arg name="initial_pose_a" default="0.0"/>
<arg name="custom_amcl_launch_file" default="$(find turtlebot_navigation)/launch/includes/amcl/$(arg 3d_sensor)_amcl.launch.xml"/>
接下来用刚刚定义的四个输入参数,加载实际的导航demo。
<include file="$(arg custom_amcl_launch_file)">
<arg name="initial_pose_x" value="$(arg initial_pose_x)"/>
<arg name="initial_pose_y" value="$(arg initial_pose_y)"/>
<arg name="initial_pose_a" value="$(arg initial_pose_a)"/>
</include>
最后,加载一个底盘的控制launch文件。
<include file="$(find turtlebot_navigation)/launch/includes/move_base.launch.xml"/>
</launch>
在上面的amcl_demo.launch文件中除了加载运行了一个map_server的节点之外,还导入了两个launch文件。 amcl.launch.xml的内容很简单,就是定义了一些输入参数,并根据这些参数运行amcl节点。其内容大体如下不再做详细的解释。
<launch>
<!-- 定义了各种输入参数arg,省略之 -->
<node pkg="amcl" type="amcl" name="amcl">
<!-- 定义了各种运行参数param,省略之 -->
</node>
</launch>
move_base.launch.xml的内容就相对复杂了一点,这个launch文件主要是加载了一个move_base的节点。 这个节点提供了一个action,用于控制底盘运动到世界中的指定地点上。在文件的一开始就导入了两个launch文件,分别用于平滑速度以及安全驾驶。
然后定义了一堆输入参数arg,用于在运行move_base节点的时候设置各种id和主题名称。紧接着就加载运行了move_base节点,在该节点中导入了很多参数文件,也定义了很多运行参数。 具体的参数内容我们不再赘述了。
<launch>
<include file="$(find turtlebot_navigation)/launch/includes/velocity_smoother.launch.xml"/>
<include file="$(find turtlebot_navigation)/launch/includes/safety_controller.launch.xml"/>
<!-- 定义了各种输入参数arg,省略之 -->
<node pkg="move_base" type="move_base" respawn="false" name="move_base" output="screen">
<!-- 导入了各种yaml文件,定义了各种运行参数param,省略之 -->
</node>
</launch>
下面是用于平滑速度的velocity_smoother.launch.xml文件内容,它是一个nodelet。
<launch>
<node pkg="nodelet" type="nodelet" name="navigation_velocity_smoother" args="load yocs_velocity_smoother/VelocitySmootherNodelet mobile_base_nodelet_manager">
<rosparam file="$(find turtlebot_bringup)/param/defaults/smoother.yaml" command="load"/>
<remap from="navigation_velocity_smoother/smooth_cmd_vel" to="cmd_vel_mux/input/navi"/>
<!-- Robot velocity feedbacks; use the default base configuration -->
<remap from="navigation_velocity_smoother/odometry" to="odom"/>
<remap from="navigation_velocity_smoother/robot_cmd_vel" to="mobile_base/commands/velocity"/>
</node>
</launch>
下面是Kobuki底盘的安全驾驶仪,内容如下:
<launch>
<node pkg="nodelet" type="nodelet" name="kobuki_safety_controller" args="load kobuki_safety_controller/SafetyControllerNodelet mobile_base_nodelet_manager">
<remap from="kobuki_safety_controller/cmd_vel" to="cmd_vel_mux/input/safety_controller"/>
<remap from="kobuki_safety_controller/events/bumper" to="mobile_base/events/bumper"/>
<remap from="kobuki_safety_controller/events/cliff" to="mobile_base/events/cliff"/>
<remap from="kobuki_safety_controller/events/wheel_drop" to="mobile_base/events/wheel_drop"/>
</node>
</launch>