4. 环境感知与建图(上):占据栅格地图原理、Gmapping SLAM算法原理与实战

各位同学,大家好。今天我们进入一个非常核心的话题——环境感知与建图。说白了,就是让机器人知道“我在哪”以及“周围长什么样”。

我个人习惯把建图比作“给机器人配一副眼镜”。没有地图,路径规划就是瞎指挥。今天我们先聊上半部分:占据栅格地图的原理,以及经典的Gmapping SLAM算法。

4.1 占据栅格地图:机器人的“视力表”

先问大家一个问题:机器人怎么表示一个房间?用照片?用CAD图纸?都不对。机器人用的是占据栅格地图(Occupancy Grid Map)

简单来说,就是把环境切成一个个小格子。每个格子存一个概率值:0表示绝对空,1表示绝对有障碍物,0.5表示未知。

核心公式(贝叶斯更新)

每个栅格的状态更新,其实是一个贝叶斯滤波过程:

P(occ | z) = P(z | occ) * P(occ) / P(z)

实际工程中,我们通常用对数几率(log-odds)来避免数值下溢:

l_i = l_i + log( P(z|occ) / P(z|free) )

我在项目中遇到过一个问题:直接用概率相乘,很快所有格子都变成0或1了,失去了不确定性。后来改用对数形式,才稳定下来。嗯,这里要注意,初始值一般设为0(对应概率0.5)

4.2 占据栅格地图的更新流程

机器人每走一步,激光雷达扫一圈,我们就更新一次地图。流程如下:

  1. 射线投射:从机器人位置出发,沿激光方向打一条射线。
  2. 命中点:射线终点对应的栅格,标记为“占据”。
  3. 穿过的栅格:射线路径上的其他栅格,标记为“空闲”。
  4. 更新概率:用贝叶斯公式更新每个栅格的log-odds值。

避坑指南

我曾经在更新时忘了处理“未知区域”。结果机器人一开机,地图全是黑的。后来加了一个判断:如果栅格从未被观测过,跳过更新。这才正常。

4.3 Gmapping SLAM:经典中的经典

Gmapping 是ROS里最常用的2D SLAM算法。它基于粒子滤波(RBPF),说白了就是:用一堆粒子来猜机器人的位姿,每个粒子带一张地图。

为什么它这么流行?因为它在小场景(比如家庭、办公室)里又快又准。我当年做扫地机器人项目,第一版用的就是Gmapping,效果相当不错。

4.4 Gmapping的核心原理

Gmapping 的核心思想是:先估计位姿,再更新地图。具体分三步:

  • 提议分布:用里程计+激光雷达的观测,生成粒子的候选位姿。
  • 权重计算:每个粒子根据观测与地图的匹配程度,计算权重。
  • 重采样:扔掉权重低的粒子,复制权重高的粒子。

你想想看,如果只用里程计,粒子会越散越开。但Gmapping用激光雷达的观测来“拉回”粒子,这就是它精度高的原因。

注意

Gmapping 对激光雷达的帧率有要求。我试过用5Hz的雷达,结果粒子发散得一塌糊涂。建议至少10Hz以上。

4.5 实战:在ROS中运行Gmapping

好了,理论讲完,我们直接上手。以下是我在ROS Noetic上跑Gmapping的步骤:

4.5.1 安装与启动

# 安装Gmapping
sudo apt install ros-noetic-gmapping

# 启动Gmapping节点
rosrun gmapping slam_gmapping scan:=/scan

这里要注意,scan:=/scan 是把激光雷达的话题重映射到Gmapping默认的输入话题。如果你的雷达话题是/laser/scan,就改成scan:=/laser/scan

4.5.2 参数调优

Gmapping 的参数很多,但核心就几个:

参数名 默认值 说明
particles 30 粒子数。越大越准,但越慢。我一般设50~80。
delta 0.05 地图分辨率(米/像素)。0.05就是5cm一格。
linearUpdate 1.0 机器人移动多少米触发一次更新。
angularUpdate 0.5 机器人旋转多少弧度触发一次更新。

我的经验

如果地图出现“重影”,通常是linearUpdate设得太大了。我一般设0.5米,效果会好很多。

4.6 知识体系总览

为了让大家更直观地理解本章的知识结构,我画了一张图:

环境感知与建图(上)知识体系 占据栅格地图 Gmapping SLAM ROS实战 贝叶斯更新 对数几率 射线投射 概率更新 粒子滤波 提议分布 权重计算 重采样 节点启动 话题重映射 参数调优 地图保存 核心逻辑:先估计位姿 → 再更新地图 → 循环迭代 最终输出:一张完整的占据栅格地图 + 机器人轨迹

4.7 实战中的常见问题

最后,分享几个我踩过的坑:

  • 地图漂移:通常是里程计不准。可以试试增加粒子数,或者用IMU辅助。
  • 建图速度慢:把particles从30降到20,或者增大linearUpdate
  • 地图有空洞:激光雷达的盲区。可以调整雷达安装高度,或者用多传感器融合。

一句话总结

占据栅格地图是机器人的“视力表”,Gmapping是“配眼镜的师傅”。两者结合,才能让机器人看清世界。

专注资料整理