3. 占据栅格地图构建:概率栅格地图原理、激光雷达逆传感器模型、gmapping与cartographer算法对比

各位同学,欢迎来到第三章。前两章我们搞定了激光雷达的底层驱动和点云预处理,现在终于要进入一个核心环节——地图构建。

你想想看,机器人要在未知环境里导航,它首先得知道“我在哪”以及“周围长什么样”。地图就是它的“眼睛”和“记忆”。这一章,我们就来聊聊占据栅格地图(Occupancy Grid Map)是怎么建起来的,以及主流的两种SLAM方案——gmapping和Cartographer,到底有什么区别。

本章核心知识点

  • 概率栅格地图的数学原理与更新公式
  • 激光雷达逆传感器模型(Inverse Sensor Model)
  • gmapping与Cartographer算法核心差异对比
  • 实际工程中的选型建议与避坑指南

3.1 概率栅格地图原理

先问一个问题:地图里的每个格子,到底该标记为“有障碍物”还是“没有障碍物”?

直接给0或1太武断了。传感器有噪声,测量有误差,你永远无法100%确定某个格子到底有没有东西。所以,我们引入概率。

每个栅格(cell)维护一个概率值 p(m_i = 1),表示该格子被占据的概率。初始时,我们通常设为0.5,表示完全未知。

当激光雷达打出一束射线,我们就要根据测量结果来更新这个概率。更新公式用的是贝叶斯法则的变体——对数几率(Log-Odds)形式。

// 对数几率更新公式
l(m_i | z_t, x_t) = l(m_i | z_t, x_t) + l(m_i) - l(m_i_prior)

// 其中:
// l(m_i) = log( p(m_i) / (1 - p(m_i)) )
// l(m_i_prior) 是初始先验对数几率
// l(m_i | z_t, x_t) 是逆传感器模型给出的测量对数几率

为什么用对数几率?因为加法比乘法好算,而且数值稳定。我早期做项目时直接拿概率相乘,结果浮点数下溢得一塌糊涂,后来老老实实换成了Log-Odds,问题立刻解决。

个人经验:在实际嵌入式平台上,建议将概率值映射到整数区间(比如0~100),用查表法代替对数运算,能省下不少CPU周期。我在STM32H7上做过测试,整数查表比浮点log快了一个数量级。

3.2 激光雷达逆传感器模型

逆传感器模型,说白了就是:给定一次激光测量结果,反过来推断每个栅格被占据的概率是多少。

举个例子。激光雷达打出一束射线,测到距离是3米。那么:

  • 射线路径上(0~3米)的格子:大概率是空闲(free)
  • 终点(3米处)的格子:大概率是占据(occupied)
  • 终点之后的格子:未知(unknown),因为没有信息

但实际没这么简单。激光有波束宽度,有测量噪声,还有多路径反射。所以我们需要一个概率模型来描述这种不确定性。

我常用的一个简化模型长这样:

// 逆传感器模型伪代码
function inverseSensorModel(z, x, cell_position):
    r = distance(cell_position, x)  // 格子到传感器中心的距离
    phi = angle(cell_position, x)   // 格子相对于传感器朝向的角度

    if r > z + alpha/2 or |phi| > beta/2:
        return l_prior  // 超出测量范围,保持先验

    if |r - z| < epsilon:
        return l_occ     // 终点附近,标记为占据

    if r < z:
        return l_free    // 路径上,标记为空闲

    return l_prior

这里的 alpha 是距离不确定性,beta 是角度不确定性,epsilon 是终点判定阈值。这些参数需要根据实际激光雷达的噪声特性来调。

我曾经踩过的坑:有一次在玻璃幕墙环境下测试,激光直接穿透玻璃打到后面的墙上,导致地图上出现大量“鬼影”障碍物。后来我在逆传感器模型里加入了最大距离截断和多回波处理,才把这个问题压下去。如果你也在做室内导航,务必注意玻璃、镜面等反射材质。

3.3 gmapping vs Cartographer:核心差异对比

这两个算法是ROS生态里最常用的2D激光SLAM方案。很多新手问我:“老师,我该用哪个?”

我的回答是:看场景。下面这张表可以帮你快速决策。

对比维度 gmapping Cartographer
核心思想 粒子滤波(RBPF) 图优化(Graph SLAM)
地图表示 概率栅格地图 概率栅格地图 + 子图(Submap)
闭环检测 依赖粒子多样性,弱 基于分支定界搜索,强
计算资源 低(适合嵌入式) 高(需要GPU或强CPU)
建图精度 中等,易漂移 高,闭环后全局一致
实时性 好,轻量级 较好,但需调参
适用场景 小场景、低成本硬件 大场景、高精度需求

我个人的经验是:如果你用的是树莓派+RPLIDAR这种低成本组合,gmapping是更稳妥的选择。但如果你做的是仓储机器人、商用清洁机器人,需要在大面积环境里稳定运行,那Cartographer是必选项。

3.4 算法流程对比:一张图看懂

下面这张SVG图,我把两个算法的核心流程画了出来。你可以对照着看,理解它们各自的关键步骤。

gmapping vs Cartographer 核心流程对比 gmapping (粒子滤波 RBPF) 1. 根据运动模型采样新粒子 2. 激光扫描匹配 → 更新粒子权重 3. 重采样(低方差采样) 4. 更新占据栅格地图 ⚠ 无显式闭环检测,依赖粒子多样性 Cartographer (图优化) 1. 局部子图构建(实时扫描匹配) 2. 插入子图 → 维护位姿图 3. 后台闭环检测(分支定界搜索) 4. 全局优化 → 更新所有位姿 ✅ 闭环后全局地图一致性高 关键差异总结 • gmapping:轻量、实时、适合小场景;无闭环,长距离会漂移 • Cartographer:精度高、闭环强、适合大场景;计算资源需求高 • 选型建议:低成本嵌入式选gmapping,高精度商用选Cartographer

3.5 工程选型建议与避坑

最后,我结合自己的项目经验,给你几条实在的建议。

  1. 不要盲目追求“最新”。Cartographer虽然精度高,但参数调起来非常痛苦。我见过有人调了两个月还没跑通闭环。如果你的场景只有几十平米,gmapping完全够用。
  2. 注意传感器同步。无论是gmapping还是Cartographer,对激光雷达和里程计的时序同步要求都很高。我习惯在驱动层就打上硬件时间戳,而不是靠ROS的近似时间同步。
  3. 地图分辨率不是越高越好。5cm分辨率在很多场景下已经足够。分辨率太高,不仅内存爆炸,而且更新频率跟不上,反而容易导致地图不一致。
  4. 逆传感器模型的参数要实测标定。不要照搬里的数值。拿一把卷尺,在几个距离上实测激光的噪声分布,然后反推模型参数。这一步偷懒,后面建图质量会大打折扣。

一个小技巧:在调试阶段,把每个栅格的对数几率值实时可视化出来,而不是只看最终的二值地图。这样你能直观看到“不确定性”的分布,快速定位传感器噪声或运动畸变的问题。

好了,这一章的内容就到这里。占据栅格地图是SLAM的基石,逆传感器模型是连接测量和地图的桥梁,而gmapping和Cartographer则是两种典型的实现路径。理解了这些,你就能根据实际需求做出合理的技术选型。