坐标系基础:地理坐标系(NED/ENU)、机体坐标系、坐标系之间的转换关系
各位同学,欢迎来到姿态解算的第一课。
说实话,很多新手一上来就盯着四元数、卡尔曼滤波猛啃,结果代码跑起来天旋地转。为什么?因为坐标系没搞明白。你想想看,连“北”在哪儿都没定义清楚,算出来的姿态能准吗?
我个人习惯,做飞控第一件事就是先把坐标系钉死。今天我们就来聊聊这三个最基础的东西:地理坐标系、机体坐标系,以及它们怎么互相转换。
1. 地理坐标系:你的绝对参考系
地理坐标系,说白了就是“大地给你的参考”。我们飞无人机,总得知道哪边是北、哪边是地吧?
业内主流有两种定义方式:NED 和 ENU。
| 坐标系 | X轴 | Y轴 | Z轴 | 常见场景 |
|---|---|---|---|---|
| NED | 北 (North) | 东 (East) | 地 (Down) | PX4、ArduPilot、航模 |
| ENU | 东 (East) | 北 (North) | 天 (Up) | ROS、GPS、机器人 |
我在项目中遇到过最坑的事:团队里有人用NED,有人用ENU,结果融合出来的航向角差了90度。飞机一解锁直接原地打转……嗯,从那以后我规定:所有代码注释里必须写明坐标系定义。
核心记忆点:
- NED:Z轴朝下,符合“重力向下”的直觉,飞控常用。
- ENU:Z轴朝上,符合“右手系”数学习惯,ROS常用。
2. 机体坐标系:跟着飞机转的参考系
机体坐标系是固定在飞机上的。不管飞机怎么翻,这个坐标系都跟着它一起动。
标准定义是这样的:
- X轴:指向机头(前进方向)
- Y轴:指向机身右侧(右翼方向)
- Z轴:指向机身下方(符合右手定则)
你想想看,机载的IMU(惯性测量单元)测量到的加速度和角速度,其实都是相对于机体坐标系的。但我们要控制飞机,必须知道它在“大地”里是什么姿态。这就引出了下一个问题——怎么转?
一个小技巧: 我习惯在飞控板上贴一个标签,标出X/Y/Z的正方向。调试时看一眼就知道传感器安装有没有歪。曾经有一次,就是因为IMU焊偏了0.5度,导致悬停时一直往右飘,排查了整整两天。
3. 坐标系转换:从机体到地理
转换的核心就是旋转矩阵。说白了,就是把机体坐标系下的向量,投影到地理坐标系下。
假设我们有一个向量在机体坐标系下表示为 [x_b, y_b, z_b]^T,想转到NED坐标系下:
// 伪代码:机体到NED的旋转
// 已知欧拉角:roll(φ), pitch(θ), yaw(ψ)
// 旋转顺序:Z-Y-X (yaw -> pitch -> roll)
R = R_z(ψ) * R_y(θ) * R_x(φ)
// 其中:
// R_x(φ) = [1, 0, 0;
// 0, cosφ, -sinφ;
// 0, sinφ, cosφ]
// R_y(θ) = [ cosθ, 0, sinθ;
// 0, 1, 0;
// -sinθ, 0, cosθ]
// R_z(ψ) = [cosψ, -sinψ, 0;
// sinψ, cosψ, 0;
// 0, 0, 1]
// 最终转换:
v_ned = R * v_body
这里有个坑:旋转顺序不能乱。我见过有人把yaw和pitch的顺序搞反了,结果飞机低头时航向也跟着变。嗯,这其实是数学上的“非交换性”——旋转不满足交换律。
避坑指南: 我曾经在移植PX4代码时,发现它的旋转顺序是Z-Y-X,而另一套库用的是X-Y-Z。两者差了十万八千里。所以移植时一定要确认:
- 旋转顺序是什么?
- 用的是NED还是ENU?
- 欧拉角定义是“绕固定轴”还是“绕动轴”?
4. 知识体系总览
下面这张图是我自己整理的坐标系知识脉络。每次带新人时,我都会先让他们看这个图,再动手写代码。
5. 实战中的坐标系选择建议
说了这么多理论,到底怎么选?我个人的经验是这样的:
- 做飞控固件:用NED。PX4、ArduPilot都是这么干的,生态统一。
- 做地面站或ROS节点:用ENU。ROS的tf树默认就是ENU,别跟它对着干。
- 做仿真:看你的工具链。Gazebo用ENU,FlightGear用NED,别搞混。
我的习惯: 在代码里定义一个全局宏,比如 #define COORDINATE_SYSTEM NED。所有转换函数都依赖这个宏。这样换平台时,只需要改一个地方。嗯,这招帮我省了不少事。
好了,坐标系基础就讲到这里。记住一句话:坐标系是飞控的“语言”,语言不通,飞机就乱飞。下一节我们会基于这个基础,开始讲姿态的数学表示——欧拉角、旋转矩阵、四元数。到时候你会发现,坐标系搞明白了,后面全是水到渠成的事。
公众号:蓝海资料掘金营,微信deep3321