本文是 RTKLlib详解 系列文章的一篇,目前该系列文章还在持续总结写作中,以发表的如下,有兴趣的可以翻阅。
[学习] RTKlib详解:功能、工具与源码结构解析
[学习]RTKLib详解:pntpos.c与postpos.c
[学习]RTKLib详解:rtkcmn.c与rtkpos.c
[学习]RTKLib详解:ppp.c与ppp_ar.c
[学习]RTKLib详解:ephemeris.c与rinex.c
Part A : rtksvr
–
一、整体作用与工作流程分析
rtksvr.c
是RTK(实时动态定位)服务器的核心模块,负责处理多源输入数据(如观测值、星历、SSR修正等),执行实时动态差分定位解算,并输出高精度定位结果。其工作流程如下:
- 数据输入:通过多个流(
stream
)接收原始观测数据、星历、SSR修正等。 - 数据解码:调用
decoderaw
解析原始数据或RTCM格式数据,提取观测值、星历等信息。 - 状态更新:通过
updatesvr
更新服务器状态,包括导航数据、天线位置、SSR修正等。 - 定位解算:利用RTK算法(如双差载波相位处理)计算移动站位置。
- 结果输出:通过
writesol
将解算结果写入输出流,并保存至缓冲区或监控端口。
二、函数详细说明
1. writesolhead
:写入解算结果头部
- 功能:生成并写入解算结果的头部信息(如坐标系、时间格式)。
- 参数:
stream_t *stream
:输出流指针。solopt_t *solopt
:解算选项(如输出格式)。
- 流程:调用
outsolheads
生成头部数据,通过strwrite
写入流。
2. saveoutbuf
:保存输出缓冲区
- 功能:将解算结果存入环形缓冲区,支持多线程安全。
- 参数:
rtksvr_t *svr
:RTK服务器结构体。unsigned char *buff
:待保存的数据缓冲区。int n
:数据长度。int index
:缓冲区索引(区分不同输出流)。
- 关键操作:加锁(
rtksvrlock
)后复制数据至svr->sbuf[index]
,更新缓冲区指针nsb
。
3. writesol
:输出解算结果
- 功能:将定位结果写入输出流,并保存至缓冲区和监控端口。
- 参数:
rtksvr_t *svr
(服务器状态)、int index
(流索引)。 - 流程:
- 调用
outsols
生成标准解算结果,outsolexs
生成扩展结果。 - 通过
strwrite
写入流,并调用saveoutbuf
保存数据。 - 监控端口输出使用简化格式(
solopt_default
)。
- 调用
4. updatenav
:更新导航数据波长
- 功能:计算卫星信号的波长( λ \lambda λ),用于载波相位解算。
- 数学原理:波长公式为 λ = c / f \lambda = c / f λ=c/f,其中 c c c为光速, f f f为频率。
- 参数:
nav_t *nav
(导航数据结构体)。 - 实现:遍历所有卫星和频率,调用
satwavelen
计算波长并更新nav->lam
。
5. updatefcn
:更新GLONASS频率信道
- 功能:同步不同数据流中的GLONASS卫星频率信道号(
frq
)。 - 参数:
rtksvr_t *svr
。 - 流程:遍历GLONASS卫星,从任意流中获取有效
frq
,更新其他流的导航数据。
6. updatesvr
:更新服务器状态
- 功能:根据解码结果更新导航数据、观测值、SSR修正等。
- 参数:
rtksvr_t *svr
:服务器状态。ret
:数据类型标识(如1=观测值,2=星历)。obs_t *obs
:观测数据结构体。nav_t *nav
:导航数据结构体。
- 关键逻辑:
- 观测值:筛选有效数据并排序。
- 星历:更新GPS/GLONASS星历,确保时效性。
- SSR修正:检查轨道与钟差IOD一致性,避免数据冲突。
7. decoderaw
:解码原始数据
- 功能:解析原始数据或RTCM消息,提取观测值、星历等信息。
- 参数:
rtksvr_t *svr
、int index
(流索引)。 - 返回:解码结果状态(如1=观测值解码成功)。
三、函数调用关系图(Mermaid)
四、数学原理与公式
RTK定位基于双差载波相位观测模型,关键公式如下:
双差观测方程:
∇ Δ ϕ = ∇ Δ ρ + λ ∇ Δ N + ∇ Δ ϵ \nabla\Delta\phi = \nabla\Delta\rho + \lambda\nabla\Delta N + \nabla\Delta\epsilon ∇Δϕ=∇Δρ+λ∇ΔN+∇Δϵ- ∇ Δ ϕ \nabla\Delta\phi ∇Δϕ:双差载波相位(单位:周)。
- ∇ Δ ρ \nabla\Delta\rho ∇Δρ:双差几何距离。
- ∇ Δ N \nabla\Delta N ∇ΔN:双差整周模糊度。
- λ \lambda λ:信号波长。
Kalman滤波状态更新:
x ^ k = x ^ k − 1 + K k ( z k − H k x ^ k − 1 ) \hat{x}_k = \hat{x}_{k-1} + K_k(z_k - H_k\hat{x}_{k-1}) x^k=x^k−1+Kk(zk−Hkx^k−1)- K k K_k Kk:卡尔曼增益。
- z k z_k zk:观测向量。
- H k H_k Hk:设计矩阵。
五、关键数据结构
rtksvr_t
:包含服务器状态、缓冲区、导航数据(nav
)、解算结果(rtk
)等。nav_t
:存储星历、电离层参数、SSR修正等。solopt_t
:定义解算结果的输出格式选项。
Part A:streamsvr.c
一、整体作用与工作流程分析
streamsvr.c
是 RTKLIB 流服务器模块的核心部分,主要用于 多源数据流的格式转换与分发,支持将输入流(如接收机原始数据)转换为指定格式(如 RTCM 消息)并输出。其核心功能包括:
- 数据流转换:支持从原始数据(
raw_t
)或 RTCM 数据(rtcm_t
)转换为目标格式。 - 消息生成:按配置生成观测数据(OBS)、导航数据(NAV)及站信息(STA)的 RTCM 消息。
- 周期性输出:根据时间间隔(
tint
)控制消息的发送频率,支持循环发送导航数据。
工作流程:
- 初始化转换器:调用
strconvnew
创建流转换器,解析消息类型与时间间隔。 - 数据解码与转换:根据输入流类型(
itype
)调用raw2rtcm
或rtcm2rtcm
将数据复制到目标结构。 - 消息生成与发送:通过
write_obs
和write_nav
生成 RTCM 消息,调用strwrite
写入输出流。 - 循环导航数据:
write_nav_cycle
使用nextsat
选择下一颗卫星的星历,周期性发送。
二、函数详细说明
1. strconvnew
:创建流转换器
- 功能:初始化流转换器,解析消息类型与时间间隔,分配内存并配置 RTCM/原始数据结构。
- 参数:
int itype
:输入流类型(如STR_RAW
或STR_RTCM
)。int otype
:输出流类型(如STRFMT_RTCM3
)。const char *msgs
:消息类型与间隔(如"1019(30),1020(30)"
)。int staid
:站 ID。int stasel
:站信息选择(0=远程,1=本地)。
- 关键逻辑:
- 解析
msgs
字符串,提取消息类型(如 1019)和间隔(如 30 秒)。 - 初始化
rtcm_t
和raw_t
结构,配置选项(如-EPHALL
强制包含所有星历)。
- 解析
2. raw2rtcm
:原始数据转 RTCM
- 功能:将接收机原始数据(
raw_t
)复制到 RTCM 结构(rtcm_t
)。 - 参数:
rtcm_t *out
:目标 RTCM 结构。const raw_t *raw
:源原始数据。int ret
:数据类型标识(1=观测值,2=星历,9=UTC/电离层参数)。
- 数据映射:
- 观测值:
out->obs.data[i] = raw->obs.data[i]
。 - 星历:根据卫星系统(GPS/GLONASS)复制到
nav.eph
或nav.geph
。
- 观测值:
3. write_obs
:生成观测数据消息
- 功能:按配置生成观测数据 RTCM 消息并写入输出流。
- 参数:
gtime_t time
:当前时间。stream_t *str
:输出流指针。strconv_t *conv
:流转换器。
- 逻辑:
- 检查消息类型是否为观测数据(
is_obsmsg
)且满足时间间隔(is_tint
)。 - 调用
gen_rtcm2
或gen_rtcm3
生成消息,通过strwrite
发送。
- 检查消息类型是否为观测数据(
4. nextsat
:选择下一颗卫星
- 功能:循环选择下一颗卫星的星历,用于周期性导航数据输出。
- 参数:
nav_t *nav
:导航数据结构。int sat
:当前卫星编号。int msg
:消息类型(如 1019=GPS 星历)。
- 逻辑:
- 根据消息类型确定卫星系统(如 1019 对应 GPS),遍历 PRN 号寻找有效星历。
- 返回下一颗有效卫星编号,若无则重置为起始 PRN。
三、函数调用关系图(Mermaid)
四、数学原理与关键公式
时间间隔检查:
is_tint ( t ) = { 1 if mod ( t GPST + Δ , T ) ≤ 2 Δ 0 otherwise \text{is\_tint}(t) = \begin{cases} 1 & \text{if } \text{mod}(t_{\text{GPST}} + \Delta, T) \leq 2\Delta \\ 0 & \text{otherwise} \end{cases} is_tint(t)={10if mod(tGPST+Δ,T)≤2Δotherwise- 其中 t GPST t_{\text{GPST}} tGPST 为 GPS 时间, T T T 为间隔, Δ \Delta Δ 为容差(
DTTOL
)。
- 其中 t GPST t_{\text{GPST}} tGPST 为 GPS 时间, T T T 为间隔, Δ \Delta Δ 为容差(
星历循环逻辑:
- 对卫星 PRN 号进行模运算,确保周期性遍历所有有效星历:
p next = { p 1 if p ≥ p 2 p + 1 otherwise p_{\text{next}} = \begin{cases} p_1 & \text{if } p \geq p_2 \\ p + 1 & \text{otherwise} \end{cases} pnext={p1p+1if p≥p2otherwise- p 1 p_1 p1 和 p 2 p_2 p2 为 PRN 范围(如 GPS: 1-32)。
- 对卫星 PRN 号进行模运算,确保周期性遍历所有有效星历:
五、关键数据结构
strconv_t
:流转换器配置,包含消息列表、时间间隔、RTCM/原始数据实例。rtcm_t
:存储 RTCM 消息的观测值、星历、站信息及生成缓冲区。nav_t
:导航数据,包括星历(eph
)、GLONASS 星历(geph
)、电离层参数等。
研究学习不易,点赞易。
工作生活不易,收藏易,点收藏不迷茫 :)