万向节死锁

先记录核心概念和结论

  • 左乘 = 新矩阵放在旧矩阵左边,对应绕世界固定轴转;右乘 = 新矩阵放在旧矩阵右边,对应绕物体自身轴转。
  • 叠加新矩阵时,把新矩阵放在旧矩阵的左边,就叫"新矩阵左乘旧矩阵";放在右边,就叫"新矩阵右乘旧矩阵"
  • 相对于世界转,新旋转放左边;相对于自身转,新旋转放右边。
  • 左乘和右乘,本质上是在说"这个新旋转是相对于世界坐标系,还是相对于物体自身坐标系"
  • 同一个最终姿态,可以用外旋解释,也可以用内旋解释,但旋转顺序必须反过来,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 棍。

  1. 先绕 Z 棍转一下------Z 棍不动,X、Y 棍在水平面转。
  2. 再绕 Y 棍转。当转到 90° 时,X 棍会倒下来,正好和原来的 Z 棍方向重合。
  3. 这时你命令"绕 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° 时,第一次和第三次旋转的轴共线,两个自由度合并成一个。无论外旋还是内旋,无论怎么解释,这个结论都不变。要彻底避免,请使用四元数或旋转矩阵。

相关推荐
亿道电子Emdoor1 小时前
【Perforce】Klocwork-kwgcheck图形化界面无法打开如何解决
git·python·github
迅猛龙办公室3 小时前
python实现倒序输出数字
开发语言·python
全栈练习生13 小时前
AI Agent 沙箱
python·ai
SEO_juper14 小时前
用 Python 写一个 GEO 可见性检查脚本:你的网站现在能被 AI 引用吗
开发语言·人工智能·爬虫·python·seo·外贸独立站
用户83562907805115 小时前
使用 Python 对 Excel 工作表进行排序
后端·python
for_ever_love__15 小时前
MySQL 全文索引实战:FULLTEXT、ngram 中文分词与 MATCH AGAINST 到底该怎么用
java·python·mysql·全文检索·分词·索引·ngram
用户83562907805115 小时前
使用 Python 合并 PowerPoint 演示文稿
后端·python
weixin_4617694015 小时前
VS Code 中创建 Jupyter 文件(.ipynb)
ide·python·jupyter
2601_9669496516 小时前
多市场量化策略的数据接口应该如何设计:从数据层架构到策略接入
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash