4. SLAM建图基础

在ROS2 Nav2自主移动机器人导航系统中,SLAM(Simultaneous Localization and Mapping,同步定位与建图)是导航链路的第一环。没有一张质量可靠的静态地图,后续的全局路径规划、代价地图膨胀、AMCL定位都将失去参照基准。本章聚焦三种主流2D激光SLAM算法——Gmapping、Cartographer、SLAM Toolbox,从原理差异、适用场景、建图流程到参数调优逐一拆解,帮助你在实际机器人平台上做出正确选型并产出可用地图。

2D激光SLAM算法选型与建图链路 输入数据 /scan 激光话题 /odom 里程计 /tf 坐标变换 Gmapping RBPF粒子滤波 小场景/低算力 需里程计 无回环检测 Cartographer 图优化+子图 大场景/回环 可无里程计 算力要求高 SLAM Toolbox 基于Gmapping改进 支持序列化地图 ROS2原生 轻量级 建图输出 /map 栅格地图话题 → map_server 保存为 pgm/yaml 占用概率栅格:free(0) / occupied(100) / unknown(-1) 参数调优关键点 激光帧率/里程计精度/粒子数/最小匹配得分/子图大小 地图分辨率/更新频率/传感器外参标定

4.1 三种SLAM算法的核心原理与对比

Gmapping基于Rao-Blackwellized粒子滤波(RBPF),核心思想是用一组粒子表示机器人位姿的后验分布,每个粒子携带一张独立的栅格地图。随着粒子数量增加,地图精度提升,但计算量线性增长。Gmapping对里程计依赖较强,因为粒子滤波的提议分布通常由里程计运动模型给出,若里程计误差过大,粒子退化严重,地图会出现重影或错位。它没有显式的回环检测机制,因此在大场景或长时间建图时,累积误差无法消除。

Cartographer采用图优化框架,将激光扫描匹配结果作为约束,构建位姿图(Pose Graph)。它内部维护多个子图(Submap),每个子图由一定数量的激光帧构成,当新的扫描帧与子图匹配成功后,会插入子图并更新约束。Cartographer的核心优势在于回环检测——当机器人回到已探索区域时,通过分支定界(Branch and Bound)搜索算法快速找到历史匹配,从而消除累积漂移。它可以在没有里程计的情况下仅靠激光数据运行(纯2D SLAM模式),但需要较高的CPU算力。

SLAM Toolbox是ROS2社区专门为Nav2开发的建图工具,它继承了Gmapping的粒子滤波思想,但做了大量工程化改进:支持地图的序列化与反序列化(保存/加载.pbstream文件)、支持建图过程中的地图实时更新、提供更灵活的配置参数。SLAM Toolbox在中小场景下精度与Gmapping相当,但API设计更贴合ROS2生命周期节点,且支持在运行中动态调整参数,适合需要频繁迭代地图的调试场景。

对比维度GmappingCartographerSLAM Toolbox
核心算法RBPF粒子滤波图优化+子图匹配粒子滤波(改进)
回环检测无有(分支定界)无(依赖前端)
里程计依赖强依赖弱依赖(可纯激光)中等依赖
CPU占用低高低-中
地图精度(大场景)较差(累积漂移)优秀(回环修正)中等
ROS2原生支持需移植官方支持官方支持
典型场景50m×50m内室内100m×100m以上或长廊中小场景快速建图
选型判断路径:若你的机器人是室内轮式底盘,配备2D激光雷达和轮式里程计,建图范围在80m×80m以内,优先选择SLAM Toolbox或Gmapping;若需要建大面积厂房、地下车库或存在回环走廊,直接选择Cartographer;若你的里程计质量差(如全向轮打滑严重),Cartographer的纯激光模式是唯一可靠选择。

4.2 建图流程与关键操作步骤

无论选择哪种算法,建图流程都遵循“数据准备 → 启动SLAM → 控制机器人运动 → 保存地图”的通用框架。但在ROS2中,具体实现有差异。

  1. 数据准备:确认激光雷达话题(如/scan)发布频率≥10Hz,里程计话题(/odom)发布频率≥20Hz,TF树完整(map→odom→base_link→laser)。使用ros2 run tf2_tools view_frames检查TF树。
  2. 启动SLAM节点:以SLAM Toolbox为例,运行ros2 launch slam_toolbox online_async_launch.py,该启动文件会加载slam_toolbox节点并订阅/scan和/tf。Cartographer则使用ros2 launch cartographer_ros cartographer.launch.py。
  3. 控制机器人运动:使用遥控器或teleop_twist_keyboard节点发布/cmd_vel,以0.2-0.4m/s的线速度、0.3-0.5rad/s的角速度移动。运动策略:先绕行环境边界一圈,再以“弓”字形扫描内部区域,最后回到起点附近验证回环。
  4. 保存地图:SLAM Toolbox使用ros2 run slam_toolbox map_saver -f map_name保存pgm和yaml文件;Cartographer使用ros2 run cartographer_ros cartographer_pbstream_to_map -pbstream map.pbstream -resolution 0.05转换格式。
常见误区:很多初学者在启动SLAM后立即快速移动机器人,导致激光帧间位移过大,匹配失败。正确做法是:先原地旋转激光雷达扫描一圈,让算法初始化地图,再缓慢移动。另外,建图过程中不要人为搬动机器人,否则里程计跳变会直接破坏地图。

4.3 参数调优实战:以SLAM Toolbox为例

SLAM Toolbox的核心参数集中在slam_toolbox_params.yaml中,以下参数直接影响建图质量:

slam_toolbox:
  ros__parameters:
    # 激光帧间最小匹配得分,低于此值认为匹配失败
    minimum_travel_distance: 0.1
    minimum_travel_heading: 0.2
    # 粒子滤波相关
    max_laser_range: 12.0
    minimum_time_interval: 0.5
    # 地图更新策略
    map_update_interval: 5.0
    resolution: 0.05
    # 匹配得分阈值
    minimum_score: 0.65
    # 回环搜索半径(米)
    loop_search_space: 8.0

调优步骤:首先调整minimum_score,若建图时频繁出现“Scan Matching Failed”警告,说明阈值过高或激光数据质量差,可降至0.5-0.6;若地图出现错位但无警告,说明阈值过低,应提高至0.7以上。resolution决定地图精细度,0.05m适合室内,0.1m适合室外大场景,但分辨率越高,内存占用越大。map_update_interval控制地图发布频率,建图时建议设为5.0s,避免频繁更新导致Rviz卡顿。

经验值参考:对于10Hz的激光雷达,minimum_travel_distance设为0.15m、minimum_travel_heading设为0.3rad,可保证每帧激光都有足够位移用于匹配,又不至于漏掉关键帧。若你的雷达是20Hz,可适当减小这两个值。

4.4 案例拆解:某仓储机器人建图失败排查

背景:某仓储AGV采用SLAM Toolbox建图,环境为80m×60m的货架区,激光雷达安装高度0.3m,里程计为双轮差速编码器。建图过程中,地图在货架通道处出现“重影”,且机器人回到起点后地图无法闭合。

初始现象:Rviz中地图出现两条平行货架线,间距约0.2m;/diagnostics显示里程计频率正常,但编码器存在轻微打滑。

分析过程:首先检查TF树,发现laser_frame到base_link的静态变换为0.3m,但激光雷达实际安装高度为0.35m,存在5cm的外参误差。其次,货架通道宽度仅1.2m,激光束打到货架底部反光条上产生噪声点。最后,里程计在AGV急转弯时打滑,导致粒子滤波退化。

操作步骤:①重新标定激光雷达安装高度,更新tf变换;②在slam_toolbox参数中增加scan_buffer_size: 100,扩大扫描匹配的搜索窗口;③将minimum_score从0.65降至0.55,容忍货架反光造成的匹配误差;④在AGV控制程序中限制最大角速度从0.8rad/s降至0.4rad/s,减少打滑。

结果对比:调整后重新建图,货架重影消失,回环闭合误差从0.35m降至0.08m。但代价是建图时间从15分钟延长至22分钟,因为降低了角速度导致扫描覆盖变慢。

复盘经验:建图问题80%源于传感器外参标定和运动控制质量,而非算法本身。在调参之前,务必用ros2 run tf2_ros static_transform_publisher验证外参,并用ros2 bag record录制数据离线调试,避免反复实车测试。

4.5 常见误区与总结

  • 误区一:认为粒子数越多越好。Gmapping中粒子数从30增加到80,地图精度提升有限,但CPU占用翻倍。建议从30开始,逐步增加至地图无明显重影为止。
  • 误区二:忽略激光雷达的扫描频率。若雷达频率低于5Hz,SLAM算法无法捕捉快速运动,建议使用ros2 topic hz /scan检查实际频率。
  • 误区三:建图完成后直接用于导航,不做地图清理。栅格地图中的噪点(如移动物体产生的拖影)会导致代价地图膨胀,应使用图像编辑工具手动清理。
  • 误区四:Cartographer参数照搬默认配置。Cartographer的trajectory_builder_2d.lua中num_accumulated_range_data默认值为1,若激光帧率较高,可增大至10以降低计算量。

总结:SLAM建图是Nav2导航的基石,选型应基于场景规模、里程计质量和算力约束。Gmapping适合教学和简单场景,Cartographer是大型场景的工业级选择,SLAM Toolbox则是ROS2生态下最平衡的建图方案。建图流程的核心是“慢而稳”的运动控制与严格的外参标定,参数调优则需结合日志和Rviz可视化逐步迭代。建议在正式建图前,先录制ros2 bag数据,离线调整参数,确认地图质量后再上实车,这样能大幅缩短调试周期。