【自动驾驶和机器人控制】万向锁(Gimbal Lock)原理详解 + 和欧拉角 / 四元数 / SO(3)对比

万向锁(Gimbal Lock)原理详解 + 和欧拉角 / 四元数 / SO(3)对比

前置:欧拉角是用「三次依次绕坐标轴转动」来描述姿态 ,例如车辆常用的 Yaw (偏航‑Z)、Pitch (俯仰‑Y)、Roll (滚转‑X),不同书籍旋转顺序不一样(Z‑Y‑X、X‑Y‑Z 等),万向锁本质来源于「顺序旋转」这个机制,不是数值 bug,是数学结构问题
注意:万向锁不是不能旋转了,是丢失一个旋转自由度,有一组姿态会出现多解、奇异,微分方程退化,角速度和欧拉角导数矩阵奇异,IMU 积分直接崩掉

1. 什么是欧拉角(Z‑Y‑X 顺序举例,车载常用)

姿态 = 连续做三次旋转,顺序至关重要,不能调换

  1. Yaw(偏航)ψ\psiψ:绕世界 Z 轴旋转(车头左右转向)

  2. Pitch(俯仰)θ\thetaθ:绕转动之后的 Y 轴旋转(车头抬头低头)

  3. Roll(滚转)ϕ\phiϕ:绕转动之后的 X 轴旋转(车身左右倾斜)

⚠关键点:后面每一次旋转的坐标轴,是上一步旋转之后被改动过的本体坐标轴,不是固定世界轴

2. 万向锁发生过程(Z‑Y‑X 顺序,pitch=90°)

当俯仰角 θ=90∘\boldsymbol{\theta=90^\circ}θ=90∘(车头完全朝上,竖直指向天空):

  • 第二步 Pitch 绕 Y 轴转 90° 之后:
    原来的本体 X 轴,和世界 Z 轴重合了

原本:

  • Yaw:绕世界 Z

  • Roll:绕本体 X

现在两个旋转轴重合到同一根轴。

👉原本互相独立的两个旋转(Yaw 偏航、Roll 滚转),变成绕同一根轴转动

3 个输入角度,但是物理上只剩下 2 个有效自由度;丢失 1 个自由度,这就是万向锁

数学表现:

此时,yaw+5°,roll不变yaw不变,roll‑5°,得到完全一模一样的最终姿态

不同的欧拉角组合,输出同一个姿态 → 多值奇异点。

反过来,同一个姿态,无法唯一反推欧拉角。
实物类比(传统机械万向节陀螺仪):

三个环,内环、中环、外环;当中环转到 90°,内环外环的旋转轴叠在一起,其中一个环的转动不再产生新姿态,机构 "卡死",这就是名字 Gimbal Lock 的来源。

软件数学上没有物理卡死,但是自由度退化、雅可比矩阵奇异

3. 对工程最大的危害(IMU/SLAM 场景,重点!)

欧拉角的角速度和欧拉角变化率的关系:

ωb\boldsymbol\omega_bωb 是 IMU 输出的车体三维角速度;

MMM 是转换矩阵。

当来到万向锁奇异位置(pitch=±90°):

矩阵MMM 行列式等于 0,矩阵奇异,不可逆

👉你拿到 IMU 真实角速度,**无法求解欧拉角的变化率 **ϕ˙,θ˙,ψ˙\dot\phi,\dot\theta,\dot\psiϕ˙,θ˙,ψ˙。

工程后果:

  1. IMU 姿态积分直接失效,数值爆炸;

  2. 做优化求雅可比的时候矩阵奇异,求解器崩溃;

  3. 明明载体可以做三维任意旋转,但是欧拉角数学模型在这里算不动。

注意:

不是物理上车子不能抬头 90 度;是欧拉角这套数学描述工具,在这个姿态点数学模型坏掉
只要你的运动有可能接近 pitch ±90°(无人机、翻滚机器人),欧拉角做姿态积分就很危险。

汽车一般路面行驶,pitch 角度很小,工程上很多简单 Demo 会用欧拉角;但一旦上坡下坡剧烈,依然会靠近奇异点。

4. 重要澄清误区

  1. ❌误区:万向锁是程序 bug,改代码就能修复。

    ✅真相:是顺序旋转的欧拉角参数化本身的内在数学缺陷,无论怎么写代码,只要使用顺序旋转欧拉角,就一定存在奇异点。

  2. ❌误区:发生万向锁之后物体不能转动。

    ✅真相:物理物体依然可以随便转,但是欧拉角这套描述方式发生退化,算导数、做积分、求逆的时候失效

  3. ❌误区:换一个旋转顺序就可以彻底消除万向锁。

    ✅真相:换顺序,只是把奇异点换到另外一组角度上,不能消除。例如 X‑Y‑Z 顺序,奇异点出现在 Y=±90°。

你可以把欧拉角想象成「地球经纬度」:

在北极点,所有的经度全部重合;同一个点有无穷多组经纬度。

经纬度可以描述地球表面,但在极点奇异;欧拉角同理,总有一组姿态是奇异点。

5. 欧拉角、四元数、SO (3) 李群三者完整工程对比

结合 SLAM/IMU/ 自动驾驶真实应用场景

对比维度 欧拉角(RPY/YPR) 单位四元数 SO (3) 旋转矩阵(李群)
参数数量 3 个参数 (roll,pitch,yaw) 4 个参数,约束$ q
自由度 物理 3 自由度 4 参数表达 3 自由度,有等式约束 9 参数表达 3 自由度,多个等式约束
万向锁奇异点 ✅存在!必然存在奇异位置;矩阵会奇异,不能求逆 完全没有奇异点,全局光滑;不存在万向锁 完全没有奇异点,全局光滑;不存在万向锁
IMU 角速度积分 非常麻烦,需要乘变换矩阵;靠近奇异点矩阵奇异,数值崩坏 适合 IMU 积分;有一阶近似版本(motion.cpp);全局无奇点 适合 IMU 积分,罗德里格斯解析解,无截断误差,全局无奇点
优化求导 有奇异点,不能直接用于姿态优化 不直接作为优化变量(4 维,冗余约束);增量用 so (3) 不能直接矩阵加减;增量使用 so (3) 李代数扰动模型
坐标变换 先转成旋转矩阵再做乘法 直接旋转点;或者转矩阵 直接矩阵乘法做坐标变换
内存占用 3 个浮点数,最小 4 个浮点数 9 个浮点数,最大
人类可读性 很好,人直观理解翻滚俯仰偏航 人很难直接看懂四元数数值代表什么姿态 人几乎读不懂矩阵数字含义

工程取舍总结:

  1. 人机交互、打印日志、UI 界面显示姿态 → 用欧拉角(人看得懂)。

  2. 内部 IMU 解算、仿真、SLAM 后端优化 → 绝对不用欧拉角;用四元数 / SO (3) 李群,规避万向锁奇异。

现实代码的典型写法:

内部存储姿态:四元数 / SO3;

需要打印给人看的时候,才把四元数 / 矩阵转换成欧拉角输出

只在输出环节用欧拉角,绝对不拿欧拉角做积分迭代

6. 回到 motion.cpp 仿真例子做对比

如果我们把 motion.cpp 改成欧拉角做姿态更新会发生什么:

小车不断绕 Z 轴转圈,pitch 始终 = 0,不会触发万向锁,短时间看好像可以跑。

但是如果修改仿真,让小车持续抬头,pitch 慢慢抬升到 90°。

此时欧拉角对应的角速度转换矩阵奇异,积分直接数值崩坏。

而四元数 / SO3 版本:无论 pitch 转到多少度,哪怕 90、180 度,完全不会出现奇异,仿真继续稳定运行。

7. 补充:为什么四元数、SO3 没有万向锁?

  • 欧拉角:用局部的分段参数化描述整个旋转空间,必然存在奇异(类似地球经纬度极点)。

  • 四元数:用 4 维单位球面映射三维旋转空间,是全局光滑的双覆盖映射,没有奇异点。

  • SO (3) 流形:李群本身的几何结构,是光滑流形;求导、指数对数映射全局都可以运算,不存在奇异位置。

但是注意:四元数存在二义性:qqq 和 −q-q−q 代表同一个旋转,这不是万向锁,只是双表示,工程上很容易处理。

8. 反思

问:什么是万向锁?为什么 IMU 不用欧拉角积分?

答:

万向锁是欧拉角顺序旋转带来的数学奇异现象。当其中一个转角到达 ±90°,另外两个旋转轴会重合,丢失一个有效自由度。此时角速度到欧拉角导数的转换矩阵奇异不可逆,姿态积分和求导计算失效。

万向锁不是程序 bug,更换旋转顺序仅仅移动奇异点,不能消除。

四元数与 SO (3) 李群全局光滑无奇点,因此 IMU、SLAM 内部姿态迭代优先使用四元数或者 SO3,欧拉角仅用于人机显示输出。

矩阵奇异不可逆 vs 矩阵可逆:结合IMU工程场景解释

欧拉角下角速度与欧拉角变化率关系:

  • ωb\boldsymbol{\omega}_bωb:IMU 硬件输出的机体角速度(已知测量值)

  • ϕ˙,θ˙,ψ˙\dot\phi,\dot\theta,\dot\psiϕ˙,θ˙,ψ˙:欧拉角的变化速率,做积分需要拿到这组量

  • MMM:转换矩阵。

方程含义:已知 IMU 角速度ωb\boldsymbol{\omega}bωb,乘矩阵MMM,得到欧拉角变化率,之后做数值积分:ϕk+1=ϕk+ϕ˙⋅dt\phi{k+1}=\phi_k+\dot\phi\cdot dtϕk+1=ϕk+ϕ˙⋅dt,更新欧拉角。

1、矩阵可逆(正常状态,pitch 远离 ±90°)

矩阵可逆等价于矩阵行列式不为 0,矩阵存在逆矩阵M−1M^{-1}M−1。

可逆带来的好处

  1. 正向计算(IMU 积分):可以由角速度算出欧拉角变化率

    Θ˙=Mωb\dot{\boldsymbol \Theta}=M \boldsymbol \omega_bΘ˙=Mωb,输入 IMU 角速度,直接算出欧拉角的变化速度,可以正常离散积分更新欧拉角。

  2. 反向可求解:已知欧拉角变化,可以反推机体角速度

    ωb=M−1Θ˙\boldsymbol{\omega}_b = M^{-1}\dot{\boldsymbol{\Theta}}ωb=M−1Θ˙

    当你知道姿态变化快慢,可以反解载体本体角速度;仿真、状态估计、残差计算都需要这个反向映射。

  3. 雅可比矩阵数值稳定

    SLAM、滤波求雅可比的时候,矩阵条件数良好;高斯‑牛顿 / LM 优化器可以正常求解增量,不会出现数值爆炸。

通俗:矩阵可逆 = 这套方程通路是通的,输入可以得到输出,输出也可以反推输入,计算稳定。

2、矩阵奇异不可逆 (万向锁位置,pitch=±90°,行列式det⁡(M)=0\det(M)=0det(M)=0)

矩阵奇异,M−1M^{-1}M−1不存在。此时方程组:Θ˙=Mωb\dot{\boldsymbol \Theta}=M\boldsymbol{\omega}_bΘ˙=Mωb。

带来的实际工程影响,逐条对应现实代码

  1. 正向:部分角速度分量无法转化为欧拉角变化率

    IMU 真实输出三维角速度,但是矩阵MMM降秩,会丢失一个维度信息。

    部分机体角速度输入,不会产生任何欧拉角变化。硬件明明检测到载体在转动,欧拉角却纹丝不动,姿态积分直接出错。

  2. 反向完全断掉:无法由欧拉角变化反推机体角速度

    逆矩阵不存在,ωb=M−1Θ˙\boldsymbol{\omega}_b = M^{-1}\dot{\boldsymbol{\Theta}}ωb=M−1Θ˙这个式子彻底不能计算。

  3. 方程组有无穷多解,不是唯一解

    同一个 IMU 角速度输入,可以对应无穷多组ϕ˙,θ˙,ψ˙\dot\phi,\dot\theta,\dot\psiϕ˙,θ˙,ψ˙。计算机没有办法选出正确那一组解。

数学现象:物理上载体只有一个真实运动,但是数学模型给不出唯一结果。

  1. 数值计算爆炸(浮点数污染)

    即使没有严格等于 90°,只要很靠近奇异点,矩阵条件数变得极大,就是病态矩阵

    浮点数微小 IMU 噪声,会被矩阵疯狂放大;欧拉角输出跳变、震荡、数值飞掉。

  2. 优化、滤波求解失败

    ESKF、BA 需要求该矩阵的雅可比;靠近奇异点雅可比病态,求解器增量巨大,迭代发散,程序直接跑崩。

⚠重点区分:

不是物理刚体不能转动;刚体物理运动完全正常,只是欧拉角这套参数化的数学模型在这里失效。IMU 硬件依然正常输出角速度,但是数学公式算不出正确姿态增量。

3、对比举例(通俗类比)

想象一个信号转换模块:

  • 可逆矩阵:信号正常双向转换,输入 A 得到 B;输入 B 可以还原 A,信号不失真。

  • 奇异矩阵:模块内部某一路通路短路,一个维度信号直接丢失。给输入信号,输出结果乱跳;并且无法反向还原原始信号。

4、为什么四元数 / SO (3) 不会出现这个问题?

四元数、SO3 李群的姿态更新方程,不依赖这个奇异的转换矩阵 M

  • IMU 角速度ωb\boldsymbol\omega_bωb直接作为李代数;

  • 通过指数映射Exp(ω,dt)Exp(\boldsymbol\omega,dt)Exp(ω,dt)直接生成旋转增量;

  • 不存在MMM矩阵,自然不存在矩阵奇异、降秩、不可逆的问题;

    全姿态空间处处计算有效。

注意:四元数有单位模长约束;SO3 有正交约束,但这是等式约束,不是微分方程的奇异病态,和万向锁矩阵奇异是两回事。

5、总结

  1. 欧拉角姿态更新依赖转换矩阵MMM,Θ˙=Mωb\dot{\boldsymbol \Theta}=M\boldsymbol{\omega}_bΘ˙=Mωb。

  2. 矩阵可逆:行列式不为 0,存在逆矩阵;既可以由 IMU 角速度计算欧拉角变化率用于积分,也可以反向由姿态变化反推角速度;雅可比数值稳定,优化 / 滤波正常工作。

  3. 万向锁位置矩阵奇异不可逆:det⁡(M)=0\det(M)=0det(M)=0,无逆矩阵;方程丢失维度,解不唯一;部分角速度无法转化为欧拉角变化,姿态积分失效;靠近奇异点矩阵病态,噪声被放大,数值震荡发散;后端优化求解失败。

  1. 四元数与 SO (3) 不使用该奇异转换矩阵,采用指数映射直接处理角速度,全局无奇点。

6.反思

问:万向锁处矩阵奇异不可逆会带来什么后果?

答:

欧拉角姿态积分依靠转换矩阵MMM完成机体角速度到欧拉角变化率转换。矩阵可逆时,可以双向完成角速度和姿态变化率换算,数值稳定。

奇异不可逆时逆矩阵不存在,方程组丢失自由度、解不唯一;IMU 角速度无法正确换算欧拉角变化率,姿态积分失效;临近奇异点矩阵病态,噪声放大造成数值震荡;滤波、优化的雅可比求解发散。

四元数 / SO3 不依赖该矩阵,规避该问题。

相关推荐
Felven1 小时前
A. Eating Game
算法
小程序设计2 小时前
机械设计光伏板智能清洁机器人结构设计-
机器人·机械设计
血小板要健康2 小时前
队列 + 宽搜(BFS):二叉树层序遍历 算法总结
java·数据结构·笔记·算法·leetcode·宽度优先
Felven2 小时前
A. Riptide
算法·c 算法
m0_739312872 小时前
四元数、李群SO(3)/李代数so(3)的作用及应用场景
算法·机器人·自动驾驶
artificiali3 小时前
880 第4章多元
人工智能·算法
Felven3 小时前
B. Deja Vu
数据结构·算法
小玮看世界3 小时前
[Python]螺旋遍历 vs 最短路径:方向控制类算法的“同源异流”
开发语言·python·算法
m0_739312873 小时前
【自动驾驶/机器人控制】之坐标系&运动学仿真代码工程分析(一)
人工智能·机器人·自动驾驶