VS2012编译RTKLIB——GNSS定位开源库

       

         RTKLIB开源库有着强大的GPS数据实时和后处理功能,由于笔者的毕业设计中需要对GPS载波相位观测量进行RTK解算,故而,对RTKLIB开源库进行了学习与研究。

RTKLIB提供了很多底层的函数,笔者准备直接对源码进行编译输出标准DLL的方式供C#调用。所用的VS平台是VS2012(其它VS版本类似),RTKLIB库用的是网上使用的最多,相对稳定的rtklib_2.4.2版本编译的项目采用“相对路径”,即工程可移植到任何地方,方便以后使用。

GNSS标准&精密定位开源程序包 rtklib_2.4.2 下载

目前(2018.6.21)RTKLIB开源库最新版本:rtklib_2.4.3 官网最新版本下载

也可直接参考笔者编译好的RTKLIB VS2012工程 下载 

一、RTKLIB简介

        RTKLIB是全球导航卫星系统GNSS(global navigation satellite system)的标准&精密定位开源程序包,RTKLIB由日本东京海洋大学(Tokyo Universityof Marine Science and Technology)的高须知二(Tomoji Takasu)开发。RTKLIB由一个便携式程序库和多个AP(应用程序)工具库组成。

RTKLIB的主要功能有:

1)支持多个GNSS系统的标准和精密定位算法,包括GPSGLONASSBeidouGalileoQZSSSBAS

2)支持多种GNSS实时和后处理定位模式:单点定位、DGPS/DGNSS,动态RTK、静态RTK、移动基站、PPP

3)支持多种GNSS标准格式和协议:RINEX2.10RINEX2.11RINEX2.12RINEX3.00RINEX3.01RINEX3.02RTCM2.3RTCM3.1RTCM3.2BINEXNTRIPNMEA0183SP3ANTEX1.4IONEX1.0NGS PCVEMS 2.0

4)支持多种GNSS接收机专有数据协议格式:NovAtel:OEM4/V/6OEM3, OEMStarSuperstar II HemisphereCrescentublox:LEA-4T/5T/6TSkyTraqJAVAD GW10-II/IIINVS

5)支持外部通信:SerialTCP/IPNTRIP、本地日志文件(记录和播发)FTP/HTTP

6)提供许多函数库和APIapplication program interfaces):卫星和导航系统函数、矩阵和向量函数,时间和字符串函数、坐标的转换,输入和输出函数、调试跟踪函数、平台依赖函数、定位模型、大气模型、天线模型、地球潮汐模型、大地水准面模型、基准转换、RINEX函数、星历和时钟函数、精密星历和时钟、接收机原始数据函数、RTCM函数,解算函数、谷歌地球KML转换、SBAS函数、选项(option)函数、流数据输入和输出函数、整周模糊度解算、标准定位、精密定位、后处理定位(解算)、流服务器函数、RTK服务器函数、下载函数。


二、基于VSRTKLIB编译

1.新建工程。首先,我们在VS2012下先新建一个win32的dll项目(空项目)



Win32应用程序设置如下:



2. 复制库文件。把在github上下载的rtklib2.4.2里的所有文件夹及文件复制到刚刚建立的RTKLIB工程项目文件所在目录下,如图




RTKLIB开源库(RTKLIB开源库是用C++Builder建立的工程,与VS不同)下文件目录结构及各文件夹功能:

\app-- APs构建环境         \bin--可执行二进制APs和windows链接库

\data-- APs样本数据         \doc--文档文件                       

\lib --库生成环境               \src--RTKLIB库的源程序                

\test--测试程序和数据        \util-- 实用程序工具                    

然后我们删掉的RTKLIB工程目录下的两个文件(github开源项目的配置文件)

其实,由于我们现在只是为了编译这个开源库, RTKLIB开源库中除“src文件夹”其它的我们暂时都用不到,但为了保持库的完整性以及防止以后做工程会用的到,此处都留下了,做实际工程应用的话,可以删除其它用不到的文件夹。


3.添加库文件。为了与库文件结构保持一致,我们首先在“源文件”文件夹,右击—》添加—》新建筛选器,接下来先添加头文件(在src文件夹中,只有一个头文件:rtklib.h),

然后是源文件—》添加—》现有项(添加除rtklib.h所有源文件,)“rcv”子文件夹中添加“src/rcv”目录下的所有源文件,添加完成之后,如图:



4.初步编译。“解决方案管资源理器”下,右击“RTKLIB”项目—》生成,进行编译。因为RTKLIB是在C++ Builder编译器下写的,但是我们现在用VS进行编译,会出现一堆的错误,现在我们就一个个来解决。



5. 错误类型1:error C4996: 'strncpy': This function or variable may beunsafe. Consider using strncpy_s instead. To disable deprecation, use_CRT_SECURE_NO_WARNINGS. See online help for details.     

解决:这是由于函数安全性问题,编译器已经给出建议,添加预编译指令【_CRT_SECURE_NO_WARNINGS】。我们打开调试下的项目属性,然后在 配置属性 -> C/C++ -> 预处理器 -> 预处理器定义 -> 编辑。在下面添加上【_CRT_SECURE_NO_WARNINGS】


看到网上有人编译的时候提示类似上面的另一错误,解决方法也类似,同样在预处理器定义-> 编辑。在下面添加上【_WINSOCK_DEPRECATED_NO_WARNINGS

笔者这里并没有出现,不过为了以防万一,也在“预处理器定义”中添加上此宏。



接下来,我们再次Build工程,继续解决下一错误。


6. 错误类型2: error C2466: 不能分配常量大小为 0 的数组        


解决:这个主要是编译器的问题,用g++就没有问题,在vc中定义数组,需要一个常量值。

我们双击此错误,在有问题的数组定义处,按F12,看到数组大小定义的确实是0


同样的,我们像上面一样在“预处理器定义”里面加入【ENAGLO】

接下来,我们再次Build工程,继续解决下一错误。


7. 错误类型3:error C1083: 无法打开包括文件:rtklib.h: No such file ordirectory    

解决:这是因为rcv里的文件找不到rtklib.h这个头文件。我们继续在项目属性里,在配置属性-> C/C++ 常规-> 附加包含目录-> 编辑 。在上面添加rtklib.h的相对路径使用相对路径,工程才可以移植到任何地方,否则,换个目录路径,还是会提示此错误)在项目里的src找到rtklib.h并查看它的绝对路径

要想设置相对路径,我们首先要了解.< \与..\的区别> 

.\     表示项目文件所在目录之下的目录。                   

..\     表示项目文件所在目录向上一级目录下的目录。        

..\..\   表示项目文件所在目录向上二级目录之下的目录。       

都是针对项目文件所在目录而言,用于定位其它文件的路径位置。

因此,在“附加包含目录”下,添加:【.\src】




接下来,我们再次Build工程,继续解决下一错误。


8. 错误类型4:error C2099: 初始值设定项不是常量        

解决:我们双击此错误,定位到如下代码段


初始值设定项不是常量,这是因为c编译器不支持函数外动态声明变量和分配空间,如果要必须是常量值(在数学中,0/0这种形式一般称之为不定式。 [1]  因为计算0/0就是求出一个数,使之与0相乘结果仍得0,显然,其结果可以等于任何数。 [2] 0/0”型的函数极限的结果也没有一般的规律。)故此,我们把这条语句变量定义的初值初始化为【=0.0】

接下来,我们再次Build工程,继续解决下一错误。


9. 错误类型5:error C4703: 使用了可能未初始化的本地指针变量“sbs  

解决:我们双击此错误,定位到如下代码段,做如下修改




接下来,我们再次Build工程,编译后发现又蹦出来20个莫名的错误。


10. 错误类型6:error LNK2019: 无法解析的外部符号 _showmsg,该符号在函数 _convrnx 中被引用   

解决:一查showmsg这个函数如果在DLL中需要自己定义,rtklib里面已经做好了处理需要在预处理器里面加入【DLL】即可,我们找到之前预处理器定义处,在下面添加【DLL】,再找到项目属性,在配置属性 -> 链接器 -> 输入 -> 附加依赖项里添加 【winmm.lib】和 【ws2_32.lib】


再次Build工程,没有错误,大功告成。




11.部分警告处理。大多数是什么类型转换上的Warning,暂时没有影响,暂不处理。



12.总结与补充。一般的“变量初始化”等错误,我们都能通过错误列表定位到代码段,进而解决,而添加宏定义、头文件包含路径,容易被开发者忽略。下面总结一下我们在此次编译RTKLIB开源库中,所做的添加宏定义、头文件包含路径等操作。

(1)C/C++下预处理器 里面我们添加了

配置属性 ->C/C++ -> 预处理器-> 预处理器定义-> 编辑

        _CRT_SECURE_NO_WARNINGS

        _WINSOCK_DEPRECATED_NO_WARNINGS

        ENAGLO

        DLL

 

(2)C/C++下的附加包含目录 里面我们添加了

配置属性 ->C/C++ 常规-> 附加包含目录-> 编辑

       .\src

(3)连接器下的附加依赖项 里面我们添加了

 (配置属性 -> 链接器 -> 输入 -> 附加依赖项

        winmm.lib

        ws2_32.lib

  

补充:

         通过上面的设置,我们可以发现,我们大多操作的是[C/C++]下的配置选项,而同样,在[VC++]配置选项下,

同样有[包含目录],作用几乎与[C/C++]下面的[附加包含目录]一样,我们首先了解【包含目录、库目录、附加包含目录、附加库目录、附加依赖项区别】

VC++目录:

    包含目录:寻找#include<xxxx.h>中的xxxx.h的搜索目录

    库目录:寻找.lib文件的搜索目录

C/C++:

    常规->附加包含目录:寻找#include<xxxx.h>中的xxxx.h的搜索目录(每一项对应一个文件夹XXXX,文件夹中包含了编译时所需的头文件,使用时直接#include<XXXX>即可)

链接器:

    常规->附加库目录:寻找.lib文件的搜索目录

    输入->附加依赖项:lib库(C++的库会把函数、类的声明放在*.h中,实现放在*.cpp或*.cc中。编译之后,*.cpp,*.cc,*.c会被打包成一个.lib文件,这样可以保护源代码)

故,包含目录和附加包含目录(库目录和附加库目录)的区别:

    包含目录:修改了系统的include宏的值,是全局的;

    附加包含目录:用于当前项目,对其他项目没有影响。

    (库目录和附加库目录的区别同上)

进而可知包含目录和附加包含目录(库目录和附加库目录)的区别主要在于全局还是当前,那么当需要对某工程添加这些目录时,通常情况下,都是在附加包含目录和附加库目录中添加的。

补充这些是因为,笔者刚开始编译RTKLIB库时,头文件的包含路径都是添加在[VC++/包含目录]下的,当时惊奇的发现,即使笔者一开始在[VC++/包含目录]下包含的是“绝对路径”,工程也是可以编译通过,并可以移植到任何地方的。但了解到以上以后,建议我们一般使用C/C++Linker下面的设置,而一般不建议使用VC++下面的设置。












猜你喜欢

转载自blog.csdn.net/WalterBrien/article/details/80754215