先记录核心概念和结论
- 左乘 = 新矩阵放在旧矩阵左边,对应绕世界固定轴转;右乘 = 新矩阵放在旧矩阵右边,对应绕物体自身轴转。
- 叠加新矩阵时,把新矩阵放在旧矩阵的左边,就叫"新矩阵左乘旧矩阵";放在右边,就叫"新矩阵右乘旧矩阵"
- 相对于世界转,新旋转放左边;相对于自身转,新旋转放右边。
- 左乘和右乘,本质上是在说"这个新旋转是相对于世界坐标系,还是相对于物体自身坐标系"
- 同一个最终姿态,可以用外旋解释,也可以用内旋解释,但旋转顺序必须反过来,3个角度值相同,最终合成的R矩阵也相同,最终都是左乘点坐标列向量。
- 无论是动态欧拉角还是静态欧拉角都存在死锁现象,而且都是第2轴90度时触发,第1轴和第3轴90度时不触发
- 动态欧拉角是沿着物体自身的机体坐标系的轴运动的,每次运动轴都在动,静态欧拉角是沿着世界坐标系的轴运动的,无论物体怎么运动,坐标轴不变,对应内旋转和外旋的概念
- 万向节死锁的本质,就是第三个旋转的轴,恰好和第一个旋转的轴,在物体坐标系下变成了同一个轴,以静态欧拉角(外旋,相对世界坐标系旋转)为例,第一旋转时转的是机体坐标系的X轴,第三旋转时仍然转的时机体坐标系的X轴,导致歧义少了一个自由度。
- 第一旋转轴和第三旋转轴转90度不会出现死锁:例如外旋场景下,第一次旋转世界坐标系的X轴,世界坐标系X轴和机体坐标系X轴重合,X轴动90度,此时机体坐标系Y轴和世界坐标系Z轴重合,机体坐标系Z轴和世界坐标系Y轴重合,然后进行第二次旋转,转动动世界坐标系Y轴,对应的是动的机体坐标系的Z轴,如果这个转动值是0,转动世界坐标系的Z轴时,实际动的是机体坐标系Y轴,并没有重复动机体坐标系的某个轴,不会出现死锁。
- 死锁问题可以结合公式看出来,缺少自由度。
- 任意三维旋转,既可以用三个欧拉角分三步表示,也可以用"绕某个轴转一个角度"的轴角表示。两者描述的是同一个最终姿态。
- 欧拉角定理:三维空间中任意一个旋转,都可以表示为绕某一固定轴旋转一个角度。
一、什么是万向节死锁?
万向节死锁是欧拉角表示三维旋转时的一个固有缺陷:当三个旋转中的中间那个角达到 ±90° 时,第一次旋转和第三次旋转的轴会共线,导致丢失一个自由度。
这不是物理上的卡死,而是数学表示上的奇异性。物体仍然可以自由旋转,但无法用三个独立的欧拉角来唯一描述它。
二、坐标系定义
我们采用航空标准坐标系:
- X 轴朝前(机头方向)
- Y 轴朝左(左翼方向)
- Z 轴朝天(垂直机身向上)
这是一个右手系:
X×Y=Z X \times Y = Z X×Y=Z
对应的旋转:
| 轴 | 旋转名称 | 符号 |
|---|---|---|
| X | 滚转 | γ\gammaγ |
| Y | 俯仰 | β\betaβ |
| Z | 偏航 | α\alphaα |
三、旋转矩阵基础
3.1 三个基本旋转矩阵
绕 X 轴滚转 γ\gammaγ:
Rx(γ)=1000cosγ−sinγ0sinγcosγ R_x(\gamma)= \begin{bmatrix} 1 & 0 & 0\\ 0 & \cos\gamma & -\sin\gamma\\ 0 & \sin\gamma & \cos\gamma \end{bmatrix} Rx(γ)= 1000cosγsinγ0−sinγcosγ
绕 Y 轴俯仰 β\betaβ:
Ry(β)=cosβ0sinβ010−sinβ0cosβ R_y(\beta)= \begin{bmatrix} \cos\beta & 0 & \sin\beta\\ 0 & 1 & 0\\ -\sin\beta & 0 & \cos\beta \end{bmatrix} Ry(β)= cosβ0−sinβ010sinβ0cosβ
绕 Z 轴偏航 α\alphaα:
Rz(α)=cosα−sinα0sinαcosα0001 R_z(\alpha)= \begin{bmatrix} \cos\alpha & -\sin\alpha & 0\\ \sin\alpha & \cos\alpha & 0\\ 0 & 0 & 1 \end{bmatrix} Rz(α)= cosαsinα0−sinαcosα0001
3.2 总旋转矩阵
按顺序 RzRyRxR_z R_y R_xRzRyRx:
R=Rz(α) Ry(β) Rx(γ) R = R_z(\alpha)\,R_y(\beta)\,R_x(\gamma) R=Rz(α)Ry(β)Rx(γ)
展开后:
R=cosαcosβcosαsinβsinγ−sinαcosγcosαsinβcosγ+sinαsinγsinαcosβsinαsinβsinγ+cosαcosγsinαsinβcosγ−cosαsinγ−sinβcosβsinγcosβcosγ R= \begin{bmatrix} \cos\alpha\cos\beta & \cos\alpha\sin\beta\sin\gamma-\sin\alpha\cos\gamma & \cos\alpha\sin\beta\cos\gamma+\sin\alpha\sin\gamma\\ \sin\alpha\cos\beta & \sin\alpha\sin\beta\sin\gamma+\cos\alpha\cos\gamma & \sin\alpha\sin\beta\cos\gamma-\cos\alpha\sin\gamma\\ -\sin\beta & \cos\beta\sin\gamma & \cos\beta\cos\gamma \end{bmatrix} R= cosαcosβsinαcosβ−sinβcosαsinβsinγ−sinαcosγsinαsinβsinγ+cosαcosγcosβsinγcosαsinβcosγ+sinαsinγsinαsinβcosγ−cosαsinγcosβcosγ
点写成列向量 ppp,旋转作用为:
p′=R p p' = R\,p p′=Rp
四、外旋与内旋
4.1 外旋(固定轴旋转)
每次旋转都绕世界固定轴转。
顺序:先绕世界 X 转 γ\gammaγ,再绕世界 Y 转 β\betaβ,最后绕世界 Z 转 α\alphaα。
矩阵累积方式:新旋转左乘旧矩阵。
R=Rz(α) Ry(β) Rx(γ) R = R_z(\alpha)\,R_y(\beta)\,R_x(\gamma) R=Rz(α)Ry(β)Rx(γ)
通俗理解:你站在世界地图上,每次都在地图上画一个箭头,让物体绕这个箭头转。新箭头相对于地图,所以直接叠加到当前世界坐标上。
4.2 内旋(体轴旋转)
每次旋转都绕物体当前自身的轴转。
顺序:先绕体 Z 转 α\alphaα,再绕体 Y 转 β\betaβ,最后绕体 X 转 γ\gammaγ。
矩阵累积方式:新旋转右乘旧矩阵。
R=Rz(α) Ry(β) Rx(γ) R = R_z(\alpha)\,R_y(\beta)\,R_x(\gamma) R=Rz(α)Ry(β)Rx(γ)
通俗理解:你贴在物体上,每次都在物体身上画一个箭头,让物体绕这个箭头转。新箭头相对于物体自身,所以作用在物体内部坐标上。
4.3 对偶关系
| 外旋(固定轴) | 内旋(体轴) | 总矩阵 |
|---|---|---|
| X → Y → Z | Z → Y → X | RzRyRxR_z R_y R_xRzRyRx |
两者得到完全相同的矩阵,角度值相同,执行顺序相反。这就是内外旋的对偶性。
4.4 左乘与右乘
| 写法 | 说法 | 含义 |
|---|---|---|
| NMN MNM | NNN 左乘 MMM | 新矩阵在左边 |
| MNM NMN | NNN 右乘 MMM | 新矩阵在右边 |
- 外旋:新旋转左乘旧矩阵(相对于世界转)
- 内旋:新旋转右乘旧矩阵(相对于自身转)
五、万向节死锁的数学本质
5.1 俯仰角 β=90∘\beta = 90^\circβ=90∘ 时
代入 cosβ=0, sinβ=1\cos\beta=0,\ \sin\beta=1cosβ=0, sinβ=1:
R(α,90∘,γ)=0sin(γ−α)cos(γ−α)0cos(γ−α)−sin(γ−α)−100 R(\alpha,90^\circ,\gamma)= \begin{bmatrix} 0 & \sin(\gamma-\alpha) & \cos(\gamma-\alpha)\\ 0 & \cos(\gamma-\alpha) & -\sin(\gamma-\alpha)\\ -1 & 0 & 0 \end{bmatrix} R(α,90∘,γ)= 00−1sin(γ−α)cos(γ−α)0cos(γ−α)−sin(γ−α)0
关键观察 :矩阵中只出现 γ−α\gamma-\alphaγ−α 这个差值!
这意味着:
- 单独改变 α\alphaα(偏航)或单独改变 γ\gammaγ(滚转),只要保持 γ−α\gamma-\alphaγ−α 不变,最终旋转矩阵完全一样。
- 偏航和滚转的自由度退化成了一个。
- 你无法分辨 α\alphaα 和 γ\gammaγ 各自是多少。
这就是万向节死锁的数学本质。
5.2 滚转角 γ=90∘\gamma = 90^\circγ=90∘ 时
代入 cosγ=0, sinγ=1\cos\gamma=0,\ \sin\gamma=1cosγ=0, sinγ=1:
R(α,β,90∘)=cosαcosβcosαsinβsinαsinαcosβsinαsinβ−cosα−sinβcosβ0 R(\alpha,\beta,90^\circ)= \begin{bmatrix} \cos\alpha\cos\beta & \cos\alpha\sin\beta & \sin\alpha\\ \sin\alpha\cos\beta & \sin\alpha\sin\beta & -\cos\alpha\\ -\sin\beta & \cos\beta & 0 \end{bmatrix} R(α,β,90∘)= cosαcosβsinαcosβ−sinβcosαsinβsinαsinβcosβsinα−cosα0
这个矩阵中,α\alphaα 和 β\betaβ 仍然各自独立出现,没有耦合。所以滚转 90∘90^\circ90∘ 不会导致死锁。
5.3 对比总结
| 情况 | 总矩阵特征 | 参数是否耦合 | 是否死锁 |
|---|---|---|---|
| 一般情况 | α,β,γ\alpha,\beta,\gammaα,β,γ 独立 | 否 | 否 |
| 俯仰 β=90∘\beta=90^\circβ=90∘ | 只含 γ−α\gamma-\alphaγ−α | 耦合,丢失一个自由度 | 是 |
| 滚转 γ=90∘\gamma=90^\circγ=90∘ | 含 α\alphaα 和 β\betaβ 的独立项 | 仍然独立 | 否 |
结论 :万向节死锁只由中间那个旋转角 达到 ±90∘\pm90^\circ±90∘ 触发。在 RzRyRxR_zR_yR_xRzRyRx 顺序中,中间角是俯仰 β\betaβ。
六、为什么中间角是"凶手"?
6.1 外旋视角
外旋顺序:世界 X → 世界 Y → 世界 Z。
- 第一次旋转轴:世界 X
- 第三次旋转轴:世界 Z
俯仰 90∘90^\circ90∘ 后,物体的 X 轴转到了世界 Z 方向。于是第三次旋转(绕世界 Z)和第一次旋转(绕世界 X)在物体上变成了同一个轴。
6.2 内旋视角
内旋顺序:体 Z → 体 Y → 体 X。
- 第一次旋转轴:体 Z
- 第三次旋转轴:体 X
俯仰 90∘90^\circ90∘ 后,体 X 轴转到了和初始体 Z 轴共线的方向。于是第三次旋转(绕体 X)和第一次旋转(绕体 Z)变成了同一个轴。
6.3 核心结论
无论外旋还是内旋:
当中间旋转角达到 ±90° 时,第一次旋转的轴和第三次旋转的轴在物体上共线,导致这两个旋转效果重合,丢失一个自由度。
七、为什么滚转 90° 不会死锁?
7.1 外旋视角
滚转 90∘90^\circ90∘ 后:
- 物体 Y 轴转到世界 Z 方向
- 物体 Z 轴转到世界 -Y 方向
第三次旋转轴(世界 Z)在物体看来是 Y 轴,而第一次旋转轴是 X 轴。两者不同,仍然独立。
7.2 内旋视角
滚转 90∘90^\circ90∘ 后:
- 体 Y 轴转到和初始体 Z 轴共线
但第一次旋转轴是体 Z,第三次旋转轴是体 X。体 X 和体 Z 仍然垂直,没有共线。
7.3 对比表
| 情况 | 第一次旋转轴 | 第三次旋转轴 | 是否共线 | 死锁? |
|---|---|---|---|---|
| 俯仰 90∘90^\circ90∘ | 体 X(外旋:世界 X) | 体 X(外旋:世界 Z) | 是 | 是 |
| 滚转 90∘90^\circ90∘ | 体 Z(外旋:世界 X) | 体 Y(外旋:世界 Z) | 否 | 否 |
八、通俗比喻
8.1 万向节支架
想象一个由三个环组成的万向节:
- 最外环控制偏航(绕 Z)
- 中间环控制俯仰(绕 Y)
- 最内环控制滚转(绕 X)
正常情况下,三个环的轴互相垂直,你可以独立调整三个角度。
但当中间环(俯仰)转到 90° 时,最内环的 X 轴和最外环的 Z 轴对齐了。这时你转动最外环(偏航)和转动最内环(滚转),实际上都是让里面的物体绕同一个轴转。你失去了一个独立的控制方向。
就像飞机的机头垂直向上时,你拉偏航杆和压滚转杆,飞机都会绕垂直轴旋转------你分不清哪个是偏航、哪个是滚转。
8.2 三根棍子
想象你手里拿着三根互相垂直的棍子:Z 棍、Y 棍、X 棍。
- 先绕 Z 棍转一下------Z 棍不动,X、Y 棍在水平面转。
- 再绕 Y 棍转。当转到 90° 时,X 棍会倒下来,正好和原来的 Z 棍方向重合。
- 这时你命令"绕 X 棍转"。但 X 棍现在和 Z 棍是同一个方向了。你转 X 棍,等于在转 Z 棍。
你当然是在"上次的基础上"转的,但上次的基础已经让两根棍子重合了。
8.3 动态欧拉角的困惑
有人会问:动态欧拉角每一步都是绕当前物体轴转,轴跟着物体动,为什么还会死锁?
答案:正是因为轴跟着物体动,中间那次旋转才会把第三个轴"带"到和第一个轴重合的位置。如果轴永远固定不动,三个轴永远垂直,永远不会死锁。死锁不是"没有基于上次变化",而是"基于上次变化之后,两个轴碰巧共线了"。
九、万向节死锁的后果
- 丢失一个自由度:三个欧拉角本来可以表示三个独立旋转,但在死锁点,只有两个独立方向。
- 欧拉角不唯一 :同一个姿态可以用无穷多组 (α,90∘,γ)(\alpha, 90^\circ, \gamma)(α,90∘,γ) 表示,因为改变 α\alphaα 和 γ\gammaγ 的效果相同。
- 插值不连续:在动画或控制中,角度插值会突然跳变,运动不自然。
- 微分关系退化:角速度到欧拉角导数的映射矩阵奇异,无法反解。
十、如何避免万向节死锁?
- 四元数:四个数,无奇点,插值平滑。是游戏引擎和机器人的首选。
- 旋转矩阵:九个数,有正交约束,但无死锁。
- 轴角 或李代数 so(3)\mathfrak{so}(3)so(3):在优化中常用。
- 如果必须用欧拉角:避免俯仰角接近 ±90°,或采用其他旋转顺序。
十一、总结
| 概念 | 说明 |
|---|---|
| 外旋 | 绕世界固定轴转,新旋转左乘旧矩阵 |
| 内旋 | 绕物体自身轴转,新旋转右乘旧矩阵 |
| 对偶 | 外旋 X→Y→Z 等价于内旋 Z→Y→X,角度相同,顺序相反 |
| 死锁条件 | 中间旋转角达到 ±90° |
| 死锁本质 | 第一次旋转轴和第三次旋转轴在物体上共线 |
| 数学表现 | 总矩阵只依赖两个角的差值,如 γ−α\gamma-\alphaγ−α |
| 滚转 90° | 不会死锁,因为第一次和第三次旋转轴仍然垂直 |
一句话总结:
万向节死锁是欧拉角参数化的内在缺陷。当中间旋转角达到 ±90° 时,第一次和第三次旋转的轴共线,两个自由度合并成一个。无论外旋还是内旋,无论怎么解释,这个结论都不变。要彻底避免,请使用四元数或旋转矩阵。