首页 关于
树枝想去撕裂天空 / 却只戳了几个微小的窟窿 / 它透出天外的光亮 / 人们把它叫做月亮和星星
目录

amcl_demo之机器人定位器——amcl

amcl_demo的launch文件中,通过如下的形式开启了节点amcl。 首先根据系统环境变量"TURTLEBOT_3D_SENSOR"指定用于定位的传感器,并根据该传感器设定加载amcl的launch文件。此外还定义了关于初始位姿的三个参数"initial_pose_x", "initial_pose_y"和"initial_pose_a"。

    <arg name="3d_sensor" default="$(env TURTLEBOT_3D_SENSOR)"/>
    <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"/>
有了这些参数之后,我们就可以加载实际的定位器了。
    <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>

通过如下的指令,我们可以查询到定位使用的传感器是asus_xtion_pro。对应的,我们需要加载的amcl的launch文件是asus_xtion_pro_amcl.launch.xml, 但在源代码中这个文件实际上是一个指向amcl.launch.xml的软链接,所以实际加载的是amcl.launch.xml。

    $ env | grep TURTLEBOT_3D_SENSOR
    TURTLEBOT_3D_SENSOR=asus_xtion_pro

1. amcl.launch.xml

amcl.launch.xml是实际运行节点amcl的脚本, 在一开始,定义了一堆参数。"use_map_topic"是ROS导航栈在1.4.2版本新增的功能,amcl将订阅一个map主题来接收地图数据。否则通过请求map_server的服务来获取地图数据。 "scan_topic"则是激光传感器的扫描数据主题。"initial_pose_x(y)"分别是机器人的初始位置,"initial_pose_a"则是机器人的初始方向角。 "odom_frame_id", "base_frame_id"和"global_frame_id"分别是用于定位的里程计坐标系、底盘坐标系、地图坐标系。

        <arg name="use_map_topic"   default="false"/>
        <arg name="scan_topic"      default="scan"/> 
        <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="odom_frame_id"   default="odom"/>
        <arg name="base_frame_id"   default="base_footprint"/>
        <arg name="global_frame_id" default="map"/>

然后我们开启amcl节点,在开启的过程中定义了各种运行参数。在代码片段中我们将之省略了, 下面我们翻译官方Wiki中对这些参数的解释。

        <node pkg="amcl" type="amcl" name="amcl">
            <!-- 定义了各种运行参数param,省略之 -->
        </node>

总体上节点amcl的参数可以分为三大类:粒子滤波器配置、激光雷达模型和里程计模型。

表1 粒子滤波配置

参数名称 数据类型 默认值 说明
~min_particles int 100 粒子滤波器使用的最小粒子数量。
~max_particles int 5000 粒子滤波器使用的最大粒子数量。
~kld_err double 0.01 真实分布与估计分布之间的最大误差。
~kld_z double 0.99 上标准分位数(1-p),其中p是估计分布上误差小于kld_err的概率。
~update_min_d double 0.2m 执行一次滤波器更新所需的最小位移。
~update_min_a double \(\frac{\pi}{6}\) 执行一次滤波器更新所需的最小转角。
~resample_interval int 2 重采样间隔,即至少进行了~resample_interval次的滤波器更新之后,才能进行一次重采样。
~transform_tolerance double 0.1s 推迟发布坐标变换的时间,to indicate that this transform is valid into the future
~recovery_alpha_slow double 0.0(disabled) 慢速平均权重滤波器(slow average weight filter)的指数衰减速率,用于确定添加随机位姿的时机,以达到recover的目的。一般可以取0.001。
~recovery_alpha_fast double 0.0(disabled) 快速平均权重滤波器(fast average weight filter)的指数衰减速率,用于确定添加随机位姿的时机,以达到recover的目的。一般可以取0.1。
~initial_pose_x double 0.0 初始位姿中心的x分量,用作初始位姿的高斯分布的均值。
~initial_pose_y double 0.0 初始位姿中心的y分量,用作初始位姿的高斯分布的均值。
~initial_pose_a double 0.0 初始方向角,用作初始位姿的高斯分布的均值。
~initial_cov_xx double 0.5 * 0.5 初始位姿方差(x*x),用作初始位姿的高斯分布的协方差矩阵。
~initial_cov_yy double 0.5 * 0.5 初始位姿方差(y*y),用作初始位姿的高斯分布的协方差矩阵。
~initial_cov_aa double \(\frac{\pi}{12}×\frac{\pi}{12}\) 初始方向角方差(a*a),用作初始位姿的高斯分布的协方差矩阵。
~gui_publish_rate double -1Hz(disabled) 发布扫描数据和路径到可视化界面的最大频率,-1关闭此功能。
~save_pose_rate double 0.5Hz 保存最近一次估计的位姿和协方差到参数服务器中的最大频率,即修改~initial_pos_*和~intial_cov*。-1关闭此功能。
~use_map_topic bool false 该参数为真时,amcl将订阅一个map主题来接收地图数据。否则通过请求map_server的服务来获取地图数据。
~first_map_only bool false 该参数为真时,amcl将只使用所订阅主题的第一帧地图数据进行定位,而不再更新地图。

表2 雷达模型配置

参数名称 数据类型 默认值 说明
~laser_min_range double -1.0 激光扫描的最小距离,该值为-1时,amcl将使用激光传感器上报数据中的最小值。
~laser_max_range double -1.0 激光扫描的最大距离,该值为-1时,amcl将使用激光传感器上报数据中的最大值。
~laser_max_beams double 30.0 更新滤波器的时候,使用激光扫描束的间隔。一方面可以减少计算量,另一方面也是因为临近的激光数据之间也不是独立的。
~laser_z_hit double 0.95 传感器模型中的z_hit部分的混合权重。
~laser_z_short double 0.1 传感器模型中的z_short部分的混合权重。
~laser_z_max double 0.05 传感器模型中的z_max部分的混合权重。
~laser_z_rand double 0.05 传感器模型中的z_rand部分的混合权重。
~laser_sigma_hit double 0.2m z_hit部分的高斯标准差。
~laser_lambda_short double 0.1 z_short部分的指数衰减系数。
~laser_likelihood_max_dist double 2.0m 似然场模型中,对障碍物膨胀的最大距离。
~laser_model_type string "likelihood_field" 激光传感器模型,可以是"beam"、"likelihood_field"、"likelihood_field_prob"。

表3 里程计模型配置

参数名称 数据类型 默认值 说明
~odom_model_type string diff 里程计模型类型,可以是"diff"、"omni"、"diff-corrected"、"omni-corrected"。
~odom_alpha1 double 0.2 机器人运动模型中,旋转部分的旋转期望噪声。
~odom_alpha2 double 0.2 机器人运动模型的平移部分的旋转期望噪声。
~odom_alpha3 double 0.2 机器人运动模型的平移部分的平移期望噪声。
~odom_alpha4 double 0.2 机器人运动模型的旋转部分的平移期望噪声。
~odom_alpha5 double 0.2 平移相关的噪声参数(只适用于"omni"类型的里程计)。
~odom_frame_id string "odom" 里程计坐标系。
~base_frame_id string "base_link" 机器人底盘坐标系。
~global_frame_id string "map" 定位系统的全局坐标系。
~tf_broadcast bool true 设置为false,将不发布从全局坐标到里程计坐标的变换关系。

2. amcl运行分析

我们分别在三个终端中运行如下的指令,依次开启Gazebo仿真环境,运行amcl_demo,打开可视化界面rviz,详细可以参见Turtlebot你好!

        $ roslaunch turtlebot_gazebo turtlebot_world.launch
        $ roslaunch turtlebot_gazebo amcl_demo.launch
        $ roslaunch turtlebot_rviz_launchers view_navigation.launch

通过工具rosnode,我们可以查看节点amcl的运行状态。下面的日志片段描述了amcl发布的主题。

        $ rosnode info /amcl
        --------------------------------------------------------------------------------
        Node [/amcl]
        Publications: 
         * /amcl/parameter_descriptions [dynamic_reconfigure/ConfigDescription]
         * /amcl/parameter_updates [dynamic_reconfigure/Config]
         * /amcl_pose [geometry_msgs/PoseWithCovarianceStamped]
         * /diagnostics [diagnostic_msgs/DiagnosticArray]
         * /particlecloud [geometry_msgs/PoseArray]
         * /rosout [rosgraph_msgs/Log]
         * /tf [tf2_msgs/TFMessage]

其中主题"/amcl/parameter_descriptions"和"/amcl/parameter_updates"是两个用于动态配置节点运行参数的主题。在我们的示例环境中,这两个主题没有订阅者,与amcl的定位算法无关,不再展开。

主题"/amcl_pose"是amcl的输出, 它以[geometry_msgs/PoseWithCovarianceStamped]的消息形式发布带有协方差信息的机器人位姿。 这个消息类型大体上可以分为三个字段:"header"是一个通用的消息头,它为每条消息打上了一个时间戳和坐标系。"pose"记录了笛卡尔坐标系下的xyz三轴坐标,并用四元数的方式记录了机器人的姿态。 "covariance"是一个\(6 \times 6\)的协方差矩阵。

主题"/diagnostics"和"/rosout"都与日志和调试相关,不再描述。

"/particlecloud"主题输出的是amcl算法的粒子位姿。右图是对rviz的截图,机器人周围的绿色箭头就是rviz接收到的"/particlecloud"的消息的可视化。每个箭头对应着一个粒子,箭头的方向是粒子的朝向, 位置则是粒子的位置。amcl以参数"initial_pose_x", "initial_pose_y"和"initial_pose_a"为中心,按照正态分布的形式初始化粒子位姿。系统刚开始运行的时候,粒子分布比较松散。 随着机器人运动,我们将可以看到粒子集合逐渐收敛。

主题"/tf"用于描述系统的坐标变换关系。

下面的日志片段列举了amcl订阅的主题。其中"/clock"是gazebo仿真的时钟系统,"/tf"和"/tf_static"描述了坐标变换关系,"/scan"则是激光传感器的扫描数据, "initialpose"是用于重新初始化amcl的粒子位姿的主题。

        Subscriptions: 
         * /clock [rosgraph_msgs/Clock]
         * /initialpose [geometry_msgs/PoseWithCovarianceStamped]
         * /scan [sensor_msgs/LaserScan]
         * /tf [tf2_msgs/TFMessage]
         * /tf_static [tf2_msgs/TFMessage]

下面的日志片段则列举了amcl提供的服务。其中"/amcl/get_loggers"和"/amcl/set_logger_level"与系统日志等级有关,"/amcl/set_parameters"看字面意思就是用来设定运行参数的。

        Services: 
         * /amcl/get_loggers
         * /amcl/set_logger_level
         * /amcl/set_parameters
         * /global_localization
         * /request_nomotion_update
         * /set_map

服务"/global_localization"是一个用于全局定位的服务。当调用该服务之后,amcl将把所有的粒子散布在地图中的空闲空间中,并开始全局定位。"request_nomotion_update"用于手动更新粒子并发布。 "/set_map"用于手动设定新的地图和位姿。

3. 完

amcl在acml_demo中扮演了机器人定位器的角色。它订阅了"/scan"和"/tf"来获取激光传感器的参数和里程计的坐标变换,通过主题"/map"获取环境地图。使用粒子滤波的方式进行机器人定位, 并通过主题"/amcl_pose"和"/particlecloud"发布对机器人位姿的估计以及粒子的位姿。




Copyright @ 高乙超. All Rights Reserved. 京ICP备16033081号-1