2. 定位技术基础
做多源融合定位,第一件事不是调滤波参数,而是把坐标系和时间对齐。我见过太多项目,明明传感器数据质量不错,最后融合结果却飘得离谱——查来查去,原来是坐标系定义没统一。说白了,坐标系和时间基准就是融合定位的“普通话”,各传感器各说各的方言,肯定没法聊。
2.1 常用坐标系:WGS84、ECEF、ENU
咱们搞导航的,天天跟这三个坐标系打交道。我习惯把它们分成两类:全局坐标系和局部坐标系。WGS84 和 ECEF 是全局的,ENU 是局部的。
- WGS84:大地坐标系,用经纬度、海拔高度表示。GPS 直接输出的就是 WGS84 坐标。注意,它是个椭球模型,不是正球体。
- ECEF:地心地固坐标系,原点在地球质心,X 轴指向本初子午线与赤道交点,Z 轴指向北极。做组合导航时,我通常把 GNSS 的位置转到 ECEF 下再跟惯导解算。
- ENU:站心坐标系(东-北-天),原点在载体或测站,东、北、天三个方向。做视觉惯导融合时,ENU 特别直观,因为加速度计和陀螺的测量天然跟 ENU 的“天向”有关。
💡 我个人习惯:在融合滤波器内部统一用 ECEF,避免大范围移动时 ENU 的曲率修正问题。但做可视化或局部规划时,再转回 ENU。
2.2 时间基准:GPST 与 UTC
时间不同步,融合就是一团浆糊。GPS 时间(GPST)是连续的时间系统,不插入闰秒,从 1980 年 1 月 6 日开始计数。而 UTC 是协调世界时,会通过闰秒调整跟天文时间对齐。
你想想看,如果 IMU 用 UTC 打时间戳,GNSS 接收机用 GPST,两者差了 18 秒(目前闰秒差),直接做紧耦合肯定炸。我曾在某车载项目里遇到过这个问题——IMU 数据明明很干净,但位置误差每 10 秒漂 2 米,查了两天才发现是时间基准没对齐。
| 时间系统 | 特点 | 典型用途 |
|---|---|---|
| GPST | 连续,无闰秒,与 UTC 差整数秒 | GNSS 观测值、星历 |
| UTC | 有闰秒,不连续 | 系统日志、人机交互 |
| TAI | 国际原子时,稳定 | 科学基准 |
⚠️ 我曾经踩过的坑:ROS 中默认使用 sim_time 或 wall clock,但如果你把 GPST 直接当成 UTC 存 rosbag,回放时时间戳会跳变。建议统一转成 TAI 或 GPS 周内秒做内部计算。
2.3 坐标转换误差建模
坐标转换不是简单的乘个旋转矩阵就完事。实际工程中,转换误差主要来自三方面:
- 椭球参数误差:WGS84 椭球本身有近似,不同地区用不同椭球(如 CGCS2000)会引入系统偏差。
- 旋转矩阵线性化误差:大角度旋转时,小角度近似会失效。我建议用四元数或罗德里格斯公式,别偷懒用欧拉角。
- 时间戳抖动导致的动态误差:高速运动时,1ms 的时间不同步可能造成分米级的位置偏差。
下面这个代码片段是我常用的 ECEF ↔ ENU 转换(带误差补偿接口):
// 简化版 ECEF → ENU 旋转矩阵 (基于参考经纬度)
// 实际项目中我会加入椭球改正和杠杆臂补偿
Matrix3d ecef2enu_matrix(double lat, double lon) {
double slat = sin(lat), clat = cos(lat);
double slon = sin(lon), clon = cos(lon);
Matrix3d R;
R << -slon, clon, 0,
-slat*clon, -slat*slon, clat,
clat*clon, clat*slon, slat;
return R;
}
🔧 避坑指南:坐标转换前务必确认经纬度单位是弧度还是度。我见过有人把度直接传进 sin/cos,结果整个轨迹歪了 100 多公里。
2.4 工程中的误差补偿技巧
说点实在的。我一般在融合前做三步:
- 杠杆臂补偿:IMU 和 GNSS 天线不在同一个点,杆臂效应在转弯时特别明显。用刚体运动学把 GNSS 位置投影到 IMU 中心。
- 时间戳插值:如果传感器频率不同(比如 IMU 200Hz,GNSS 10Hz),我会用三次样条插值把 GNSS 观测值对齐到 IMU 时间戳。
- 椭球高改正:WGS84 高程是椭球高,而实际海拔是正高,两者差一个大地水准面起伏。做无人机融合时,这个差异能到几十米,必须查 EGM2008 模型。
💡 我建议:在代码里把坐标转换封装成独立模块,单元测试覆盖旋转矩阵的行列式是否为 1、逆矩阵是否等于转置。这些小细节能省下大量调试时间。
嗯,坐标系和时间系统这部分,说白了就是“地基”。地基没打牢,上层滤波再花哨也白搭。下一章我们会深入 GNSS 的误差源,到时候你会更理解为什么坐标转换的精度直接影响定位结果。