坐标系与刚体运动基础
各位同学,今天我们来聊聊飞控里最基础、也最容易搞混的一块内容——坐标系与刚体运动。
说实话,我刚入行那会儿,觉得坐标系不就是个参考系嘛,有啥好学的?结果第一次调四旋翼,飞机在天上乱转,我盯着日志看了三天,才发现是欧拉角顺序搞反了。嗯,从那以后,我再也不敢小看这部分内容了。
世界坐标系与机体坐标系
先说说世界坐标系。你可以把它想象成一个“绝对参考系”。
我习惯用东北天坐标系(ENU)作为世界坐标系:
- X轴:指向东
- Y轴:指向北
- Z轴:指向天(向上)
为什么用这个?因为GPS给的数据就是基于这个系的,省得来回转换。
机体坐标系就简单了——它跟着飞机走。原点在飞机质心:
- X轴:指向机头
- Y轴:指向右翼
- Z轴:指向机腹(向下)
你想想看,IMU测出来的加速度、角速度,都是相对于机体坐标系的。但你要控制飞机往东飞,就得把机体坐标系下的数据转换到世界坐标系下。怎么转?这就引出了欧拉角。
欧拉角:直观但暗藏陷阱
欧拉角说白了就是三个旋转角度:
- 偏航角(Yaw,ψ):绕Z轴旋转
- 俯仰角(Pitch,θ):绕Y轴旋转
- 横滚角(Roll,φ):绕X轴旋转
这里有个坑——旋转顺序。我见过太多新手在这里翻车了。
我曾经在项目里遇到过,一个同事用了Z-X-Y顺序,结果飞机在悬停时莫名其妙地往一边漂。查了两天,才发现是旋转顺序的问题。从那以后,我每次写代码都会在注释里明确标注旋转顺序。
欧拉角还有一个致命问题——万向锁。当俯仰角接近±90°时,偏航和横滚会耦合在一起,丢失一个自由度。所以,实际飞控里很少直接用欧拉角做姿态控制。
四元数:飞控的“真香”选择
四元数是什么?说白了就是一个四维复数:
q = w + xi + yj + zk
其中 w 是实部,x、y、z 是虚部。它满足:
i² = j² = k² = ijk = -1
为什么飞控都用四元数?三个原因:
- 无万向锁——随便你怎么转,不会丢自由度
- 计算量小——只有4个参数,比旋转矩阵的9个参数省多了
- 插值平滑——做姿态平滑时,四元数的球面线性插值(SLERP)非常自然
我个人的习惯是:IMU数据进来后,直接用四元数做姿态解算。只有在给地面站显示姿态时,才转成欧拉角给人看。
旋转矩阵:从理论到代码
旋转矩阵是一个3×3的正交矩阵,行列式为1。它可以把一个向量从一个坐标系旋转到另一个坐标系。
从四元数到旋转矩阵的转换公式:
R = [
[1-2(y²+z²), 2(xy-wz), 2(xz+wy)],
[2(xy+wz), 1-2(x²+z²), 2(yz-wx)],
[2(xz-wy), 2(yz+wx), 1-2(x²+y²)]
]
看着复杂?其实在代码里就是几行矩阵运算的事。我建议你把这个公式存成工具函数,别每次都手算——我当年手算错过一次符号,飞机直接翻了180°。
齐次变换矩阵:把旋转和平移打包
齐次变换矩阵是个4×4的矩阵,它把旋转和平移合在一起:
T = [R t]
[0 1]
其中 R 是3×3旋转矩阵,t 是3×1平移向量。
为什么要用齐次?因为你可以把多个变换连乘在一起:
T_world_to_camera = T_world_to_body × T_body_to_gimbal × T_gimbal_to_camera
这样,一个矩阵就包含了从世界坐标系到相机坐标系的所有变换。我在做视觉SLAM时,天天跟这个打交道。
知识体系总览
下面这张图,是我自己总结的坐标系与刚体运动的知识结构:
实际项目中的选择建议
说了这么多,到底该用哪个?我根据经验给你个参考:
| 场景 | 推荐表示 | 原因 |
|---|---|---|
| IMU姿态解算 | 四元数 | 无万向锁,计算快 |
| 地面站显示 | 欧拉角 | 人眼直观,容易理解 |
| 视觉SLAM | 齐次变换矩阵 | 方便连乘,统一旋转和平移 |
| 路径规划 | 四元数 + 旋转矩阵 | 插值平滑,转换灵活 |
核心要点:
- 世界坐标系用ENU,机体坐标系用FRD
- 欧拉角只用于显示,别用于控制
- 四元数是飞控的“标配”,记得归一化
- 齐次变换矩阵是“瑞士军刀”,一个矩阵搞定所有变换
好了,这一章的内容就到这儿。坐标系这东西,你刚开始觉得简单,但真正用起来处处是坑。我建议你动手写几行代码,把四元数转旋转矩阵、旋转矩阵转欧拉角这些函数自己实现一遍。相信我,踩过坑之后,你才会真正理解它们。