笔记数学机器人常青更新 2026.08阅读约 7 分钟 Lie theory 是把旋转、位姿这类"弯曲空间"上的优化搬回普通向量微积分的通用语言。这篇从 manifold、tangent space 讲到 hat/vee 与 exp/log,合成 manifold 上的一步优化,最后给出手写 SO(3) 的代码小样。
学习笔记,源自 Aalok Patwardhan 的 A Visual Introduction to Lie Theory[1],并补上了具体推导与代码。
§1预备知识
正文将反复用到下面几个概念,每个写成「中文名 = 英文名 = 最小定义」三元组:
- 流形 = manifold = 一个光滑弯曲的空间,局部看起来像平直的 Rn、整体是弯的。[2]
- 李群 = Lie group = 既是 manifold、群运算(矩阵乘法与求逆)又光滑的对象。[4]
- 切空间 = tangent space = 贴在 manifold 某一点处的平直切平面。[2]
- 李代数 = Lie algebra = Lie group 在单位元处的那张特殊 tangent space(旋转群的记作 so(n))。[2]
- 反对称矩阵 = skew-symmetric matrix = 满足 A⊤=−A 的矩阵;旋转群的 Lie algebra 元素恰好取这种形式。[2]
- 指数映射 / 对数映射 = exponential map / logarithm map = 在 tangent space 与 manifold 之间往返的一对互逆映射;对旋转就是矩阵指数 / 矩阵对数。[4]
§2回顾:欧氏空间里的优化
先看"一切都很顺"的情形。给定 cost function f:Rn→R,我们想找让它最小的 x。gradient descent 的套路是:
- perturb:在 x 附近扰动一点点;
- gradient:算出 ∇f(x),它指向上升最快的方向;
- step:沿 −∇f 走一小步。
xk+1=xk−α∇f(xk)
这里的关键前提是:x 是一个自由的 vector。它的每个分量都可以独立地加上一个小量 δ,加完仍然是合法的输入。Rn 是"平的",加法自由,所以扰动和步进都天经地义。
§3困境:在一个 rotation 上做优化
以 2D 旋转为例,rotation matrix 是:
R(θ)=[cosθsinθ−sinθcosθ]
它有 4 个元素,但并不自由——必须同时满足两个约束:
R⊤R=I(orthogonal,列向量单位正交),detR=1(保持右手系、不翻转)
假设我们像在 R4 里那样,直接把左上角那个 cosθ 加上一个小量 δ:
[cosθ+δsinθ−sinθcosθ]
这正是普通优化撞墙的地方:合法旋转并不构成一个平坦的向量空间,而是一个弯曲的、有约束的子集。要在上面做微积分,得换工具。
§4Manifolds 与 Lie groups
所有合法的 2D 旋转组成的集合,叫 special orthogonal group SO(2);3D 的叫 SO(3):
SO(n)={R∈Rn×n ∣ R⊤R=I, detR=1}
它们是 manifold:一个光滑弯曲的空间,局部看起来像平直的 Rn(就像地球表面局部近似一张平地图),但整体是弯的。既是 manifold、群运算(矩阵乘法与求逆)又光滑,这样的对象就是 Lie group[4]。

图 1. Lie group 上一点 X,其 tangent space 是一张贴在该点的"平面";平面又与 Rn 同构。所有优化都在最右侧进行。
§5Lie algebra 与 tangent space
在 manifold 上某一点 X 处,可以贴一张平直的切平面,叫 tangent space。在单位元 I 处的那张特殊的 tangent space,就是这个 Lie group 的 Lie algebra,记作 so(n)[2]。
对旋转来说,Lie algebra 的元素恰好是 skew-symmetric matrix(反对称矩阵,A⊤=−A):
so(2)
只有一个自由参数:
θ∧=[0θ−θ0]=θG[01−10]
so(3)
三个自由参数 ω=(ω1,ω2,ω3):
ω∧=0ω3−ω2−ω30ω1ω2−ω10
它同时也是叉乘算子:ω∧v=ω×v。
注意 skew-symmetric matrix 的独立分量个数(SO(2) 是 1,SO(3) 是 3)正好等于 manifold 的内在维数。这不是巧合——tangent space 的维数就是自由度个数。这给了我们一个平坦、无约束的空间来做数学。
§6hat 与 vee:Rn 作为代理 tangent space
tangent space(那些反对称矩阵)虽然是平的,但写成矩阵仍不方便直接喂给优化器。好在它与普通向量空间 Rn 同构——两者之间用两个互逆的算子搬运:
- hat (⋅)∧: Rn→so(n):把工作区向量"抬"进 Lie algebra;
- vee (⋅)∨: so(n)→Rn:把 Lie algebra 元素"压"回工作区向量。
ω∈R3 (⋅)∧ ω∧∈so(3) (⋅)∨ ω∈R3,((ω∧))∨=ω
于是我们真正拿去做 gradient descent 的对象,就是那个朴素的 3 维向量 ω——它没有任何约束,爱怎么扰动怎么扰动。
§7exp 与 log:连接弯与平
最后一块拼图,是在 manifold 与 tangent space 之间往返的桥:
- exponential map exp: m→M:把 tangent space 里的一个元素"卷"回弯曲的 manifold 上;
- logarithm map log: M→m:反过来,把 manifold 上的元素"摊平"到 tangent space。
X=exp(τ∧),τ∧=log(X)
对旋转,这里的 exp/log 就是矩阵指数 / 矩阵对数。
SO(2):一眼看穿
把 θ∧=θG 代入矩阵指数的级数并利用 G2=−I,可以逐项凑出 sin/cos:
exp(θG)=I+θG+2!θ2G2+⋯=cosθI+sinθG=[cosθsinθ−sinθcosθ]=R(θ)
反过来 logR(θ)=θG,即 θ=atan2(R21,R11)。tangent space 里的那个数 θ,就是转角本身。
SO(3):Rodrigues 公式
设 ω=θu^,其中 θ=∥ω∥ 是转角、u^ 是单位转轴。利用 so(3) 的恒等式 (ω∧)3=−θ2ω∧ 把级数收拢,得到 Rodrigues' rotation formula[2][3]:
R=exp(ω∧)=I+θsinθω∧+θ21−cosθ(ω∧)2
逆映射(log map):
θ=arccos(2tr(R)−1),ω∧=log(R)=2sinθθ(R−R⊤)
§8合起来:manifold 上的一步优化
现在把三个空间串成一个闭环。设 cost function f(X) 定义在 manifold 上(X∈SO(3))。核心技巧是用 right perturbation 把 X 参数化成一个局部的、无约束的小向量 τ∈R3:
X(τ)=Xexp(τ∧)≡X⊞τ
(⊞ 记号沿用 micro Lie theory 的约定[2]。)
在 τ=0 处对 f 关于 τ 求梯度(这一步完全发生在平坦的 R3 里,普通链式法则),拿到 gradient g∈R3,然后:
这就是全篇那张图的落地:log 摊平 → 在 Rn 优化 → exp 卷回。约束被 exp 天然保证,优化器眼里始终只有一个自由的小向量。
§9代码小样:手写 SO(3) 的 hat / vee / exp / log
NumPy 实现
python
import numpy as np
def hat(w): # R^3 -> so(3)
wx, wy, wz = w
return np.array([[0, -wz, wy],
[wz, 0, -wx],
[-wy, wx, 0]])
def vee(W): # so(3) -> R^3
return np.array([W[2, 1], W[0, 2], W[1, 0]])
def exp_so3(w): # Rodrigues: R^3 -> SO(3)
theta = np.linalg.norm(w)
W = hat(w)
if theta < 1e-8: # θ→0 用 Taylor 兜底
return np.eye(3) + W
a = np.sin(theta) / theta
b = (1 - np.cos(theta)) / theta**2
return np.eye(3) + a * W + b * (W @ W)
def log_so3(R): # SO(3) -> R^3
theta = np.arccos(np.clip((np.trace(R) - 1) / 2, -1.0, 1.0))
if theta < 1e-8:
return vee(R - np.eye(3))
return theta / (2 * np.sin(theta)) * vee(R - R.T)
自检
python
w = np.array([0.3, -0.7, 1.1])
R = exp_so3(w)
assert np.allclose(R.T @ R, np.eye(3)) # 仍是 orthogonal
assert np.allclose(np.linalg.det(R), 1.0) # det = 1
assert np.allclose(log_so3(R), w) # log ∘ exp = id
现成的库
真实项目里别自己造轮子,直接用成熟实现:
- Sophus(C++,
SO3/SE3,含 Jacobian)
- manif(C++/Python,micro Lie theory[2] 的参考实现)
- GTSAM / Ceres(把 manifold 优化封装成 factor graph /
Manifold 类型)
§10为什么这套东西重要
Lie theory 是现代机器人状态估计的通用语言[2][3]。凡是要对旋转、位姿做优化或积分的地方,几乎都在用它:
§11References
- Aalok Patwardhan, A Visual Introduction to Lie Theory, aalok.uk 交互式教程 — 本笔记的原文。
- J. Solà, J. Deray, D. Atchuthan, A micro Lie theory for state estimation in robotics, arXiv:1812.01537(2018)— 工程视角的权威小册子,配套库为 manif。
- T. D. Barfoot, State Estimation for Robotics, Cambridge University Press(2017)— 系统教材,第 7 章讲 SO(3)/SE(3)。
- B. C. Hall, Lie Groups, Lie Algebras, and Representations: An Elementary Introduction, 2nd ed., Springer, Graduate Texts in Mathematics 222(2015)。