第八章 矩阵李群(优化版)
Chapter 8 Matrix Lie Groups (Optimized)
本章导航 / Chapter Navigator
一句话总结(TL;DR)
旋转矩阵不能用向量加法——李群理论把旋转状态拆成”大的均值(在流形上)+ 小的扰动(在向量空间里)“,让 EKF/MAP 得以正常工作。
阅读路径建议:
- 🟢 快速浏览:读完”直觉图解”即可把握核心思想
- 🔵 理解算法:阅读”概念层”的公式和解释
- ⚫ 深度推导:展开”推导层”查看完整数学
8.1 为什么普通向量不够用?
🎯 直觉:旋转矩阵的”加法陷阱”
问题 1:普通高斯如何用?
普通高斯分布:,其中 。
但旋转矩阵 不能这样写!为什么?
- 两个旋转矩阵相加: 不是旋转矩阵(行列式不为 1)
- 零矩阵 不是旋转矩阵
问题 2:欧拉角有奇点(万向锁),不能全局使用。
解决方案:李群的”两全其美”
| 分量 | 存放位置 | 好处 |
|---|---|---|
| 大的均值 | 李群 | 无奇点、满足所有约束 |
| 小的扰动 | 李代数 | 可以做普通线性代数 |
🔑 概念层:李代数是什么?
李代数是李群在单位元处的切平面——一个平的向量空间!
- 的李代数 :所有 反对称矩阵
- 的李代数 : 矩阵
两者通过指数映射连接:
左扰动方案(核心工具):
用途:EKF 中更新 时用普通向量加法,再指数映射回旋转矩阵。
8.2 指数映射:切平面到流形
🎯 直觉:从”线性速度”到”旋转”
想象你在控制一个旋转的刚体:
- 角速度 是线性的(向量)
- 积分角速度得到旋转 ,需要处理非线性
指数映射 就是”把线性速度积分成旋转”的数学工具。
🔑 概念层: 的 Rodrigues 公式
指数映射有闭合形式(无需无穷级数):
其中 , 是单位轴。
这正是 Rodrigues 公式! 指数映射统一了所有旋转参数化。
🧮 数值示例:验证指数映射
问题:绕 z 轴旋转 90° 的旋转矩阵是什么?
解答:
- 轴:
- 角:
✓ 这正是绕 z 轴转 90° 的旋转矩阵。
📐 推导层:指数映射的级数展开
展开:从矩阵指数到 Rodrigues 公式
矩阵指数定义为:
对反对称矩阵,有恒等式:
因此高阶幂可以化简:
将级数按奇偶分开,利用三角函数的泰勒级数,即得 Rodrigues 公式。
8.3 :位姿的李群
🎯 直觉:旋转+平移的联合
位姿 同时包含旋转 和平移 :
问题:平移 和旋转 不是独立的——先转再移和先移再转结果不同!
李代数 用 6 维向量描述:
其中 是”平移方向”(不是真实平移!), 是旋转轴。
🔑 概念层:指数映射与左雅可比
的指数映射:
左雅可比矩阵 ():
作用:把李代数中的平移 “拉伸”成真实的平移 。
| 情形 | 近似 | 物理意义 |
|---|---|---|
| 小旋转时, | ||
| 大 | 显著偏离 | 旋转导致平移被”扭曲” |
8.4 伴随表示:协方差的坐标变换
🎯 直觉:不确定性随坐标系移动
假设机器人相对于世界坐标系的位姿有不确定性。如果机器人移动到一个新的位姿,它相对于新坐标系的不确定性如何变化?
答案:通过伴随矩阵 变换。
🔑 概念层:伴随矩阵的定义与作用
对 ,伴随矩阵()为:
关键性质:
- 将李代数向量从一个坐标系”传输”到另一个:
- 协方差精确变换:
位姿复合中的协方差传播: 若 ,则
类比:这类似于线性系统 的协方差传播 ,只是这里的”变换矩阵”是 的伴随矩阵。
8.5 扰动微积分:在流形上优化
🎯 直觉:“围绕当前猜测的小步调整”
普通高斯-牛顿:更新
李群上的高斯-牛顿:更新
核心区别:
- 用指数映射保证结果仍在 中
- 对扰动 做普通向量优化(无约束)
- 避免了欧拉角的奇点问题
🔑 概念层:左李导数
问题:计算 关于扰动 的导数。
左李导数:
意义:导数只依赖于当前估计点旋转后的向量 ,再取反对称。
版本:
其中 是”点算子”,将齐次坐标转化为 矩阵。
🧮 数值示例:位姿优化
场景:用 ICP(迭代最近点)对齐两个点云。
目标:最小化
左扰动 GN 迭代:
- 在当前位姿 处线性化
- 求解 6 维线性系统得到最优扰动
- 更新:
- 重复直到收敛
好处:
- 无奇点(对比欧拉角)
- 每步只需解 6×6 系统(对比四元数+约束)
- 结果自动满足 约束
8.6 概率:李群上的高斯分布
🎯 直觉:均值在流形上,协方差在切平面上
定义: 上的随机变量为
验证均值:
关键性质:
- 是”均值旋转”
- 是普通的 协方差矩阵
- 扰动 小,远离 奇点
🔑 概念层:不确定性变换
确定性变换:若 ( 确定),则
- 均值:
- 协方差:(普通旋转协方差)
版本:若 ,协方差通过伴随变换
注意:这是精确变换,无需线性化近似!
📐 推导层:旋转向量的期望偏差
展开:为什么 $E[\mathbf{C}\mathbf{x}] \neq \bar{\mathbf{C}}\mathbf{x}$
对 ,展开到二阶:
取期望,,但 :
利用 ,得到:
这就是二阶”Jensen 偏差”——类似于非线性函数的期望不等于期望的函数。
8.7 运动学:时间上的李群积分
🎯 直觉:角速度积分得到旋转
泊松方程(李群形式):
数值积分(恒定角速度):
结果自动在 中,无需后处理归一化!
🔑 概念层: 运动学
位姿运动学:
其中 是线速度, 是角速度。
数值积分(恒定广义速度):
线性化扰动运动学:
这是 EKF 中过程噪声传播的基础。
本章自检清单
阅读完本章,你应该能回答:
- 为什么旋转矩阵不能直接用向量加法?(不封闭)
- 李群的”两全其美”是什么?(均值在流形上,扰动在向量空间里)
- 指数映射的作用是什么?(连接李代数与李群)
- 左雅可比矩阵 的物理意义?(把李代数平移”拉伸”成真实平移)
- 伴随矩阵的作用?(协方差的精确坐标变换)
- 左扰动 Gauss-Newton 的三个好处?(无奇点、无约束、自动满足约束)
如果以上都清楚,你掌握了 Lie 群估计的核心!
延伸阅读与代码
Python 实现(核心函数):
import numpy as np
def skew(v):
"""向量转反对称矩阵"""
return np.array([[0, -v[2], v[1]],
[v[2], 0, -v[0]],
[-v[1], v[0], 0]])
def unskew(M):
"""反对称矩阵转向量"""
return np.array([M[2,1], M[0,2], M[1,0]])
def so3_exp(phi):
"""SO(3) 指数映射(Rodrigues 公式)"""
phi_norm = np.linalg.norm(phi)
if phi_norm < 1e-10:
return np.eye(3)
a = phi / phi_norm
sin_phi = np.sin(phi_norm)
cos_phi = np.cos(phi_norm)
return (cos_phi * np.eye(3) +
(1 - cos_phi) * np.outer(a, a) +
sin_phi * skew(a))
def so3_log(C):
"""SO(3) 对数映射"""
cos_phi = (np.trace(C) - 1) / 2
cos_phi = np.clip(cos_phi, -1, 1)
phi = np.arccos(cos_phi)
if abs(phi) < 1e-10:
return unskew(C - C.T) / 2
return phi / (2 * np.sin(phi)) * unskew(C - C.T)
def left_jacobian_so3(phi):
"""SO(3) 左雅可比矩阵"""
phi_norm = np.linalg.norm(phi)
if phi_norm < 1e-10:
return np.eye(3)
a = phi / phi_norm
sin_phi = np.sin(phi_norm)
cos_phi = np.cos(phi_norm)
return (sin_phi / phi_norm * np.eye(3) +
(1 - sin_phi / phi_norm) * np.outer(a, a) +
(1 - cos_phi) / phi_norm * skew(a))
def se3_exp(xi):
"""SE(3) 指数映射,xi = [rho; phi]"""
rho, phi = xi[:3], xi[3:]
C = so3_exp(phi)
J = left_jacobian_so3(phi)
r = J @ rho
T = np.eye(4)
T[:3, :3] = C
T[:3, 3] = r
return T
def se3_adjoint(T):
"""SE(3) 伴随矩阵"""
C = T[:3, :3]
r = T[:3, 3]
Ad = np.zeros((6, 6))
Ad[:3, :3] = C
Ad[:3, 3:] = skew(r) @ C
Ad[3:, 3:] = C
return Ad
def gauss_newton_so3(C_op, v, target, max_iter=10):
"""
用左扰动 GN 优化旋转使 C*v 接近 target
C_op: 初始旋转矩阵 (3x3)
v: 被旋转的向量
target: 目标向量
"""
C = C_op.copy()
for _ in range(max_iter):
residual = C @ v - target
# 左李导数: - (C_op @ v)^wedge
J = -skew(C @ v)
# 求解线性系统
delta_phi = np.linalg.solve(J.T @ J, -J.T @ residual)
# 更新
C = so3_exp(delta_phi) @ C
if np.linalg.norm(delta_phi) < 1e-6:
break
return C下一章将用这些工具解决三维位姿估计的经典问题。