第21章 高级表示:李群与李代数

码枢沄社 · 嵌入式体系化教程平台
高级 👤 已掌握旋转矩阵与四元数,希望深入理解机器人运动数学本质的开发者 🔧 用于SLAM后端优化、连续轨迹插值与求导、复杂运动学建模
本章你将学到
  • 李群与李代数的基本概念及其在机器人学中的对应关系
  • 如何用李代数表示旋转和平移,并进行指数/对数映射
  • 李群上的扰动模型,用于优化问题中的导数计算
核心概念李群李代数

当你用旋转矩阵或四元数进行连续插值,或者在SLAM后端优化中调整机器人的位姿时,本质上是在一个光滑的“形状”上进行操作。这个形状不是简单的平面或球面,而是一种称为“李群”的数学结构。李代数则是描述这个形状在局部“看起来像什么”的工具。理解它们,是解锁现代机器人状态估计和运动规划核心算法的钥匙。

生活类比:想象一个可以自由旋转和移动的魔方(李群)。你手里有一本说明书(李代数),上面记录了从当前状态出发,进行所有微小转动和滑动操作的“配方”。这本说明书只在魔方当前位置附近有效,但它能精确指导你如何到达附近的任何状态。

技术定义:在机器人学中,李群是一个同时是光滑流形(连续空间)和群的集合,例如所有三维旋转(SO(3))或所有三维刚体运动(SE(3))。李代数则是对应李群在单位元处的切空间,它描述了群元素在无穷小变化下的行为,通常用向量表示。

21.1 从旋转群SO(3)到李代数so(3)

我们熟悉的旋转矩阵集合SO(3)就是一个李群。它的李代数so(3)是一个由三维向量组成的空间。这个三维向量有一个奇妙的性质:它可以生成一个反对称矩阵。

旋转群 SO(3)
李代数 so(3)
旋转矩阵 R
旋转向量 φ

具体来说,对于李代数 so(3) 中的一个向量 φ = [φ₁, φ₂, φ₃]ᵀ,我们可以通过一个“帽子”算子(∧)将其映射为一个3x3的反对称矩阵:

// 三维向量到反对称矩阵
Eigen::Vector3d phi(phi_x, phi_y, phi_z);
Eigen::Matrix3d phi_hat;
phi_hat << 0, -phi_z,  phi_y,
           phi_z,  0, -phi_x,
          -phi_y,  phi_x,  0;

这个反对称矩阵 φ^ 就是李代数 so(3) 的元素。它和旋转矩阵 R(李群 SO(3) 的元素)之间通过指数映射和对数映射联系起来:

指数映射: 将李代数 so(3) 中的元素 φ 映射到李群 SO(3) 中的旋转矩阵 R。物理意义是:绕轴 φ/‖φ‖ 旋转角度 ‖φ‖。公式为 R = exp(φ^)。在实际计算中,我们使用罗德里格斯公式来高效计算这个指数映射。

对数映射: 将旋转矩阵 R 映射回李代数 so(3) 中的向量 φ。这是指数映射的逆运算,φ = log(R)∨(∨是∧的逆运算,将反对称矩阵变回向量)。

为什么需要这个转换?因为李代数 so(3) 只是一个普通的三维向量空间。在其上进行加法、求导等运算,比直接在旋转矩阵(有正交约束 RᵀR=I)上进行要简单得多。我在一个机械臂轨迹优化项目中就踩过坑:直接在旋转矩阵上做梯度下降,迭代几步后旋转矩阵就不再正交了,导致整个优化崩溃。后来改用李代数空间进行优化,问题迎刃而解。

21.2 刚体运动群SE(3)与李代数se(3)

机器人的位姿包含旋转和平移,对应的李群是特殊欧氏群 SE(3)。它的李代数 se(3) 是一个六维向量空间。

SE(3)与SO(3)的对比
特性旋转群 SO(3)刚体运动群 SE(3)
群元素3x3 旋转矩阵 R4x4 变换矩阵 T = [R t; 0 1]
自由度36
李代数so(3): 三维向量 φse(3): 六维向量 ξ = [ρ, φ]ᵀ
李代数元素形式3x3 反对称矩阵 φ^4x4 矩阵 ξ^ = [φ^ ρ; 0 0]
指数映射R = exp(φ^)T = exp(ξ^)

这里,ξ 是 se(3) 的元素,由平移部分 ρ(一个三维向量)和旋转部分 φ(一个三维向量)组成。它的“帽子”算子生成一个4x4矩阵。SE(3)的指数映射也有闭式解(虽然比SO(3)的罗德里格斯公式复杂一些),它同时生成了旋转和平移。

常见误区

  • 混淆李代数的维度和含义: 误以为 se(3) 的平移部分 ρ 就是世界坐标系下的平移向量 t。实际上,ρ 与 t 和旋转 φ 都有关,具体关系由指数映射的公式决定。在代码中,应使用库函数(如Sophus库)进行转换,而不是自己猜测。
  • 在错误的空间做加法: 李群上的元素不能直接相加(比如 T1 + T2 无意义)。所有的加法、求导操作都应在对应的李代数向量空间(如 se(3) 的六维向量)中进行,然后通过指数映射“拉回”到李群上。
  • 忽略指数映射的奇异性: 当旋转角度 ‖φ‖ 接近 2π 时,对数映射 log(R) 会出现多值性和奇异性(类似于欧拉角的万向节锁)。在实际编程中,需要处理这种边界情况。

21.3 李群上的扰动模型与求导

这是李群李代数在机器人学中最核心的应用。在优化问题(如SLAM、视觉里程计)中,我们需要调整机器人的位姿 T 以最小化误差函数。这就要求我们计算误差函数关于位姿 T 的导数。

由于 T 是李群元素,我们无法定义“T + ΔT”。正确的做法是定义两种扰动模型:

左扰动模型

  • 在姿态T的左侧乘以一个微小扰动 exp(δξ^)
  • 新位姿:T_new = exp(δξ^) · T
  • 扰动δξ在李代数se(3)中

右扰动模型

  • 在姿态T的右侧乘以一个微小扰动 exp(δξ^)
  • 新位姿:T_new = T · exp(δξ^)
  • 扰动δξ在李代数se(3)中

两种模型在理论上是等价的,只是导数形式略有不同。实际开发中,大部分SLAM库(如g2o, Ceres-Solver的Sophus接口)默认使用左扰动模型。选择一个并保持一致即可。

假设我们有一个误差函数 e(T),它计算观测值与基于位姿 T 的预测值之间的差。我们需要求 ∂e/∂T。使用左扰动模型,我们实际上计算的是误差函数对李代数扰动 δξ 的导数:

// 伪代码:利用扰动模型计算雅可比矩阵的核心思想
Eigen::Matrix<double, 2, 6> jacobian; // 假设误差e是2维,位姿有6自由度
for (int i = 0; i < 6; ++i) {
    // 1. 生成第i个自由度上的微小扰动向量δξ
    Eigen::Vector6d delta = Eigen::Vector6d::Zero();
    delta(i) = 1e-6; // 微小量
    // 2. 将扰动向量转换为李群上的扰动变换
    Sophus::SE3d T_perturbed = Sophus::SE3d::exp(delta) * T;
    // 3. 计算扰动后的误差
    Eigen::Vector2d e_perturbed = computeError(T_perturbed);
    // 4. 数值导数作为雅可比矩阵的第i列
    jacobian.col(i) = (e_perturbed - e) / 1e-6;
}

当然,对于许多常见的误差函数(如重投影误差),我们可以推导出解析的雅可比矩阵形式,这比数值微分更高效、更精确。但上述数值微分的思路清晰地展示了扰动模型的用法。

编者提示: 在实际项目中,我强烈建议使用成熟的数学库(如 Eigen 配合 Sophus 库)来处理李群李代数的运算。Sophus库提供了SO(3)、SE(3)等类的实现,包括指数/对数映射、扰动模型求导等。自己实现这些运算极易出错,特别是SE(3)指数映射的闭式解涉及复杂的矩阵运算。直接调用 Sophus::SE3d::exp(xi)T.log() 既安全又高效。

21.4 应用实例:在SLAM后端优化中的角色

让我们通过一个简化的图优化SLAM后端流程,看看李群李代数如何嵌入其中。

构建位姿图
定义李群上的误差项
在李代数空间线性化并求解增量
将增量映射回李群更新位姿

1. 构建位姿图: 节点是机器人在不同时刻的位姿 T_i ∈ SE(3),边是两个位姿间的相对运动约束(来自里程计或闭环检测)T_ij。

2. 定义误差: 对于连接T_i和T_j的边,其预测值为 T_j 相对于 T_i 的变换:T_ij_pred = T_i⁻¹ · T_j。误差定义在李群上:e_ij = log( (T_ij_pred)⁻¹ · T_ij_meas )∨。这个误差 e_ij 是一个六维向量(se(3)的元素)。

3. 线性化求解: 将所有边的误差堆叠成总误差向量 e。我们需要求解位姿的增量 δξ(李代数向量),使得 e(δξ) 最小化。这需要计算误差 e 关于每个位姿 T_k 的雅可比矩阵 J_k = ∂e/∂δξ_k(使用左扰动或右扰动模型)。然后通过高斯牛顿或列文伯格-马夸尔特算法求解线性方程 (JᵀJ) δξ = -Jᵀe。

4. 更新位姿: 求解得到的 δξ_k 是每个节点在李代数空间中的增量。我们通过指数映射更新位姿:T_k_new = exp(δξ_k) · T_k_old(左扰动模型)。

整个优化过程在李代数空间(一个无约束的向量空间)中进行迭代求解,而位姿的表示和存储始终保持在李群 SE(3) 上。这完美地解决了在流形上进行优化的问题。

动手试一试

使用 Eigen 和 Sophus 库(一个用于李群李代数的C++库)完成以下小实验:

  1. 定义一个初始位姿 T1(旋转绕Z轴45度,平移[1,0,0])。
  2. 定义一个李代数向量 ξ(例如 [0.1, 0, 0, 0, 0, 0.2]ᵀ)。
  3. 使用 Sophus::SE3d::exp(xi) 计算扰动变换。
  4. 分别用左扰动和右扰动模型计算新的位姿:T_left = exp(xi) * T1T_right = T1 * exp(xi)
  5. 打印 T1, T_left, T_right 的矩阵,并计算 T1.inverse() * T_leftT_right * T1.inverse(),观察结果。理解左扰动和右扰动对位姿影响的区别。

检验你的理解

  1. 判断题:李代数 so(3) 的元素是一个三维向量,这个向量的方向代表旋转轴,模长代表旋转角度。
  2. 选择题:在SE(3)的优化中,我们通常在哪里进行加法运算和求导运算?
    A) 直接在4x4变换矩阵T上
    B) 在对应的六维李代数向量ξ上
    C) 在平移向量t和四元数q上分别进行
  3. 判断题:左扰动模型 T_new = exp(δξ) * T_old 和右扰动模型 T_new = T_old * exp(δξ) 计算出的新位姿 T_new 是相同的。

本章小结

  • 李群(如SO(3), SE(3))是描述旋转和刚体运动的连续空间,其元素(旋转矩阵、变换矩阵)受约束(如正交性)。
  • 李代数(如so(3), se(3))是对应李群在单位元处的切空间,是一个向量空间,元素是向量(三维或六维),便于进行加法和求导。
  • 指数映射与对数映射是连接李群和李代数的桥梁,实现了局部向量空间与全局流形之间的转换。
  • 扰动模型(左/右扰动)是计算李群上函数导数的标准工具,通过在李群上乘以一个由李代数生成的微小扰动来实现,这是机器人状态估计和优化算法的数学基础。
  • 在实践中,应使用成熟的数学库(如Sophus)来处理相关运算,避免手动实现复杂的映射公式。
← 上一章 返回目录