Non-linear Optimization

SLAM 状态估计最终都归结为最小化一个代价函数

F(x)=12iei(x)Σi12F(\mathbf{x}) = \frac{1}{2}\sum_i \|\mathbf{e}_i(\mathbf{x})\|^2_{\Sigma_i^{-1}}

该函数是关于状态 x\mathbf{x}(位姿、地图点、偏置)的函数,其中每个 ei\mathbf{e}_i 是一个残差——可以是重投影误差、里程计误差或 IMU 误差——并按其逆协方差加权。这些残差相对于状态是非线性的:相机投影涉及除以深度,而旋转位于一个弯曲的流形上。因此不存在闭式解,我们必须进行迭代。

迭代下降的通用模板

所有实用求解器都共享同一个循环:从初始猜测 x0\mathbf{x}_0 出发,反复寻找能降低代价的更新量 Δx\Delta\mathbf{x},应用它,并在更新量或梯度变得足够小时停止。不同方法的区别在于如何选取 Δx\Delta\mathbf{x}

在流形上进行优化

相机位姿是 SE(3)\mathrm{SE}(3) 中的元素,而不是向量——如果简单地将更新量加到旋转矩阵上,会破坏其正交性。标准的解决方法是在李代数中优化一个局部扰动 ξR6\boldsymbol{\xi} \in \mathbb{R}^6,并通过指数映射将其应用回去:

TTexp(ξ^)T \leftarrow T \cdot \exp(\hat{\boldsymbol{\xi}})

求解器始终只看到小向量 ξ\boldsymbol{\xi};这个回缩(retraction)操作使状态保持在流形上。每个 SLAM 库都实现了这一点(Ceres 中的局部参数化,g2o 中顶点的 oplus,GTSAM 中的 retraction)。

什么使得 SLAM 问题可解

解读求解器的输出

迭代会在以下实用准则下停止:每次迭代的代价下降量低于某个容差、更新量的范数 Δx\|\Delta\mathbf{x}\| 变得可忽略、梯度范数趋近于零,或迭代次数/时间预算耗尽(实时系统通常将每个关键帧的光束法平差限制在少数几次迭代内)。当求解出问题时,症状能对应到具体原因:代价爆炸通常意味着初始猜测不好或雅可比矩阵有 bug;代价停滞在较高水平且每步更新都很小,则可能是收敛到了较差的局部最小值,或存在未建模的外点;正规方程矩阵秩不足则指向不可观测的方向(规范自由度、未约束的地图点),需要引入先验或加以固定。

对SLAM的意义

现代每一个 SLAM 系统的后端——光束法平差、位姿图优化、VIO 滑动窗口、直接光度对齐——都是在流形上用高斯-牛顿/LM 迭代求解的稀疏非线性最小二乘问题的一个实例。概率视角(MLE & MAP)说明最小化什么;非线性优化说明如何最小化。熟练掌握这部分内容会在各处产生回报:读懂一篇论文中”我们最小化以下能量函数”的段落、诊断发散问题(初始化不好?参数化方式错误?存在外点?),以及有效使用 Ceres/g2o/GTSAM,都建立在这些知识之上。

动手实践

相关条目