4、SLAM建图:使用SLAM Toolbox进行在线建图、保存地图、地图优化技巧

说到SLAM建图,很多新手第一反应就是跑个gmapping或者Cartographer。但我个人习惯,现在更推荐用SLAM Toolbox。为什么?因为它太懂我们做工程的人了——既能在线建图,又能随时保存、重定位、甚至做地图的后期优化。说白了,它就是ROS2生态里最趁手的建图工具之一。

4.1 为什么选择SLAM Toolbox?

我最早接触SLAM Toolbox是在一个仓储机器人的项目里。当时客户要求机器人能快速部署到不同仓库,每次都要重新建图。用gmapping建完图,机器人一旦关机,地图就丢了,下次还得重来。而SLAM Toolbox支持序列化地图,建到一半关机?没关系,下次加载继续建。这个特性在实际项目中太救命了。

它的核心优势有几点:

  • 支持在线与离线建图:你可以实时看着地图一点点生成,也可以事后用录好的bag包建图。
  • 地图序列化:建图过程中的所有状态都可以保存为文件,下次直接加载,继续建。
  • 自带重定位功能:地图建好后,机器人可以在地图中定位,不需要额外跑AMCL。
  • 地图优化工具:建完图后还能做手动或自动的图优化,修正漂移。
我的小建议:如果你只是临时测试,用gmapping没问题。但如果是产品级项目,直接上SLAM Toolbox,省心太多。

4.2 快速上手:启动SLAM Toolbox在线建图

嗯,这里要注意,SLAM Toolbox在ROS2里已经作为正式包发布了。安装很简单:

sudo apt install ros-humble-slam-toolbox

启动建图,我一般用这个launch文件:

ros2 launch slam_toolbox online_async_launch.py
  slam_params_file:=./slam_toolbox_params.yaml
  use_sim_time:=false

参数文件是关键。我分享一份我常用的配置,你直接拿去用:

slam_toolbox:
  ros__parameters:
    # 核心参数
    mode: mapping          # mapping 或 localization
    base_frame: base_footprint
    odom_frame: odom
    map_frame: map

    # 激光雷达参数
    max_laser_range: 12.0
    minimum_time_interval: 0.5
    transform_timeout: 0.2

    # 图优化参数
    ceres_linear_solver: SPARSE_NORMAL_CHOLESKY
    ceres_preconditioner: SCHUR_JACOBI
    ceres_loss_function: HuberLoss

    # 地图更新
    map_update_interval: 5.0
    resolution: 0.05

启动后,用键盘控制机器人走一圈,你会在RViz里看到地图一点点展开。那种感觉,就像在黑暗中慢慢点亮一盏灯。

我曾经踩过的坑:有一次我忘了设置 minimum_time_interval,结果激光数据太密集,CPU直接飙到100%。机器人走两步就卡死。后来我把这个值设成0.5秒,问题就解决了。别小看这个参数。

4.3 保存地图:不只是存一张图片

很多人以为保存地图就是 map_saver 存个pgm和yaml。但SLAM Toolbox的保存方式更强大——它保存的是整个图优化的状态

保存地图的命令:

ros2 run slam_toolbox map_saver_cli -f my_map

这会生成两个文件:

  • my_map.yaml:地图元数据
  • my_map.pgm:栅格图像

但如果你想要保存完整的SLAM状态(包括所有节点、约束、未优化的图),用这个:

ros2 service call /slam_toolbox/serialize_map
  slam_toolbox/srv/SerializeMap
  "{filename: 'my_full_map'}"

这会生成一个 .posegraph 文件。下次启动时加载它,就能接着上次的进度继续建图。我在一个大型商场项目里,就是靠这个功能分多次建完了一整层楼的地图。

关键区别:
  • map_saver:存的是最终栅格图,适合导航用。
  • serialize_map:存的是完整SLAM状态,适合继续建图或后期优化。

4.4 地图优化技巧:让地图更干净

建完图后,你可能会发现地图上有一些噪点、重影或者漂移。别急,SLAM Toolbox提供了几个优化手段。

4.4.1 手动图优化

SLAM Toolbox自带一个交互式优化工具。启动后,你可以在RViz里手动调整节点位置:

ros2 run slam_toolbox slam_toolbox_manual_loop_closure

操作方式:

  1. 在RViz中选中两个应该重叠但实际没对齐的区域。
  2. 点击「Add Loop Closure」添加回环约束。
  3. 运行图优化,地图会自动调整。

我记得有一次建一个回字形走廊,因为激光雷达视角受限,地图在拐角处出现了明显的错位。手动加了两个回环约束后,地图瞬间对齐了。那种成就感,嗯,你试试就知道了。

4.4.2 自动优化参数调优

如果你不想手动干预,可以调整这些参数让SLAM Toolbox自动优化:

参数 作用 推荐值
loop_search_max_distance 回环检测的最大搜索距离 8.0 米
loop_search_max_angle 回环检测的最大角度偏差 0.3 弧度
correlation_search_space_dimension 相关性搜索窗口大小 0.5 米
correlation_search_space_resolution 搜索分辨率 0.01 米

你想想看,如果走廊很长,loop_search_max_distance 设得太小,回环就检测不到。设得太大,计算量又上去了。我一般先设8米,如果发现回环检测不到,再逐步加大。

4.4.3 地图后处理

建完图后,我还会用一些外部工具做最后的清理:

  • 膨胀处理:用 nav2_map_servermap_saver 配合膨胀半径参数,把障碍物边缘加宽,防止机器人撞墙。
  • 手动编辑:用GIMP或Photoshop打开pgm文件,把噪点涂掉。虽然土,但有效。
  • 降采样:如果地图太大,可以用 image_magic 把分辨率从0.05降到0.1,文件大小直接缩到1/4。
我的经验:地图不是越精细越好。0.05分辨率适合室内精细导航,但如果是室外或大场景,0.1甚至0.2都够用。地图文件太大,导航时的计算开销也会成倍增加。

4.5 避坑指南:我踩过的那些坑

最后,分享几个我实际项目中遇到的坑,你遇到了可以少走弯路:

  • 激光雷达安装角度:如果激光雷达装歪了,建出来的地图会整体倾斜。记得用 tf2 做静态变换补偿。
  • 轮子打滑:在光滑地面上,轮子打滑会导致里程计漂移,地图出现重影。解决办法是加IMU做融合,或者用更可靠的编码器。
  • 动态物体干扰:建图时如果有人走来走去,地图上会留下「鬼影」。我一般选择在无人时段建图,或者用 scan_filter 过滤掉动态点。
  • 地图保存路径serialize_map 服务保存的文件默认在 ~/.ros 目录下。别像我一样找了半天才发现。

好了,这一章的内容就到这里。SLAM建图这件事,说白了就是让机器人「看懂」它所在的世界。工具再好,也得多动手试。你拿着这份指南去跑一遍,遇到问题再回来翻翻,应该能省不少时间。