2. SLAM基础回顾

在进入“语义标签与地图标注联动”这一核心主题之前,我们必须先夯实SLAM(Simultaneous Localization and Mapping,同步定位与建图)的基础。SLAM解决的是“机器人在哪里”和“周围环境长什么样”这两个互为前提的问题——定位需要地图,建图需要位姿,二者必须同时求解。在ROS2生态中,Cartographer和SLAM Toolbox是两款主流的2D SLAM工具,它们各自代表了不同的算法流派与工程权衡。本章将系统梳理SLAM的基本原理、ROS2中的工具选型、地图的数据表示方式以及关键术语,为后续语义标签的叠加与联动建立共同的语言基础。

ROS2 SLAM 工具与地图表示知识框架 传感器输入 激光雷达 (LaserScan) IMU (姿态/角速度) 里程计 (Odometry) 深度相机 (可选) SLAM 核心处理 前端:扫描匹配/帧间配准 后端:图优化/位姿图 回环检测:闭环修正 栅格概率更新 输出产物 栅格地图 (OccupancyGrid) 点云地图 (PointCloud2) 机器人位姿 (TF) 轨迹/位姿图 ROS2 工具选型 Cartographer:多传感器融合、2D/3D、 子图回环、适合复杂环境 SLAM Toolbox:轻量、异步、适合简单场景 语义标签与地图标注联动 在栅格/点云地图上叠加语义信息 实现"位置+语义"的增强地图 为导航、交互、任务决策提供支持 语义SLAM 增强地图

2.1 SLAM核心原理:从概率估计到图优化

SLAM的本质是一个状态估计问题。机器人携带传感器在未知环境中运动,我们需要同时估计两个未知量:机器人自身的轨迹(位姿序列)和环境的地图。在数学上,这可以建模为最大后验概率(MAP)估计问题:给定传感器观测数据 \( z_{1:t} \) 和控制输入 \( u_{1:t} \),求解最可能的机器人位姿 \( x_{1:t} \) 和地图 \( m \)。

现代SLAM系统普遍采用图优化(Graph-based SLAM)框架,将问题转化为一个稀疏图的优化问题。图中节点表示机器人的位姿或 landmark,边表示位姿之间的约束(来自里程计、扫描匹配或回环检测)。优化目标是调整所有节点的位姿,使所有约束的误差最小化。这种方法的优势在于:回环检测可以一次性修正历史轨迹的累积漂移,而不是像滤波方法(如EKF-SLAM)那样只能局部修正。

在ROS2中,SLAM工具链通常分为前端(Front-end)和后端(Back-end)两部分。前端负责处理传感器数据,进行帧间配准(scan-to-scan或scan-to-map),输出相对位姿约束;后端则维护位姿图,执行图优化和回环检测。以Cartographer为例,其前端使用Ceres Solver进行非线性最小二乘优化,后端则采用稀疏位姿图(SPA)方法,通过分支定界(Branch and Bound)算法加速回环搜索。

核心要点:SLAM不是单一算法,而是一个系统架构。理解前端与后端的解耦、回环检测的重要性,是掌握任何SLAM工具的关键。在ROS2中,slam_toolbox和cartographer都遵循这一架构,但实现细节和参数调优差异显著。

2.2 地图表示:栅格地图与点云地图

地图是SLAM的输出,也是后续语义标注的载体。在ROS2中,最常用的两种地图表示是栅格地图(Occupancy Grid Map)和点云地图(Point Cloud Map)。它们各有优劣,适用于不同的任务场景。

维度 栅格地图 (OccupancyGrid) 点云地图 (PointCloud2)
数据结构 二维数组,每个格子存储占据概率(0-100) 三维点集,每个点包含(x,y,z)坐标及可选属性(强度、RGB)
ROS2消息类型 nav_msgs/msg/OccupancyGrid sensor_msgs/msg/PointCloud2
空间维度 2D(平面) 2D或3D
分辨率 固定分辨率(如0.05m/像素) 点密度可变,无固定分辨率
内存占用 低(与地图面积成正比) 高(与点数成正比)
适用场景 2D导航、路径规划、成本地图 3D感知、语义分割、可视化、碰撞检测
语义标注难度 容易(每个格子可附加标签) 中等(需要对点云进行分割/聚类)

栅格地图是ROS2导航栈(Nav2)的标准输入。它通过贝叶斯更新维护每个格子的占据概率,值域为[0,100],其中0表示完全空闲,100表示完全占据,-1表示未知。栅格地图的优点是计算高效、便于路径规划(如A*、Dijkstra算法直接作用于栅格),缺点是丢失了高度信息和物体细节。

点云地图则保留了环境的几何细节,适合进行语义分割(如识别墙壁、地面、物体)。在ROS2中,点云通常由激光雷达或深度相机生成,通过sensor_msgs/msg/PointCloud2消息发布。点云地图的缺点是数据量大、处理复杂,且需要额外的配准算法(如ICP)来拼接多帧点云。

经验提醒:在语义标签联动场景中,推荐采用“栅格地图为底图 + 点云地图为语义载体”的混合方案。栅格地图负责导航与定位,点云地图负责语义识别与标注,二者通过TF坐标变换关联。

2.3 ROS2中的SLAM工具:Cartographer与SLAM Toolbox

ROS2生态中,Cartographer和SLAM Toolbox是两款最常用的2D SLAM工具。它们都支持实时建图与定位,但在设计哲学、算法细节和适用场景上存在显著差异。

2.3.1 Cartographer:多传感器融合的图优化SLAM

Cartographer由Google开发,支持2D和3D建图。其核心优势在于多传感器融合——可以同时接收激光雷达、IMU、里程计甚至GPS数据,通过图优化框架实现高精度建图。Cartographer引入了子图(Submap)概念:将连续帧激光数据配准到局部子图中,当子图不再变化时,将其加入全局位姿图进行回环检测。

在ROS2中使用Cartographer,需要配置三个文件:lua脚本(算法参数)、urdf(机器人模型)和launch文件。关键参数包括:map_frame(地图坐标系)、tracking_frame(跟踪坐标系)、num_range_data(子图包含的扫描帧数)等。Cartographer的调参较为复杂,但一旦调好,精度和鲁棒性都非常出色。

# Cartographer 2D 建图 launch 示例(ROS2)
ros2 launch cartographer_ros cartographer.launch.py \
  configuration_basename:="backpack_2d.lua"

2.3.2 SLAM Toolbox:轻量高效的异步SLAM

SLAM Toolbox是Steve Macenski开发的轻量级SLAM工具,专为ROS2设计。它基于Karto SLAM算法,采用异步处理架构——前端扫描匹配与后端图优化在不同线程中运行,避免阻塞。SLAM Toolbox的优势在于:配置简单、资源占用低、支持串行化(Serialization)——可以将建好的地图和位姿图保存为文件,下次启动时直接加载,无需重新建图。

SLAM Toolbox的核心参数包括:scan_topic(激光话题)、map_update_interval(地图更新频率)、minimum_travel_distance(触发建图的最小移动距离)等。它还提供了生命周期节点(Lifecycle Node)支持,可以动态启停建图过程。

# SLAM Toolbox 建图 launch 示例(ROS2)
ros2 launch slam_toolbox online_async_launch.py \
  slam_params_file:=./config/mapper_params_online_async.yaml
对比维度 Cartographer SLAM Toolbox
算法基础 图优化 + 子图 + 分支定界回环 Karto SLAM(图优化)
传感器支持 激光 + IMU + 里程计 + GPS 激光 + 里程计(可选IMU)
3D支持 支持(Cartographer 3D) 仅2D
配置复杂度 高(Lua脚本 + URDF) 低(YAML文件)
回环检测 实时、全局搜索 基于栅格搜索
地图保存/加载 通过map_saver保存PGM/YAML 支持串行化(.posegraph / .data)
典型场景 复杂环境、多传感器融合、3D建图 简单环境、资源受限、快速部署

2.4 常用术语与坐标系约定

在SLAM和语义标注中,术语和坐标系的统一至关重要。以下是ROS2 SLAM中必须掌握的术语:

  • 位姿(Pose):机器人在空间中的位置和朝向,通常表示为 (x, y, θ) 或 (x, y, z, qx, qy, qz, qw)。
  • TF树(Transform Tree):ROS2中维护坐标系变换关系的树状结构,SLAM节点负责发布 map → odom → base_link 的变换。
  • 扫描匹配(Scan Matching):将当前激光帧与已有地图或上一帧进行配准,得到相对位姿变化。
  • 回环检测(Loop Closure):识别机器人回到曾经访问过的位置,并修正累积漂移。
  • 子图(Submap):Cartographer中的局部地图单元,由若干连续激光帧构成。
  • 占据概率(Occupancy Probability):栅格地图中每个格子被占据的概率值。
  • 成本地图(Costmap):在栅格地图基础上叠加膨胀层、障碍层等,用于导航规划。

坐标系约定方面,ROS2标准规定:map坐标系是全局固定坐标系,odom坐标系是里程计局部坐标系,base_link是机器人本体坐标系。SLAM节点负责维护 map → odom 的变换,而 odom → base_link 由里程计提供。语义标注时,必须确保标签数据在正确的坐标系下发布,通常使用 map 坐标系作为全局语义地图的参考系。

风险提示:坐标系混淆是SLAM应用中最常见的错误之一。在编写语义标注代码时,务必使用 tf2 库进行坐标变换,不要假设坐标系固定不变。特别是在机器人运动过程中,base_link 相对于 map 的变换是持续更新的。

2.5 实战案例:使用SLAM Toolbox建图并导出栅格地图

下面通过一个完整的案例,演示如何在ROS2中使用SLAM Toolbox完成建图,并导出栅格地图供后续语义标注使用。假设我们有一个差速驱动机器人,搭载2D激光雷达,运行在室内走廊环境。

场景与约束:机器人需要构建一张50m × 30m的走廊地图,激光雷达扫描频率10Hz,最大测距30m。要求地图分辨率0.05m/像素,建图完成后保存地图文件。

操作步骤:

  1. 启动机器人驱动和激光雷达:确保 /scan 话题正常发布 LaserScan 消息。
  2. 配置SLAM Toolbox参数文件(mapper_params_online_async.yaml):
slam_toolbox:
  ros__parameters:
    use_sim_time: false
    scan_topic: /scan
    mode: mapping
    map_frame: map
    odom_frame: odom
    base_frame: base_link
    resolution: 0.05
    max_laser_range: 30.0
    minimum_time_interval: 0.5
    minimum_travel_distance: 0.2
    map_update_interval: 5.0
    loop_match_minimum_chain_size: 10
    loop_match_maximum_variance_coarse: 3.0
    loop_match_minimum_response_coarse: 0.35
    loop_match_minimum_response_fine: 0.45
  1. 启动SLAM Toolbox节点:
ros2 launch slam_toolbox online_async_launch.py \
  slam_params_file:=./config/mapper_params_online_async.yaml
  1. 手动遥控机器人遍历环境:使用 teleop_twist_keyboard 控制机器人缓慢移动,确保激光雷达覆盖所有区域,重点在走廊交叉口和转角处减速,便于回环检测。
  2. 观察建图效果:在RViz2中添加 Map 显示,订阅 /map 话题,实时查看栅格地图构建情况。若发现地图漂移或错位,可调整 minimum_travel_distance 和 loop_match_minimum_response_fine 参数。
  3. 保存地图:使用 map_saver 工具保存地图为PGM和YAML文件:
ros2 run nav2_map_server map_saver_cli -f corridor_map \
  --ros-args -p map_topic:=/map

结果与复盘:建图完成后,我们得到了 corridor_map.pgm 和 corridor_map.yaml 文件。PGM文件是灰度图像,白色表示空闲,黑色表示占据,灰色表示未知。YAML文件包含地图元数据(分辨率、原点、坐标系等)。在后续语义标注中,我们可以加载这张栅格地图作为底图,通过图像坐标到地图坐标的变换,将语义标签(如“门”、“消火栓”、“安全出口”)叠加到对应位置。

风险与代价:建图过程中,如果机器人移动过快或激光雷达数据丢帧,可能导致地图出现“重影”或“断裂”。此时需要重新建图,或者使用Cartographer的多传感器融合来增强鲁棒性。此外,SLAM Toolbox的串行化功能可以保存位姿图,但需要额外配置 serialization_directory 参数。

2.6 常见误区与总结复盘

在SLAM工具的使用和地图表示的理解上,初学者常犯以下错误:

  • 误区一:混淆栅格地图与点云地图的用途。栅格地图用于导航,点云地图用于感知和语义。不要试图在栅格地图上做精细的物体识别,也不要用点云地图直接做路径规划。
  • 误区二:忽略TF树的重要性。SLAM建图失败,80%以上是TF配置错误。务必检查 map → odom → base_link → laser 的变换是否完整且频率正常。
  • 误区三:盲目追求高分辨率。栅格地图分辨率越高,内存占用和计算量越大。0.05m分辨率通常足够,过高的分辨率反而会导致地图噪声增大。
  • 误区四:忽视回环检测的触发条件。回环检测需要机器人回到已探索区域,且视角相近。如果建图过程中机器人没有形成闭环,地图漂移将无法修正。
  • 误区五:认为SLAM工具可以“开箱即用”。无论是Cartographer还是SLAM Toolbox,都需要根据机器人平台、传感器特性和环境特点进行参数调优。
总结:本章回顾了SLAM的基本原理(图优化框架)、地图表示(栅格地图与点云地图的对比)、ROS2中两款主流SLAM工具(Cartographer与SLAM Toolbox)的选型与配置,以及关键术语和坐标系约定。这些知识是后续实现“语义标签和地图标注联动”的基石——只有理解了地图如何生成、坐标系如何变换,才能将语义信息准确地绑定到地图的特定位置。在下一章中,我们将深入探讨语义标签的数据结构设计与存储方案,敬请期待。