两个互相依赖的问题
想象你在一栋陌生的大楼里醒来,没有地图,也不知道身在何处。要弄清自己在哪,你得拿眼前所见去比对一张地图——可你没有地图。于是你改为亲手画一张,边走边把每个房间画下来。但要把房间画在图上的正确位置,你得知道自己看到它时站在哪——而这恰恰是你不知道的。两件事都在等对方先动手。
这就是先有鸡还是先有蛋这一悖论的核心。定位,即算出机器人在哪,通常假定你已经有一张可供比对的地图。建图,即构建对世界的模型,通常假定你已经知道机器人的位姿,这样每次测量才能放到正确位置。有地图,找位姿就容易;知道位姿,画地图也容易。两样都没有,看上去就卡住了。
同时定位与建图(SLAM)跳出这个陷阱的办法,是干脆不去选谁先来。它不先求位姿再求地图,而是把两者放在一起求解,当作一个彼此缠绕的大估计,随着机器人移动不断扩展、不断收紧。这个诀窍并非魔法——它依靠的是这样一个事实:每一次新测量都会同时透露一点点关于地图的信息和一点点关于位姿的信息。
同时求解两者
走出这个循环的办法是自举。机器人先信任自己的运动。车轮转动、惯性传感器,或匹配的相机帧,能给出里程计——对自上一时刻以来移动了多远、朝哪个方向的一个滚动估计。这足以得出一个粗略的初始位姿,从而把最初的观测摆成一张粗略的初始地图。地图很晃,位姿也很晃,但两者都不再是空白了。
从那以后,两个估计便互相牵引。单靠里程计会漂移:每一步的小误差不断累积,走久了机器人对自身位姿的判断可能偏出好几米。但当机器人看到一面先前已建图的墙时,那个旧地图特征就像一个锚点,把漂移的位姿拉回来。作为回报,更准的位姿又让机器人修正每个地图特征的真实位置。一轮又一轮,二者彼此修补。
这也解释了为何回到已知地点如此有力。当机器人认出一处很久以前到过的地方——即回环检测——它能把一整段漂移的轨迹一下子拉回对齐,而这一修正会顺着共享的不确定性流过去,把地图也一并修好。在对的位置上一次好的观测,就能理清积攒了好几分钟的误差。
前端与后端
真正的 SLAM 系统会把工作分成扮演截然不同角色的两半。这种划分为前端与后端,是整个领域里最有用的心智模型之一,因为它把读取传感器这件杂乱的活,与处理几何这件干净的活分了开来。
决定成败的那个安静步骤:数据关联
上面所有内容都立在一个明摆着却容易被忽视的假设上:前端正确地判定每一个新观测对应于它之前见过的哪样东西。这就是数据关联问题,它是那个不声不响、却决定整个系统成败的步骤。判对了,后端就有干净的约束去优化;判错了,你就给侦探递了一张伪造的便条。
危险在于世界充满了相似之物。两条办公走廊、两根一模一样的柱子、两段平淡的白墙,都能骗过匹配器,让它以为机器人身处某个并不在的地方。仅仅一次错误匹配——比如,在两个不过是长得像的地方之间宣布一次错误的回环检测——就能把整张地图扯进一道再也无法挽回的褶皱。正因如此,对着一张干净的地标地图做关联,并用几何(而不只是外观)来确认匹配,才如此重要。
好的系统对数据关联深怀戒心。它们要求一次匹配不仅在特征长什么样上吻合,还要在「以当前位姿估计来看它本应在哪」上吻合;它们剔除任何无法用自洽几何解释的离群点;它们宁可保持存疑,也不轻易认定一个可能错误的猜测。SLAM 那个精巧的循环弥合了先有鸡还是先有蛋的裂缝——但前提始终是:它把对的蛋配给了对的鸡。