当前位置: 首页 > ds >正文

RTKLIB读取星历文件,观测数据

       笔者尝试在RTKLIB的基础上进行各种功能的测试,首先想通过利用RTKLIB,读取广播星历文件,在利用星历解析函数计算出星历文件中卫星的位置信息等等。但过程及其曲折,问题频出。考虑了文件本身原因,程序问题。后来分开单独测试,通过内部手动设置模拟导航数据测试eph2pos函数,发现是可以成功的。然后单独测试文件读取,就一直读取失败。

        检测发现文件时能读到的,但有时候是直接读不出来;或者是读取后发现读了一点就卡死了。最后偶然发现是文件路径包含中文。

问题核心:为什么中文路径导致 readrnx() 读取失败?

这是因为 RTKLIB(尤其是 demo5 分支中的原生实现)使用的是标准 C 函数来处理文件路径,比如:

FILE *fp = fopen(filepath, "r");

这些函数默认使用 ANSI(GBK)编码读取路径,而不是 UTF-8 或 Unicode。

💥 所以当路径中含有中文字符(如“桌面”)时,会导致:

  • fopen() 打开失败;

  • readrnx() 返回失败(-1);

  • 报错:"读取观测文件失败"。


解决方法:

你已经找到了最直接的方案:

把路径改成全英文目录路径,例如:D:\RTKLIB_TEST\xxx.obs

也可以选用以下方案之一(进阶):

  • 使用 VS 工程中设置为 UTF-8 编译,并使用 _wfopen 打开 Unicode 路径(需修改 RTKLIB 源码);

  • 把数据放在全英文目录路径下再运行;

  • 避免在中文用户名、桌面路径下运行 RTKLIB 程序。


🧪 2. 尝试用 satid() 打印卫星编号失败

  • 原代码使用了 satid(sat),但 satid() 并不是 RTKLIB 正式暴露的函数(或未包含头文件);

  • 报错为 “implicit declaration of function 'satid'”;

  • 改用 satsys() 成功获取了卫星系统和 PRN。


✅ 3. 成功读取数据,打印前5个历元信息

int stat = readrnx(rnx_file, 1, "", &obs, &nav, &sta);

  • 使用 VS 工程中设置为 UTF-8 编译,并使用 _wfopen 打开 Unicode 路径(需修改 RTKLIB 源码);

  • 把数据放在全英文目录路径下再运行;

  • 避免在中文用户名、桌面路径下运行 RTKLIB 程序。

    🧪 1. 初次尝试读取观测文件失败

    int stat = readrnx(rnx_file, 1, "", &obs, &nav, &sta);

  • 观测文件路径含中文,如:D:\Users\Wang\桌面\RTKLIB\...

  • 报错信息为:“读取观测文件失败!”

  • 实际是 fopen() 无法识别中文路径。

  • 原代码使用了 satid(sat),但 satid() 并不是 RTKLIB 正式暴露的函数(或未包含头文件);

  • 报错为 “implicit declaration of function 'satid'”;

  • 改用 satsys() 成功获取了卫星系统和 PRN。

    • 成功输出如下:

    • 读取成功,观测历元总数:948
      历元 1 时间:2005/04/02 00:00:00.000 卫星:G03
      频点1: P = 24767686.375
      频点2: P = 24767684.822
      ...

      📌 代码模板(可收藏复用)
      #include <stdio.h>
      #include "rtklib.h"int main(void) {obs_t obs = {0};nav_t nav = {0};sta_t sta = {0};const char *rnx_file = "d:\\RTKLIB_TEST\\yourfile.obs"; // 英文路径int stat = readrnx(rnx_file, 1, "", &obs, &nav, &sta);if (stat <= 0) {printf("读取观测文件失败!请检查路径或文件格式\n");return -1;}printf("读取成功,观测历元总数:%d\n", obs.n);for (int i = 0; i < obs.n && i < 5; i++) {gtime_t t = obs.data[i].time;double ep[6];time2epoch(t, ep);int prn;int sys = satsys(obs.data[i].sat, &prn);const char *sys_id = sys == SYS_GPS ? "G" :sys == SYS_GLO ? "R" :sys == SYS_GAL ? "E" :sys == SYS_QZS ? "J" :sys == SYS_CMP ? "C" : "?";printf("历元 %d 时间:%04.0f/%02.0f/%02.0f %02.0f:%02.0f:%06.3f 卫星:%s%02d\n",i + 1, ep[0], ep[1], ep[2], ep[3], ep[4], ep[5], sys_id, prn);for (int j = 0; j < NFREQ && j < 3; j++) {if (obs.data[i].P[j] != 0.0)printf("  频点%d: P = %.3f\n", j + 1, obs.data[i].P[j]);}}free(obs.data);free(nav.eph);free(nav.geph);return 0;
      }

http://www.xdnf.cn/news/15825.html

相关文章:

  • 解决Flutter运行android提示Deprecated imperative apply of Flutter‘s Gradle plugins
  • 电解电容串联均衡电阻计算
  • 模板初阶和C++内存管理
  • 功能安全之BIST的基本原理
  • 第7天 | openGauss中一个数据库中可以创建多个模式
  • 6月零售数据超预期引发市场波动:基于AI多因子模型的黄金价格解析
  • Axios泛型参数解析与使用指南
  • 当系统盘快满时,可以删除哪些数据
  • 排序【各种题型+对应LeetCode习题练习】
  • 如何阅读Spring源码
  • 【LVGL】Linux LVGL程序几十分钟后UI卡死
  • effective python 条款11 学会对序列做切片
  • Onload 用户指南 (UG1586)-笔记
  • 【机器学习】安装Jupyter及基本操作
  • 内存泄漏系列专题分析之二十九:高通相机CamX--Android通用GPU内存分配和释放原理
  • 虚拟商品自动化实践:闲鱼订单防漏发与模板化管理的技术解析
  • JVM常用运行时参数说明
  • 【C# in .NET】17. 探秘类成员-构造函数与析构函数:对象生命周期管理
  • [3-02-01].第01章:框架概述 - Spring生态
  • 基于Spring Boot的农村农产品销售系统设计与实现
  • 【Python】DRF核心组件详解:Mixin与Generic视图
  • ARINC818航空总线机载视频处理系统设计
  • 第二篇 html5和css3开发基础与应用
  • 28、鸿蒙Harmony Next开发:不依赖UI组件的全局气泡提示 (openPopup)和不依赖UI组件的全局菜单 (openMenu)、Toast
  • 数据结构入门:像整理收纳一样简单!
  • Jmeter系列(6)-测试计划
  • 李超线段树模板
  • Vue3 中使用 Element Plus 实现自定义按钮的 ElNotification 提示框
  • 「源力觉醒 创作者计划」_巅峰对话:文心 4.5 vs. DeepSeek / Qwen 3.0 深度解析(实战优化版)
  • Matlab打开慢、加载慢的解决办法