JOVANA
Library Glossary Getting Started Three Levels Fields How it works Mission
Join the mission
All guides

欧拉角、万向锁与四元数

用三个角度命名旋转的友好方式、它会掉进的陷阱,以及工程师实际采用的四数修正方案。

三次转动命名任意朝向

假设一架无人机正在悬停,而你想描述它指向哪里。它的位置告诉你它在哪里;它的朝向则告诉你它在空间中如何扭转。给这种扭转命名最直观的方式,就是把它拆成三种熟悉的转动:横滚(左右倾斜)、俯仰(机头上下)和偏航(像指南针那样旋转)。这三个数就是欧拉角,几乎所有人都会先想到它们,因为它们对应着人类能够想象出来的词。

关键在于这三次转动是有先后顺序的:你一个接一个地施加,每次绕某个轴转动。从一个参考坐标系(比如世界坐标系)出发,你先偏航、再俯仰、最后横滚,物体最终落在哪里就是它的最终朝向。把这三次按顺序组合起来,你就得到一个完整的描述,它等价于一个完整的旋转矩阵——只不过用三个友好的角度来存储,而不是九个数。

陷阱:万向锁

欧拉角读起来很美好,却藏着一道锋利的刃。想象三个嵌套的环,每个都能绕一个轴自由旋转——这就是曾经用来稳定船用罗盘和航天仪器的机械万向架。只要这些环彼此保持一定角度,你就能到达任意朝向。但只要把中间那个环倾斜 90 度,其中两个环就会对齐。此时它们绕同一个轴旋转,你三次独立转动中的一次就悄悄地不再产生任何新变化了。这种坍缩就是万向锁

具体地说,在 ZYX(偏航-俯仰-横滚)约定下,把机头俯仰到正上方 90 度,偏航轴和横滚轴此时就指向同一个方向。偏航和横滚变得无法区分——你在描述中丢失了一个自由度,尽管物理上的无人机依然能朝各个方向自由旋转。被卡住的从来不是物体,而是你那套三角度的命名方案。阿波罗任务的惯性导航平台正是出于这个原因,才会面临真实的万向锁隐患。

一根轴、一个角,没有锁

这里有一条逃生通道。一个深刻的结论——欧拉旋转定理——指出:任何你能通过三次转动到达的朝向,也都能通过绕某根巧妙选定的轴转动一次来到达。这就给出了轴-角表示:指定一个单位向量(要绕之旋转的轴)和一个角度(转多远)。它不是三次会彼此坍缩的连续转动,而是一次诚实的旋转——而且没有中间环可对齐,所以万向锁根本不会发生。

工程师真正采用的表示法,把这个轴-角思想打包成四个数,它们能优雅地组合与插值:单位四元数。一个四元数把一个标量和一个三数的向量部分捆在一起;对于绕单位轴 (x, y, z) 转角 θ 的旋转,你存储半角的余弦,以及被半角正弦缩放后的轴。半角乍看很怪,但正是它让两次旋转能够通过简单的乘法组合起来。

axis-angle:  unit axis n = (x, y, z),  angle theta

unit quaternion q = ( w, vx, vy, vz )
   w  = cos(theta/2)
   vx = x * sin(theta/2)
   vy = y * sin(theta/2)
   vz = z * sin(theta/2)

always keep ||q|| = sqrt(w^2 + vx^2 + vy^2 + vz^2) = 1  (a UNIT quaternion)
q and -q name the SAME rotation
从一根轴和一个角到四元数的四个数。把长度保持为 1,才使它成为一个有效的旋转。

两大好处让四元数成为机器人、游戏引擎,以及融合陀螺仪读数的 IMU 代码中的默认选择。第一,没有万向锁——每个朝向都被同样平滑地表示,没有谁特殊。第二,你可以用一种叫作球面线性插值(slerp)的干净运算,沿最短路径混合两个朝向,得到欧拉角无法保证的、稳定而均匀的镜头扫摄与关节运动。在内部,这些都是活在同一个群——SO(3)——里的旋转;四元数不过是它们一组紧凑、性质良好的坐标。

经验法则:用欧拉角读,用四元数算

这些表示法没有谁是错的;它们各擅其长。大多数机器人团队遵循的实用工作流,是一种清晰的分工:在人看的地方用友好的那一种,在跑数学的地方用稳健的那一种。

  1. 把朝向展示给人看时——仪表盘、日志、控制滑块——用欧拉角,因为横滚、俯仰、偏航容易想象和推理。
  2. 一旦你需要在代码里存储、组合或插值一个旋转,就转换成单位四元数,把所有真正的运算都放在那里做,远离任何万向锁奇异点。
  3. 每次乘法之后,把四元数重新归一化回长度 1,这样累积的浮点误差就永远不会让它偏离一个有效的旋转。
  4. 只在最后、为了显示,才转换回欧拉角——并记住 q 与 -q 是同一个旋转,所以当符号翻转时不必惊讶。