本文转载自[Andy的GNSS工坊],已获得作者授权。所有权利归原作者所有。
原文链接: https://shenqislx.github.io/gnss-workshop.github.io/
GNSS导航电文比特解码
导航电文解码是GNSS接收机软件的关键环节之一,也是很多从业者入门时领取到的“新手村任务”之一。首先,让我们给它下个定义:
导航电文(Navigation Message) 是调制在GNSS射频载波上的0-1数据流,其本质是包含卫星轨道、时钟、系统状态等关键参数的二进制比特流。
比特解码(Bit Decoding) 是指将从卫星信号中剥离出的原始数据比特流,按照特定帧格式和编码规则,解析并重构为可供定位算法使用的、有实际意义的工程参数的过程。
电文解码的目的
电文解码的目的很明确,主要有如下两方面,分别对应定位解算的两个必要条件:接收机观测数据和卫星轨道钟数据。以GPS L-NAV为例:
补全发射时间 :在帧同步之前,跟踪环路提取到的码相位和电文比特没有时间基准,无法直接拼接伪距观测。通过帧同步找到电文数据帧的边界,可以建立比特数与电文数据帧的对应关系。此外,导航电文中提供了信号播发对应到系统时的周计数(WN, Week Number)和周内秒(TOW, Time Of Week),两者结合可以计算出电文比特对应的绝对时间,从而拼接完整伪距观测。
P R = T r x − T t x PR = T_{rx} - T_{tx} PR=Trx−Ttx
T t x = W N + T O W + B i t _ m s + C o d e _ p h a s e C o d e _ l e n g t h T_{tx} = WN + TOW + Bit\_ms + \frac{Code\_phase}{Code\_length} Ttx=WN+TOW+Bit_ms+Code_lengthCode_phase
获取星历历书 :导航电文包含了卫星的轨道、钟差、健康状况等关键参数,有了发射时刻和卫星轨道钟数据,就能够计算卫星的位置速度,作为PVT解算的输入。
电文解码的常规流程
尽管各GNSS系统的电文格式存在差异,但其核心结构和解码逻辑相似。通常采用分层帧结构,以GPS L-NAV为例,其结构如下:
- 比特(Bit): 电文的基本单位,值为0或1。
- 字(Word): 固定数量的比特组合(如GPS为30比特)。
- 通常包含数据位和校验位(如奇偶校验)。
- 子帧(Subframe): 由固定数量的字组成(如GPS每个子帧含10个字,共300比特)。
- 帧(Frame): 由固定数量的子帧组成(如GPS一帧含5个子帧,共1500比特,其中子帧13是一套完整的星历信息,子帧45是历书数据)。
- 超帧(Superframe): 由多个帧组成的完整数据集合,包含一套完整的卫星历书信息。
解码的核心任务就是逆向上溯这个过程:比特流 -> 校验与纠错 -> 组成字 -> 解析子帧 -> 得到星历/历书等参数。
帧同步(Frame Synchronism)
- 目的:在比特流中找到子帧和帧的起始位置。
- 原理:利用电文中固定的前导码(Preamble) 或同步字(Sync Word)。例如,GPS每个子帧的第一个字的前8比特是一个固定的模式
0b10001011(八进制表示为0x8B)。接收机通过在比特流中滑动搜索这个固定模式来实现同步。 - 要点:一旦成功检测到同步头,即可将后续的比特流按子帧和帧的结构进行划分。
奇偶校验与纠错(Parity Check & Error Correction)
- 目的:验证数据的完整性,检测并可能纠正传输中产生的比特错误。
- 原理:
- GPS(汉明码):每个30比特的字的最后6比特是奇偶校验位。接收机使用规定的校验算法(涉及上一字的最后两位作为“奇偶性基准”)重新计算校验和,并与接收到的校验和对比。若不匹配,则表明该字存在错误。
- 现代GNSS(BDS, Galileo):通常采用更强大的前向纠错(FEC)编码,如卷积码或LDPC码,能有效纠正连续比特错误,提升数据解码的鲁棒性。
- 要点:校验是确保数据可靠性的关键。对于关键数据(如星历),通常需要无错误地接收完整子帧。
数据解析(Data Parsing)**
- 目的:从已同步且通过校验的二进制数据中,根据协议规定提取出各个参数。
- 原理:根据GNSS接口控制文件(ICD)中定义的电文结构、参数位置、数据格式(如二进制补码、浮点数、比例因子) 进行解析。
- 例如,GPS子帧1的第3-10字包含了卫星精度、健康状况、星期数(WN)等信息;子帧2和3则包含了详细的星历参数(开普勒轨道参数、摄动项等)。
- 要点:必须严格遵循官方ICD文档。参数通常分散在不同的字、甚至不同的子帧中,需要先完成整个帧的接收和存储,再进行统一解析。
参数转换与工程单位化
- 目的:将解析出的二进制数转换为有物理意义的工程值。
- 原理:应用ICD中提供的比例因子(Scale Factor)、偏移量(Bias) 和单位。
- 例如,一个16比特的参数
N,ICD规定其表示的时间参数T = N * 2^(-10)秒。接收机软件需进行此计算。
- 例如,一个16比特的参数
- 要点:忽略比例因子或符号位处理错误是常见的编程错误来源。
工程实践
帧同步,还可以做什么
9比特同步头
前面提到,GPS的前导码是一个8位的数据0b10001011,虚警概率较高
2
−
8
=
3.91
E
−
3
2^{-8}=3.91E-3
2−8=3.91E−3 。受益于LNAV电文字的独特设计,TLM字的前一个字的最后一个比特D30也是可以确认的。
因此一般工程实践中会将D30-连带TLM字的D1~D8一起作为同步头,即9比特同步头。虚警概率为 2 − 9 = 1.95 E − 3 2^{-9}=1.95E-3 2−9=1.95E−3 ,降低了一半。
同步前字回收(Word Restore)
成功检测到同步头之后,就可以开始按字和子帧的格式收集后续的比特流。
提示一下,同步头不仅仅是一个子帧的开始,它也是一个子帧的结束。为了充分利用帧同步之前收集的数据,同步头之前的比特不能浪费掉。
于是,在检测到同步头后,可以将同步头之前的比特同样按照字和子帧的格式收集,最多可以回收1个子帧的数据。这就是**字回收(Word Restore)**的工作原理。
刚找到帧头时的比特缓存器:
|Bit0-Bit31|Bit32-Bit63|... |Bit(n*32)-(Bit_cnt_restored-1) |
|<-------IncompleteWord------>|<--EmptyBits-->|
|<----------------- 32 bits ----------------->|
|uint32[0] |uint32[1] |... |uint32[n] |
|WordX |WordX+1 |... |TLM Word |
|SubframeY |SubframeY+1
其中,Bit_cnt_restored是同步头之前收集的比特数,n是对应的字数(向上取整)。Bit_cnt_restored-1是同步头之前的最后一个比特的位置。
由于找同步头的过程是滑动窗口,因此Bit_cnt_restored-1往前数30个比特是TLM字,即比特缓存器中的比特并没有按照字对齐。
为了方便后续的解析,需要将比特缓存器中的比特按照字对齐,并移除未收集完整的字。
按字对齐后的比特缓存器:
|Bit0-Bit31|Bit32-Bit63|... |Bit((n-1)*32)-Bit((n-1)*32+31)|
|<---------- 32 bits --------->|
|uint32[0] |uint32[1] |... |uint32[n-1] |
|Word9 |Word8 |... |WordX+1 |
如果你是从右(TLM)至左一个一个收集字,那要小心,字的顺序可能跟子帧中的顺序是反向的,也就是说,缓冲器中的第一个字是子帧中的最后一个字(Word9)。
按字收集星历
一套完整的GPS LNAV星历播发占用30秒,如果按照顺序等3个子帧都收集齐后再解码星历,中间有一个字出现问题,就得重新等待30秒。
为了提升解码鲁棒性,一般工程上采用按字收集星历,即不管你是哪个子帧,只要这个字奇偶校验通过就可以被收集。等收集齐30个字就可以解码星历,这样就不需要保证连续的校验通过。
需要注意,为了避免跨星历更新边界收集星历,导致把两套不同龄期的星历拼接在一起,需要在子帧收集时检校星历标识符IOD,当发现IOD更新时及时清空缓存。
这一点非常重要,对于字回收逻辑同样适用。
良好的设计:有限状态机(Finite State Machine)
GPS帧同步不是一个简单的“一次比较,立马确认”的过程。接收机最初并不知道帧的起始位置,它需要在比特流中进行搜索。这个搜索和确认过程天然地包含多个阶段和状态,包括搜索、验证、以及成功或失败后的处理。因此,用状态机来建模是最自然、最直接的。
良好的状态机设计,最首要、最关键的好处,就是大幅提升了可靠性。通过多级验证机制,指数级地降低虚警概率。
其次,它能让接收机解码具备容错和从失步中自动恢复的能力。比如,在同步状态下,信道可能突然恶化(如车辆进入隧道),导致连续几个帧的同步头都无法正确检测。因此,可以这样设计:如果在连续M个帧周期内都没有在预期位置检测到同步头,状态机不会立即崩溃,而是认为同步可能已经丢失,优雅地退回到“搜索状态”,重新开始捕获过程。
此外,状态机可以优化资源效率:仅在需要时进行密集搜索,同步后计算开销极小。
最后,也是工程代码中很重要的一点,状态机可以优化代码结构,做到逻辑清晰,模块化,易于开发和维护。可维护性对于大型的工程代码至关重要,相信在大厂工作过的朋友们一定深有体会。
由于不同厂商对于帧同步的实现细节可能不同,这里给出一个状态机的设计原则,仅供参考:
+---------------------------+
| |
| 搜索状态 |<-----------------+
| (Search State) | |
| | |
+------------+--------------+ |
| |
触发值 > 阈值_TH1 | |
v |
+---------------------------+ |
| | |
| 验证状态 | |
| (Verify State) | |
| | |
+------------+--------------+ |
| |
连续N次验证成功 | 验证失败 / 超时 |
v |
+---------------------------+ |
| | |
| 同步状态 | |
| (Sync State) | |
| | |
+------------+--------------+ |
| |
连续M次同步失败 | |
v |
+---------------------------+ |
| | |
| 失步状态 |------------------+
| (Loss-of-Sync State) |
| |
+---------------------------+
主要GNSS系统的电文
| 系统 | 电文类型 | 显著特点与解码要点 |
|---|---|---|
| GPS L1 C/A | LNAV | 传统结构,30比特/字,6比特奇偶校验,采用汉明码。需注意奇偶校验算法中的“奇偶性基准”位。 |
| GPS L2C/L5 | CNAV, CNAV-2 | 消息结构更灵活(类似于数据包),采用FEC(卷积码),性能更优,数据内容更丰富。 |
| BDS-3 B1C | B-CNAV1 | 采用LDPC编码,抗误码能力极强。电文结构为可变长度的消息,包含导频序列和CRC校验。 |
| Galileo | F/NAV, I/NAV | 使用卷积码和CRC校验。页面结构,含同步模式、数据段和尾比特。完整性信息更丰富。 |
要点总结(顺口溜)
- 同步是基石:帧同步是解码的前提,同步失败将导致整个解码链失效。
- 校验保可靠:奇偶校验或FEC解码是确保数据在低信噪比环境下仍能正确解码的核心手段,不可或缺。
- ICD是圣经:任何解析工作都必须以官方发布的接口控制文件(ICD) 为绝对依据,不可臆测参数的位置和格式。
- 注意数据格式:正确处理二进制补码、符号位、比例因子和偏移量是获得正确参数值的关键。
- 考虑比特顺序:需注意传输的比特顺序是MSB(最高有效位优先) 还是LSB(最低有效位优先)。
- 系统有差异:不同GNSS系统及其不同信号的电文结构、编码方式和校验算法存在显著差异,实现解码器时需分别处理。
- 鲁棒性设计:在实际应用中,应设计状态机来处理同步丢失、校验失败、数据不完整等异常情况,保证解码过程的鲁棒性。
- 效率与实时性:解码算法通常嵌入在嵌入式系统中,需考虑计算复杂度和内存占用的平衡,优化查找和计算过程。
204

被折叠的 条评论
为什么被折叠?



