RTKLIB是全球導航衛星系統GNSS(global navigation satellite system)的標准&精密定位開源程序包,RTKLIB由日本東京海洋大學(Tokyo University of Marine Science and Technology)的高須知二(Tomoji Takasu)開發。RTKLIB由一個便攜式程序庫和多個AP(應用程序)工具庫組成。RTKLIB的主要功能有:
(1)支持多個GNSS系統的標准和精密定位算法,包括GPS,GLONASS,Beidou,Galileo,QZSS和SBAS
(2)支持多種GNSS實時和后處理定位模式:單點定位、DGPS/DGNSS,動態RTK、靜態RTK、移動基站、PPP
(3)支持多種GNSS標准格式和協議:RINEX2.10、RINEX2.11、RINEX2.12、RINEX3.00、RINEX3.01、RINEX3.02、RTCM2.3、RTCM3.1、RTCM3.2、BINEX、NTRIP、NMEA0183、SP3、ANTEX1.4、IONEX1.0、NGS PCV、EMS 2.0
(4)支持多種GNSS接收機專有數據協議格式:NovAtel:OEM4/V/6,OEM3, OEMStar、Superstar II、 Hemisphere、Crescent、u‐blox:LEA-4T/5T/6T、SkyTraq、JAVAD 、GW10-II/III和NVS
(5)支持外部通信:Serial、TCP/IP、NTRIP、本地日志文件(記錄和播發)和FTP/HTTP
(6)提供許多函數庫和API(application program interfaces):衛星和導航系統函數、矩陣和向量函數,時間和字符串函數、坐標的轉換,輸入和輸出函數、調試跟蹤函數、平台依賴函數、定位模型、大氣模型、天線模型、地球潮汐模型、大地水准面模型、基准轉換、RINEX函數、星歷和時鍾函數、精密星歷和時鍾、接收機原始數據函數、RTCM函數,解算函數、谷歌地球KML轉換、SBAS函數、選項(option)函數、流數據輸入和輸出函數、整周模糊度解算、標准定位、精密定位、后處理定位(解算)、流服務器函數、RTK服務器函數、下載函數。
2、基於VS的RTKLIB編譯
基於VS的RTKLIB的編譯范例在網絡上已經有較多的版本,比較成熟且切實有效的當屬博主【D10.天地弦(湖南桃江)】在博客園中發表的博客《VS2013使用rtklib中需要注意的一些問題(編譯)》,里面詳細闡述了利用VS2013編譯RTKLIB的過程及可能遇到的問題,筆者也采用了其部分編譯策略,初次編譯RTKLIB的朋友可以去參考。
當我們深入研究RTKLIB代碼后,會發現僅僅采用上述網友提供的問題解決方法仍不能完全解決RTKLIB編譯過程中的問題,需要我們進一步的研究,以下是筆者在實際應用過程中發現的一些問題,分享出來供大家參考。
(1)預編譯器定義的問題。
RTKLIB中為了適應不同的應用需求,定義了諸多的宏,常見的包括ENAGLO,ENACMP ,_CRT_SECURE_NO_WARNINGS,_WINSOCK_DEPRECATED_NO_WARNINGS等。這些預編譯器定義存在的根本目的是為了控制代碼編譯的走向,以確保功能的實現,為此我們需要詳細了解各個宏定義的存在的目的。例如,_CRT_SECURE_NO_WARNINGS存在的目的是確保strcmp等VS認為不安全的函數的有效執行。_WINSOCK_DEPRECATED_NO_WARNINGS存在的目的是確保通信sock函數的有效執行。ENAGLO,ENACMP,WIN_DLL,TRACE存在的目的是確保與GLONASS、與北斗、與windows動態庫編譯、與TRACE信息輸出相關的函數的有效執行。通過合理的預編譯器定義,我們可以得到不同功能的RTKLIB動態庫。
(2)附加依賴項的問題
在《VS2013使用rtklib中需要注意的一些問題(編譯)》博客中,作者為了規避"找不到error LNK2019: 無法解析的外部符號…"的問題,選擇了在添加附加庫[連接器->輸入->附加依賴庫]中添加winmm.lib, ws2_32.lib。雖然可以解決問題,但是不夠直觀,很容易被其他開發人員忽略。筆者認為直接在頭文件代碼中添加#pragma comment(lib, "winmm.lib")和#pragma comment(lib, "ws2_32.lib")更為直觀明了,一勞永逸。
在完成了RTKLIB動態庫編譯后,筆者利用動態庫構建了簡單的RTCM數據讀取的Demo。Demo程序讀取保存的實時RTCM觀測信息並輸出觀測值文件、導航文件以及TRACE日志信息。Demo代碼如下:
1 #include "rtklib.h" 2 int main() 3 { 4 char ifile[1024] = "C:xxx.rtcm"; 5 char ofile[9][1024] = { "", "", "", "", "", "", "", "" }; 6 char *pofile[9] = { "" }; 7 char tracefile[1024] = ""; 8 int format = STRFMT_RTCM3; 9 10 double ep_rtcm[6] = { 2017, 9, 4, 14, 00, 00 }; 11 gtime_t time_rtcm = epoch2time(ep_rtcm); 12 13 rnxopt_t opt = { 0 }; 14 opt.tint = 0.00; 15 opt.tunit = 86400; 16 opt.rnxver = 3.02; 17 opt.navsys = 37; 18 opt.obstype = OBSTYPE_ALL; 19 opt.freqtype = 0x03; 20 opt.scanobs = 1; 21 opt.outiono = 1; 22 opt.outtime = 1; 23 opt.trtcm = time_rtcm; 24 25 strcpy(ofile[0], ifile); 26 strcat(ofile[0], ".obs"); 27 28 strcpy(ofile[1], ifile); 29 strcat(ofile[1], ".nav"); 30 31 strcpy(tracefile, ifile); 32 strcat(tracefile, ".trace"); 33 traceopen(tracefile); 34 tracelevel(5); 35 for (int i = 0; i < 9; i++) { 36 pofile[i] = malloc(sizeof(char) * 1024); 37 memcpy(pofile[i], &ofile[i], 1024); 38 } 39 if (convrnx(format, &opt, ifile, pofile)) printf("\n數據轉換成功!\n"); 40 traceclose(); 41 getchar(); 42 return 0; 43 }
在調試Demo過程中,筆者發現RTKLIB庫仍存在兩個問題:
(1)添加TRACE預編譯器定義后,軟件運行到scan_obstype函數的trace(3,"scan_obstype: nf=%s, opt=%s\n",nf,opt)語句時會提示內存出錯,調試后發現該語句中nf的輸出類型出錯,應將"%s"更改為"%d",即trace(3,"scan_obstype: nf=%d, opt=%s\n",nf,opt)。這反映了RTKLIB原始編碼系統環境與VS IDE的差異,后續應用庫文件時需要多加注意。
(2)convrnx函數在執行完成退出動態庫回到主函數main時,Debug模式下會彈出"Run-Time Check Failure #2 - Stack around the variable 'opt_' was corrupted."異常。Release模式下不彈出該異常。網絡上關於該異常主體上認為時由於內存越界造成的,筆者暫未找出opt_變量越界的原因,后續會做深入研究。該異常的最快捷的解決方案時將"project->配置屬性->c/c++->代碼生成->基本運行時檢查"改為"默認值"即可。