地图构建:占据栅格地图原理、SLAM基本概念、Gmapping与Cartographer简介
地图构建这事儿,说白了就是让机器人回答三个问题:我在哪?周围有什么?怎么过去? 我刚开始做机器人那会儿,以为地图就是一张照片,后来才发现完全不是那么回事。机器人看到的世界,跟我们人眼看到的完全不一样。
今天咱们就聊聊地图构建的核心——占据栅格地图,以及两个非常主流的SLAM方案:Gmapping和Cartographer。嗯,这里面的坑我踩过不少,慢慢跟你讲。
占据栅格地图:机器人的"格子本"
你想想看,机器人怎么表示一个房间?它没有"沙发"、"茶几"这种概念。最朴素的办法,就是把空间切成一个个小格子,每个格子记录"这里有东西吗"的概率。
这就是占据栅格地图(Occupancy Grid Map)的核心思想。
核心公式(贝叶斯更新)
l(m_i | z_{1:t}, x_{1:t}) = l(m_i | z_{1:t-1}, x_{1:t-1}) + l(m_i | z_t, x_t) - l(m_i)
其中 l 表示对数几率(log-odds),m_i 是第 i 个栅格,z 是观测,x 是位姿。
每个格子存一个值,范围从0到1:
- 0:空闲(比如走廊中间)
- 1:占据(比如墙)
- 0.5:未知(还没探测到)
我在项目里遇到过一个问题:直接用概率值做加法会溢出。后来改用对数几率(log-odds)就好多了。说白了就是把概率映射到(-∞, +∞)的实数域,加减法随便做,最后再映射回0~1。
工程小技巧
实际代码里,栅格值通常用整数表示,比如0~100。0代表空闲,100代表占据,50代表未知。这样省内存,计算也快。
SLAM基本概念:鸡生蛋还是蛋生鸡?
SLAM(Simultaneous Localization and Mapping)——同时定位与地图构建。这名字听着高大上,其实核心矛盾就一个:
要定位,得先有地图;要建图,得先知道位置。
这不就是鸡生蛋蛋生鸡吗?
解决办法是:一边猜一边修正。机器人先假设一个初始位置,然后根据传感器数据一点点修正地图,再用新地图反过来修正位置。循环往复,直到收敛。
我个人习惯把SLAM拆成三个子问题:
- 前端(Front-end):数据关联。把当前观测跟已有地图对上号。
- 后端(Back-end):优化。根据约束条件调整所有位姿和地图点。
- 回环检测(Loop Closure):认出"我来过这里",然后修正累积误差。
我曾经在一个大厂房里跑SLAM,跑了半小时,地图越偏越离谱。后来发现是回环检测没开——机器人转了一圈回来,不认得自己走过的路,误差就这么一点点攒起来了。
注意
回环检测不是万能的。如果环境对称性太强(比如全是白墙的走廊),回环检测很容易误匹配。我建议在特征明显的区域手动触发回环,或者加一些人工标记。
Gmapping:经典中的经典
Gmapping是基于粒子滤波(Particle Filter)的2D SLAM方案。它用一堆粒子来猜测机器人的可能位置,每个粒子带一张小地图。
核心思路:
- 每个粒子代表一个可能的机器人轨迹
- 根据激光雷达数据更新粒子权重
- 权重低的粒子被淘汰,权重高的粒子被复制
- 最后所有粒子加权平均,得到最终位姿
我当年第一次跑Gmapping,觉得它像个"笨办法"——用大量粒子暴力求解。但后来发现,在室内小场景里,它又快又稳。
| 特性 | Gmapping |
|---|---|
| 算法类型 | 粒子滤波(RBPF) |
| 适用场景 | 室内小场景(< 1000m²) |
| 传感器要求 | 激光雷达 + 里程计 |
| 优点 | 轻量、实时性好、调参简单 |
| 缺点 | 大场景粒子数爆炸、无回环检测 |
Gmapping有个致命伤:没有显式的回环检测。一旦走远,误差就收不回来了。所以它只适合小范围、闭环路径的场景。
Cartographer:Google的"大杀器"
Cartographer是Google开源的一套SLAM方案,支持2D和3D。它用图优化(Graph Optimization)代替了粒子滤波,解决了Gmapping在大场景下的痛点。
核心思路:
- 把每一帧激光数据建成一个"子图(Submap)"
- 子图之间通过约束连接成一个大图
- 定期做全局优化,把所有子图对齐
- 回环检测自动修正累积误差
Cartographer的"扫描匹配"核心
// 使用Ceres Solver做非线性优化
problem.AddResidualBlock(
new AutoDiffCostFunction<ScanMatcherCost, 2, 3>(...),
nullptr,
pose_estimate);
problem.Solve(&options, &summary);
这段代码把当前激光帧跟子图做匹配,找到最优位姿。
我去年在一个2000m²的仓库里跑Cartographer,效果出奇的好。跑了半小时,回环一检测,地图几乎没漂移。但代价是计算量大——普通工控机跑起来CPU直接拉满。
| 特性 | Cartographer |
|---|---|
| 算法类型 | 图优化(Graph SLAM) |
| 适用场景 | 大场景(> 1000m²)、复杂环境 |
| 传感器要求 | 激光雷达 + IMU + 里程计 |
| 优点 | 回环检测强、大场景稳定 |
| 缺点 | 计算量大、调参复杂 |
Gmapping vs Cartographer:怎么选?
我个人的经验是:
- 小房间、走廊、家庭环境 → 用Gmapping。省资源,调参快,够用。
- 大仓库、商场、工厂 → 用Cartographer。虽然重,但稳。
- 预算有限、硬件差 → 优先Gmapping。Cartographer对CPU和内存要求高。
- 需要3D建图 → 只能上Cartographer。Gmapping只支持2D。
避坑指南
我曾经在一个全是玻璃墙的展厅里跑SLAM,激光雷达直接穿透玻璃,地图上全是"幽灵点"。后来加了IMU做辅助,才勉强稳住。记住:激光雷达不是万能的,多传感器融合才是王道。
知识体系总览
下面这张图,把本章的核心逻辑串起来了。你可以把它当个"地图"——嗯,建图的地图。
嗯,地图构建这块内容不少,但核心就三件事:格子怎么表示、位置怎么猜、误差怎么消。Gmapping和Cartographer只是两种实现思路,理解了底层逻辑,换什么方案都不怕。
我建议你动手跑一跑。先拿Gmapping跑个室内小房间,再拿Cartographer跑个大走廊。对比一下地图质量和CPU占用,感受会深很多。