SLAM 完整原理:從機率表述到 EKF、粒子濾波與圖優化三大解法

2026-07-24
  • slam
  • ekf-slam
  • particle-filter
  • pose-graph
  • loop-closure
  • bundle-adjustment

問題定義

SLAM(Simultaneous Localization and Mapping,同步定位與建圖)要解決的是:一個機器人在完全未知的環境裡移動,只有里程計(odometry,可能有噪聲與漂移)與感測器觀測(相機、光達,同樣有噪聲),要同時估計自己走過的位姿軌跡,以及環境的地圖。用機率語言表示,SLAM 要求解的是以下聯合後驗機率分布:

p(x1:t,mz1:t,u1:t)p(x_{1:t}, m \mid z_{1:t}, u_{1:t})

其中 x1:tx_{1:t} 是機器人從時刻 1 到 tt 的位姿軌跡、mm 是地圖(可能是地標點集合、或佔據網格)、z1:tz_{1:t} 是感測器觀測序列、u1:tu_{1:t} 是控制輸入(或里程計讀數)序列。這個聯合分布同時包含位姿與地圖兩組互相耦合的未知數,正是前面 FAQ 提到「先有雞先有蛋」困難的數學表達——地圖 mm 的估計依賴軌跡 x1:tx_{1:t},軌跡的估計又依賴地圖提供的參考點,兩者必須聯合求解,不能拆開依序處理。

兩大解法路線:濾波 vs 圖優化

歷史上 SLAM 的解法可以分成兩條主要路線,理解這個分野是理解整個 SLAM 領域演進脈絡的關鍵。

濾波路線(Filtering) 把問題表述成遞迴狀態估計:只維護「目前時刻」的狀態估計(機器人目前位姿 + 地圖),每次新的觀測進來就更新這個估計,不重新處理過去的所有資料,因此是嚴格意義上的線上(online)演算法,記憶體與計算量不隨時間累積增長(但可能隨地圖大小增長,見下面 EKF-SLAM 一節)。EKF-SLAM 與 FastSLAM(Rao-Blackwellized 粒子濾波)都屬於這條路線。

平滑/圖優化路線(Smoothing / Graph-based) 把整個問題表述成一個大型非線性最小平方最佳化問題:同時對整條軌跡的所有位姿與地圖做聯合最佳化,不只是遞迴更新目前狀態。這條路線在計算上通常更貴(要重新最佳化整個圖,或至少一個滑動窗口),但精度與一致性明顯更好,因為每次迴圈閉合都能把整條軌跡的誤差重新分散修正,而不只是修正目前這一個時刻。現代主流 SLAM 系統(ORB-SLAM、LOAM、Cartographer、LIO-SAM 等)幾乎都是這條路線。

EKF-SLAM:狀態擴增與地標相關性

EKF-SLAM 把機器人位姿與所有已觀測到的地標位置全部塞進同一個擴增狀態向量:

x^=[xrobotm1m2mn],P=[PxxPxm1PxmnPm1xPm1m1Pm1mnPmnxPmnxPmnmn]\hat{x} = \begin{bmatrix} x_{\text{robot}} \\ m_1 \\ m_2 \\ \vdots \\ m_n \end{bmatrix}, \qquad P = \begin{bmatrix} P_{xx} & P_{xm_1} & \cdots & P_{xm_n} \\ P_{m_1x} & P_{m_1m_1} & \cdots & P_{m_1m_n} \\ \vdots & \vdots & \ddots & \vdots \\ P_{m_nx} & P_{m_nx} & \cdots & P_{m_nm_n} \end{bmatrix}

預測步驟:用運動模型 g(ut,xt1)g(u_t, x_{t-1}) 預測機器人位姿如何隨控制輸入變化,地標位置本身假設靜止不動(mim_i 在預測步驟不變),協方差矩陣依運動模型的雅可比矩陣 GtG_t 傳播:

xˉt=g(ut,xt1),Pˉt=GtPt1GtT+Rt\bar{x}_t = g(u_t, x_{t-1}), \qquad \bar{P}_t = G_t P_{t-1} G_t^T + R_t

更新步驟:當機器人觀測到一個地標,用觀測模型 h(xt,mi)h(x_t, m_i)(例如量到地標相對機器人的距離與方位角)算出預測觀測值與實際觀測值的差距(新息,innovation),透過卡爾曼增益 KtK_t 修正整個狀態向量:

Kt=PˉtHtT(HtPˉtHtT+Qt)1,xt=xˉt+Kt(zth(xˉt)),Pt=(IKtHt)PˉtK_t = \bar{P}_t H_t^T (H_t \bar{P}_t H_t^T + Q_t)^{-1}, \qquad x_t = \bar{x}_t + K_t(z_t - h(\bar{x}_t)), \qquad P_t = (I - K_t H_t)\bar{P}_t

這裡有個容易被忽略、但是 EKF-SLAM 最關鍵的洞察:即使某次觀測只量到一個地標,更新步驟透過卡爾曼增益的矩陣運算,會同時修正機器人位姿估計、以及所有其他地標的位置估計——因為協方差矩陣裡的交叉項 PxmiP_{xm_i}PmimjP_{m_im_j} 記錄了地標之間、地標與機器人之間透過共同觀測歷史累積出的相關性。這個相關性正是 EKF-SLAM 能夠利用「重新觀測到一個舊地標」來修正其他從未直接被這次觀測涉及的地標的數學機制。但這個好處是有代價的:協方差矩陣是 (3+2n)×(3+2n)(3+2n) \times (3+2n)nn 是地標數,2D 情況下每個地標佔 2 維),每次更新需要對這個矩陣做矩陣乘法,計算複雜度是 O(n2)O(n^2),地標數一多(幾千個以上)就會變得無法即時運算,這是 EKF-SLAM 在大規模場景下被淘汰的主因。

FastSLAM:Rao-Blackwellized 粒子濾波如何繞開 O(n²)

FastSLAM 的關鍵洞察是對 SLAM 後驗做因式分解(Rao-Blackwellization):

p(x1:t,mz1:t,u1:t)=p(x1:tz1:t,u1:t)i=1np(mix1:t,z1:t)p(x_{1:t}, m \mid z_{1:t}, u_{1:t}) = p(x_{1:t} \mid z_{1:t}, u_{1:t}) \prod_{i=1}^{n} p(m_i \mid x_{1:t}, z_{1:t})

這個分解成立的關鍵前提是:如果機器人的完整軌跡已知,各個地標的位置估計彼此條件獨立——因為地標之間的相關性完全是透過共享的、不確定的機器人軌跡間接產生的,一旦軌跡已知(不再不確定),這條相關性的橋樑就斷開了。

FastSLAM 用粒子濾波表示軌跡的分布 p(x1:t)p(x_{1:t} \mid \cdot):每個粒子代表一條完整軌跡的假設,而每個粒子各自獨立維護一套自己的地標估計(通常每個地標用一個獨立的小型 EKF,因為條件獨立,這些小型 EKF 彼此之間不需要協方差交叉項)。這帶來的好處是:地標更新的計算複雜度從 EKF-SLAM 的 O(n2)O(n^2)(因為要更新整個大協方差矩陣的交叉項)降到 O(n)O(n)(每個地標的小 EKF 互相獨立,可以並行更新),代價是需要維護多個粒子(每個粒子都是一整套獨立的地圖假設),粒子數不夠多時,地圖估計的多樣性可能不足以涵蓋真實的不確定性,也存在粒子退化(particle degeneracy)的問題——多次重採樣之後,多樣性可能會坍縮成極少數幾條軌跡假設。

圖優化:把 SLAM 重新表述成非線性最小平方問題

現代主流 SLAM 後端把問題表示成一個圖:節點是各時刻的機器人位姿(或地標位置),是節點之間的約束——里程計邊連接相鄰時刻的位姿(約束來自運動模型或視覺/光達里程計)、觀測邊連接位姿與地標(約束來自感測器觀測)、迴圈閉合邊連接兩個時間上相隔很遠、但被辨識出是同一個實際地點的位姿節點。

整個問題化簡成一個非線性最小平方問題:找出一組位姿與地標估計,使得所有邊的約束殘差平方和最小:

minx1:t,m (i,j)edgeseij(xi,xj)Σij12\min_{x_{1:t}, m} \ \sum_{(i,j) \in \text{edges}} \left\| e_{ij}(x_i, x_j) \right\|_{\Sigma_{ij}^{-1}}^2

eije_{ij} 是邊 (i,j)(i,j) 的殘差函數(例如預測的相對位姿變換跟里程計量測值之間的差距),Σij\Sigma_{ij} 是該約束的不確定性協方差。這個問題用 Gauss-Newton 或 Levenberg-Marquardt 迭代求解,關鍵的工程優化是:這個問題的雅可比矩陣是稀疏的(每個約束只涉及少數幾個節點,不像 EKF 那樣是稠密矩陣),可以用稀疏 Cholesky 分解等技術大幅加速求解——這正是圖優化即使規模比 EKF-SLAM 大上幾個數量級(幾萬個位姿節點),仍然能維持可行計算時間的關鍵原因,也是 g2o、GTSAM、Ceres Solver 這些圖優化函式庫存在的核心價值。

迴圈閉合(loop closure)在圖優化框架下的角色特別關鍵:機器人長時間移動累積的里程計漂移,會讓軌跡估計逐漸偏離真實路徑;當機器人回到一個先前去過的地點,辨識出「這裡我來過」並加入一條迴圈閉合邊之後,圖優化會把這個新約束跟其餘所有邊一起重新求解,讓累積誤差沿著整條軌跡重新分散、大幅修正——這是圖優化相對純里程計遞推估計最大的優勢,也是為什麼迴圈閉合是所有 SLAM 系統精度的關鍵瓶頸(見 FAQ 中誤判迴圈閉合造成災難性錯誤的討論)。

前端與後端的架構切分

實務上幾乎所有現代 SLAM 系統都切分成兩個模組:前端(front-end) 負責處理原始感測器資料、抽取特徵、做資料關聯(data association,判斷這次觀測對應到地圖上哪個已知地標,或是否為新地標)、估計相鄰幀之間的相對運動;後端(back-end) 拿前端產生的約束(位姿節點與邊)做圖優化,輸出全域一致的軌跡與地圖估計。這個切分讓兩個問題可以獨立最佳化——前端關注感知與資料關聯的正確性,後端關注大規模非線性最佳化的效率與數值穩定性,ORB-SLAM 的三線程架構就是這個前後端切分思路的具體實作案例。

常見錯誤

  • 資料關聯錯誤沒有嚴格把關:把一次觀測錯誤地關聯到錯誤的地標(或錯誤地判定為新地標),這個錯誤會直接污染後續所有依賴這個地標的估計,是 SLAM 系統最常見、也最難事後修復的錯誤來源。
  • EKF-SLAM 線性化誤差長期累積導致濾波器過度自信(inconsistency):EKF 每一步都用局部線性近似,長期運行下這些近似誤差會累積,導致濾波器估計出的協方差(不確定性)比真實誤差小得多,濾波器「以為自己很準」但實際上已經明顯偏移,這是 EKF-SLAM 相對圖優化在長時間運行穩定性上的結構性弱點。
  • 迴圈閉合候選沒有做嚴格幾何驗證就直接加入圖優化:外觀相似但實際上是不同地點(例如同一種走廊重複出現)容易造成誤判,沒有幾何一致性檢查(例如驗證特徵匹配後估計出的相對變換是否合理)會讓錯誤約束進入優化問題,產生地圖結構錯亂。
  • 把濾波方法用在需要大規模迴圈閉合的長時間運行場景:EKF-SLAM 與 FastSLAM 在地標數量大、需要頻繁全域一致性修正的場景下,計算與精度都明顯不如圖優化,選錯解法路線會讓系統在規模擴大後直接不可用。

延伸閱讀

常見問題

faq_01.log
SLAM 為什麼被稱為『先有雞先有蛋』的問題?
因為定位(localization)需要一張已知的地圖才能把感測器量到的特徵跟地圖比對、算出自己在哪;建圖(mapping)則需要知道自己精確的位置軌跡,才能把感測器觀察到的特徵正確地擺放到地圖上的絕對座標。SLAM 要求兩者同時從零開始估計——沒有地圖就沒辦法定位,沒有精確的位置就沒辦法建出準確的地圖,這個相互依賴的循環正是 SLAM 在演算法設計上比單獨的定位或建圖問題困難得多的根本原因,也是為什麼幾乎所有 SLAM 解法都必須用機率方法同時對位置與地圖的不確定性建模,而不能簡單地分成兩個獨立步驟依序求解。
faq_02.log
EKF-SLAM 現在還有人用嗎,還是已經完全被圖優化取代?
在特徵地標數量少、需要嚴格線上(online)即時估計、且系統本身就已經接近線性的應用裡(例如只追蹤幾十個信標或標記點的室內定位系統),EKF-SLAM 因為結構簡單、有明確的機率一致性理論分析,仍然有人使用。但在特徵點數以千計、且需要處理大範圍迴圈閉合的現代視覺/光達 SLAM 系統裡,EKF-SLAM 的 O(n²) 計算與記憶體複雜度、以及線性化誤差長期累積導致的不一致性問題,讓它幾乎完全被圖優化方法取代——這也是為什麼 ORB-SLAM、LOAM、Cartographer 這些主流現代 SLAM 系統的後端都是圖優化,而不是濾波器。
faq_03.log
迴圈閉合失敗(誤判)跟迴圈閉合漏掉,哪個對系統的傷害比較大?
誤判(false positive,把兩個實際上不同的地點錯誤地判定為同一個地點並加入迴圈閉合約束)的傷害通常遠大於漏掉(false negative,錯過了一次真實的迴圈閉合機會)。漏掉迴圈閉合只是讓系統的累積漂移沒有被修正,地圖仍然是自洽的、只是全域座標偏移;但一個錯誤的迴圈閉合約束會在圖優化中強行把兩個不該連在一起的位姿節點拉近,這會讓優化器產生一個在數學上『自洽』但物理上完全扭曲、錯亂的地圖——地圖可能出現折疊、交錯這類災難性的結構錯誤,而且優化器本身通常沒有辦法自動分辨這個約束是錯的。這也是為什麼幾乎所有實用 SLAM 系統的迴圈閉合模組,都會在候選匹配之後加上嚴格的幾何驗證(geometric verification)步驟,寧可保守地拒絕一些真實的迴圈閉合,也要盡量把誤判率壓到接近零。