3、SLAM Toolbox在线建图:启动SLAM Toolbox、使用遥控器建图、保存地图为PGM/YAML
好,咱们进入正题。上一章我们把机器人底盘和传感器都跑通了,现在终于可以开始建图了。说实话,我第一次用SLAM Toolbox的时候,心里还挺没底的——毕竟建图这事儿,一步错,后面导航全完蛋。但别怕,今天我就带你一步步走通这个流程。
3.1 为什么选SLAM Toolbox?
ROS2里建图工具不少,比如gmapping、cartographer。但我个人习惯用SLAM Toolbox。为什么?因为它有个杀手锏——在线重定位。你想想看,建图过程中机器人万一打滑、撞墙,地图歪了怎么办?SLAM Toolbox可以随时修正,不用从头再来。
另外,它支持异步模式。什么意思?就是建图的时候,CPU不用一直100%跑满,留点余量给其他节点。我在项目里遇到过,用gmapping建图时,机器人稍微跑快点,地图就开始飘。换成SLAM Toolbox后,稳多了。
核心优势总结:
- 支持在线重定位,建图过程中可修正
- 异步模式,降低CPU占用
- 地图保存格式直接支持PGM/YAML,无需转换
- 与Nav2无缝集成,参数配置灵活
3.2 启动SLAM Toolbox
启动之前,先确认你的机器人底盘和激光雷达都在跑。我习惯用一个launch文件把事都办了,但为了讲清楚,咱们分步来。
首先,启动SLAM Toolbox节点。打开终端,输入:
ros2 launch slam_toolbox online_async_launch.py \
slam_params_file:=./src/my_robot/config/mapper_params_online_async.yaml
这里有个坑——参数文件路径一定要写对。我曾经因为路径写错,折腾了半小时,结果发现是少了个点。嗯,这种低级错误,谁没犯过呢?
参数文件长什么样?我给你看个精简版:
slam_toolbox:
ros__parameters:
use_sim_time: false
odom_frame: odom
map_frame: map
base_frame: base_footprint
scan_topic: /scan
mode: mapping # mapping 或 localization
resolution: 0.05 # 地图分辨率,单位米/像素
max_laser_range: 12.0
minimum_time_interval: 0.5
transform_timeout: 0.2
注意resolution: 0.05这个参数。0.05米/像素,也就是5厘米一个格子。这个值越小,地图越精细,但文件也越大。我一般室内场景用0.05,室外大场景用0.1。你根据实际需求调。
小技巧:如果你用的是真实机器人,记得把use_sim_time设为false。仿真环境才设true。我见过有人忘了改这个,结果建图时时间戳全乱套。
3.3 使用遥控器建图
SLAM Toolbox跑起来后,你会看到Rviz2里出现一个空白地图。这时候,你需要遥控机器人到处走走,让激光雷达扫描环境。
遥控方式有两种:
- 键盘遥控:用
teleop_twist_keyboard包,按键盘控制 - 手柄遥控:用
joy包,接个游戏手柄
我个人推荐手柄。为什么?因为建图时你需要同时盯着Rviz2屏幕,键盘遥控得低头找按键,容易撞墙。手柄盲操方便多了。
启动键盘遥控:
ros2 run teleop_twist_keyboard teleop_twist_keyboard
然后按i前进,j左转,l右转,k停止。记住,速度别太快。我建议线速度0.2m/s,角速度0.5rad/s。太快了,SLAM算法跟不上,地图会糊。
避坑指南:我曾经建图时,为了省时间,让机器人跑得飞快。结果地图边缘全是锯齿,回环检测死活闭合不上。后来老老实实慢速跑了一圈,地图就完美了。建图这事儿,急不得。
建图过程中,注意观察Rviz2里的地图变化。你应该看到:
- 黑色区域:障碍物(墙、家具)
- 白色区域:可通行区域(地面)
- 灰色区域:未探索区域
当机器人走完一圈,回到起点附近时,你会看到地图突然"啪"一下闭合了——这就是回环检测生效了。如果没闭合,说明你的路径有问题,或者参数没调好。
3.4 保存地图为PGM/YAML
地图建好了,怎么保存?SLAM Toolbox提供了专门的service。打开一个新终端,输入:
ros2 service call /slam_toolbox/save_map slam_toolbox/srv/SaveMap \
"{name: {data: 'my_map'}, destination: '/home/user/maps'}"
这条命令会生成两个文件:
my_map.pgm:图片格式的地图,黑白像素my_map.yaml:地图的元数据文件
YAML文件内容大概这样:
image: my_map.pgm
resolution: 0.050000
origin: [-10.000000, -10.000000, 0.000000]
negate: 0
occupied_thresh: 0.65
free_thresh: 0.196
解释一下关键字段:
| 字段 | 含义 | 说明 |
|---|---|---|
image |
地图图片文件名 | 相对路径,与YAML同目录 |
resolution |
地图分辨率 | 单位米/像素,与建图参数一致 |
origin |
地图原点坐标 | [x, y, yaw],通常为地图左下角 |
occupied_thresh |
障碍物阈值 | 像素值高于此阈值视为障碍物 |
free_thresh |
自由空间阈值 | 像素值低于此阈值视为可通行 |
重要提醒:保存地图时,确保机器人已经完成了完整的回环。如果地图边缘有大量灰色区域,说明还有地方没扫到。我建议你保存前,在Rviz2里旋转视角,检查一下地图完整性。
如果你不想用service,也可以用命令行工具:
ros2 run nav2_map_server map_saver_cli -f my_map
这个命令更简单,但需要先安装nav2_map_server包。两种方式效果一样,选你顺手的。
3.5 本章知识体系
下面这张图,帮你理清SLAM Toolbox建图的完整流程:
这张图把整个流程串起来了。你从启动SLAM Toolbox开始,到遥控建图,再到回环检测,最后保存地图。每一步都有坑,但只要你按部就班来,基本不会出大问题。
最后说一句,地图保存后,建议你用图片查看器打开PGM文件看看。如果发现地图有断层、黑块,说明建图过程中出了问题。别慌,重新来一遍,注意控制速度,让机器人走稳一点。
我的个人习惯:每次建图前,我都会先手动推着机器人走一遍路径,确认没有障碍物挡路。这样建图时,机器人不会突然卡住。你想想看,要是建图到一半,机器人被电线绊倒了,那多尴尬。
好了,地图已经保存好了。下一章,我们会用这张地图来做导航定位。到时候你就知道,一张好地图有多重要了。