3、姿态表示方法:欧拉角、旋转矩阵、四元数
姿态解算,说白了就是搞清楚一个物体在空间里「转成什么样了」。
这个问题我做了十几年,遇到过各种奇葩情况。有一次在无人机飞控调试现场,飞机刚离地就疯狂自旋——后来发现是姿态表示方法选错了,导致解算发散。嗯,从那以后我对这三种表示方法就格外上心。
今天咱们就把欧拉角、旋转矩阵、四元数这三兄弟掰开揉碎讲清楚。你想想看,它们本质上都是在描述同一个东西:刚体在三维空间里的朝向。但为什么会有三种?各自有什么坑?
3.1 欧拉角表示法
欧拉角是最直观的。它用三个角度来描述旋转:绕X轴转的叫横滚角(Roll),绕Y轴转的叫俯仰角(Pitch),绕Z轴转的叫偏航角(Yaw)。
我习惯把欧拉角想象成「拆解动作」——一个大旋转拆成三步走。比如飞机抬头、侧倾、转向,每一步都很清晰。
核心公式:
绕Z轴旋转:Rz(ψ) = [cosψ -sinψ 0; sinψ cosψ 0; 0 0 1]
绕Y轴旋转:Ry(θ) = [cosθ 0 sinθ; 0 1 0; -sinθ 0 cosθ]
绕X轴旋转:Rx(φ) = [1 0 0; 0 cosφ -sinφ; 0 sinφ cosφ]
但欧拉角有个致命问题——万向锁。当俯仰角达到±90°时,横滚和偏航就分不清了。我在做惯性导航系统时遇到过这个坑,当时数据突然跳变,查了半天才发现是万向锁导致的。
避坑指南:
我曾经在四轴飞行器上只用欧拉角做姿态控制,结果在大角度机动时直接失控。后来才明白,欧拉角只适合小角度场景(±45°以内)。如果你要做全姿态运动,千万别只用欧拉角。
3.2 旋转矩阵表示法
旋转矩阵用3×3的矩阵来表示旋转。它没有万向锁问题,而且可以连续旋转——说白了就是矩阵乘法。
旋转矩阵的数学形式是这样的:
R = [r11 r12 r13
r21 r22 r23
r31 r32 r33]
其中每一列都是单位正交向量。这个性质很重要——旋转矩阵必须是正交矩阵,行列式为+1。
我个人习惯用旋转矩阵做坐标变换。比如把机体坐标系下的加速度转换到导航坐标系:
a_nav = R * a_body
简单直接,对吧?但旋转矩阵也有缺点——9个参数,冗余度太高。而且每次更新都要做矩阵乘法,计算量不小。我在做嵌入式实现时,发现旋转矩阵在STM32F4上跑一次更新要花几十微秒,对于1000Hz的控制循环来说,这个开销有点大。
小技巧:
如果你用旋转矩阵,记得定期做正交化处理。否则累积误差会让矩阵慢慢「变形」,不再是真正的旋转矩阵。我一般每100次更新做一次Gram-Schmidt正交化。
3.3 四元数表示法
四元数是我最喜欢用的姿态表示方法。它用四个数来描述旋转:一个标量部分和三个矢量部分。
形式是这样的:
q = [q0, q1, q2, q3]
其中q0是标量部分,q1,q2,q3是矢量部分。而且满足归一化条件:q0² + q1² + q2² + q3² = 1
四元数最大的好处是——没有奇点,计算量小,而且插值平滑。我在做云台控制时,用四元数做姿态插值,效果比欧拉角好太多了。
四元数更新公式也很简洁:
q_dot = 0.5 * q ⊗ ω
其中ω是角速度,⊗表示四元数乘法。这个公式在嵌入式上实现起来非常快,只需要几个乘法和加法。
为什么我推荐四元数?
- 无奇点:全姿态可用
- 计算量小:比旋转矩阵少5个参数
- 插值平滑:可以做球面线性插值(SLERP)
- 容易归一化:直接除以模长就行
3.4 三种方法对比
咱们直接上表格,一目了然:
| 特性 | 欧拉角 | 旋转矩阵 | 四元数 |
|---|---|---|---|
| 参数数量 | 3个 | 9个 | 4个 |
| 奇点问题 | 有(万向锁) | 无 | 无 |
| 计算量 | 小 | 大 | 中 |
| 直观性 | 最直观 | 一般 | 不直观 |
| 插值平滑性 | 差 | 一般 | 好 |
| 适合场景 | 小角度、人机交互 | 坐标变换、理论推导 | 全姿态、嵌入式实时系统 |
你想想看,在实际项目中怎么选?
- 如果你做的是遥控器、游戏手柄这种小角度场景,欧拉角完全够用
- 如果你在做理论推导、需要矩阵运算,旋转矩阵是首选
- 如果你在做飞控、云台、机器人这种需要全姿态实时解算的,四元数是最佳选择
重要提醒:
三种表示方法可以互相转换。我在项目中经常这样做:用四元数做核心解算,需要显示时转成欧拉角,需要做坐标变换时转成旋转矩阵。但要注意转换时的精度损失——尤其是欧拉角转四元数时,万向锁附近会有问题。
3.5 知识体系图
下面这张图展示了三种姿态表示方法的关系和适用场景:
这张图把三种方法的优缺点和适用场景都标出来了。我个人建议,如果你刚开始做姿态解算,先从四元数入手。虽然它不如欧拉角直观,但一旦上手,你会发现它真的很好用。
我的经验:
在实际项目中,我通常这样搭配:
- 传感器数据融合(IMU)→ 用四元数做核心解算
- 控制输出 → 转成欧拉角方便调试
- 坐标变换 → 转成旋转矩阵
这样既发挥了四元数的计算优势,又保留了欧拉角的直观性。你试试看,效果不错。
公众号:蓝海资料掘金营,微信deep3321