ROS小车研究笔记:二维SLAM建图简介与源码分析

  • Post author:
  • Post category:其他


ROS提供了现成的各类建图算法实现。如果只是应用的话不需要了解详细算法原理,只需要了解其需要的输入输出即可。

1 Gmapping

Gmapping使用粒子滤波算法进行建图,在小场景下准确度高,但是在大场地中会导致较大计算量和内存需求

Gmapping需要机器人提供深度信息,IMU信息,和里程计信息这三个中至少两个。利用这些输入信息gmapping算法可以输出栅格地图即小车在地图中定位

在这里插入图片描述

Gmapping订阅话题tf和scan。tf话题包含激光雷达和机器人基坐标系位置关系,scan包含激光雷达信息和IMU加速度信息。Gmapping可以通过话题和服务两种方式发布地图信息。其中map话题发布实时地图栅格数据,而服务dynamic_map只有在客户端发布请求是才会发布最新地图,相对于话题可以节省通信开支

在这里插入图片描述

对于odom里程计信息,Gmapping不用话题获取,而是通过TF树进行维护。其中 -> base_link为激光雷达相对base_link(默认的机器人基坐标系)位置,这一值一般为静态,在小车模型文件中定义好。

base_link ->odom为机器人位置相对于里程计原点坐标。其中odom坐标系位置为小车开始运行时里程计位置。通过速度积分得到base_link和odom的距离即可得到小车里程信息

map->odom 为地图中机器人位置关于里程计坐标。这里map和odom都为1不同的参考坐标系,odom是里程计测得的位置坐标,依靠小车自身移动速度积分得到,map为激光雷达测得的小车在地图上位置坐标。两者坐标系差距即为里程计的偏移

小车源码:

1 mapping.launch 启动建图的launch文件(只保留和gmapping相关内容)

<launch>
  <arg name="mapping_mode"  default="gmapping" doc="opt: gmapping,hector,cartographer,karto"/>


  <!-- turn on lidar开启雷达  -->
  <include file="$(find turn_on_wheeltec_robot)/launch/wheeltec_lidar.launch" />

  <!-- 开启gmapping建图算法  -->
  <group if="$(eval mapping_mode == 'gmapping')">
  <include file="$(find turn_on_wheeltec_robot)/launch/include/algorithm_gmapping.launch" />
  <!-- 开启机器人底层相关节点  -->
  <include file="$(find turn_on_wheeltec_robot)/launch/turn_on_wheeltec_robot.launch">
    <arg name="navigation" value="$(arg navigation)"/>
    <arg name="is_cartographer" value="false"/>
    <arg name="odom_frame_id"   value="$(arg odom_frame_id)"/>
  </include>
  </group>
</launch>

这里我们可以看到在开启gmapping 建图算法中,我们启动了文件turn_on_wheeltec_robot/launch/include/algorithm_gmapping.launch

该文件内容如下:

 
<launch>
  <arg name="scan_topic"  default="scan" />
  <arg name="base_frame"  default="base_footprint"/>
  <arg name="odom_frame"  default="odom_combined"/>

  <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)"/>
    <param name="map_update_interval" value="0.01"/>
    <param name="maxUrange" value="9.0"/>
    <param name="maxRange" value="10.0"/>
    <param name="sigma" value="0.05"/>
    <param name="kernelSize" value="3"/>
    <param name="lstep" value="0.05"/>
    <param name="astep" value="0.05"/>
    <param name="iterations" value="5"/>
    <param name="lsigma" value="0.075"/>
    <param name="ogain" value="3.0"/>
    <param name="lskip" value="0"/>
    <param name="minimumScore" value="30"/>
    <param name="srr" value="0.01"/>
    <param name="srt" value="0.02"/>
    <param name="str" value="0.01"/>
    <param name="stt" value="0.02"/>
    <param name="linearUpdate" value="0.02"/>
    <param name="angularUpdate" value="0.02"/>
    <param name="temporalUpdate" value="-1.0"/>
    <param name="resampleThreshold" value="0.25"/>
    <param name="particles" value="8"/>

    <param name="xmin" value="-5.0"/>
    <param name="ymin" value="-4.0"/>
    <param name="xmax" value="5.0"/>
    <param name="ymax" value="4.0"/>

    <param name="delta" value="0.05"/>
    <param name="llsamplerange" value="0.01"/>
    <param name="llsamplestep" value="0.01"/>
    <param name="lasamplerange" value="0.005"/>
    <param name="lasamplestep" value="0.005"/>
    <remap from="scan" to="$(arg scan_topic)"/>
  </node>
</launch>
  

这里有大量和gmapping算法本身的参数,如果不了解算法底层原理可以直接使用默认值。我们可以对这些参数进行调优以使用不同应用场景

里程计tf坐标发布

(代码位置/turn_on_wheeltec_robot/launch/turn_on_wheeltec_robot.launch)

  <!-- 发布用于建图、导航的TF关系与小车外形可视化 -->
  <include file="$(find turn_on_wheeltec_robot)/launch/robot_model_visualization.launch" unless="$(arg repeat)">
    <arg name="car_mode" value="$(arg car_mode)"/>
    <arg name="if_voice" value="$(arg if_voice)"/>
  </include>

  <!-- 扩张卡尔曼滤波 发布odom_combined到footprint的TF,即小车定位 使用cartographer算法时不使用该滤波算法-->
  <include file="$(find turn_on_wheeltec_robot)/launch/include/robot_pose_ekf.launch" unless="$(arg repeat)">
    <arg name="is_cartographer" value="$(arg is_cartographer)"/>
  </include>
 </launch>

这里涉及到的robot_pose_ekf节点是ros中常用的卡尔曼滤波算法,用于对里程计坐标信息进去预处理以提高精度

2 Cartographer

Cartographer相比于Gmapping更适用于大场地的建图。其包含回环检测可以防止累积误差。并且Cartographer只依靠雷达建图,不需要里程计

Cartographer检测步骤分为两步,local scan和global scan。其中local scan为雷达实时检测,而global scan将local scan的检测结果汇总,进行回环检测,以减小地图误差



版权声明:本文为Raine_Yang原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。