2. 坐标系与坐标变换:地球坐标系、机体坐标系、欧拉角与四元数,搞懂旋转的数学本质
说实话,坐标系这东西,刚入行时我觉得挺简单的。
不就是几个箭头嘛,东、北、天,或者前、右、下。但真正开始写飞控代码后,我才发现——坐标系搞错了,飞机在天上就是另一回事了。我见过有人把机体坐标系和地球坐标系搞混,结果飞机一抬头就往反方向飞,差点炸机。
所以这一章,咱们把坐标系和旋转的数学本质彻底讲透。
2.1 地球坐标系:我们到底在哪个“世界”里描述运动?
地球坐标系,也叫导航坐标系。说白了,就是给无人机一个“绝对”的参考系。
我个人习惯用 NED(北东地) 坐标系:
- X轴:指向地理北
- Y轴:指向地理东
- Z轴:指向地心(向下)
为什么用NED?因为大多数IMU(惯性测量单元)输出的加速度和角速度,默认就是NED方向。你想想看,如果选ENU(东北天),Z轴向上,那重力加速度就是负的,处理起来容易搞混符号。
2.2 机体坐标系:飞机自己的“身体”坐标系
机体坐标系是固定在无人机上的。不管飞机怎么转,这个坐标系跟着它一起动。
通常定义:
- X轴:指向机头(前进方向)
- Y轴:指向机身右侧
- Z轴:指向机身下方(符合右手定则)
嗯,这里要注意:机体坐标系和地球坐标系之间,差的就是飞机的姿态。
我在项目中遇到过一个问题:有个同事把机体坐标系的Z轴定义成了向上,结果做姿态解算时,俯仰角和滚转角的正负号全反了。排查了一整天,最后发现是坐标系定义不一致。
2.3 欧拉角:直观但“有坑”的旋转表示
欧拉角是最直观的旋转表示方式。三个角度:
- 偏航角(Yaw,ψ):绕Z轴旋转
- 俯仰角(Pitch,θ):绕Y轴旋转
- 滚转角(Roll,φ):绕X轴旋转
旋转顺序通常是:Yaw → Pitch → Roll(Z-Y-X顺序)。
为什么是这个顺序?因为先转偏航,再转俯仰,最后转滚转,最符合人的直觉。你想想看,飞机先调头(偏航),再抬头(俯仰),最后侧倾(滚转)。
但欧拉角有个致命问题——万向锁(Gimbal Lock)。
当俯仰角接近±90°时,偏航和滚转的旋转轴会重合,导致丢失一个自由度。说白了,就是飞机垂直向上或向下时,你没法区分偏航和滚转。
2.4 四元数:旋转的“数学本质”
四元数,听起来很玄乎。其实它就是一个四维复数:
q = w + xi + yj + zk
其中 w 是实部,x、y、z 是虚部。约束条件:w² + x² + y² + z² = 1(单位四元数)。
为什么用四元数?三个理由:
- 无万向锁:任何姿态都能唯一表示
- 计算高效:只需要乘法和加法,没有三角函数
- 插值平滑:可以做球面线性插值(SLERP),姿态过渡自然
我记得第一次用四元数做姿态控制时,被它的乘法规则搞晕了。其实记住一点就行:四元数乘法不满足交换律,q1 * q2 和 q2 * q1 结果不同。
旋转公式也很简单:
v' = q * v * q⁻¹
其中 v 是三维向量(用纯四元数表示),q 是旋转四元数,q⁻¹ 是 q 的共轭。
2.5 坐标系变换:从机体到地球,怎么转?
有了四元数,坐标系变换就简单了。
假设我们有一个机体坐标系下的向量 v_body,想转到地球坐标系:
v_earth = q * v_body * q⁻¹
反过来,从地球到机体:
v_body = q⁻¹ * v_earth * q
在实际飞控中,我们经常需要做这种变换。比如:
- 加速度计测的是机体坐标系下的加速度,但导航需要地球坐标系下的值
- 控制输出的是地球坐标系下的期望姿态,但电机控制需要机体坐标系下的指令
我建议把坐标系变换封装成函数,别到处写裸代码。这样出错了也好排查。
2.6 知识体系总览
下面这张图,是我自己总结的坐标系与旋转知识体系。你看一遍,心里就有谱了。
2.7 总结与建议
这一章内容不少,我帮你捋一下重点:
- 地球坐标系:用NED,别用ENU,省得给自己找麻烦
- 机体坐标系:前右下,和传感器对齐
- 欧拉角:直观但有万向锁,适合显示不适合计算
- 四元数:飞控内部的首选,没有万向锁,计算快
- 坐标系变换:用四元数乘法,封装成函数
说实话,这些概念刚接触时确实有点绕。但只要你动手写几行代码,把四元数转成欧拉角,再把欧拉角转回四元数,来回验证几次,就彻底明白了。
我当年就是这么过来的。第一次写四元数代码时,调试了一整晚,最后发现是共轭求错了。嗯,从那以后,我每次写旋转相关的代码,都会先写单元测试。
公众号:蓝海资料掘金营,微信deep3321