[学习]RTKLib详解:rtksvr.c与streamsvr.c

news2025/5/11 12:41:29

本文是 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`
    • 一、整体作用与工作流程分析
    • 二、函数详细说明
      • 1. `writesolhead`:写入解算结果头部
      • 2. `saveoutbuf`:保存输出缓冲区
      • 3. `writesol`:输出解算结果
      • 4. `updatenav`:更新导航数据波长
      • 5. `updatefcn`:更新GLONASS频率信道
      • 6. `updatesvr`:更新服务器状态
      • 7. `decoderaw`:解码原始数据
    • 三、函数调用关系图(Mermaid)
    • 四、数学原理与公式
    • 五、关键数据结构
  • Part A:`streamsvr.c`
    • 一、整体作用与工作流程分析
    • 二、函数详细说明
      • 1. `strconvnew`:创建流转换器
      • 2. `raw2rtcm`:原始数据转 RTCM
      • 3. `write_obs`:生成观测数据消息
      • 4. `nextsat`:选择下一颗卫星
    • 三、函数调用关系图(Mermaid)
    • 四、数学原理与关键公式
    • 五、关键数据结构


Part A : rtksvr

一、整体作用与工作流程分析

rtksvr.c是RTK(实时动态定位)服务器的核心模块,负责处理多源输入数据(如观测值、星历、SSR修正等),执行实时动态差分定位解算,并输出高精度定位结果。其工作流程如下:

  1. 数据输入:通过多个流(stream)接收原始观测数据、星历、SSR修正等。
  2. 数据解码:调用decoderaw解析原始数据或RTCM格式数据,提取观测值、星历等信息。
  3. 状态更新:通过updatesvr更新服务器状态,包括导航数据、天线位置、SSR修正等。
  4. 定位解算:利用RTK算法(如双差载波相位处理)计算移动站位置。
  5. 结果输出:通过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 *svrint index(流索引)。
  • 返回:解码结果状态(如1=观测值解码成功)。

三、函数调用关系图(Mermaid)

解析数据
更新星历
更新GLONASS频率
触发解算
写入头部
保存数据
decoderaw
updatesvr
updatenav
updatefcn
writesol
writesolhead
saveoutbuf

四、数学原理与公式

RTK定位基于双差载波相位观测模型,关键公式如下:

  1. 双差观测方程
    ∇ Δ ϕ = ∇ Δ ρ + λ ∇ Δ 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 λ:信号波长。
  2. 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^k1+Kk(zkHkx^k1)

    • 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.cRTKLIB 流服务器模块的核心部分,主要用于 多源数据流的格式转换与分发,支持将输入流(如接收机原始数据)转换为指定格式(如 RTCM 消息)并输出。其核心功能包括:

  1. 数据流转换:支持从原始数据(raw_t)或 RTCM 数据(rtcm_t)转换为目标格式。
  2. 消息生成:按配置生成观测数据(OBS)、导航数据(NAV)及站信息(STA)的 RTCM 消息。
  3. 周期性输出:根据时间间隔(tint)控制消息的发送频率,支持循环发送导航数据。

工作流程

  1. 初始化转换器:调用 strconvnew 创建流转换器,解析消息类型与时间间隔。
  2. 数据解码与转换:根据输入流类型(itype)调用 raw2rtcmrtcm2rtcm 将数据复制到目标结构。
  3. 消息生成与发送:通过 write_obswrite_nav 生成 RTCM 消息,调用 strwrite 写入输出流。
  4. 循环导航数据write_nav_cycle 使用 nextsat 选择下一颗卫星的星历,周期性发送。

二、函数详细说明

1. strconvnew:创建流转换器

  • 功能:初始化流转换器,解析消息类型与时间间隔,分配内存并配置 RTCM/原始数据结构。
  • 参数
    • int itype:输入流类型(如 STR_RAWSTR_RTCM)。
    • int otype:输出流类型(如 STRFMT_RTCM3)。
    • const char *msgs:消息类型与间隔(如 "1019(30),1020(30)")。
    • int staid:站 ID。
    • int stasel:站信息选择(0=远程,1=本地)。
  • 关键逻辑
    • 解析 msgs 字符串,提取消息类型(如 1019)和间隔(如 30 秒)。
    • 初始化 rtcm_traw_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.ephnav.geph

3. write_obs:生成观测数据消息

  • 功能:按配置生成观测数据 RTCM 消息并写入输出流。
  • 参数
    • gtime_t time:当前时间。
    • stream_t *str:输出流指针。
    • strconv_t *conv:流转换器。
  • 逻辑
    • 检查消息类型是否为观测数据(is_obsmsg)且满足时间间隔(is_tint)。
    • 调用 gen_rtcm2gen_rtcm3 生成消息,通过 strwrite 发送。

4. nextsat:选择下一颗卫星

  • 功能:循环选择下一颗卫星的星历,用于周期性导航数据输出。
  • 参数
    • nav_t *nav:导航数据结构。
    • int sat:当前卫星编号。
    • int msg:消息类型(如 1019=GPS 星历)。
  • 逻辑
    • 根据消息类型确定卫星系统(如 1019 对应 GPS),遍历 PRN 号寻找有效星历。
    • 返回下一颗有效卫星编号,若无则重置为起始 PRN。

三、函数调用关系图(Mermaid)

初始化
初始化
配置选项
数据转换
写入数据
生成消息
发送消息
选择卫星
更新星历
生成消息
strconvnew
init_rtcm
init_raw
gen_rtcm2/gen_rtcm3
raw2rtcm
write_obs
strwrite
write_nav_cycle
nextsat

四、数学原理与关键公式

  1. 时间间隔检查
    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)otherwise

    • 其中 t GPST t_{\text{GPST}} tGPST 为 GPS 时间, T T T 为间隔, Δ \Delta Δ 为容差(DTTOL)。
  2. 星历循环逻辑

    • 对卫星 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 pp2otherwise
      • p 1 p_1 p1 p 2 p_2 p2 为 PRN 范围(如 GPS: 1-32)。

五、关键数据结构

  • strconv_t:流转换器配置,包含消息列表、时间间隔、RTCM/原始数据实例。
  • rtcm_t:存储 RTCM 消息的观测值、星历、站信息及生成缓冲区。
  • nav_t:导航数据,包括星历(eph)、GLONASS 星历(geph)、电离层参数等。

研究学习不易,点赞易。
工作生活不易,收藏易,点收藏不迷茫 :)


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2373120.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

串口屏调试 1.0

http://wiki.tjc1688.com 先把商家的链接贴过来 淘晶驰T1系列3.2寸串口屏tft液晶屏显示屏HMI触摸屏超12864液晶屏 这是主包的型号 打开这个玩意 有十个基本的功能区 新建工程 在界面的右边,指令一定要写在page前面,这里的波特率等等什么的都可以…

windows 环境下 python环境安装与配置

运行环境安装 第一步安装包下载 python开发工具安装包下载官网: https://www.python.org/ 根据自己的实际需求选择。 这里记录了各个版本的区别和差异。根据区别和差异选择适合自己的版本。 Windows Installer和Windows embeddable package是两种不同的软件包类…

浅谈装饰模式

一、前言 hello大家好,本次打算简单聊一下装饰者模式,其实写有关设计模式的内容还是蛮有挑战性的,首先呢就是小永哥实力有限担心说不明白,其次设计模式是为了解决某些问题场景,在当前技术生态圈如此完善的情况下&#…

LeetCode 270:在二叉搜索树中寻找最接近的值(Swift 实战解析)

文章目录 摘要描述题解答案题解代码分析示例测试及结果时间复杂度空间复杂度总结 摘要 在日常开发中,我们经常需要在一组有序的数据中快速找到最接近某个目标值的元素。LeetCode 第 270 题“Closest Binary Search Tree Value”正是这样一个问题。本文将深入解析该…

WPF 3D图形编程核心技术解析

一、三维坐标系系统 WPF采用右手坐标系系统,空间定位遵循: X 轴 → 右 Y 轴 → 上 Z 轴 → 观察方向 X轴 \rightarrow 右\quad Y轴 \rightarrow 上\quad Z轴 \rightarrow 观察方向 X轴→右Y轴→上Z轴→观察方向 三维坐标值表示为 ( x , y , z ) (x, y,…

暗物质卯引力挂载技术

1、物体质量以及其所受到的引力约束(暗物质压力差) 自然界的所有物体,其本身都是没有质量的。我们所理解的质量,其实是物体球周空间的暗物质对物体的挤压,压力差。 对于宇宙空间中的单个星球而言,它的球周各处压力是相同的,所以,它处于平衡状态,漂浮在宇宙中。 对于星…

comfyui 如何优雅的从Hugging Face 下载模型,文件夹

如下图所示 使用git 下载整个仓库然后把需要的放到对应的位置

通过user-agent来源判断阻止爬虫访问网站,并防止生成[ error ] NULL日志

一、TP5.0通过行为&#xff08;Behavior&#xff09;拦截爬虫并避免生成 [ error ] NULL 错误日志 1. 创建行为类&#xff08;拦截爬虫&#xff09; 在 application/common/behavior 目录下新建BlockBot.php &#xff0c;用于识别并拦截爬虫请求&#xff1a; <?php name…

IBM BAW(原BPM升级版)使用教程第七讲

续前篇&#xff01; 一、团队 在 IBM Business Automation Workflow (BAW) 中&#xff0c;团队&#xff08;Team&#xff09; 是流程管理的关键部分&#xff0c;用于定义参与某个流程的用户、角色、组以及服务等。在团队配置中&#xff0c;有许多重要概念&#xff0c;特别是 …

【论文阅读】Efficient and secure federated learning against backdoor attacks

Efficient and secure federated learning against backdoor attacks -- 高效且安全的可抵御后门攻击的联邦学习 论文来源问题背景TLDR系统及威胁模型实体威胁模型 方法展开服务器初始化本地更新本地压缩高斯噪声与自适应扰动聚合与解压缩总体算法 总结优点缺点 论文来源 名称…

Java中的代理机制

目录 什么叫代理 静态代理 优缺点 优点&#xff1a; 缺点&#xff1a; 动态代理 JDK动态代理 核心类 JDK动态代理的实现 步骤 示例 特点 CGLIB动态代理 代理机制对比 总结 什么叫代理 代理模式是一种比较好理解的设计模式。简单来说就是我们使用代理对象来代替…

Jenkins linux安装

jenkins启动 service jenkins start 重启 service jenkins restart 停止 service jenkins stop jenkins安装 命令切换到自己的下载目录 直接用命令下载 wget http://pkg.jenkins-ci.org/redhat-stable/jenkins-2.190.3-1.1.noarch.rpm 下载直接安装 rpm -ivh jenkins-2.190.3-…

Webug4.0靶场通关笔记-靶场搭建方法(3种方法)

目录 一、虚拟机绿色版本 1. 开启phpstudy 2. 访问靶场 二、Docker版本 1.拉取镜像 2.启动镜像 三、源码安装版本 1. 搭建环境 &#xff08;1&#xff09;安装PHPStudy &#xff08;2&#xff09;WeBug4.0靶场源码 &#xff08;3&#xff09;安装Navicat &#xff…

【Web】LACTF 2025 wp

目录 arclbroth lucky-flag whack-a-mole arclbroth 看到username为admin能拿到flag 但不能重复注册存在的用户 这题是secure-sqlite这个库的问题&#xff0c;底层用的是C&#xff0c;没处理好\0字符截断的问题 &#xff08;在 Node.js 中&#xff0c;由于其字符串表示方式…

【日撸 Java 三百行】综合任务 1

目录 Day 10&#xff1a;综合任务 1 一、题目分析 1. 数据结构 2. 相关函数基本知识 二、模块介绍 1. 初始化与成绩矩阵的构建 2. 创建总成绩数组 3. 寻找成绩极值 三、代码与测试 小结 拓展&#xff1a;关于求极值的相关算法 Day 10&#xff1a;综合任务 1 Task&…

华为私有协议Hybrid

实验top图 理论环节 1. 基本概念 Hybrid接口&#xff1a; 支持同时处理多个VLAN流量&#xff0c;且能针对不同VLAN配置是否携带标签&#xff08;Tagged/Untagged&#xff09;。 核心特性&#xff1a; 灵活控制数据帧的标签处理方式&#xff0c;适用于复杂网络场景。 2. 工作…

数据库实验10

设计性实验 1&#xff0e;实验要求 1.编写函数FsumXXX&#xff0c;1~n&#xff08;参数&#xff09;求和&#xff1b; GO CREATE FUNCTION Fsum065 (n INT) RETURNS INT AS BEGIN DECLARE sum INT 0 WHILE n > 0 BEGIN SET sum sum n SET n n - 1 END RETURN sum END …

jflash下载时出现 Could not read unit serial number! 的解决方法

出现的原因是由于Jlink原厂固件SN码是-1 我用的版本是v6.40 解决方法&#xff1a;添加序列号 1.打开&#xff1a;J-Link commander 之后在命令栏输入&#xff1a;exec setsnxxxxxxxx 2.添加序列号到license&#xff0c;打开J-Link License Manager V6.40 jlink-v640下载软件…

Linux 信号终篇(总结)

前文&#xff1a;本文是对信号从产生到被处理的过程中的概念和原理的总结&#xff0c;如果想了解具体实现&#xff0c;请查看前两篇博客&#xff1a;Linux 信号-CSDN博客、Linux 信号&#xff08;下篇&#xff09;-CSDN博客 一、信号的产生 1.1 信号产生的五种条件 ①键盘组…

LVGL对象(Objects)

文章目录 &#x1f9f1; 一、LVGL 中的对象&#xff08;lv\_obj&#xff09;&#x1f539; lv\_obj\_t 的作用 &#x1f9e9; 二、对象的分类结构&#xff08;类比继承&#xff09;&#x1f9f0; 三、对象的创建与销毁✅ 创建对象示例&#xff1a;创建一个按钮❌ 删除对象 &…