第一章 姿态描述基础:欧拉角、方向余弦矩阵、四元数的定义与物理意义
各位同学好,我是老张。搞了十几年惯性导航,今天咱们来聊聊姿态描述这件事。
你想想看,一个物体在三维空间里怎么转?怎么描述它当前是「正着」还是「歪着」?这就是姿态描述要解决的问题。说白了,就是给旋转一个数学语言。
我个人习惯把姿态描述比作「给旋转拍三张照片」——每张照片的角度不同,但拍的都是同一个东西。嗯,咱们一个一个来看。
1.1 欧拉角:最直观,但最坑
欧拉角是什么?就是三个角度:航向角(Yaw)、俯仰角(Pitch)、横滚角(Roll)。你坐飞机时,机头左右转是Yaw,抬头低头是Pitch,机身侧倾是Roll。很直观对吧?
我在项目中遇到过不少新手,上来就用欧拉角做姿态更新。结果呢?飞到一半,姿态突然「卡死」了。为什么?因为欧拉角有个致命问题——万向锁(Gimbal Lock)。
欧拉角的物理意义很清晰:三次绕轴旋转。但它的数学缺陷也很明显——旋转顺序依赖性强,而且存在奇异点。一般我们只在地面站显示或者人机交互时用欧拉角,内部计算尽量避开它。
1.2 方向余弦矩阵:稳定,但笨重
方向余弦矩阵(DCM),说白了就是一个3×3的矩阵。它把两个坐标系之间的旋转关系,用9个元素全部存下来。
你想想看,一个向量在A坐标系里是[1,0,0],转到B坐标系后变成[0.707, 0.707, 0]——这个变换关系,DCM用一个矩阵就搞定了。
DCM的好处是什么?没有奇异点,任意姿态都能表示。而且它可以直接用于向量旋转计算,非常方便。
但坏处也很明显——9个元素,冗余度太高。每次更新都要保证它是正交矩阵,否则误差会越滚越大。我记得在早期的一个导航项目中,用DCM做姿态更新,每跑100步就得做一次正交化修正,计算量不小。
💡 核心要点: DCM的物理意义就是「两个坐标系之间的旋转映射」。它稳定、无奇异,但9个参数太冗余,不适合嵌入式实时计算。
1.3 四元数:嵌入式的最爱
好了,终于说到四元数了。这东西刚接触时确实有点抽象——一个四维向量,怎么就表示三维旋转了?
四元数的形式是:q = w + xi + yj + zk,其中w是实部,x、y、z是虚部。它的物理意义是:绕一个单位轴旋转一个角度。
举个例子:绕Z轴转90°,对应的四元数就是:
q = cos(45°) + 0*i + 0*j + sin(45°)*k
= 0.707 + 0i + 0j + 0.707k
你看,是不是很简洁?4个参数,没有奇异点,计算效率高。这就是为什么嵌入式惯导系统几乎都用四元数做姿态更新。
我在项目中遇到过最典型的场景:IMU数据以1000Hz的频率进来,每次都要做姿态更新。如果用DCM,9个元素乘9个元素,再加上正交化,CPU直接拉满。换成四元数,4个元素乘4个元素,计算量直接砍半。
🔧 实用技巧: 四元数乘法虽然看起来复杂,但实际代码实现时,我建议你直接写死公式,不要用循环。比如:
// 四元数乘法,直接展开
q_out.w = q1.w*q2.w - q1.x*q2.x - q1.y*q2.y - q1.z*q2.z;
q_out.x = q1.w*q2.x + q1.x*q2.w + q1.y*q2.z - q1.z*q2.y;
q_out.y = q1.w*q2.y - q1.x*q2.z + q1.y*q2.w + q1.z*q2.x;
q_out.z = q1.w*q2.z + q1.x*q2.y - q1.y*q2.x + q1.z*q2.w;
这样写,编译器能优化到极致,跑起来飞快。
1.4 三种方法的对比与选择
咱们来做个对比,方便你理解什么时候该用哪个:
| 特性 | 欧拉角 | 方向余弦矩阵 | 四元数 |
|---|---|---|---|
| 参数数量 | 3 | 9 | 4 |
| 有无奇异点 | 有(万向锁) | 无 | 无 |
| 计算效率 | 高 | 低 | 高 |
| 直观性 | 非常直观 | 一般 | 抽象 |
| 适用场景 | 显示、人机交互 | 理论分析、稳定计算 | 嵌入式实时更新 |
我个人建议:内部计算用四元数,显示输出转欧拉角,理论推导用DCM。三者之间可以互相转换,代码里准备好转换函数就行。
1.5 知识体系总览
为了让你更直观地理解这三者的关系,我画了一张图:
这张图把三者的关系说清楚了。你从左边看起,欧拉角最直观但最危险;中间DCM最稳定但最笨重;右边四元数最均衡,是嵌入式的不二之选。
1.6 本章小结
嗯,咱们这一章就讲到这里。总结一下:
- 欧拉角:直观但有万向锁,适合显示不适合计算
- 方向余弦矩阵:稳定无奇异,但9个参数太冗余
- 四元数:4个参数、无奇异、计算快,嵌入式首选
下一章,我会带你手写四元数姿态更新的核心代码。到时候咱们把陀螺仪数据喂进去,看看四元数是怎么一步步转起来的。
公众号:蓝海资料掘金营,微信deep3321