第4章 RTK定位技术:差分定位原理、基准站与流动站、RTCM协议解析、固定解与浮点解
各位好,我是老张。今天咱们聊聊RTK定位技术。说实话,在座舱系统里搞高精度定位,RTK是绕不开的一关。我当年在MTK8676平台上第一次调通RTK时,那种感觉——嗯,就像打通了任督二脉。废话不多说,直接上干货。
4.1 差分定位原理:为什么普通GPS不够用?
普通GPS的精度,大概在3到5米。你想想看,在高速公路上,3米的误差可能让你错过一个匝道。在自动驾驶场景里,这误差甚至能让你开到对向车道去。
为什么会这样?因为卫星信号穿过大气层时,会受到电离层、对流层的干扰。这些干扰是缓慢变化的,而且在一定区域内是高度相关的。
差分定位的核心思想很简单:既然误差是相关的,那我们就找个已知位置的点,测出误差,然后告诉别人怎么修正。
关键公式(理解即可):
流动站真实位置 = 流动站观测位置 - (基准站观测误差)
其中,基准站观测误差 = 基准站已知位置 - 基准站观测位置
我在项目中遇到过一种情况:明明差分信号已经收到了,但定位结果还是飘。后来发现是基准站坐标输入错了——一个数字之差,差出去几十米。所以,基准站坐标一定要反复核对。
4.2 基准站与流动站:谁是谁?
RTK系统里有两个角色:
- 基准站:架设在已知精确坐标的位置上。它接收GPS信号,计算出误差,然后通过数据链(通常是4G或电台)发送给流动站。
- 流动站:装在车上(或者你的座舱系统里)。它接收卫星信号,同时接收基准站的差分修正数据,然后解算出自己的精确位置。
说白了,基准站就是个“已知答案的学霸”,流动站是个“正在考试的学渣”。学霸把答案(误差修正值)传给学渣,学渣就能考出高分。
在MTK8676平台上,基准站和流动站的配置其实很相似。我建议你把基准站和流动站的硬件设计成一样的,只是通过软件配置来区分角色。这样生产、维护都方便。
我的经验: 基准站的天线一定要架设在开阔、无遮挡的地方。我曾经为了省事,把基准站天线放在楼顶的空调外机旁边,结果定位精度直接掉到分米级。后来发现是空调的金属外壳反射了信号。
4.3 RTCM协议解析:差分数据的“通用语言”
基准站和流动站之间怎么通信?靠RTCM协议。RTCM是Radio Technical Commission for Maritime Services的缩写,是差分定位的行业标准协议。
RTCM协议有很多版本,目前主流的是RTCM 3.3。在MTK8676上,我们主要关注以下几个消息类型:
| 消息类型 | 内容 | 说明 |
|---|---|---|
| 1004 | GPS观测值 | 包含伪距、载波相位等 |
| 1019 | GPS星历 | 卫星轨道参数 |
| 1020 | GLONASS星历 | 俄罗斯卫星系统 |
| 1074 | GPS MSM4 | 多信号消息,更高效 |
| 1084 | GLONASS MSM4 | 同上,针对GLONASS |
RTCM数据帧的结构是这样的:
// RTCM 3.3 帧结构
// 前导码: 0xD3 (固定)
// 保留位: 6 bits
// 消息长度: 10 bits
// 可变长度消息体
// CRC: 24 bits
// 解析示例(伪代码)
uint8_t preamble = read_byte();
if (preamble != 0xD3) {
// 不是RTCM帧,丢弃
return;
}
uint16_t length = read_bits(10); // 消息长度
uint8_t* message = read_bytes(length);
uint32_t crc = read_bits(24);
// 校验CRC...
我个人习惯是先解析消息类型,再根据类型解析具体内容。不要一股脑全解析,那样效率低,还容易出错。
注意: RTCM协议里有很多保留字段和可选字段。不同厂商的基准站,发送的消息类型可能不一样。我曾经遇到过一台基准站只发1004和1019,另一台却发1074和1084。你的流动站必须能兼容多种消息类型。
4.4 固定解与浮点解:RTK的“灵魂拷问”
RTK解算的结果,有两种状态:固定解和浮点解。
- 固定解(Fixed):整周模糊度已经正确求解。精度可以达到厘米级。这是我们要的最终状态。
- 浮点解(Float):整周模糊度还没有固定,只是一个浮点数估计。精度在分米到米级。比普通GPS好,但还不够。
为什么会这样?因为RTK的核心是求解整周模糊度——也就是卫星信号从卫星到接收机,到底走了多少个完整的波长。这个整数解对了,精度就上去了;解不对,就只能用浮点数凑合。
在MTK8676上,你可以通过以下方式判断当前解的状态:
// 从GNSS模块获取解状态
typedef enum {
SOL_FIXED = 0, // 固定解
SOL_FLOAT = 1, // 浮点解
SOL_SINGLE = 2, // 单点定位(无差分)
SOL_NONE = 3 // 无解
} solution_status_t;
// 实际代码中,我建议这样处理
solution_status_t status = get_solution_status();
if (status == SOL_FIXED) {
// 放心使用定位数据
use_position(position);
} else if (status == SOL_FLOAT) {
// 可以显示,但要加警告
show_position(position, "精度有限");
} else {
// 别用了,等一等
wait_for_better_solution();
}
我记得有一次在测试场,车辆明明停在原地,定位结果却显示在缓慢移动。一看状态,是浮点解。后来发现是基准站和流动站之间的数据链延迟太大,导致差分数据过期了。
避坑指南: 我曾经因为天线相位中心偏差没校准,导致固定解状态下还有5厘米的误差。后来在MTK8676的配置里加上了天线参数校准,问题才解决。所以,天线校准参数一定要写对。
4.5 实战要点:在MTK8676上集成RTK
在MTK8676座舱平台上集成RTK,有几个关键点:
- 数据链选择:建议用4G网络传输RTCM数据。电台虽然稳定,但需要额外硬件。4G方便,但要注意网络延迟。
- 基准站配置:基准站坐标要精确到厘米级。可以用CORS站(连续运行参考站)的数据,或者自己用静态测量方式获取。
- 流动站初始化:刚开机时,流动站需要一段时间来收敛。我建议在UI上显示“正在初始化RTK”,而不是直接显示一个不准的位置。
- 解状态监控:实时监控固定解/浮点解状态。如果长时间无法固定,可以尝试重置模糊度搜索。
嗯,这里要注意:RTK不是万能的。在高楼林立的城市峡谷、隧道、地下停车场,RTK信号会丢失。这时候需要融合IMU(惯性测量单元)和轮速传感器,做组合导航。这部分内容,我们后面的章节会详细讲。
好了,第4章就到这里。RTK定位技术,说白了就是“已知点帮未知点算误差”。理解了这一点,后面的内容就好办了。下一章我们聊聊IMU与组合导航,敬请期待。
公众号:蓝海资料掘金营,微信deep3321