3. 数学基础(二):李群与李代数、指数映射与对数映射、扰动模型
好,咱们接着聊。上一章我们把三维空间里的旋转和变换捋了一遍,搞清楚了旋转矩阵、变换矩阵这些玩意儿。但有个问题不知道你发现没有——这些矩阵虽然好用,可一旦涉及到优化、求导,就特别麻烦。
为什么?因为旋转矩阵有约束条件。它必须是正交阵,行列式还得是1。你想想看,做优化的时候,我们通常是在参数空间里随便加一个小量,然后看结果怎么变。可你要是随便给旋转矩阵加个ΔR,它很可能就不再是旋转矩阵了。这就很头疼。
所以,我们需要一个更“自由”的表达方式。这就是李群和李代数登场的地方。
3.1 从“群”说起
先别被名字吓到。李群(Lie Group)说白了,就是一群连续变换的集合,而且这个集合本身还满足群的四条公理:封闭性、结合律、单位元、逆元。
我们最关心的,是三维空间里的旋转群 SO(3) 和刚体变换群 SE(3)。
- SO(3):所有3x3旋转矩阵的集合。它是个群,也是个光滑的流形。
- SE(3):所有4x4变换矩阵的集合。同样,它也是个李群。
那李代数又是什么?李代数(Lie Algebra)可以理解为李群在单位元处的“切空间”。
我打个比方。你想象一个光滑的球面,球面上的每个点代表一个旋转矩阵。那球面本身是李群。而球面上某一点(比如北极点)的切平面,就是李代数。在这个切平面上,你可以随便走,没有约束。这就方便多了。
核心思想:李群描述的是“状态”本身,李代数描述的是“状态的变化”。我们在李代数上做优化,再映射回李群,就能保证结果始终合法。
3.2 SO(3) 与 so(3)
对于 SO(3),它的李代数记作 so(3)。so(3) 里的元素是三维向量,或者说是三维向量的反对称矩阵。
具体来说,一个三维向量 φ = [φ₁, φ₂, φ₃]ᵀ,可以对应一个反对称矩阵:
φ^ = [ 0 -φ₃ φ₂
φ₃ 0 -φ₁
-φ₂ φ₁ 0 ]
这个 φ 其实就是我们常说的“旋转向量”。它的方向代表旋转轴,模长代表旋转角度。
我个人习惯把 so(3) 理解成“角速度的集合”。你想想看,一个刚体在旋转,它的瞬时角速度就是一个三维向量。这个向量就在 so(3) 里。
3.3 指数映射与对数映射
现在关键问题来了:怎么从李代数(切空间)跑到李群(流形)上?
答案是指数映射(Exponential Map)。
对于 SO(3) 和 so(3),指数映射就是 Rodrigues 公式:
R = exp(φ^) = I + (sinθ/θ) φ^ + ((1-cosθ)/θ²) (φ^)²
其中 θ = ||φ||。
反过来,从李群到李代数,就是对数映射:
φ = ln(R)^∨
这里的 ∨ 表示从反对称矩阵恢复成向量。
实用技巧:在实际代码里,我们很少真的去算指数映射的级数展开。直接用 Eigen 或 Sophus 库里的 SO3::exp() 和 SO3::log() 就行。我曾经手写过一次 Rodrigues 公式做验证,结果发现跟库函数结果完全一致,后来就再也没自己写过了。
3.4 SE(3) 与 se(3)
SE(3) 的情况类似。它的李代数是 se(3),元素是一个六维向量:
ξ = [ρ, φ]ᵀ
其中 ρ 是平移部分,φ 是旋转部分(也就是 so(3))。
se(3) 的指数映射稍微复杂一点:
T = exp(ξ^) = [ R t
0 1 ]
其中:
- R = exp(φ^)
- t = J ρ
- J 是左雅可比矩阵:J = (sinθ/θ) I + (1 - sinθ/θ) aaᵀ + ((1-cosθ)/θ) a^
这里 a = φ/θ 是单位旋转轴。
嗯,这个 J 矩阵看着有点复杂。不过别担心,在实际工程中,我们通常用 Sophus 库一行代码搞定:
Sophus::SE3d T = Sophus::SE3d::exp(xi);
3.5 扰动模型——为什么我们需要它?
好,现在到了最实用的部分。我们为什么要学李群李代数?说白了,就是为了求导。
在 SLAM 里,我们经常要优化位姿。比如,给定一个误差函数 e(T),我们要找 T 使得 e 最小。这就要用到导数。
但直接在李群上求导很麻烦。所以有两种方式:
- 用李代数表示位姿,然后对李代数求导。这叫“李代数求导模型”。
- 在李群上左乘一个小扰动,然后对扰动的李代数求导。这叫“扰动模型”。
我个人更推荐第二种。为什么?因为扰动模型更简洁,而且不涉及雅可比矩阵的复杂计算。
3.6 SO(3) 上的扰动模型
假设我们有一个旋转 R,对它左乘一个小扰动 ΔR = exp(δφ^)。那么:
∂(R p) / ∂δφ = - (R p)^
这个结果非常漂亮。它告诉我们:旋转一个点,然后对旋转的扰动求导,结果就是旋转后位置的反对称矩阵。
我在做 VIO 初始化的时候,经常用到这个公式。比如优化重力方向时,对旋转的雅可比矩阵就是靠这个算出来的。
3.7 SE(3) 上的扰动模型
对于 SE(3),扰动模型稍微复杂一点,但思路一样。
假设变换 T = [R, t],左乘扰动 ΔT = exp(δξ^),其中 δξ = [δρ, δφ]ᵀ。那么:
∂(T p) / ∂δξ = [ I, -(R p + t)^ ]
[ 0ᵀ, 0ᵀ ]
这个 4x6 的矩阵,就是空间点经过变换后,对位姿扰动的雅可比。
避坑指南:我曾经在写 BA(Bundle Adjustment)的时候,把扰动模型里的左乘和右乘搞混了。结果优化死活不收敛。后来查了半天才发现,左乘扰动和右乘扰动对应的雅可比矩阵差一个伴随变换。所以,一定要统一约定好是用左乘还是右乘。我个人习惯用左乘。
3.8 知识体系总览
为了让你更直观地理解这一章的知识结构,我画了一张图:
3.9 实战中的选择
在实际的 VIO 系统里,我们通常这样用:
| 场景 | 推荐方法 | 原因 |
|---|---|---|
| 优化旋转 R | SO(3) 扰动模型 | 雅可比简单,只有 3x3 |
| 优化位姿 T | SE(3) 扰动模型 | 统一处理旋转和平移 |
| 插值/平滑 | 李代数线性插值 | 避免万向锁 |
| 闭环检测 | 李群上的图优化 | 保证位姿约束 |
我的建议:刚开始接触的时候,别急着啃数学推导。先用 Sophus 库把指数映射、对数映射、扰动模型跑通。写几个小例子,比如随机生成一个旋转,用扰动模型算雅可比,跟数值微分对比一下。等用熟了,再回头理解背后的数学。这样效率最高。
好了,这一章的内容就到这儿。李群和李代数是 VIO 的数学基石,理解了它们,后面讲预积分、图优化的时候,你就会觉得顺理成章了。
公众号:蓝海资料掘金营,微信deep3321