3、李群与李代数:SO(3)与SE(3)的定义、指数映射与对数映射、BCH近似公式、扰动模型

好,咱们进入第三章。这一章可以说是整个SLAM后端优化的数学基石。说实话,我刚接触这部分时,也被那些符号绕得头晕。但后来我发现,只要抓住几个核心概念,李群李代数其实没那么可怕。

3.1 为什么需要李群与李代数?

先问个问题:我们在做SLAM时,经常要优化相机的位姿。位姿本身是旋转矩阵R和平移向量t,它们构成一个刚体变换。但旋转矩阵R有个约束——它是正交矩阵,行列式为1。这意味着你不能直接对R做加法,比如R + ΔR,结果很可能不再是旋转矩阵。

这就麻烦了。优化算法通常需要求导,而旋转矩阵所在的欧氏空间并不“平坦”。说白了,你没法在流形上直接做梯度下降。

李群和李代数就是来解决这个问题的。它们提供了一种方式:在流形上做优化,但在切空间里求导。我个人习惯把李代数想象成“速度空间”,而李群是“位置空间”。

核心思想: 李群是流形本身(如SO(3)),李代数是流形在单位元处的切空间(如so(3))。通过指数映射和对数映射,我们可以在两者之间自由切换。

3.2 SO(3)与SE(3)的定义

3.2.1 特殊正交群 SO(3)

SO(3)就是三维旋转矩阵的集合:

SO(3) = { R ∈ ℝ³ˣ³ | RᵀR = I, det(R) = 1 }

嗯,这里要注意:SO(3)是一个群,满足封闭性、结合律、有单位元、有逆元。同时它也是一个流形——三维空间中的旋转可以看作是一个三维球面。

3.2.2 特殊欧氏群 SE(3)

SE(3)是三维刚体变换的集合,包含旋转和平移:

SE(3) = { T = [R t; 0 1] ∈ ℝ⁴ˣ⁴ | R ∈ SO(3), t ∈ ℝ³ }

SE(3)的维度是6(3个旋转自由度 + 3个平移自由度)。

群 维度 描述 应用场景
SO(3) 3 三维旋转 相机姿态、IMU姿态
SE(3) 6 三维刚体变换 相机位姿、机器人位姿

3.3 指数映射与对数映射

这是李群和李代数之间的桥梁。我记得第一次看到指数映射公式时,觉得它长得吓人。但说白了,它就是矩阵指数函数。

3.3.1 so(3) → SO(3) 的指数映射

对于so(3)中的元素φ(一个三维向量),其对应的反对称矩阵为φ^∧。指数映射为:

R = exp(φ^∧) = I + (sinθ/θ) φ^∧ + ((1-cosθ)/θ²) (φ^∧)²

其中θ = ||φ||。这个公式其实就是罗德里格斯公式。我在项目中遇到过一个问题:当θ很小时,sinθ/θ和(1-cosθ)/θ²会出现数值不稳定。解决办法是用泰勒展开近似。

3.3.2 SO(3) → so(3) 的对数映射

反过来,从旋转矩阵R求李代数φ:

θ = arccos((tr(R) - 1) / 2)
φ^∧ = (θ / (2 sinθ)) (R - Rᵀ)

同样要注意:当θ接近0或π时,公式会退化。我曾经在调试一个视觉里程计时,就因为没处理θ=0的情况,导致程序崩溃。后来加了个阈值判断才解决。

实用技巧: 在实际代码中,建议使用Sophus库或Eigen的几何模块,它们已经帮你处理好了这些边界情况。但理解底层原理仍然很重要,否则出了问题你都不知道怎么排查。

3.4 BCH近似公式

BCH公式解决的是这样一个问题:两个李代数指数映射的乘积,对应哪个李代数?

完整公式很复杂:

ln(exp(A) exp(B)) = A + B + ½[A,B] + ¹⁄₁₂[A,[A,B]] - ¹⁄₁₂[B,[A,B]] + ...

但在SLAM中,我们通常只关心一阶近似。假设其中一个量很小(比如优化中的增量Δφ):

ln(exp(φ₁^∧) exp(φ₂^∧))^∨ ≈ 
  Jₗ(φ₂)⁻¹ φ₁ + φ₂   (左乘模型)
  或
  φ₁ + Jᵣ(φ₁)⁻¹ φ₂   (右乘模型)

其中Jₗ和Jᵣ分别是左雅可比和右雅可比。我个人习惯用左乘模型,因为它在视觉SLAM中更常见。

避坑指南: 我曾经在优化代码中搞混了左乘和右乘,结果迭代了50步都不收敛。后来发现是雅可比矩阵用反了。记住:左乘模型对应的是在原始位姿左侧乘一个小扰动,右乘模型对应右侧。两者差一个伴随变换。

3.5 扰动模型

扰动模型是BCH公式的直接应用。在SLAM后端优化中,我们需要对位姿求导。扰动模型提供了一种优雅的方式:

3.5.1 SO(3)上的扰动模型

假设我们有一个旋转R,想求R对某个小扰动δφ的导数。左扰动模型:

∂(R p) / ∂δφ = -R p^∧

这个公式非常简洁。你想想看,如果没有李代数,你要对旋转矩阵直接求导,那得多复杂?

3.5.2 SE(3)上的扰动模型

对于SE(3),扰动模型稍微复杂一点,但思路相同。假设位姿T = [R t; 0 1],左扰动δξ = [δρ, δφ]ᵀ:

∂(T p) / ∂δξ = [I, - (R p + t)^∧; 0, 0]

这个雅可比矩阵在BA(光束法平差)中会反复用到。

为什么扰动模型这么重要? 因为它让我们可以在切空间(李代数)中做优化,然后通过指数映射回到流形(李群)上。这样既保证了优化结果始终是合法的旋转/变换,又简化了求导过程。

3.6 知识体系总览

下面这张图总结了本章的核心逻辑:

李群与李代数核心知识体系 李群 (Lie Group) SO(3): 旋转矩阵 R SE(3): 变换矩阵 T 流形上的点,不可直接加法 李代数 (Lie Algebra) so(3): 旋转向量 φ se(3): 六维向量 ξ 切空间上的向量,可加法可求导 指数映射 exp(φ^∧) 对数映射 ln(R)^∨ BCH近似公式 ln(exp(A)exp(B)) ≈ A + B + ½[A,B] + ... 一阶近似:左乘雅可比 Jₗ 或右乘雅可比 Jᵣ 扰动模型 ∂(R p)/∂δφ = -R p^∧ 在切空间求导 → 指数映射回流形 应用 桥梁 核心流程:流形(李群) → 切空间(李代数)求导 → 指数映射更新 → 回到流形

3.7 实践中的注意事项

最后,分享几个我在实际项目中踩过的坑:

  • 数值稳定性: 指数映射和对数映射在θ接近0或π时,一定要做特殊处理。我一般设一个阈值,比如1e-6,小于这个值就用泰勒展开。
  • 左乘 vs 右乘: 一旦选定一种约定,整个代码库都要统一。混用会导致优化不收敛。
  • 雅可比矩阵的维度: SO(3)的雅可比是3×3,SE(3)的是6×6。别搞混了。
  • BCH近似的精度: 一阶近似在增量较小时效果很好。如果增量太大,可能需要更高阶的近似,或者采用更稳健的优化策略。

我的建议: 刚开始学习时,先用Sophus库做实验。写几个小demo,验证指数映射和对数映射的互逆性,再试试BCH近似的效果。亲手跑一遍代码,比看十遍公式都管用。

嗯,这一章的内容就到这里。李群李代数是SLAM后端的核心工具,理解透了,后面的BA优化、位姿图优化都会轻松很多。