Skip to content

李群与李代数:旋转为什么不能当向量加

WARNING

🧪 Beta公测版本提示:教程主体已完成,正在优化细节,欢迎大家提Issue反馈问题或建议。

三维旋转矩阵 R 满足 RR=IdetR=1,全体记作 SO(3)。两个旋转的「平均」或「一点点增量」都不能把九个数字当 R9 加减——会走出合法姿态。正确的小量住在单位元处的切空间 so(3)(反对称矩阵),再用 指数映射 送回 SO(3)。本章把「为什么欧拉角会万向节死锁、hat 从哪来、Rodrigues 每项在干什么」写清楚。平面刚体的「转 + 移」见 旋量。DH 链上的 R 块正是这里的点,见 建模


一、通俗理解:姿态不是平面上的一个角

平面里一个 θ,加 0.1 还是角。空间里三个欧拉角看起来也像向量,但:

  1. 乘法不交换RxRzRzRx 不是同一个姿态。先低头再转身,和先转身再低头,鼻子朝向不同。
  2. 欧拉角有万向节死锁(gimbal lock):中间角到 ±90 时,另外两轴重合,丢了一个自由度。飞机、相机云台、欧拉积分的仿真都会踩。
  3. 九个矩阵元只有三个自由:必须 RR=IdetR=1。把 R1R2 逐元平均,结果一般不再正交。

所以姿态的合法集合是弯曲的三维流形(可以想成一个三维的「球面」),不是 R3R9。在流形上,切空间里的向量才可以加;加完再用指数映射贴回流形。

SO(3) 与 so(3)

图解说明:左:球面示意旋转流形,切平面是 so(3),曲线箭头是 exp。右:ω 变成 ω^,Rodrigues 给出绕轴转角。群上的点是姿态,代数上的向量是「转多少」。

动画说明:左先 Rz90Rx90,右先 RxRz。红 x / 绿 y / 蓝 z。终点姿态不同,所以欧拉角不能当 R3 加减。

量子信息里的幺正群 U(n) 是同一类故事;见 量子信息。线性代数复习见 向量与矩阵

旋转不可交换

图解说明:先 XZ 与先 ZX 终点姿态不同。右下:中间角到 90 时两轴重合,万向节死锁。

保姆级:欧拉角为什么看起来像向量却不是。 滚转、俯仰、偏航各是一个角,三个数排成向量很诱人。可是「加 5 俯仰」依赖于你现在已经转了多少——姿态流形是弯曲的,切空间的向量只能在当地加。万向节死锁是弯曲的一个症状:参数化在某点退化,三个角不再覆盖三个独立方向。


二、无穷小旋转为什么一定是反对称矩阵

R(t)R(0)=I。正交性 RR=I 两边对 t0 求导:

R˙+R˙=0R˙=R˙.

所以 R˙(0) 必须反对称。三维反对称矩阵恰好三个自由量,与轴角向量 ωR3 一一对应(hat):

ω^=(0ωzωyωz0ωxωyωx0).

直接验证 ω^p=ω×p。角速度就是「此刻姿态在切空间里的速度」。练习 hat_02 钉死矩阵 (0,2) 格是 +ωy——符号写反则转反。

逐步推导:正交性 RR=I 怎样逼出反对称(点击展开)

R(t) 是一条合法旋转曲线,R(0)=I。对任意 tR(t)R(t)=I。两边对 t 求导:

R˙(t)R(t)+R(t)R˙(t)=0.

t=0R(0)=I,得到

R˙(0)+R˙(0)=0,

R˙(0) 反对称。三维反对称矩阵的独立元恰好三个:可放在 (0,1)(0,2)(1,2) 位置,其余由 A=A 决定。把这三个数叫做 ωz,ωy,ωx(符号约定使 ω^p=ω×p),就得到正文的 hat 矩阵。

反过来:任意反对称 K 给出曲线 R(t)=exp(tK),Rodrigues 保证它永远正交且行列式为 1,所以切空间维数 = 流形维数 =3


三、Rodrigues:有限转角的闭式 exp

θ=ωK=ω^不是单位反对称阵)。绕轴 n=ω/θθ 弧度:

exp(ω^)=I+sinθθK+1cosθθ2K2(θ0 时退回 I+K).

保姆级读三项:

  • I:不转。
  • sinθ 项:在垂直于轴的平面里把向量拧一截(像二维旋转的 sin)。
  • (1cosθ) 项:把向量往轴上「拉近」再送回去(二维旋转的 1cos)。

教材若写单位轴 n^ 与转角 θ,则 K=θn^,两种写法等价。θ0sinθ/θ1,代码用阈值避免除零。

逐步推导:Rodrigues 公式从指数级数来(点击展开)

矩阵指数 exp(K)=n=0Kn/n!。反对称 K=ω^ 满足 Cayley–Hamilton 的二维旋转类关系:令 θ=ωn=ω/θKu=n^,则 K=θKu,且

Ku3=Ku

(三次叉乘绕回来,像复数 i3=i)。于是高次幂只在 KuKu2 之间振荡,级数收成

exp(θKu)=I+sinθKu+(1cosθ)Ku2.

代回 K=θKu 得到正文(sinθ/θ(1cosθ)/θ2)。几何:I 不动沿轴分量;Ku 在垂直平面里转 90Ku2 把垂直分量翻到轴的反方向——合起来就是绕 nθ

θ0 用等价无穷小 exp(K)I+K,与「角速度 × 时间 = 小转角」一致。

对数映射反向:从 R 读出转角与轴,

θ=arccostr(R)12,n=12sinθ(R32R23R13R31R21R12),ω=θn.

tr(R)=1+2cosθθ0log 返回 0θ=π 时轴的符号有两点歧义(转 180 与转 180 同一姿态),数值上要小心——demo 用的 ω 模长约 0.86<π,无此问题。

四元数(不展开实现):单位四元数也表示 SO(3),插值(slerp)比欧拉干净,与 exp 是同一轴角的另一套坐标。IMU 滤波常用。


四、数字例与 C++

同一组 ω=(0.3,0.1,0.8)

  • Python so3_exp / so3_log 验证 log(exp(ω))ωRRIdetR=1,并把立方体顶点转过去;
  • so3.hpphat / so3_exp 是同样的 Rodrigues;demo.cpp 只印 det(R)
bash
cd docs/robotics/lie-groups/code
python demo.py
g++ -std=c++17 demo.cpp -o so3_demo

头文件 header-only。数值应 det1


五、常见疑问

Q:那我积分姿态能不能 θθ+ωΔt
平面可以。三维应对反对称矩阵做 exp(ω^Δt) 再左乘(或右乘,看 ω 在体坐标还是空间坐标)。欧拉角积分既慢又死锁。

Q:两个旋转怎么平均?
不能 (R1+R2)/2。正确做法在切空间:R¯=R1exp(12log(R1R2))(测地中点)。这就是「先变回向量、加完再贴回去」。

Q:SO(3) 和旋转向量差在哪?
旋转向量 ω 是切空间坐标,ω2π 会绕回来,不是全局一一对应。滤波时误差取小 ω,名义姿态用 R 或四元数。

Q:和 DH 什么关系?
每一帧 Ai 的左上 3×3 都是 SO(3) 里的点。关节转 Δθ,相当于沿该关节 z 轴做一次 exp


六、代码在做什么

demo.py 打印往返误差与正交性,三维散点图 so3_exp.png:灰点原立方体,橙点 Rp,蓝箭头是 ω 轴。

指数映射旋转立方体


七、小结

概念一句话
SO(3)合法三维旋转;弯曲的,不能逐元加
欧拉角看起来像 R3,有死锁、不交换
so(3)反对称;3 个数 =ω
hatR3 叉乘矩阵
exp/log切空间
下游位姿滤波、IMU、旋量 SE(3)

下一章 机构学 先离开矩阵,看闭链怎么动。把转动与平移合成螺旋见 旋量

📥 Code

FileViewDownload
demo.pyOpenDownload
so3.hppDownload
demo.cppDownload
exercise.pyOpenDownload

参考

  1. Murray, Li, Sastry, A Mathematical Introduction to Robotic Manipulation
  2. Solà, “Quaternion kinematics for the error-state Kalman filter”
  3. 3Blue1Brown 之外,可视化 SO(3) 可看 Modern Robotics 第 3 讲