3. 三维空间刚体运动

各位同学,欢迎来到多传感器融合定位的第一道硬菜。

说实话,刚接触SLAM的人,十有八九会被李群李代数劝退。我当年也一样,看着SO(3)、se(3)这些符号,脑子里全是问号。但后来在实际项目中吃过亏——直接用旋转矩阵做优化,结果矩阵不满足正交约束,整个系统直接崩了。从那以后,我老老实实把这块啃了下来。

今天我们就把它讲透。你不需要成为数学家,只需要理解:李群和李代数,是解决旋转求导问题的利器。

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

先问一个问题:在SLAM里,我们要优化什么?

答案是位姿。位姿由旋转+平移组成。旋转可以用旋转矩阵R表示,平移用向量t。但问题来了——

  • 旋转矩阵R是正交矩阵,有9个参数,但自由度只有3。直接优化R,你很难保证优化后的结果还是正交矩阵。
  • 求导困难。旋转矩阵对时间的导数,不是简单的线性关系。

李群和李代数,就是来解决这两个问题的。它把旋转矩阵映射到一个无约束的向量空间,在这个空间里做优化,再映射回旋转矩阵。

核心思想:在流形(李群)上做优化太麻烦,我们到切空间(李代数)里做,做完再映射回去。

3.2 李群 SO(3) 与 SE(3)

先看定义。

SO(3):特殊正交群。就是所有3x3旋转矩阵的集合。

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

SE(3):特殊欧氏群。就是所有4x4变换矩阵的集合。

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

这两个都是群。群是什么?简单说就是:集合 + 一种运算(乘法),满足封闭性、结合律、有单位元、有逆元。

旋转矩阵乘法满足封闭性——两个旋转矩阵相乘,结果还是旋转矩阵。这就是群。

我的经验:刚开始不用深究群论的公理。你只需要记住:SO(3)里的元素是旋转矩阵,SE(3)里的元素是变换矩阵。它们可以相乘,可以求逆。

3.3 李代数 so(3) 与 se(3)

李代数,是李群在单位元处的切空间。

听起来抽象?换个说法:李代数就是旋转的“速度”空间。

so(3):对应SO(3)的李代数。元素是3x3的反对称矩阵。

so(3) = { Φ = φ^ ∈ ℝ³ˣ³ | φ ∈ ℝ³ }

其中φ是一个三维向量,φ^表示它的反对称矩阵:

φ = [φ₁, φ₂, φ₃]ᵀ

φ^ = [0   -φ₃  φ₂;
      φ₃   0  -φ₁;
     -φ₂  φ₁   0 ]

se(3):对应SE(3)的李代数。元素是4x4矩阵。

se(3) = { ξ^ = [φ^  ρ; 0 0] ∈ ℝ⁴ˣ⁴ | ρ, φ ∈ ℝ³ }

这里ξ = [ρ, φ]ᵀ是一个六维向量。ρ是平移部分,φ是旋转部分。

记住这个对应关系:

李群李代数维度
SO(3)so(3)3
SE(3)se(3)6

3.4 指数映射与对数映射

这是最核心的部分。李群和李代数之间,通过指数映射和对数映射相互转换。

3.4.1 SO(3) 上的指数映射

从so(3)到SO(3):指数映射。

给定一个旋转向量φ(就是so(3)里的元素),指数映射得到旋转矩阵R:

R = exp(φ^)

这个公式怎么算?用罗德里格斯公式:

R = I + sinθ · n^ + (1 - cosθ) · n^²

其中θ = ||φ||,n = φ/θ。

反过来,从SO(3)到so(3):对数映射。

φ = ln(R)^∨

给定旋转矩阵R,可以求出旋转向量φ。θ = arccos((tr(R)-1)/2),n = (R - Rᵀ)∨ / (2sinθ)。

注意:当θ接近0时,公式有数值不稳定性。我曾在IMU初始化时踩过这个坑——旋转角度极小,arccos直接算出来NaN。解决方案是用泰勒展开近似。

3.4.2 SE(3) 上的指数映射

从se(3)到SE(3):

T = exp(ξ^) = [R  t; 0  1]

其中:

R = exp(φ^)
t = Jρ

J是左雅可比矩阵:

J = sinθ/θ · I + (1 - sinθ/θ) · nnᵀ + (1 - cosθ)/θ · n^

反过来,从SE(3)到se(3):

φ = ln(R)^∨
ρ = J⁻¹t

我的建议:不要死记硬背这些公式。实际开发中,我们直接用Eigen或Sophus库。但你要理解背后的几何意义——指数映射把“旋转速度”变成“旋转”,对数映射反过来。

3.5 李代数求导与扰动模型

终于到了最实用的部分。在SLAM中,我们要对位姿求导。比如:

  • 给定一个点p,经过变换T得到p' = Tp
  • 我们要计算p'对T的导数

直接在SE(3)上求导?不行。因为SE(3)不是向量空间,加法不封闭。

但在李代数上可以。李代数是向量空间,可以自由加减求导。

有两种方式:

  1. 李代数求导:对R对应的李代数φ求导
  2. 扰动模型:在R左边乘一个小扰动ΔR,对扰动求导

实际中,扰动模型更常用。因为它形式简单,不需要计算雅可比矩阵。

∂(Rp)/∂φ = -(Rp)^

这个公式非常简洁。在代码里,就是一行的事。

避坑指南:我曾经在VIO系统中,因为用了错误的求导方式,导致优化不收敛。后来换成扰动模型,问题立刻解决。记住:扰动模型是SLAM中的标准做法。

3.6 代码实战:使用Sophus库

理论说完了,我们看看代码。Sophus是常用的李代数库,基于Eigen。

#include <sophus/so3.hpp>
#include <sophus/se3.hpp>

// 创建SO3
Eigen::Vector3d phi(0.1, 0.2, 0.3);
Sophus::SO3d R = Sophus::SO3d::exp(phi);

// 指数映射
Sophus::SO3d R2 = Sophus::SO3d::exp(phi);

// 对数映射
Eigen::Vector3d phi2 = R2.log();

// 创建SE3
Eigen::Vector3d t(1, 2, 3);
Sophus::SE3d T(R, t);

// 扰动模型求导
Eigen::Vector3d p(0.5, 0.6, 0.7);
Eigen::Vector3d dp_dphi = -Sophus::SO3d::hat(T * p);

这段代码,基本覆盖了日常开发中90%的李代数操作。

个人习惯:我一般在CMakeLists.txt里这样配置Sophus:

find_package(Sophus REQUIRED)
target_link_libraries(my_node Sophus::Sophus)

3.7 本章小结

来,我们捋一遍:

  • 李群:SO(3)是旋转矩阵集合,SE(3)是变换矩阵集合
  • 李代数:so(3)是旋转向量,se(3)是六维向量
  • 指数/对数映射:连接李群和李代数的桥梁
  • 扰动模型:SLAM中求导的标准方法

这些概念,你会在后续的每一章中反复用到。不管是视觉SLAM、IMU预积分,还是激光雷达定位,都离不开它们。

嗯,今天就到这里。下一章我们讲四元数——另一个绕不开的话题。

李群与李代数知识体系 李群 (Lie Group) SO(3) — 旋转矩阵集合 SE(3) — 变换矩阵集合 性质:封闭性、结合律、单位元、逆元 维度:SO(3) 3维,SE(3) 6维 李代数 (Lie Algebra) so(3) — 旋转向量 φ ∈ ℝ³ se(3) — 六维向量 ξ ∈ ℝ⁶ 性质:向量空间,可自由加减求导 对应切空间,无约束优化 指数映射 对数映射 核心应用:求导与优化 扰动模型:∂(Rp)/∂φ = -(Rp)^ 在切空间优化 → 映射回流形 → 保证约束 SLAM中标准做法:李代数求导 + 指数/对数映射 常用工具:Sophus库、Eigen库、Ceres/G2O