尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

VS配置RTKLIB卫星定位开源代码环境:从源码编译到工程集成

VS配置RTKLIB卫星定位开源代码环境:从源码编译到工程集成 搞卫星定位的人几乎没有不知道 RTKLIB 的。这套由日本学者开发维护了近二十年的开源程序库从 GPS 时代的双频 RTK到现在支持 GPS/BDS/Galileo/GLONASS/QZSS 多系统的 PPP/RTK 解算说是 GNSS 领域的一部活字典也不过分。但真正想拿它做点事第一道坎儿就是编译环境——尤其是在 Windows 下大家最常用的就是 Visual Studio也就是 VS。这篇内容就是围绕“VS 配置 RTKLIB 卫星定位开源代码环境”这件事儿把从源码下载、工程打开、编译参数调整、报错排查到后期在自己项目里集成 RTKLIB 核心代码的完整流程捋一遍。适合正在读测绘、导航、大地测量相关专业的学生也适合刚接触 GNSS 定位开发、想在 Windows 下跑通一套后处理或实时定位程序的工程师。如果你之前试过下载 RTKLIB 源码却卡在 VS 那一堆红叉叉上那这篇内容基本就是为你写的。1. 先搞清楚RTKLIB的底细1.1 RTKLIB是什么能做什么RTKLIB 本质上是一套用 C 语言写的 GNSS 定位算法库附带一堆可直接运行的工具程序。它的核心能力集中在几个方向标准单点定位SPP利用伪距观测值和广播星历做单点定位精度在米级。差分定位DGPS/DGNSS用基准站和流动站的观测数据做差分消除大部分大气误差和卫星钟差精度到亚米级甚至分米级。实时动态定位RTK利用载波相位观测值通过整周模糊度解算实现厘米级定位。这是 RTKLIB 最核心、也是用得最多的功能。精密单点定位PPP利用精密星历和精密钟差产品单站即可实现分米级到厘米级的绝对定位。RTKLIB 同时支持实时定位和后处理定位两条路线。实时路线里程序可以直接从串口、TCP/IP 网络端口读取接收机输出的 RTCM 或 NTRIP 数据流也可以从 IGS 等机构拉取差分改正信息后处理路线里则是直接读取 RINEX 格式的观测文件和星历文件解算完再把结果输出成标准格式。从工程角度看RTKLIB 的核心价值在于它把 GNSS 定位的整套保姆级算法都给你写好了包括卫星轨道计算、钟差估计、电离层对流层改正、模糊度固定、卡尔曼滤波、周跳探测这些环节。你不需要从零推导也不需要自己造轮子而是可以直接站在它的肩膀上做二次开发。1.2 为什么选择在VS上配置RTKLIB很多人会问RTKLIB 在 Linux 下用 CMake gcc 编译不是挺顺的吗为什么非要折腾 VS。坦白说我自己一开始也是 Linux 党但后来发现 Windows VS 这条路有几个不可替代的优点调试体验好VS 的断点、变量监视、调用堆栈、内存窗口对于理解 RTKLIB 里那些复杂的数据结构和算法流程来说比 gdb 友好太多。特别是想搞懂卡尔曼滤波那一堆矩阵运算时能直接在 Watch 窗口里展开每个矩阵的元素学习效率完全不一样。跟业务系统融合容易很多 GNSS 应用项目的外围代码都是 C# 或者 C 写的 Windows 程序比如接收机监控软件、测量数据处理平台、定位服务后台。把 RTKLIB 解算模块做成一个 DLL 或者静态库集成进去是最常见的需求这一步在 Linux 上做没有意义。办公环境天然适配不是所有人的开发机器都是 Linux很多单位发的电脑就是 Windows装个 VS 就能干活不用折腾双系统或者虚拟机。更重要的是VS 的工程配置本身就带了很多跟 RTKLIB 编译有关的坑。工具链选对了才能编译出稳定可用的程序这一块经验光靠看 README 是学不来的。1.3 RTKLIB的源码结构要先看明白拿到 RTKLIB 源码包之后解压出来会看到几个核心目录这里建议提前花几分钟捋一遍后面操作起来才不至于迷路app应用程序层放的是一个个可以直接运行的工具源码。比如 rtkpost后处理解算 GUI、rtknavi实时解算 GUI、rtkplot解算结果绘图工具、rnx2rtkp命令行后处理解算工具、str2str数据流转换工具串口/TCP/文件之间互转、convbinRINEX 格式转换器。VS 里一个工程对应一个 app 子目录。src核心算法源码层rtklib.h 和 rtklib.c 这两个文件的大名你后面会非常熟悉所有定位解算的算法实现都在这整个 RTKLIB 的核心资产就是它。lib第三方库或者一些辅助库比如某些版本里会依赖的编译器自带的运行库、加密库等。data示例数据里面通常放着测试用的 RINEX 文件和配置文件验证环境是否跑通全靠它。doc说明文档包括 RTKLIB 手册和各个工具的使用说明。理解这个结构之后再看 VS 工程就会明白为什么解决方案文件放在 app 目录下以及为什么里面默认会包含十几个子工程。2. 环境准备与源码获取2.1 VS版本怎么选RTKLIB 的历史比较长不同年代的代码对应不同的编译器水平。经过我多次实测简单粗暴地给一个结论VS2015、VS2017、VS2019、VS2022 都能编译 RTKLIB 2.4.3 系列。其中 VS2019 和 VS2022 是目前最主流的选择使用体验和性能都是最好的。太老的版本比如 VS2008、VS2010编译新版本源码可能因为缺少 C99 特性支持而报错不太建议用了。太新的版本比如 VS2022在编译老版本 RTKLIB 的个别工程时可能遇到“_MBCS 已弃用”之类的提示但一般不影响最终编译结果可以通过配置属性里的“将警告视为错误”选项关掉相关检查。我个人推荐直接装 VS2022 Community 版免费功能全对 C 桌面开发的支持很完善。安装的时候记得勾选“使用 C 的桌面开发”工作负载否则连 C 编译器都没有后面一切无从谈起。2.2 源码从哪拿RTKLIB 目前的主要分发渠道有两个GitHub 仓库搜“RTKLIB”能找到官方仓库也就是 tomojitakasu/RTKLIB里面都是最新维护的代码。下载方式是 Clone 或直接 Download ZIP。RTKLIB 官网rtklib.com页面比较复古但可以下载到带完整文档和示例数据的稳定发布包。需要重点说明的是RTKLIB 在 GitHub 上存在多个分支和社区 fork我用下来比较常见的有两个方向标准版2.4.3 b34 及后续官方维护版代码稳定偏教学和研究适合想了解算法原理、做学术复现的人。demo5 分支由社区大佬维护的增强版支持了更多接收机型号的专有格式、更多的对流层模型、对 PPP 和模糊度固定做了大量优化。我自己实际做工程项目时用 demo5 版本更多毕竟功能更全、bug 修得更快。新手建议从官方标准版开始跑通了再考虑切换 demo5因为 demo5 的工程文件结构稍复杂一些直接上手容易在配置环节乱套。2.3 解压与目录规范源码下载下来后解压路径尽量不要带中文和特殊字符。比如放到D:\RTKLIB_Project\RTKLIB-master这种干净路径下。这听起来像废话但真的有人因为在路径里放了中文导致后面编译时 VS 报一堆奇奇怪怪的编码错误排查了半天才发现是路径惹的祸。解压完成后进入 app 目录会看到一个.sln文件。这个文件就是用 VS 打开的解决方案入口里面串联了 rtkpost、rtknavi、rnx2rtkp、str2str 等多个子工程。3. VS编译RTKLIB的完整实操3.1 打开解决方案并选择启动项目在 app 目录下找到.sln文件双击VS 会自动加载。加载过程中如果弹出“查看和查看潜在危险内容”之类的安全提示直接确认即可这是 VS 对第三方 C 项目的常规检查。解决方案加载完成后在“解决方案资源管理器”里能看到所有子工程。这里面有个很重要的概念解决方案是一组工程的集合但最终运行的时候你需要指定一个启动项目。启动项目就是你按 F5 调试或 CtrlF5 运行时实际执行的那个程序。我建议第一次跑通时把启动项目设置成rnx2rtkp。原因很简单rnx2rtkp 是一个纯命令行程序没有 GUI不需要连接串口和网络只要给它一个 RINEX 观测文件和一个星历文件它就能在屏幕上打印出一串定位结果。这是验证 RTKLIB 编译是否成功、算法链路是否完整的最短路径。设置方法在解决方案资源管理器里右键rnx2rtkp项目选择“设为启动项目”。然后在工具栏上的调试配置里把Debug改成Release把平台改成x64或者Win32看你自己的需求。3.2 编译前必改的工程属性RTKLIB 老版本代码有个历史遗留问题大量源文件是在多字节字符集环境下写的而 VS 的新项目默认用的是 Unicode 字符集。这就导致编译时会报一堆类型不匹配的错误最典型的就是char[]往TCHAR[]上传参时报错。解决办法也很直接我强烈建议在编译前就把所有需要编译的工程统一做以下设置右键项目选择“属性”。进入“配置属性” → “高级”把“字符集”从“使用 Unicode 字符集”改为“使用多字节字符集”。进入“配置属性” → “C/C” → “命令行”在“其他选项”里加上/utf-8这能有效避免中文注释导致的代码页警告C4819。把字符集改成多字节后再看那些报错你会发现整个世界都清净了。项目属性默认只对当前配置有效如果你后面切到 Release 或者 x64 平台需要把同样的设置再重复一遍或者直接用“配置管理器”里的“配置”下拉框选择“所有配置”一次性搞定所有编译配置。3.3 耐心处理编译期的报错RTKLIB 的源码质量整体很高但毕竟是跨平台项目Windows 下编译时偶尔会冒出来几个“坑”这些坑不是设计缺陷纯粹是平台差异导致的。下面把最常见的几个出场率最高的报错列出来报错一fatal error C1083 无法打开包含文件“sys/time.h”这是最典型的跨平台坑。sys/time.h是 POSIX 系统的头文件Windows 下根本不存在。RTKLIB 的开发者在写代码时原本用条件编译来隔离平台差异但部分老版本没处理好。解决办法在报错的那个.c文件顶部找到#ifdef WIN32之类的条件编译块看看是否存在对所有 POSIX 头文件的统一排除逻辑。更好的方式是全局搜索报错的这个头文件名把所有#include sys/time.h行都改用 RTKLIB 自带的rtklib.h里已经处理过的相关类型替换。有些版本其实已经通过定义宏或者增加#include rtklib.h解决了如果你拿到的是老版本需要手动调整。报错二LNK2019 无法解析的外部符号这个通常跟某个依赖库没有链接进来有关。RTKLIB 里 str2str 工程、rtknavi 工程有时会依赖额外的网络库或者串口库。解决办法是在项目属性的“链接器” → “输入” → “附加依赖项”里把ws2_32.lib、winmm.lib等 Windows 系统库手动加进去。如果还没解决去 error list 里双击那条 LNK2019VS 会跳转到引用该符号的源文件阵地在哪儿就补哪儿。报错三C4996 使用 strcpy、sprintf 等函数被弃用VS 对 C 标准库里的部分函数比如strcpy、sprintf默认会给出安全告警原因是这些函数存在缓冲区溢出风险。对这类告警我推荐直接忽略不用真的去替换成strcpy_s那些微软专用版本因为替换完还要改一堆参数太折腾了。操作项目属性 → C/C → 预处理器 → 预处理器定义添加_CRT_SECURE_NO_WARNINGS。这个宏一加整个世界瞬间安静。3.4 编译成功后的验证流程编译成功后按CtrlF5运行 rnx2rtkp。因为这个工具是命令行程序VS 会弹出一个控制台窗口窗口里会显示一行使用说明类似于usage: rnx2rtkp [options] file file [...]这说明程序已经正常跑起来了。接下来需要给它两个输入一个 RINEX 观测文件O 文件一个星历文件N 文件导航电文文件。RTKLIB 源码包自带的 data 目录下就有几组现成的示例数据。在控制台窗口无法直接输入参数所以我平时的做法是打开这个程序所在的输出目录然后在地址栏输入cmd回车打开命令行窗口手动敲命令rnx2rtkp -p 0 -m 15 ../data/07515620.15o ../data/auto7515.15n解释一下参数-p 0表示定位模式选单点定位-m 15表示高度截止角 15 度。如果把输出重定向到文件rnx2rtkp -p 0 -m 15 ../data/07515620.15o ../data/auto7515.15n result.pos跑完以后打开 result.pos能看到一组包含时间、经纬度、高程和 Q定位质量指示符的解算结果这说明整个 VS 环境配置已经彻底打通RTKLIB 的核心算法也开始正常出数了。4. 配置开发环境与源码集成4.1 把RTKLIB核心库装进自己的工程很多人的最终目的并不是跑那几个现成的 exe而是要把 RTKLIB 的解算能力嵌到自己的业务系统里。这时候需要在自己的工程里直接引用 src 目录下的核心代码。我推荐的做法是新建一个干净的解决方案在里面创建一个新的控制台应用项目或者类库项目然后把src/rtklib.h和src/rtklib.c这两个文件直接拉进工程源码目录里。没错RTKLIB 的核心算法是单文件实现的这意味着你把这两个文件一放核心定位能力就能平移到任何 C/C 工程里。但这里有个关键点要提醒src 目录下还有一些辅助的源文件比如rtkcmn.c、rtkpos.c、ppp.c等。实际编译时rtklib.c会通过内部声明引用一部分函数而其他文件则是把相关的功能模块化。如果只放一个 rtklib.c 进去编译能过但很多跟 RTK 和 PPP 相关的功能都不能用。所以稳妥的做法是最小工程里包含 src 下所有必须的.c文件然后把包含目录指向 src 文件夹。4.2 工程属性里的几个“生死攸关”的参数在这一步你大概率会遇到链接错误或者运行不稳定基本都出在下面几个配置上运行库选择项目属性 → C/C → 代码生成 → 运行库。如果是 Release 模式建议选择“多线程 (/MT)”而不是“多线程 DLL (/MD)”。原因在于 /MT 会把 C 运行库静态链接进程序发布时不需要目标机器额外装 VC 运行库兼容性更好。RTKLIB 这类算法库体积不大静态链接不会让最终程序膨胀多少。预处理器定义在 3.3 节加过的_CRT_SECURE_NO_WARNINGS要确保在所有配置下都存在。做二次开发还会用到定义ENAGLO、ENACMP这些宏来启用特定系统的算法。比如你的项目针对北斗做了不少定制那就要确保对应的卫星系统支持被打开。附加包含目录项目属性 → C/C → 常规 → 附加包含目录把 src 目录地址填进去。有些工程还会用到 lib 目录下的东西这里的包含路径也得补。4.3 实际调试RTKLIB代码的姿势环境跑通之后强烈建议利用 VS 的调试能力把 RTKLIB 的算法流程从头到尾走一遍。这一步对你的帮助远大于会按几个按钮跑出坐标结果。打开rtklib.c或者rtkpos.c按下 F9 在pntpos()这个函数入口处下断点然后 F5 启动调试再用 rnx2rtkp 跑一组示例数据。程序会在断点处停住这时候你可以在“局部变量”窗口里看到观测值结构体obs的全部内容包括卫星编号、伪距、载波相位、多普勒、信噪比等。按 F11 单步跟踪你能亲眼看到伪距从卫星到接收机的传播路径被一层层改正先是卫星钟差然后是对流层延迟、电离层延迟、相对论效应再到最小二乘定位解算出位置。这些在书本上看一百遍都似懂非懂的知识在 VS 的调试窗口里走一遍脉络基本就通了。再说一个很有用的点VS 的“并行监视”和“即时窗口”可以动态查看卡尔曼滤波里状态协方差矩阵的变化趋势这对理解模糊度收敛过程非常有帮助。我在学习 RTKLIB 的成熟期基本就靠这些功能啃下了 PPP 和 RTK 的大部分核心逻辑。5. 编译运行常见问题与排查5.1 编译阶段的典型错误速查表编译流程中遇到的报错我整理成了一张速查表按出现频率从高到低排序基本能覆盖 90% 的场景。报错信息出现原因解决办法C4819 警告或 C2001 常量中有换行符源码编码跟编译器字符集不匹配中文注释乱码给所有项目统一加/utf-8编译选项fatal error C1083: Cannot open include file: sys/time.h跨平台代码引入了 POSIX 头文件手动把该头文件包含替换成 Windows 兼容写法或升级到新版 RTKLIBC4996: strcpy was declared deprecatedVS 安全告警预处理器定义里添加_CRT_SECURE_NO_WARNINGSLNK2019: unresolved external symbol缺少依赖库或函数没有匹配到在附加依赖项补ws2_32.lib、winmm.lib或者检查是不是只放了一个 .c 文件error C2872: UINT不明确的符号源码里的 typedef 跟 Windows SDK 冲突找到冲突处改成::UINT或者直接删掉 typedefD8016: /ZI and /O2 command-line options are incompatible调试信息选项跟优化冲突在项目属性的 C/C → 优化里改成“已禁用 (/Od)”或把调试格式从“程序数据库”改成“无”5.2 运行时易踩的坑配置文件与路径编译过了、程序能跑离真正干活还有一段距离。运行时遇到的坑十有八九出在配置文件和数据上。坑一rtknavi 打开后没有定位结果rtknavi 是实时定位 GUI启动后需要配置输入源。如果你没有配置串口或者 NTRIP 源程序界面就一直显示“等待接收数据”感觉像卡死了一样。这其实不是 bug而是没给数据。处理方法是先确认你的接收机型号和输出格式然后按 F1 打开配置设置正确的串口号、波特率、数据格式再把“RTCM 3”之类的协议选项选对。坑二命令行工具闪退很多人在 Windows 下直接双击rnx2rtkp.exe结果窗口一闪就消失了。这是因为这个程序需要命令行参数才能干活没有参数就会打印 usage 然后退出。解决办法是用 cmd 进入目录再运行或者写一个批处理文件把命令固化下来。坑三跑出来的坐标差得很远环境没问题、程序也跑了但结果跟已知坐标差了上百米这时候优先检查是不是星历文件不匹配。RINEX 观测文件的日期跟导航电文文件的日期必须一致否则算法算出来就是天差地别。另外检查高度截止角太高了会丢掉太多低仰角卫星导致解算几何强度不够。5.3 我踩过的那些坑单独拿出来说说最后分享几个我用 VS 折腾 RTKLIB 时印象最深的经验这些细节容易让人绕远路但一旦知道之后就再也不想踩第二次。经验一README 和你用的分支要匹配。如果你下载的是 demo5 分支就一定不要再对着标准版的文档操作。比如演示数据、编译选项、某些新增参数两个分支之间差异很大。我见过有人拿着标准版的手册去配置 demo5 的 rtkpost结果发现软件界面上多了一堆手册里完全没有的选项一下子就蒙了。这时候最靠谱的办法是看 demo5 自带的 doc 目录下的专属文档。经验二不要一开始就开 /O2 优化。新手调试 RTKLIB 的时候如果默认选的是 Release 最大速度优化那在调试时会发现变量的值“不可读”或者出现奇怪的结果因为优化器把变量加载顺序都打乱了。建议调试阶段无条件用 Debug 模式也不要碰优化开关。等整个链路跑通了再切换 Release测试没问题再放出去。经验三弄懂 RTKLIB 的时间系统很重要。这个不算 VS 配置的坑但属于编译之后注定要碰的硬骨头。RTKLIB 内部用的是 GPS 周和秒计数转成 UTC 或者北京时间需要额外调用函数。很多人刚开始写自己的业务程序时直接把 RTKLIB 输出的时间当 UTC 用结果小工具没问题一跨周就出 bug。利用 VS 的断点体现一次时间转换的全过程对理解这一点有很大帮助。经验四善用 str2str 来模拟数据。如果你手上暂时没有实时的接收机串口数据可以用 str2str 读一个 RINEX 文件然后以 TCP 服务器模式输出再用 rtknavi 以 TCP 客户端方式连它。这样整套实时定位链路就能在没有硬件的情况下完成闭环调试。这个技巧在 VS 环境下非常好用也是我推荐任何新手一定要尝试一遍的场景。写在最后把 VS 下的 RTKLIB 环境真正跑通看起来只是安装了 IDE、按了 F6、认了几个报错但它带来的价值远不止于此。它意味着你可以随时单步调试 GNSS 定位算法看每一颗卫星的观测值怎么参与计算意味着你可以把 RTKLIB 的核心库集成进自己的定位服务里从“调包侠”变成能对定位精度负责的人。我个人实际体会是亲手在 VS 里把 RTKLIB 从源码编译到出结果比单纯下载一个现成的 RTKLIB 程序要扎实得多因为中间遇到的每个报错、每个边界条件都会逼着你去查文档、读代码去理解 GNSS 定位的基础逻辑。如果看完这篇内容你也打算把源码下载下来试一试那别犹豫直接动手。遇到坑就在命令行后面加个-v看看详细输出或者直接在 VS 里断点单步许多问题需要你自己撞一次才能真正摸透。
返回列表