把後端看成一張圖
到現在你已經知道,SLAM 要求機器人一邊確定自己在哪裡,一邊繪製它賴以定位的那張地圖。前面幾節把這件事拆成兩半:前端把原始感測器資料轉成測量值,後端把所有資訊融合成一個一致的估計——這就是前端/後端的分工。本節講的是現代後端,而思考它最主流的方式非常直觀:把它看成一張圖。
在位姿圖 SLAM中,機器人停留過的每個位置都是一個節點,裡面裝著一個位姿——也就是位置加朝向的猜測。節點之間的邊就是測量值:「從這裡,我向前開了兩公尺,再稍微左轉。」每條邊都是一個約束,規定了兩個位姿之間應有的關係。關鍵在於,這些邊彼此略有矛盾,因為每次測量都帶著雜訊。這張圖被「過度約束」,還略微自相矛盾,而後端的任務,就是找出那唯一一種位姿排布,讓所有這些帶雜訊約束盡可能都得到滿足。
藏在它背後、更一般的表述是因子圖。在因子圖裡,我們想估計的量(位姿,有時還有路標位置)是一類節點;而每個測量都化作一個小函數——一個因子——用來打分:一組候選取值把這次觀測解釋得有多好。位姿圖其實就是因子圖的一個特例,只不過它的因子恰好全是位姿對位姿的約束。因子圖是現代 SLAM 函式庫真正使用的語言,因為它讓你能把里程計、回環、GPS 與路標觀測,全都整齊地裝進同一個結構裡。
把圖拉緊
有一個畫面能讓位姿圖 SLAM 一下子說得通。把每個節點想像成一顆珠子,每條邊想像成一根小彈簧。每根彈簧都有一個「自然長度」——也就是那次測量,它認為兩顆珠子之間應有的距離和轉角。當珠子擺錯了位置,彈簧就被拉長或壓扁,從而儲存了能量。所有彈簧儲存的總能量,就是總誤差。所謂最佳化,無非是鬆手放開這些珠子,讓彈簧把一切拉扯到一個它們都能接受、能量最低的形狀。
彈簧並非一樣硬,這一點很重要。一個很有把握的測量——比如一次乾淨俐落的雷射掃描匹配——就是一根很硬的彈簧,強烈抗拒被拉伸;一個含糊的測量則是一根軟彈簧,最佳化器幾乎不付代價就能把它彎一彎。這種「軟硬」恰恰就是測量的確定度(嚴格地說,是其共變異數的逆)。當最佳化器把整張圖安頓下來時,硬彈簧幾乎不動,軟彈簧吸收掉大部分誤差——這正是我們希望「信任」流動的方式。
total_error = 0
for each edge (i, j) with measurement z and stiffness W:
predicted = relative_pose(node[i], node[j])
residual = predicted - z # how wrong this edge is
total_error += residual^T * W * residual # stiff W -> costly
# adjust all nodes to make total_error as small as possible用相機看世界
無論用什麼感測器去填那些邊,圖本身都是一樣的——但感測器的選擇,會徹底改變成本、強健性,以及你最終得到的地圖類型。第一大門類是視覺 SLAM,它用普通相機影像來建圖。它的吸引力一目了然:相機便宜、輕、功耗低,而一張影像資訊量驚人——紋理、顏色、標誌、人臉,應有盡有。從一幀到下一幀,系統用特徵描述子追蹤那些可辨認的影像點,再反推相機必定如何移動,才會讓這些點按觀察到的方式偏移。
這種豐富恰恰也是視覺 SLAM 的軟肋。相機看到的是光,而不是幾何,因此它任由光照擺布。開進漆黑的隧道、對著一面空白的白牆、掠過一扇刺眼的窗戶,或者面對一條沒有紋理的走廊,可追蹤的點就會消失——系統恰好在你最需要它的時候變成了瞎子。此外,單隻普通相機無法從一張影像讀出絕對尺度:它能看出有東西動了,卻分不清眼前是一公尺外的玩具屋,還是遠處一棟真房子。這正是視覺系統通常要再借一隻眼睛或另一種感官的原因。
常見的補救都很實際。用雙目相機或 RGB-D 相機能恢復真實距離,直接解決尺度問題。更好的做法,是把相機與慣性感測器配對——即視覺慣性里程計——讓二者互補彼此的盲區:在相機短暫致盲的瞬間,由慣性感測器撐住估計;而相機又反過來約束慣性感測器那種緩慢的漂移。便宜、豐富、卻怕光:一句話,這就是用相機的「划算帳」。
用雷射看世界
另一大門類是雷射雷達 SLAM。雷射雷達發出雷射脈衝並對回波計時,所以它不是「推斷」距離——而是直接測量距離,每秒數十萬到數百萬個點,從而生成點雲:一團密集的三維點噴霧,勾勒出機器人周圍每一個表面。因為它自帶光源,雷射雷達在漆黑中工作得和白天一樣好,也根本不在乎牆面是有花紋還是一片空白。視覺要去「猜」幾何,雷射雷達卻直接把幾何遞到你手裡。
那麼,雷射又是怎樣給出圖的邊的呢?靠掃描匹配:拿來剛才採到的那團點雲和現在採到的這團點雲,找出一組旋轉和平移,讓其中一團最嚴絲合縫地滑到另一團上。能讓兩次掃描對齊的那個運動,恰好就是機器人在這之間的移動。這裡的主力演算法是ICP——迭代最近點——它的迴圈簡單得近乎讓人不好意思,而這正是它歷經數十年仍屹立不倒的原因之一。
- 對新掃描中的每個點,在舊掃描裡找出離它最近的點,暫且把它們當作同一處表面——一次猜測的對應關係。
- 計算出唯一的一組旋轉和平移,使這些配對點平均而言被拉得最近。
- 把這個運動施加到新掃描上,讓它朝舊掃描挪過去。
- 重複:最近點的猜測越來越準,貼合越來越緊,幾輪之後兩團點雲便嚴絲合縫地咬合在一起。累積下來的運動,就是你要的那條邊。
雷射雷達的取捨恰與視覺相對。它的幾何精確、且不怕光照,但感測器更重、更貴、更耗電;而一團裸點雲雖幾何上完美,語義上卻是「啞」的——它知道那裡有個表面,卻不知道那是一扇門還是一個人。ICP 在幾何重複的地方也容易被騙:一條又長又沒特徵的走廊,無論你是否向前滑了一公尺,看上去都一個樣,於是掃描可以沿著它自由滑動,估計隨之漂移。實踐中,這正是為什麼穩健的系統會把兩個世界融合在一起——用雷射提供堅實的結構,用相機賦予含義。
前沿:更豐富、更聰明、能終身運行
經典 SLAM 滿足於一副稀疏的骨架——只要有足夠多的路標可供定位就行。而前沿想要的更多。稠密建圖重建出完整連續的表面,於是機器人拿到的不再是一團散點,而是一個滴水不漏的模型,可以在其中規劃路徑,甚至直接算圖渲染。語義建圖更進一步,借助語義分割之類的工具給幾何賦予含義:這一塊是地板,那是一把椅子,那是一道門。一張知道「東西是什麼」的地圖,機器人就能對它進行推理,而不只是繞開它。
在前端,手工設計的特徵偵測器正越來越多地與「學習得到的特徵」並肩工作——這些神經網路經過訓練,專挑那些在嚴苛光照、天氣和視角變化下依然可辨認的點。這類學習描述子尤其擅長為回環做地點識別,能看出兩張看起來天差地別的影像,其實是同一個房間角落。底下的圖和最佳化器幾乎紋絲不動;悄然飛躍的,是餵給它們的那些邊的品質。
最棘手的開放難題是終身 SLAM:在一個拒絕靜止的世界裡,讓一張地圖維持數月仍然可用。家具會挪動,季節會更替,店鋪會重新粉刷,停著的車來來去去。一張定格在初見那一刻的地圖,會慢慢變成一個謊言。終身系統必須判斷:什麼該當作永久的來信任,什麼該當作短暫的來遺忘,以及如何更新這張圖而不讓它無止境地膨脹下去——一個長住某地的機器人,應該隨著時間越來越會在那裡穿行,而不是越來越糊塗。