欧拉角万向节死锁

  1. 四元数与其他形式的优点

  2. 1.欧拉角

  3. 2. 万向节死锁(Gimbal Lock)

    1. 2.1 什么是 Gimbal

    2. 2.2 为什么要研究 Gimbal?

    3. 2.3 Pitch、Yaw、Roll

    4. 2.4 Gimbal 中的万向节死锁

      1. 2.4.1 横滚
      2. 2.4.2 俯仰
      3. 2.4.3 偏航
      4. 2.4.4 死锁的产生
      5. 2.4.5 用小程序重现万向节死锁问题(可不看)
      6. 2.4.6 若“2.3.5”没看懂,看下面这个(可不看)
  4. 3. 总结

  5. 4. 参考文献


参考文献


四元数与其他形式的优点

四元数相对于其他形式的​优点,大略为:

  1. 解决万向节死锁
  2. 仅需 4 个浮点数,相比矩阵更轻量
  3. 无论求逆、串联等操作,相比矩阵更高效

本文简要分析“万向节死锁”形成原因。

1.欧拉角

欧拉角用于表示刚体当前的姿态。

思想​:将刚体绕某一轴的一次旋转,分解为依次分别绕 X、Y、Z 轴的三次旋转。这三个轴分别旋转的转动角度,就是一组三个欧拉角。

图片中即为上述的三次旋转(而其实可以绕某一轴,一次旋转即可达到最终位置)

动图
图 1 球体演示欧拉变换

  • 从图 1 可以看出, 欧拉角的旋转

    • 是有顺序的,旋转之后轴是固定的

上面的旋转使用角度形式可以展示为如图 2:


图 2 角度演示欧拉变换

图中有两组坐标系,我们定义为:

  • xyz :世界坐标系(固定不动)
  • XYZ :刚体坐标系(与刚体同步运动)

具体旋转步骤为:

  • 世界系z 轴,旋转 \alpha 角。绕刚体系X 轴,旋转 \beta 角。绕刚体系Z 轴,旋转 \gamma 角。

而考虑到直接的对象上,考虑固定翼无人机对象可以得到[gfycat]。

动图
图 3 固定翼无人机演示欧拉变换

动图旋转步骤为 z\rightarrow Y\rightarrow X ,按照顺序标记为 zYX ,加上角度即为一个完整欧拉角:zYX-(\psi,\theta,\phi)

  • 从上述的数学表达中可以看出,欧拉角使用的轴是 zYX,也就是图 3 中的轴,但是这个图的问题,是 z 旋转以后,YX 轴没有随着变换。正确的是,转动 z 轴后,YX 轴随之变化,而在欧拉角的视角中,z 是已经处理过的轴,因此其不变。之后的旋转按照 z 轴变换的逻辑,首先按照变换后的 Y 轴进行转动,之后按照被 zY 影响的 X 轴进行转动。

    • 如此的顺序固定于轴向固定,会导致“万向节死锁”

      • 欧拉角还有一个约束, 就是先转动的轴转动后, 其轴向是固定的, 而先转动的轴会影响后转动的轴, 后转动的轴不会影响先转动的轴, 从而会发生这样的问题
    • image
      图 4 万向节死锁演示

      • 旋转之后, xy 轴重合了, 导致 xy 轴的旋转是一致的, 无人机失去了一个运动控制的自由度
  • 但是为什么后面的轴无法带动前面的轴旋转呢?

    • 在轴的固定假设下, 欧拉角运动和平衡架运动的方式是一致的.
  • 而按照事实情况, 物体所有的轴是和物体一起旋转的

    • image
      图 5 轴与轴的运动

    • 这就涉及到欧拉角的本质定义, 欧拉角定义的是旋转的顺序和旋转的角度, 那么先调整 x 为 30 再调整 y 为 20 再调整 z 为 10 之后, 我还需要调整 x 轴旋转 10 度, 那么此时不能用 xyz 变化后的 x 轴进行调整, 由于欧拉角的定义, 此时变换变为先调整 x 为 40 再调整 y 为 20 再调整 z 为 10. 所以欧拉角不能用来表示先调整 x 为 30 再调整 y 为 20 再调整 z 为 10 再调整 x 加 10 这种叙述, 在欧拉角的语境下, 这个会变成先调整 x 为 40 再调整 y 为 20 再调整 z 为 10. 所以欧拉角不能这样描述.

    • 上面是描述的问题, 最本质的问题, 还是欧拉角的变换导致的坐标轴固定, 在两个轴重合的情况下, 欧拉角表述失去了一个自由度, 造成了万向节死锁.

      • 顺序固定 ➡️ 坐标轴固定 ➡️ 万向节死锁
      • 比如首先按照 x 轴运动,因此 x 轴固定,接着按照 y 轴运动 90 度,导致受 xy 变换影响后的 z 轴与原有的 x 轴固定,导致缺少了一个自由度
    • 这就是欧拉角的本质定义导致了无法描述运动的变换. 也就导致了欧拉角的变换会和平衡架一致的效果, 因为欧拉角的语境变换, 会导致这种轴的固定.


2. 万向节死锁(Gimbal Lock)

万向节死锁发生在欧拉角形式下,是由欧拉旋转定义本身造成的。

参考:万向节死锁(Gimbal Lock)问题

2.1 什么是 Gimbal

平衡环架(英语:Gimbal),是一具有枢纽的装置,作用是使得一物体能以单一轴旋转。由彼此垂直的枢纽轴所组成的一组三只平衡环架,则可使架在最内的环架的物体维持旋转轴不变,而应用在船上的陀螺仪、罗盘、饮料杯架等用途上,而不受船体因波浪上下震动、船身转向的影响。
————百度百科

如图:

动图

静态图:

上图就是一 Gimbal 装置,是一陀螺仪。中间有一根竖轴,穿过一个金属圆盘。金属圆盘称为转子,竖轴称为旋转轴。转子用金属制成,应该是了增加质量,从而增大惯性。竖轴外侧是三层嵌套的圆环,它们互相交叉,带来了三个方向自由度的旋转。称作陀螺仪即可。

2.2 为什么要研究 Gimbal?

考虑到欧拉角定义导致的轴向的固定与变换的固定,因此其变换形式与 Gimbal 高度相似,因此可以使用 Gimbal 对欧拉角进行理解。

2.3 Pitch、Yaw、Roll

陀螺仪分别绕 X、Y、Z 三个轴旋转时的旋转角。这里直接等同于欧拉角即可。如图:

  • 机身右方X 轴旋转,称为​pitch,俯仰
  • 机头上方Z 轴旋转,称为​Yaw,偏航
  • 机头前方Y 轴旋转,称为​Roll,横滚

可以看出,与欧拉角形式基本相同。

2.4 Gimbal 中的万向节死锁

陀螺仪是用来测量平衡和转速的工具,在载体高速转动的时候,陀螺仪始终要通过自我调节,使得转子保持原有的平衡。

为助于理解,下面是一个简单的陀螺仪示意图(省略了金属圆盘)。

把三个 Gimbal 环用不同的颜色做了标记,底部三个轴向,RGB 分别对应 XYZ。
假设现在这个陀螺仪被放在一艘船上,船头的方向沿着 +Z 轴,也就是右前方。

2.4.1 横滚

现在假设,船体发生了摇晃,是沿着前方进行旋转的摇晃,也就是横滚。由于转子和旋转轴具有较大的惯性,只要没有直接施加扭矩,就会保持原有的姿态。由于上图中绿色的活动的连接头处是可以灵活转动的,此时将发生相对旋转,从而出现以下的情形:

动图

2.4.2 俯仰

再次假设,船体发生了 pitch 摇晃,也就是俯仰。同样,由于存在相应方向的可以相对旋转的连接头(红色连接头),转子和旋转轴将仍然保持平衡,如下图:

动图

2.4.3 偏航

最后假设,船体发生了 yaw 摇晃,也就是偏航,此时船体在发生水平旋转。相对旋转发生在蓝色连接头。如下图:

动图

最终,在船体发生 Pitch、Yaw、Roll 的情况下,陀螺仪都可以通过自身的调节,而让转子和旋转轴保持平衡。

2.4.4 死锁的产生

以上陀螺仪一切正常,在船体发生任意方向摇晃都可以通过自身调节来应对。

假如,船体发生了剧烈的变化,此时船首仰起(抬头)了 90 度,此时的陀螺仪调节状态如下图:

此时,船体再次发生转动,沿着当前世界坐标的 +Z 轴(蓝色轴,应该正指向船底)进行转动,那么来看看发生了什么情况。

动图

现在,转子不平衡了,陀螺仪的三板斧不起作用了。它失去了自身的调节能力。那么这是为什么呢?

之前陀螺仪之所以能通过自身调节,保持平衡,是因为存在可以相对旋转的连接头。在这种情况下,已经不存在可以相对旋转的连接头了。

那么连接头呢?去了哪里?显然,它还是在那里,只不过是,连接头可以旋转的相对方向不是现在需要的按着 +Z 轴方向。从上图中,我们清楚地看到:

  • 红色连接头:可给予一个相对俯仰的自由度。
  • 绿色连接头:可给予一个相对偏航的自由度。
  • 蓝色连接头:可给予一个相对偏航的自由度。

没错,三个连接头,提供的自由度只对应了俯仰和偏航两个自由度,桶滚自由度丢失了。这就是陀螺仪上的“万向节死锁”问题。

  • “三个轴不还是在物体身上吗?依然可以操作啊?”

    • 回答: 在物体身上确实有这个轴。但是,负责驱动那个轴转动的“把手”(Gimbal 环/电机),被你自己转到了一个错误的位置,导致那个把手使不上劲了。
    • 可以把三个连接子看做三个电机, 当一个轴九十度的时候, 那么有两个电机的旋转就会是一致的效果, 这就是陀螺仪的万向节死锁
  • 而对于欧拉角的万向节死锁

    • 某些轴先运动, 会导致其他轴向旋转造成的效果不一样, 比如原本是俯仰旋转的变成了偏航旋转
    • 动图

  • 万向节死锁的原因还有欧拉角定义和轴的固定的影响


2.4.5 用小程序重现万向节死锁问题(可不看)

首先,预设一下接下来的欧拉角变化顺序。见下图:

上图中,红色框内的部分的列表,记录了接下来欧拉角的增长变化过程。即它会从(0,0,0)变化到(90,0,0),再变化到(90,90,0),再变化到(90,180,0),再变化到(90,180,90),再变化到(90,180,180)。下图是变化的过程演示。

动图

现在可以看到:

  • 当先执行 X 轴旋转 90 度,此时在执行 Pitch(俯仰)变化。

  • 再在 Y 轴进行变化 0-180 度,此时在执行相对自身的Roll(桶滚)变化。

  • 再在 Z 轴进行变化 0-180 度,此时仍在执行相对自身的Roll(桶滚)变化。

    • 这里的 z 轴不知道是原来的 z 轴还是什么

这里所说的俯仰、桶滚、偏航都是相对自己局部坐标系的。这与上述的陀螺仪中出现的问题是一样的,万向节死锁。也就是尽管欧拉角在 XYZ 三个轴向进行进动(持续增长或者减少),但是影响最终的结果,只对应了两个轴向。

2.4.6 若“2.3.5”没看懂,看下面这个(可不看)

我们先不考虑 Y 轴和 Z 轴,假设其一直为 0。先说 X 轴,那么围​绕 X 轴进动,最终的影响是预期的俯仰变化。如下图:

动图

然而当 Z 轴为 90 度时,围绕 X 轴进动变成了偏航变化,如下图:

动图

也就是说,欧拉角的 X 轴进动造成最后的变化结果,受到到了预先执行的 Z 轴进动的影响,它仍然会造成某个相对自身的轴向的变化,但是结果不唯一;同样,欧拉角的 Y 轴进动,则受到了 Z 轴和 X 轴的影响,结果更加不唯一。

然而,以上的过程执行,都是严格遵守欧拉角的顺规和轴向定义的。某些时刻,这种不确定的结果,就可能造成某个轴向自由度的丢失。
就拿下图来说:

动图

欧拉角 Z 轴的进动,最先执行,造成桶滚,这个没问题。
欧拉角 Y 轴的进动,最后执行,造成沿着欧拉旋转前的 Y 轴旋转,这也是根据定义执行。然而现在这种沿着 Y 轴的旋转,同样也被映射到了物体的桶滚变化。

3. 总结

总结来说,欧拉角的“万向节死锁”问题,是由于欧拉旋转定义本身造成的。这种围绕选旋转前固定轴的先 Z、再 X、再 Y 的旋转操作,与其最终所预期的三个轴向可以旋转的结果并非一定是一对一的映射。某些情况下是多对一的映射,造成一些旋转自由度的缺失,也就是“死锁”。

在编程中很难规避死锁,所以现在更多使用四元数形式进行姿态表示与旋转。


4. 参考文献

Refence:

@ 天下行走

1 操作
TangQi 在 2025-11-28 08:57:56 更新了该帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...