Skip to content

第13章 机器人SLAM

13 第 13 章 机器人 SLAM:同时定位与地图构建

SLAM(Simultaneous Localization and Mapping,同时定位与地图构建)是移动机器人自主导航的核心技术。机器人在未知环境中移动时,需要同时回答两个问题:「我在哪里?」和「周围是什么样的?」SLAM 正是解决这一「鸡生蛋」问题的关键框架。

学习目标:

  • 理解 SLAM 问题的数学定义与核心挑战;
  • 掌握 SLAM 的前端-后端架构与关键算法;
  • 了解基于激光雷达的 SLAM 方法(Gmapping、Cartographer、LOAM);
  • 了解基于视觉的 SLAM 方法(ORB-SLAM、VINS);
  • 能在 ROS2 环境中运行 SLAM 并构建地图。

13.1 SLAM 问题概述

13.1.1 什么是 SLAM

想象一个机器人被放置在一个完全陌生的房间里。它没有地图,也不知道自己的确切位置。随着机器人移动并观察环境,它需要:

  1. 定位(Localization):根据传感器观测推断自身位置;
  2. 建图(Mapping):根据观测构建环境地图。

这两个任务相互依赖——精确定位需要准确的地图,而构建准确的地图需要精确的定位。SLAM 就是同时解决这两个耦合问题的技术框架。

SLAM SLAM 我在哪 "环 "

图 13-1 上图以框图形式描绘了什么是 SLAM 的系统架构,清晰呈现了各模块之间的连接关系与信号流向。

13.1.2 SLAM 的数学定义

SLAM 问题可以形式化为概率估计问题。设:

  • $\mathbf{x}_t$:时刻 $t$ 的机器人位姿(位置 + 朝向)
  • $\mathbf{u}_t$:时刻 $t$ 的控制输入(如轮速)
  • $\mathbf{z}_t$:时刻 $t$ 的传感器观测
  • $\mathbf{m}$:环境地图

SLAM 的目标是计算后验概率分布:

$$ P(\mathbf{x}{1:t}, \mathbf{m} \mid \mathbf{z}{1:t}, \mathbf{u}_{1:t}) $$

即在给定所有观测和控制输入的条件下,联合估计机器人轨迹和地图。

13.1.3 SLAM 的核心挑战

表 13-1 SLAM 的核心挑战

挑战 说明
累积误差 里程计漂移随时间累积,导致地图变形
数据关联 判断当前观测对应地图中的哪个特征
回环检测 识别机器人重新到达之前访问过的位置
计算复杂度 地图规模增大时,优化计算量急剧上升
动态环境 行人、车辆等运动物体干扰地图构建
感知退化 长走廊、白墙等低纹理/低特征场景定位困难

13.2 SLAM 系统架构

现代 SLAM 系统通常采用前端-后端分离的架构:

IMU SLAM

图 13-2 该框图展示了 SLAM 系统架构的核心结构,读者可以从中把握各功能单元的层次划分与协作方式。

13.2.1 前端(Front-End)

前端又称「数据处理」或「视觉/激光里程计」,负责:

  • 特征提取:从传感器数据中提取有用信息(关键点、线段、平面、扫描特征等);
  • 数据关联:将当前帧特征与已知地图/上一帧特征建立对应关系;
  • 运动估计:计算相邻帧之间的相对运动(位姿变换);
  • 短期跟踪:维持实时的位姿估计。

前端对实时性要求高,通常需要在传感器帧率内完成处理。

13.2.2 后端(Back-End)

后端负责全局优化,核心任务:

  • 位姿图优化:将所有位姿节点和约束构建为图,通过非线性最小二乘求全局最优解;
  • 回环检测:发现机器人重新访问已知区域,添加约束消除累积误差;
  • 地图融合:将局部地图合并为全局一致的地图。

后端可以容忍一定延迟(非实时),但优化质量直接决定地图的全局一致性。

13.2.3 状态估计基础

SLAM 的状态估计核心是递归贝叶斯滤波。两种经典方法:

扩展卡尔曼滤波(EKF)

  • 假设运动和观测模型为高斯分布
  • 对非线性函数做一阶泰勒展开线性化
  • 计算复杂度 $O(n^2)$($n$ 为特征数量),大规模地图时不可行
  • 经典 EKF-SLAM 是早期 SLAM 方法的代表

粒子滤波(Particle Filter)

  • 用一组加权粒子近似后验分布
  • 无需高斯假设,可处理多模态分布
  • 每个粒子维护一个位姿 + 地图假设
  • Rao-Blackwellized 粒子滤波(RBPF)是 Gmapping 的核心

图优化(Graph-Based)

  • 现代 SLAM 的主流方法
  • 将位姿和特征建模为图的节点,约束为边
  • 通过最小化所有约束的误差求解
  • 工具:g2o、GTSAM、Ceres Solver

13.3 SLAM 传感器

13.3.1 激光雷达(LiDAR)

激光雷达通过发射激光脉冲并测量反射时间获取距离信息。

2D 激光雷达(如 RPLIDAR A1/A2、Hokuyo UTM-30LX):

  • 输出:一圈 360° 的距离扫描($r, \theta$ 极坐标点集)
  • 频率:5-40 Hz
  • 精度:±1-3 cm
  • 应用:室内平面 SLAM、避障

3D 激光雷达(如 Velodyne VLP-16、Livox Mid-360):

  • 输出:三维点云($x, y, z$)
  • 线数:16/32/64/128 线
  • 频率:10-20 Hz
  • 应用:自动驾驶、室外 SLAM

表 13-2 激光雷达(LiDAR)

参数 2D LiDAR 3D LiDAR
输出 2D 扫描线 3D 点云
典型价格 ¥500-5000 ¥5000-100000
精度 1-3 cm 1-5 cm
抗光干扰 较好
环境适应 室内为主 室内外均可

上述参数配置是激光雷达(LiDAR)的典型推荐值,实际工程中可根据硬件条件和性能需求进行适当调整。

13.3.2 相机

单目相机:成本最低,但缺乏尺度信息(Scale Ambiguity)。

双目/立体相机(如 Intel RealSense D435, ZED 2):通过视差计算深度,可直接获取 3D 信息。

RGB-D 相机(如 Azure Kinect, RealSense D455):同时输出彩色图像和深度图,室内效果好。

表 13-3 相机

相机类型 深度信息 尺度 适用场景
单目 需初始化 室外、成本敏感
双目 已知基线 室内外
RGB-D 直接测量 室内(结构光受日光干扰)

上表对相机中各方案的特性进行了横向对比,便于读者根据实际需求选择最合适的技术路线。

13.3.3 惯性测量单元(IMU)

IMU 提供高频(100-1000 Hz)的加速度和角速度数据。单独使用时漂移严重,但与 LiDAR 或相机融合后可显著提升 SLAM 鲁棒性:

  • 预积分:在相邻关键帧之间积分 IMU 数据,作为额外的运动约束
  • 快速运动:IMU 弥补视觉跟踪在快速运动时的不足
  • 重力方向:提供全局重力参考,约束 roll 和 pitch

13.4 基于激光雷达的 SLAM

13.4.1 扫描匹配(Scan Matching)

扫描匹配是激光 SLAM 的基础操作——将当前扫描与参考扫描(或地图)对齐,估计两者之间的位姿变换。

ICP(Iterative Closest Point)算法

输入:点集 P(当前扫描),点集 Q(参考扫描)
输出:旋转 R 和平移 t,使 P 对齐到 Q

1. 初始化 R=I, t=0
2. 重复直到收敛:
   a. 对 P 中每个点 p_i,在 Q 中找最近点 q_i
   b. 计算最小化 Σ||R·p_i + t - q_i||² 的 R, t
   c. 用 R, t 更新 P
3. 返回累积的 R, t

ICP 的变体:

表 13-4 扫描匹配(Scan Matching)

变体 改进
Point-to-Plane ICP 误差度量改为点到平面距离,收敛更快
GICP 广义 ICP,考虑点云的概率分布
NDT 正态分布变换,将点云投射到体素网格的高斯分布

以上内容归纳了扫描匹配(Scan Matching)的关键要素,为后续深入学习和工程实践提供了参考依据。

13.4.2 Gmapping(基于粒子滤波的 2D SLAM)

Gmapping 是最经典的 2D 激光 SLAM 方法之一,基于 Rao-Blackwellized 粒子滤波(RBPF)。

Gmapping (提议分布) N个 姿 +地

图 13-3 上图直观呈现了 Gmapping(基于粒子滤波的 2D SLAM)的组成要素与数据通路,有助于理解系统整体的工作机理。

核心思想:

  1. 每个粒子代表一种可能的轨迹假设,携带一份独立的地图;
  2. 利用扫描匹配改进运动模型的提议分布,减少有效粒子的退化;
  3. 通过自适应重采样平衡粒子多样性和计算效率。

优点:成熟稳定,适合中小规模室内环境。

局限:粒子数影响计算量;不适合大规模环境;无显式回环检测,依赖粒子多样性。

13.4.3 Cartographer(基于图优化的 2D/3D SLAM)

Google Cartographer 是一个强大的 SLAM 系统,支持 2D 和 3D,采用子地图(Submap)+ 图优化架构。

Cartographer Local Global IMU 姿 SPA 姿 SLAM( 图+ 姿 SLAM(

图 13-4 上图以框图形式描绘了 Cartographer(基于图优化的 2D/3D SLAM)的系统架构,清晰呈现了各模块之间的连接关系与信号流向。

关键特性:

  • 子地图机制:将环境分割为多个小地图,降低单次优化的规模;
  • 分支定界回环检测:高效的全局搜索方法,不依赖前端的特征描述符;
  • 多传感器融合:原生支持 IMU、里程计与激光雷达的融合;
  • 实时性:前端满足实时要求,后端在后台异步优化。

13.4.4 3D 激光 SLAM:LOAM 系列

LOAM(Lidar Odometry and Mapping)是 3D 激光 SLAM 的里程碑工作,后续衍生出 LeGO-LOAM、LIO-SAM、FAST-LIO 等变体。

核心思想:

  1. 特征提取:从点云中提取边缘点(曲率大)和平面点(曲率小);
  2. 激光里程计:高频(10 Hz)的帧间匹配,利用边缘-边缘和平面-平面的距离约束;
  3. 建图优化:低频(1 Hz)的全局地图优化,将新扫描融入全局点云地图。

表 13-5 3D 激光 SLAM:LOAM 系列

方法 特点 传感器
LOAM 边缘+平面特征,双频率架构 3D LiDAR
LeGO-LOAM 地面分割优化,适合地面机器人 3D LiDAR
LIO-SAM 紧耦合 LiDAR-IMU,因子图优化 3D LiDAR + IMU
FAST-LIO2 迭代卡尔曼滤波,无需特征提取 3D LiDAR + IMU

13.5 基于视觉的 SLAM

13.5.1 视觉 SLAM 概述

视觉 SLAM(Visual SLAM, VSLAM)使用相机作为主要传感器。相比激光雷达,相机成本低、信息丰富(颜色、纹理),但对光照变化和快速运动敏感。

视觉 SLAM 的典型流程:

ORB, SIFT PnP BA 优化 觉SLAM 姿

图 13-5 该框图展示了视觉 SLAM 概述的核心结构,读者可以从中把握各功能单元的层次划分与协作方式。

13.5.2 特征提取与匹配

特征点法是视觉 SLAM 的经典方法。常用特征:

表 13-6 特征提取与匹配

特征 描述维度 特点
SIFT 128 float 尺度不变,计算慢
SURF 64 float 类似 SIFT,更快
ORB 256 bit 二进制描述符,极快,ORB-SLAM 的选择
SuperPoint 256 float 深度学习特征,鲁棒性强

特征匹配流程:

  1. 在两帧图像中分别检测关键点;
  2. 计算每个关键点的描述符;
  3. 通过描述符距离(L2 或 Hamming)寻找最佳匹配;
  4. 用 RANSAC 剔除误匹配。

13.5.3 运动估计

根据可用信息的不同,运动估计有多种方法:

2D-2D(对极几何):两帧均为 2D 图像坐标,通过本质矩阵 $E$ 或基础矩阵 $F$ 恢复相对运动。适用于初始化阶段。

3D-2D(PnP, Perspective-n-Point):已知 3D 地图点和 2D 图像投影,求解相机位姿。SLAM 跟踪阶段的主力方法。

3D-3D(ICP):两组 3D 点的对齐,适用于 RGB-D 相机。

13.5.4 Bundle Adjustment(BA)

BA 是视觉 SLAM 后端优化的核心——同时优化所有相机位姿和 3D 地图点,最小化重投影误差:

$$ \min_{\mathbf{T}i, \mathbf{p}_j} \sum{i,j} | \mathbf{z}_{ij} - \pi(\mathbf{T}_i, \mathbf{p}_j) |^2 $$

其中 $\mathbf{T}i$ 是第 $i$ 帧的位姿,$\mathbf{p}_j$ 是第 $j$ 个地图点,$\pi$ 是投影函数,$\mathbf{z}{ij}$ 是观测。

BA 通常使用 Levenberg-Marquardt 算法求解,利用稀疏性加速(Schur 补 / 边际化)。

13.5.5 ORB-SLAM 系列

ORB-SLAM(1/2/3)是最具代表性的特征点视觉 SLAM 系统。

ORB SLAM ORB Mapping) Closing) DBoW2 线 线 Tracking) 取→ 姿 计→ 线 Local 点→ 部BA 线 Loop 测→ Sim3 算→ 局BA

图 13-6 上图直观呈现了 ORB-SLAM 系列的组成要素与数据通路,有助于理解系统整体的工作机理。

关键特性:

  • 三线程并行:跟踪、局部建图、回环检测分离,实时性和精度兼顾;

  • ORB 特征:速度快,旋转不变,适合实时系统;

  • DBoW2 回环检测:Bag of Words 视觉词袋,高效识别重访场景;

  • 多传感器支持(ORB-SLAM3):单目、双目、RGB-D、单目+IMU、双目+IMU。

13.5.6 视觉惯性 SLAM(VIO/VINS)

表 13-7 视觉惯性 SLAM 融合相机和 IMU,是当前最实用的方案之一:

系统 融合方式 特点
VINS-Mono 紧耦合,滑窗优化 单目+IMU,精度高
VINS-Fusion 紧耦合,多传感器 支持双目/GPS 融合
MSCKF 多状态约束卡尔曼 计算效率高
ORB-SLAM3 紧耦合,BA 优化 地图复用,回环检测

视觉和 IMU 的互补性:

  • 相机:低频(30 Hz)、提供绝对尺度(双目/RGB-D)或相对尺度、对快速运动和低纹理敏感;
  • IMU:高频(200+ Hz)、提供加速度和角速度、短期准确但长期漂移;
  • 融合:IMU 弥补帧间运动估计、提供重力方向;相机修正 IMU 积分漂移。

13.6 回环检测

回环检测(Loop Closure Detection)是 SLAM 系统消除累积误差的关键。当机器人重新回到之前访问过的位置时,回环检测识别这一事件,后端利用这一约束修正整条轨迹。

13.6.1 视觉回环检测:词袋模型

Bag of Words(BoW)是最经典的视觉回环检测方法。

工作流程:

  1. 离线训练:从大量图像中提取特征描述符,用 K-Means 聚类生成视觉词典(通常包含数万个视觉单词);
  2. 在线描述:对每帧图像提取特征,将每个描述符映射到最近的视觉单词,形成该帧的 BoW 向量(频率直方图);
  3. 相似度计算:比较当前帧和历史关键帧的 BoW 向量相似度;
  4. 几何验证:对相似度高的候选帧做特征匹配和几何一致性检查,确认回环。

代表库:DBoW2(ORB-SLAM 使用)、FBoW

13.6.2 激光回环检测

表 13-8 激光 SLAM 的回环检测方法:

方法 描述方式 特点
Scan-to-Scan Matching 将当前扫描与历史扫描直接匹配 精确但计算量大
ScanContext 将 3D 点云编码为极坐标环形描述符 旋转不变,高效
Branch-and-Bound Cartographer 使用的分支定界搜索 适合栅格地图
LiDAR Iris 类 Iris 的二进制全局描述符 快速检索

13.7 地图表示

SLAM 构建的地图有多种表示方式,适用于不同场景:

13.7.1 栅格地图(Occupancy Grid Map)

将环境离散化为 2D 网格,每个格子存储占据概率:

  • 0 = 空闲,1 = 占据,0.5 = 未知
  • 导航的标准输入(Nav2 的 Costmap 就是基于栅格地图)
  • 存储效率 $O(n^2)$,适合室内中小规模环境

13.7.2 点云地图(Point Cloud Map)

直接存储 3D 点的坐标(和可选颜色/反射率):

  • 信息丰富,表达力强
  • 存储量大(百万级点常见)
  • 可通过体素滤波降采样

13.7.3 八叉树地图(OctoMap)

基于八叉树的概率化 3D 地图:

  • 自适应分辨率:精细区域细分、空旷区域粗分
  • 存储效率远优于稠密点云
  • 支持概率更新,可处理动态变化

13.7.4 地图类型对比

表 13-9 地图类型对比

地图类型 维度 存储效率 信息丰富度 典型用途
栅格地图 2D 2D 导航
点云地图 3D 3D 重建、视觉定位
八叉树 3D 3D 导航、规划
特征地图 2D/3D 极高 纯定位(无稠密重建)
语义地图 2D/3D 视实现 极高 人机交互、任务规划

13.8 ROS2 中的 SLAM 实践

13.8.1 SLAM Toolbox

SLAM Toolbox 是 ROS2 推荐的 2D SLAM 包,由 Steve Macenski(Nav2 的主要作者)开发。

安装与使用:

# 安装
sudo apt install ros-humble-slam-toolbox

# 启动(在线模式)
ros2 launch slam_toolbox online_async_launch.py

# 在 RViz2 中查看地图
ros2 run rviz2 rviz2
# 添加 Map 显示,话题选择 /map

配置文件示例(slam_toolbox_params.yaml):

slam_toolbox:
  ros__parameters:
    # 基本参数
    odom_frame: odom
    map_frame: map
    base_frame: base_link
    scan_topic: /scan
    mode: mapping  # mapping 或 localization

    # 扫描匹配参数
    resolution: 0.05          # 地图分辨率(米/像素)
    max_laser_range: 20.0     # 最大激光范围
    minimum_travel_distance: 0.5   # 最小移动距离
    minimum_travel_heading: 0.5    # 最小转向角度

    # 回环检测
    do_loop_closing: true
    loop_match_minimum_chain_size: 10

13.8.2 Cartographer ROS2

# 安装
sudo apt install ros-humble-cartographer ros-humble-cartographer-ros

# 启动 2D SLAM
ros2 launch cartographer_ros cartographer.launch.py \
  use_sim_time:=true

Cartographer 配置(my_robot.lua):

include "map_builder.lua"
include "trajectory_builder.lua"

options = {
  map_builder = MAP_BUILDER,
  trajectory_builder = TRAJECTORY_BUILDER,
  map_frame = "map",
  tracking_frame = "base_link",
  published_frame = "odom",
  odom_frame = "odom",
  provide_odom_frame = false,
  use_odometry = true,
  use_nav_sat = false,
  num_laser_scans = 1,
  num_multi_echo_laser_scans = 0,
  num_subdivisions_per_laser_scan = 1,
  num_point_clouds = 0,
}

MAP_BUILDER.use_trajectory_builder_2d = true
TRAJECTORY_BUILDER_2D.min_range = 0.1
TRAJECTORY_BUILDER_2D.max_range = 20.0
TRAJECTORY_BUILDER_2D.use_imu_data = false

return options

13.8.3 保存与加载地图

# 保存地图(SLAM 完成后)
ros2 run nav2_map_server map_saver_cli -f ~/my_map

# 生成两个文件:
# my_map.pgm  - 栅格地图图像
# my_map.yaml - 地图元数据(分辨率、原点等)

# 加载已有地图用于定位
ros2 run nav2_map_server map_server \
  --ros-args -p yaml_filename:=~/my_map.yaml

13.8.4 完整 SLAM + 导航示例

# launch/slam_navigation.launch.py
from launch import LaunchDescription
from launch_ros.actions import Node

def generate_launch_description():
    return LaunchDescription([
        # SLAM
        Node(
            package='slam_toolbox',
            executable='async_slam_toolbox_node',
            parameters=['config/slam_params.yaml'],
        ),
        # 导航
        Node(
            package='nav2_bringup',
            executable='bringup_launch.py',
            parameters=['config/nav2_params.yaml'],
        ),
        # 可视化
        Node(
            package='rviz2',
            executable='rviz2',
            arguments=['-d', 'config/slam_nav.rviz'],
        ),
    ])

13.9 SLAM 算法对比与选型指南

13.9.1 主流 SLAM 算法对比

表 13-10 主流 SLAM 算法对比

算法 传感器 维度 后端 回环 实时性 适用场景
Gmapping 2D LiDAR 2D 粒子滤波 小型室内
Cartographer LiDAR+IMU 2D/3D 图优化 中大型室内外
LOAM 3D LiDAR 3D 特征匹配 室外
LIO-SAM LiDAR+IMU 3D 因子图 大规模室外
FAST-LIO2 LiDAR+IMU 3D 滤波 极好 高速运动
ORB-SLAM3 相机+IMU 3D BA 通用
VINS-Fusion 相机+IMU 3D 滑窗优化 无人机、手持

上表对主流 SLAM 算法对比中各方案的特性进行了横向对比,便于读者根据实际需求选择最合适的技术路线。

13.9.2 选型建议

SLAM VINS ORB SLAM3 ORB SLAM3 2D Gmapping Cartographer 3D IMU? LI SAM LOAM IMU?

图 13-7 上图以框图形式描绘了选型建议的系统架构,清晰呈现了各模块之间的连接关系与信号流向。


13.10 本章小结与拓展资源

13.10.1 关键知识点回顾

  1. SLAM 问题:在未知环境中同时估计位姿和构建地图,是概率估计问题;
  2. 系统架构:前端(特征提取、帧间匹配)+ 后端(图优化、回环检测);
  3. 激光 SLAM:ICP 扫描匹配、Gmapping(粒子滤波)、Cartographer(子地图+图优化)、LOAM 系列(3D 特征匹配);
  4. 视觉 SLAM:特征提取匹配(ORB)、BA 优化、ORB-SLAM 三线程架构、VIO 融合;
  5. 回环检测:BoW 视觉词袋(DBoW2)、ScanContext(激光);
  6. 地图表示:栅格图、点云、八叉树、语义地图;
  7. ROS2 实践:SLAM Toolbox、Cartographer ROS2、地图保存与导航集成。

13.10.2 推荐学习资源

表 13-11 推荐学习资源

资源 说明
《视觉SLAM十四讲》(高翔) 中文 VSLAM 经典,理论+代码
《Probabilistic Robotics》 Thrun 等,SLAM 数学基础圣经
OpenSLAM 开源 SLAM 实现集合
SLAM Toolbox 文档 ROS2 官方推荐 2D SLAM
ORB-SLAM3 最完整的特征点视觉 SLAM
Cartographer Google 激光 SLAM 系统
LIO-SAM 紧耦合激光惯性 SLAM

以上内容归纳了推荐学习资源的关键要素,为后续深入学习和工程实践提供了参考依据。

13.10.3 课后练习

  1. 概念理解:解释 SLAM 中「定位需要地图,建图需要定位」这一循环依赖问题,说明 EKF-SLAM 和图优化方法各自如何打破这种循环。
  2. 2D SLAM 实践:在 ROS2 中使用 SLAM Toolbox,录制一段 rosbag(含激光扫描和里程计),回放并构建二维栅格地图。
  3. 回环检测:解释为什么回环检测对于大规模 SLAM 至关重要。如果机器人在一栋大楼中绕行一圈后回到起点,没有回环检测的 SLAM 系统会出现什么问题?
  4. 算法对比:选择一个室内场景和一个室外场景,分别推荐合适的 SLAM 算法并说明理由。
  5. 挑战练习:在 Gazebo 仿真环境中,使用 Cartographer 构建一个包含多个房间和走廊的 2D 地图,观察回环检测前后地图的差异。

13.11 本章测验

Quiz results are saved to your browser's local storage and will persist between sessions.

#

1) SLAM 问题的本质挑战是什么?

#

2) 基于图优化的 SLAM 后端中,"图"的节点和边分别表示什么?

#

3) 回环检测(Loop Closure)对 SLAM 系统的作用是什么?

#

4) 以下哪种 SLAM 算法基于粒子滤波?

Quiz Progress

0 / 0 questions answered (0%)

0 correct