JOVANA
Library Glossary Getting Started Three Levels Fields How it works Mission
Join the mission
All guides

绘制地图:占据栅格地图

机器人如何把带噪声的测距数据,变成一张整洁的栅格地图,把每个格子标记为空闲、占据或未知。

建图是定位的反面

上一篇我们问的是:给定一张地图,我在哪里?这就是定位。现在我们把问题反过来。假设你已经知道自己的位姿——也就是每一刻的精确位置和朝向。那么,从传感器看到的东西里,你能了解到关于这个世界的什么呢?这个反过来的问题,就是机器人建图,它正是定位的镜像:定位是用已知的地图找出位姿,建图则是用已知的位姿来构建地图。

想象一台机器人带着旋转激光扫描仪在走廊里行进。每次扫描都告诉它:这个方向最近的墙在 3.2 米外,那个方向的墙在 1.8 米外。只要机器人知道自己站在哪里、朝着哪个方向,每一个读数就都指向房间里一个真实的位置。建图的全部任务,就是把数以百万计这样被指向的位置收集起来,整理成机器人之后真正能用得上的东西。

把世界切成格子

存储地图最常用的方式,就是占据栅格地图。它的思路妙在简单:在地面上铺一张棋盘,把世界切成一个个小方格——边长常常是 5 厘米或 10 厘米。每个格子只存一个数:那里有实体物体的概率。接近 1 表示「几乎肯定被占据」,接近 0 表示「几乎肯定是空的」,而 0.5 左右则表示「我真的拿不准」。

空闲、占据、未知这三种状态,正是机器人安全移动所需要的。空闲的格子是它可以行驶的地方;占据的格子是要避开的墙壁、家具和人;未知的格子则是边界——它还没看过的地方,而那恰恰是探索者下一步该去的方向。注意,栅格地图从不存「这是一把椅子」或「这是一道门」,它只存每个小方格有多满。这种朴素正是它的长处。

格子大小里悄悄藏着一个权衡。很小的格子能捕捉细节——细细的桌腿、窄窄的缝隙——但一个房间就需要数百万个格子,既吃内存,又拖慢每一次查询。大格子便宜又快,却会把小障碍物糊成实心的一团。选择格子大小,其实就是在选择你愿意为多少细节付出代价。

让每一次扫描投票

单独一次激光或深度读数,永远不能全信。LiDAR深度相机都受传感器噪声困扰:一束光可能擦到一粒尘埃、被玻璃反射,或者把距离多报了几厘米。所以,占据栅格地图不会让某一次读数把格子一锤定音,而是让每一次读数都投下一小票,格子相信的是群体,而不是任何单独一位投票者。

让一束光变得有信息量的诀窍就在这里。一次测距读数同时告诉你两件事。光束停下的那个点,很可能是被占据的——有东西挡住了它。但光束一路穿过、才到达那里的那整段空气,一定是空的,否则它会更早停下。所以,一条射线把一个格子推向「占据」,把它身后一连串格子推向「空闲」。这有时被称为逆传感器建模:从传感器的报告反推世界的样子。

  1. 取一次测距读数,用机器人已知的位姿,算出这束光在栅格里从哪里出发、又在哪里结束。
  2. 沿着从起点到终点的那一串格子走一遍,把每个格子都往「空闲」轻推一点——光束穿过了它们,所以它们是空的。
  3. 在光束停下的那个格子上,把它往「占据」轻推——那里有东西把光束反射了回来。
  4. 对扫描中的每一束光、以及机器人移动时的每一次扫描,都重复这个过程。有把握的格子会稳定在 0 或 1 附近;忽明忽暗、拿不准的格子,则在 0.5 附近徘徊。

正是这种投票的习惯,让地图能甩开噪声。一次把某个格子误画成占据的虚假反射,会在接下来光束十次干干净净地穿过时被票数压倒。栅格地图也悄悄应对着变化:当原本站在门口的人走开后,新涌入的「空闲」票会慢慢把他抹去。地图随着房间一起呼吸。

什么时候栅格地图是杀鸡用牛刀

占据栅格地图是一种稠密的度量地图:它锁定真实世界的距离,把地面的每一个方格都填满,无论那里有没有值得关注的东西。这让它非常适合在椅子腿间穿梭的扫地机器人,但对于一台横穿空旷大仓库的机器人来说就太浪费了——那数百万个格子,大多只是在说「空、空、空」。

一种更轻量的替代方案是路标地图(特征地图)。它不记录每一个格子,只记住一组稀疏的、有辨识度的点——这里一根柱子、那里一个墙角、装卸口上方一块醒目的标牌——以及它们的坐标。它存储起来便宜得多,匹配起来也快,但它对路标之间的空白一无所知,所以在绕开杂物方面就没那么直接好用。

更轻的还有拓扑地图,它干脆把精确距离全都丢掉,只保留一张「地点以及它们如何相连」的图:「大堂连着 A 走廊,A 走廊连着实验室。」这就像按比例绘制的平面图与地铁线路图之间的区别。这两种风格的对比——精确而稠密,对上稀疏而重连通——正是度量地图与拓扑地图的核心,而在两者间做选择,是机器人开发者最早要拍板的设计决定之一。