GNSS基础回顾:GPS/北斗信号结构、伪距与载波相位观测值、RTK定位原理、整周模糊度固定
各位同学,咱们今天聊点基础,但也是整个RTK紧耦合方案里最绕不开的东西。GNSS信号到底长什么样?伪距和载波相位到底差在哪?RTK又是怎么把厘米级精度搞出来的?这些搞不清楚,后面紧耦合的滤波器设计你肯定晕。
我当年刚入行的时候,觉得GNSS嘛,不就是收个卫星信号算个位置嘛。直到第一次做车载组合导航,发现纯单点定位的误差能飘到十几米,才意识到——嗯,这里面的水很深。今天我就把这几块核心内容掰开了讲。
核心要点:GNSS定位的本质是测距,而测距的精度决定了定位的精度。伪距粗糙但稳健,载波相位精细但模糊。RTK就是利用差分技术把载波相位的模糊度干掉,从而实现厘米级定位。
1. GPS/北斗信号结构
先说信号结构。GPS和北斗虽然系统不同,但思路差不多——都是通过扩频通信的方式,把导航电文调制到载波上发下来。
GPS目前主力是L1频段(1575.42 MHz)和L2频段(1227.60 MHz)。L1上调制了C/A码(粗捕获码)和P码(精码),还有导航电文。北斗的话,B1I(1561.098 MHz)和B2I(1207.14 MHz)是咱们最常用的。
我个人习惯把信号结构拆成三层看:
- 载波层:就是那个正弦波,频率固定。GPS L1大概是19cm波长,L2是24.4cm。北斗B1波长也差不多。
- 测距码层:C/A码周期1ms,码片长度约293米。P码周期7天,码片长度约29.3米。码片越短,测距精度越高。
- 导航电文层:包含卫星星历、钟差、电离层参数等。GPS是50bps,北斗是500bps(B-CNAV1格式)。
我的经验:做紧耦合的时候,千万别只盯着载波相位。伪距虽然粗糙,但它是模糊度浮点解的基础。我见过有人一上来就搞载波相位,结果周跳没处理好,整个滤波器发散。伪距是压舱石,别丢。
2. 伪距与载波相位观测值
这两个东西,说白了就是两种测距手段。伪距靠的是码相关,载波相位靠的是载波跟踪。
伪距观测值:接收机复制一个本地码,跟卫星发下来的码做相关,找到最大相关峰的位置,就能算出信号传播时间,乘以光速就是距离。但这里面有接收机钟差、卫星钟差、电离层延迟、对流层延迟……一堆误差。所以叫"伪距",不是真距。
伪距的观测方程长这样:
P = ρ + c*(dt_r - dt_s) + I + T + ε_P
其中ρ是几何距离,dt_r是接收机钟差,dt_s是卫星钟差,I是电离层延迟,T是对流层延迟,ε_P是噪声。
载波相位观测值:这个就精细多了。接收机跟踪卫星的载波信号,测量的是载波相位的变化量。精度能到毫米级,但有个大问题——它测的是相位差,不是绝对距离。因为整周数N是未知的,这就是整周模糊度。
载波相位方程:
Φ = ρ + c*(dt_r - dt_s) - I + T + λ*N + ε_Φ
注意电离层项前面的符号是负的,跟伪距相反。这个特性在双频组合里很有用。
避坑指南:我曾经在一个项目里,用单频接收机做RTK,结果电离层活跃期,伪距和载波相位的电离层延迟差异导致模糊度固定失败。后来我学乖了,双频是底线,能上三频就上三频。
3. RTK定位原理
RTK(Real-Time Kinematic)的核心思想就四个字:差分消除。
你想想看,基准站和流动站距离不远(一般几十公里内),它们看到的卫星相同,那么卫星钟差、电离层延迟、对流层延迟这些误差是强相关的。做一次差分,就能把这些公共误差干掉。
具体做法分两步:
- 站间单差:基准站和流动站对同一颗卫星的观测值相减,消掉卫星钟差和大部分大气延迟。
- 星间双差:再对两颗卫星的单差值做一次差分,消掉接收机钟差。
双差之后,剩下的就是几何距离差加上整周模糊度差(整数),再加上残余噪声。这时候方程就干净多了。
双差载波相位方程简化后:
∇ΔΦ = ∇Δρ + λ*∇ΔN + ∇Δε
∇ΔN就是双差整周模糊度,它是一个整数。只要能把这个整数固定下来,剩下的就是高精度的几何距离差,定位精度自然就上去了。
关键点:RTK的精度取决于两个因素——基准站和流动站的距离(基线长度),以及模糊度固定的成功率。基线越短,大气误差相关性越强,固定越容易。一般20km以内效果最好。
4. 整周模糊度固定
这是RTK里最核心、也最头疼的一步。说白了,就是要把双差载波相位方程里的那个整数N给找出来。
常用的方法是LAMBDA算法(Least-squares AMBiguity Decorrelation Adjustment)。它的思路是这样的:
- 先用最小二乘解出模糊度的浮点解(带小数)和它的协方差矩阵。
- 然后做一个Z变换,把模糊度之间的相关性降低(去相关)。
- 最后在整数空间里搜索,找到一组整数,使得残差最小。
搜索的时候,一般用Ratio检验来判断固定是否可靠。Ratio值大于某个阈值(比如3.0),就认为固定成功。
代码实现上,LAMBDA的核心搜索部分大概长这样(简化版):
// 输入:浮点解 a_float, 协方差矩阵 Q
// 输出:固定解 a_fixed, 残差平方和
1. 对Q做LDL分解
2. Z变换去相关
3. 在整数格点中搜索候选点
4. 计算每个候选点的残差平方和
5. 取残差最小的作为固定解
6. 做Z逆变换回到原始空间
我的建议:实际工程中,别指望一次固定就成功。我一般会做一个渐进策略——先尝试固定宽巷模糊度(波长更长,更容易固定),再固定窄巷。如果固定失败,就保持浮点解,等下一历元再试。千万别硬来,硬来容易出周跳。
还有一个容易被忽略的点——周跳检测。载波相位跟踪过程中,如果信号失锁,整周计数就会跳变。这个不检测出来,模糊度固定就是白搭。常用的方法有:
- GF(Geometry-Free)组合:检测电离层残差的变化
- MW(Melbourne-Wübbena)组合:检测宽巷模糊度的变化
- 高次差法:对相位做差分,看有没有异常跳变
我个人的习惯是GF和MW一起用,双保险。GF对电离层敏感,MW对多路径敏感,互补性很好。
避坑指南:我曾经在一个高架桥下的场景,卫星信号频繁遮挡,周跳一个接一个。当时没做好周跳标记,结果模糊度固定反复失败,定位结果跳来跳去。后来我加了一个"固定置信度"的指标,连续多个历元固定一致才输出固定解,问题就解决了。
好了,GNSS基础这块就聊到这儿。伪距和载波相位是RTK的两条腿,缺一不可。模糊度固定是RTK的灵魂,搞不定它,厘米级精度就是空谈。下一节咱们会把这些观测值塞进紧耦合的滤波器里,看看它们怎么跟IMU配合。
公众号:蓝海资料掘金营,微信deep3321