Andy的GNSS工坊

GNSS导航电文比特解码

GNSS导航电文比特解码

导航电文解码是GNSS接收机软件的关键环节之一,也是很多从业者入门时领取到的“新手村任务”之一。首先,让我们给它下个定义:

导航电文(Navigation Message) 是调制在GNSS射频载波上的0-1数据流,其本质是包含卫星轨道、时钟、系统状态等关键参数的二进制比特流。

比特解码(Bit Decoding) 是指将从卫星信号中剥离出的原始数据比特流,按照特定帧格式和编码规则,解析并重构为可供定位算法使用的、有实际意义的工程参数的过程。

电文解码的目的

电文解码的目的很明确,主要有如下两方面,分别对应定位解算的两个必要条件:接收机观测数据和卫星轨道钟数据。以GPS L-NAV为例:

补全发射时间 :在帧同步之前,跟踪环路提取到的码相位和电文比特没有时间基准,无法直接拼接伪距观测。通过帧同步找到电文数据帧的边界,可以建立比特数与电文数据帧的对应关系。此外,导航电文中提供了信号播发对应到系统时的周计数(WN, Week Number)和周内秒(TOW, Time Of Week),两者结合可以计算出电文比特对应的绝对时间,从而拼接完整伪距观测。

$PR = T_{rx} - T_{tx}$

$T_{tx} = WN + TOW + Bit_ms + \frac{Code_phase}{Code_length}$

获取星历历书 :导航电文包含了卫星的轨道、钟差、健康状况等关键参数,有了发射时刻和卫星轨道钟数据,就能够计算卫星的位置速度,作为PVT解算的输入。

电文解码的常规流程

尽管各GNSS系统的电文格式存在差异,但其核心结构和解码逻辑相似。通常采用分层帧结构,以GPS L-NAV为例,其结构如下:

  • 比特(Bit): 电文的基本单位,值为0或1。
  • 字(Word): 固定数量的比特组合(如GPS为30比特)。
    • 通常包含数据位校验位(如奇偶校验)。
  • 子帧(Subframe): 由固定数量的字组成(如GPS每个子帧含10个字,共300比特)。
  • 帧(Frame): 由固定数量的子帧组成(如GPS一帧含5个子帧,共1500比特,其中子帧1~3是一套完整的星历信息,子帧4~5是历书数据)。
  • 超帧(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) 秒。接收机软件需进行此计算。
  • 要点:忽略比例因子或符号位处理错误是常见的编程错误来源。

工程实践

帧同步,还可以做什么

9比特同步头

前面提到,GPS的前导码是一个8位的数据0b10001011,虚警概率较高 $2^{-8}=3.91E-3$ 。受益于LNAV电文字的独特设计,TLM字的前一个字的最后一个比特D30也是可以确认的。

因此一般工程实践中会将D30-连带TLM字的D1~D8一起作为同步头,即9比特同步头。虚警概率为 $2^{-9}=1.95E-3$ ,降低了一半。

同步前字回收(Word Restore)

成功检测到同步头之后,就可以开始按字和子帧的格式收集后续的比特流。

提示一下,同步头不仅仅是一个子帧的开始,它也是一个子帧的结束。为了充分利用帧同步之前收集的数据,同步头之前的比特不能浪费掉。

于是,在检测到同步头后,可以将同步头之前的比特同样按照字和子帧的格式收集,最多可以回收1个子帧的数据。这就是字回收(Word Restore)的工作原理。

刚找到帧头时的比特缓存器:

|Bit0-Bit31|Bit32-Bit63|... |Bit(n*32)-(Bit_cnt_restored-1)               |
                            |<-----------TLM LSB--------->|<--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字,即比特缓存器中的比特并没有按照字对齐。 为了方便后续的解析,需要将比特缓存器中的比特按照字对齐(到UINT32边界),并移除未收集完整的字。

按字对齐后的比特缓存器:

|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校验。页面结构,含同步模式、数据段和尾比特。完整性信息更丰富。

要点总结(顺口溜)

  1. 同步是基石帧同步是解码的前提,同步失败将导致整个解码链失效。
  2. 校验保可靠奇偶校验FEC解码是确保数据在低信噪比环境下仍能正确解码的核心手段,不可或缺。
  3. ICD是圣经:任何解析工作都必须以官方发布的接口控制文件(ICD) 为绝对依据,不可臆测参数的位置和格式。
  4. 注意数据格式:正确处理二进制补码、符号位、比例因子和偏移量是获得正确参数值的关键。
  5. 考虑比特顺序:需注意传输的比特顺序是MSB(最高有效位优先) 还是LSB(最低有效位优先)
  6. 系统有差异:不同GNSS系统及其不同信号的电文结构、编码方式和校验算法存在显著差异,实现解码器时需分别处理。
  7. 鲁棒性设计:在实际应用中,应设计状态机来处理同步丢失、校验失败、数据不完整等异常情况,保证解码过程的鲁棒性。
  8. 效率与实时性:解码算法通常嵌入在嵌入式系统中,需考虑计算复杂度和内存占用的平衡,优化查找和计算过程。
返回首页