坐标系基础:地球坐标系、导航坐标系、载体坐标系
做惯导这么多年,我见过太多新手一上来就盯着四元数、姿态矩阵猛啃,结果坐标系都没搞明白。说实话,坐标系这东西就像房子的地基——你地基歪了,上面算法再漂亮也是白搭。
今天咱们就把这三个坐标系彻底聊透。我保证,搞懂了它们之间的转换关系,后面你写代码会顺很多。
1. 地球坐标系(e系)
地球坐标系,说白了就是固定在地球上的一个坐标系。它跟着地球一起转,所以也叫地固坐标系。
我个人习惯用 ECEF(Earth-Centered, Earth-Fixed) 来称呼它。它的原点在地球质心,Z轴指向北极,X轴指向本初子午线与赤道的交点,Y轴按右手定则确定。
关键点:地球坐标系是旋转的。它跟着地球自转,角速度大约是 7.292115 × 10⁻⁵ rad/s。
你可能会问:「为什么不用惯性坐标系?」嗯,这个问题问得好。惯性坐标系(i系)是不动的,而地球坐标系是动的。我们做导航时,很多时候需要知道相对于地球的位置,比如经纬高,这时候就得用地球坐标系。
2. 导航坐标系(n系)
导航坐标系,也叫当地水平坐标系。它的原点在载体所在位置,通常取东北天(ENU)或者北东地(NED)两种定义。
我在项目中常用的是 东北天(ENU):
- X轴(E):指向东
- Y轴(N):指向北
- Z轴(U):指向天(垂直于当地水平面向上)
为什么叫「导航坐标系」?因为我们的惯导解算,最终输出的姿态、速度、位置,都是相对于这个坐标系的。说白了,你坐在飞机里,想知道自己朝哪个方向飞、飞得多快,这些信息都是在导航坐标系下表达的。
我的经验:做组合导航时,导航坐标系的选择会影响很多细节。比如用ENU时,Z轴向上,重力加速度是负的;用NED时,Z轴向下,重力加速度是正的。我曾经因为搞混这个,调试了整整两天才发现问题。
3. 载体坐标系(b系)
载体坐标系是固定在运动物体上的。它的原点在载体的质心,通常定义成:
- X轴:指向载体前进方向(右)
- Y轴:指向载体左侧(前)
- Z轴:指向载体上方(上)
这个坐标系,说白了就是「你坐在载体里感受到的坐标系」。IMU(惯性测量单元)输出的加速度和角速度,都是在载体坐标系下测量的。
举个例子:你拿着手机往前跑,手机里的加速度计测到的数据,就是载体坐标系下的。它可不知道地球在哪,它只知道「我往前加速了」。
4. 坐标系之间的转换关系
好了,三个坐标系都认识了。现在的问题是:它们之间怎么转?
我画了一张图,帮你理清它们的关系:
5. 转换矩阵与代码实现
坐标系之间的转换,核心就是旋转矩阵。我直接上代码,你感受一下:
import numpy as np
def ecef_to_enu(lat, lon):
"""
地球坐标系到导航坐标系的转换矩阵
lat, lon: 纬度、经度(弧度)
返回 C_e_n (3x3)
"""
slat = np.sin(lat)
clat = np.cos(lat)
slon = np.sin(lon)
clon = np.cos(lon)
C_e_n = np.array([
[-slon, clon, 0],
[-slat*clon, -slat*slon, clat],
[ clat*clon, clat*slon, slat]
])
return C_e_n
def attitude_to_dcm(roll, pitch, yaw):
"""
欧拉角转方向余弦矩阵(导航→载体)
roll, pitch, yaw: 横滚、俯仰、航向(弧度)
返回 C_n_b (3x3)
"""
cr = np.cos(roll)
sr = np.sin(roll)
cp = np.cos(pitch)
sp = np.sin(pitch)
cy = np.cos(yaw)
sy = np.sin(yaw)
C_n_b = np.array([
[cp*cy, cp*sy, -sp],
[sr*sp*cy - cr*sy, sr*sp*sy + cr*cy, sr*cp],
[cr*sp*cy + sr*sy, cr*sp*sy - sr*cy, cr*cp]
])
return C_n_b
注意:旋转矩阵是正交矩阵,它的逆等于转置。所以 C_b_n = C_n_b.T。这个性质在代码里非常有用,千万别搞反了。
6. 避坑指南
做惯导这些年,我在坐标系上踩过的坑,说出来都是泪:
- 旋转顺序:欧拉角的旋转顺序很重要。我习惯用 Z-Y-X(航向→俯仰→横滚),但不同厂家可能不一样。拿到IMU数据,先确认它的旋转顺序。
- 角度正负:航向角通常北偏东为正,但有些系统用北偏西为正。我曾经因为这个问题,让无人机在空中画了个8字。
- 单位统一:弧度还是角度?我建议代码里全部用弧度,只在显示时转成角度。否则你会在调试时疯掉。
我的习惯:每次写新项目,第一件事就是写一个坐标系转换的单元测试。输入一组已知数据,手动算一遍结果,再跟代码输出对比。这一步花不了10分钟,但能省下后面几天的调试时间。
7. 小结
好了,坐标系基础就聊到这儿。你想想看,其实就三个坐标系:地球坐标系(固定在地球上)、导航坐标系(当地水平)、载体坐标系(跟着载体转)。它们之间的转换,就是旋转矩阵的事。
搞懂了这些,后面讲姿态解算、速度更新、位置更新,你就能跟上节奏了。嗯,今天就先这样。
公众号:蓝海资料掘金营,微信deep3321