以 RTKLIB 與 RTCM SSR 訊息進行 real time PPP
這算是我論文的一部份,之前教授就說他想試, 我也糊里糊塗沒仔細評估就答應了,還好真的做的出來。 過程不難,但我自己耍蠢撞牆居多。 關鍵有幾個點:要用 rtkexplore 版本的 rtklib , RTCM 要選 products.igs-ip.net,天線要用雙頻。
無關技術的事情起緣
之前教授不知哪裡看到 real time ppp 的消息, 認為 rt-ppp 是未來的潮流, 知道現在 igs 之類的組織有在網路上提供 即時精密星曆 , 只要有網路就可以收,用接收儀做 即時精密單點定位 。
他主要是參考 rtkexplorer 的 rt ppp 文章, 就要我試試看,用平價的接收儀如 u-blox 的 f9p 晶片, 和行動網路或 wifi 接星曆做 rt-ppp。
他聯絡了另一個有 u-blox 長期使用、開發經驗的教授林修國, 要我去請教可行性之類的。 那時候我還搞不太清楚要幹麻, 想說應該一定做的起來,就沒有很認真參考。 事後想想那時就應該要拒絕,因為林修國那時是說他幾年前做過, 但他印像中 rtklib 接網路星曆的 rt-ppp 還不能直接用,要自己改 code。
這時候我就應該要拒絕了,因為我根本沒有改 code 的能力。 結果那時不知道是鬼遮眼,還是敷衍上級的老毛病又犯了, 回去後還是和教授說沒問題,可以買 f9p 了。 事後想想真是有驚無險,還好做出來了。
技術
教授買的是和 raspberry pi 接好的 f9p 晶片,和一顆雙頻的天線。
pi 開機後可以從 /dev/serial0
讀寫 f9p 的訊息,
pi 本身沒有電池,可以從 micro usb 接電源,
所以接上手機用的行動電源就可以使用。
主要流程我也是參考 rtkexplorer 的 rt ppp 文章 。
ublox 晶片連結
ublox 的 f9p 晶片是用 serial port 連到 pi 上,
windows 叫 com1,unix 則是會位在 /dev/serial0
。
(數字可能改變。)
實際上 serial0 是個指到 /dev/ttyS0
的符號連結,
總之可以動。
serial0 在 linux 下表現為 character special device,
但我一直不知道怎麼和這類裝置互動。
寫入就直接 echo foo >/dev/serial0
即可,
但讀取好像不能直接 cat /dev/serial0
?
cat 一下就讀取完就退出了,但我是需要不斷讀取他的輸出,
把他當成像標準輸入一樣的 stream 來讀。
str2str
還好 rtklib 可以直接處理這種細節, 提供了一個叫 str2str 的程式, 可以用來把一個 stream 轉到多個 stream 甚至轉存成檔案。 所以就把 serial 轉成 tcp stream 來處理; 也同時存成檔案,也就是 ubx 格式的原始記錄檔。
str2str -in serial://serial0:115200 \
-out tcpsvr://:5566 \
-out file:///home/pi/test.ubx
一個 str2str 可以從一個 stream 讀取,輸出到多個輸出。
這個指令可以把 /dev/serial0
以 115200 baud 讀取,
並在 localhost 5566 port 輸出,
並存成 /home/pi/test.ubx
的檔案。
rtklib 風格的 url 不用寫 /dev/
,直接寫裝置名稱即可,
大概是從 windows 來的習慣;
windows 下 com port 就直接叫 com1,也沒有所謂的完整路徑。
對 baud rate 我還是不太懂,要怎麼知道裝置的 baud rate, 我看之前測試的人留在 pi 裡面的設定檔才知道的。 如果不設的話,str2str 似乎會自己測?我看也是測對。
輸出除了tcpsvr,
也可以是tcpcli。
如果是 server,就是可以有多個 client 連上去讀取,
像用 nc localhost 5566
讀取;
如果是 client,就是會主動連到該 ip port 輸出資料,
類似 http post 到某一個 port 的概念。
重播用的 timetag
後來我發現,rtklib 有一個 重播 功能,
把串流存到檔案後,可以再從檔案串流出來,供事後反覆解算。
但這個功能除了原始串流資料,
還需要什麼時間串流了多少資料的時間資料。
要啟用這功能,在 rtklib 或 str2str 中的
file://
路徑結尾加上 ::T
即可,
例如 file://ublox-f9p.ubx::T
。
rtklib 用雙冒號當作參數的語法。
(怎麼不是用 querystring 的風格?)
如果在儲存時加上 T 選項,除了原始檔案,
還會多儲存一個 *.*.tag
的 timetag 檔案來記錄時間戳。
(像 ublox-f9p.ubx
和 ublox-f9p.ubx.tag
)
在讀取時如果加上 T 選項,就會照 timetag 檔案裡記錄的時間重播。
如果不用 T 選項,基本上就無法正確的重播; rtklib 只會以最快速度一次把所有資料讀完, 而不同格式的檔案間也無法配合。 所以可能星曆讀到一半,但觀測量已經讀完了, 讀取到的時間點沒重疊,無法一起解算。
很可惜的是明明多數觀測量都已經有時間戳了, 但卻還是要額外記錄一個 timetag 檔案才能正確重播。 有想過自己寫一支程式讀觀測量產生 timetag 檔案, 但後來發現超出我的能力,幾乎看不懂 rtklib 的原始碼,就放棄了。 別人已經寫好就乖乖照他的框架走就好了。
時間戳的格式
麻煩的是時間戳還有二種格式, 似乎和 c 語言中的時間戳資料結構大小有關。 在 raspberry pi 中是 4 byte, 在一般 64 bit PC 是 8 byte。
在讀取時可以用 ::P=4
或 ::P=8
來指定,
在存儲時 P 選項好像沒有用,不能更改。
而且更麻煩的是一支 rtkrcv 程序在讀取二個檔案時,
不能指定不同格式的時間戳;
得要開二支 str2str 以不同大小讀取串流,
到 tcp 上就沒有時間戳問題了。
這個選項沒有寫在手冊裡, 我去翻 原始碼才在註解裡 找到的……。 不過原始碼還是超出我能力範圍,無法修改。
時間的同步
如果在腳本中,那數支 str2str 是在不同行命令中執行, 雖然 shell 不是很快的語言,約有數十 ms 等級的時差, 但對 gnss 的速度來說算是同步的。
但如果很不幸二份檔案是在不同時間開始記錄的,
那就需要讓二者播放時能 同步 。
可以用 ::+60
的選項來快轉 60 秒。
另外 rtkrcv 中如果讀取來源是有 timetag 的檔案,
就會自動將二者同步。
如果是 str2str,則需要手動算出誤差秒數來同步。
要算同步秒數,可以在 rtkrcv console 中, 用 observ 命令來看到目前的觀測量的時間, 用 ssr 可以看到星曆的時間。 rtk 的話,二者都會顯示在 observ 裡。
ser2net
str2str 是只能單向讀取 serial 輸出到其它串流, 但 serial 是雙向的,有時需要 config 晶片, 就會需要寫入資料。
ublox 提供的 u-center 程式就是用來連結晶片, 讀取、設定晶片的程式。 u-center 是在 windows 上執行的程式, 我用 wine 跑是沒問題的。 但我不可能在 pi 上跑 wine 再跑 u-center, 所以我 google 到一支 ser2net 的 linux 程式, 可以把 serial 轉到 tcp 連線,且可以供讀寫。 u-center 除了直接連 serial,也可以連轉成 tcp 的 serial。 所以問題就解決了。
u-center 設定
u-center 可以設定 f9p 要輸出哪些訊息。 receiver > connection 裡可以選要用 com port (serial) 或 tcp 連, 連上後在 view > configuration view 裡可以改設定。
f9p 本身可以進行基本的基於電碼的定位, 可以直接以 nmea 輸出定位結果座標、衛星顆數。 也可以讀取 rtcm 後進行 rtk 定位, 但這部份怎麼設定就沒研究了。
在 configuration view 的 MSG 分類下, 可以設定在哪些 port 要輸出哪些訊息, 我看得到有 i2c uart1 uart2 usb spi 五個 port。 serial 應該是 uart1 或 uart2,所以我都開了。 如果 f9p 是用 usb 連 pi,那可能要改成開 usb。 i2c 和 spi 就不知道了。
- F0-00 NMEA GxGGA: nmea 的 gngga 訊息,直接是定位座標,
- F0-03 NMEA GxGSV: nmea 的 gngsv 訊息,衛星顆數。
- 其它訊息自行參考 nmea 標準 。
- 02-14 RXM-RAWX: 全星系的電碼與相位觀測量, 用來輸出 rinex 的 observation 檔所需。
- 02-13 RXM-SFRBX: 全星系的星曆觀測量,收廣播星曆所需。
- 沒有 X 的似乎是單一 GPS 星系的?
至少要開 rawx 和 sfrbx 才會輸出 gnss 觀測量, 方能以 rtklib 或其它程式定位。
nmea 的訊息開了之後,u-center 上的 儀表板 才看得到東西。 如果 nmea 有開,nmea 訊息會夾在 serial 輸出的二進位訊息裡, 但不會影響 ubx 二位進格式的解析。 只是檔案會變大,如果開 gngsv 的話會很大。
設定的方式是選好訊息後,在要輸出的 port 上打勾, 然後按視窗左下角的 send 按鈕,即會將設定發送到晶片上。 如果要永久保存設定,要切到 CFG, 選 save current configuration ,並選擇對應的裝置; 我選了 BBR 和 FLASH,這二個應該至少有一個是持久的, 詳細可能要讀手冊。
rtklib 版本
我本來是直接 clone rtklib github 上的 master branch, 在 raspberry pi 上編譯命令列版本的程式:
git clone https://github.com/tomojitakasu/RTKLIB rtklib.git
cd rtklib.git/app
sh makeall.sh
sudo find -type f -executable -exec install '{}' /usr/local/bin \;
但後來發現都解不出來,收下來的資料都只有單頻。 (而我選了雙頻,所以解不出來。) 後來發現 2.4.2 2.4.3 版的 rtklib, 用 convbin 轉出來的資料都只有 L1 波段, 也就是說這二版的 rtklib 都不支援 ublox 的 L2 波段資料。 我試 teqc 也是一樣的結果。
後來找到 rtkexplorer 談 f9p ppp 的文章 , 才看到 他釋出的支援 ublox f9p 的 rtklib 版本 。 因為他只有提供 windows 的執行檔, 而且 pi 不是 x64 要另外編譯,就直接 clone 他的 github 原始碼自己編譯。
git clone https://github.com/rtklibexplorer/RTKLIB rtklib-explorer.git
cd rtklib-explorer.git/app
make -j4 # 四核心編譯
sudo make install # 預設裝到 /usr/local/bin
之後 convbin 轉出來的就有 L2 了, 預設也從 rinex 2.11 變成 3.03。 也就代表 rtkrcv 程式可以解析 ublox 雙頻訊號。
雙頻天線問題
後來發現天線也有分雙頻單頻。 之前有從教授拿到一個單頻的 skytraq 接收儀, 有附一個小小的磁鐵天線,可以黏在車頂。 在宿舍頂樓測試時,因為 ublox 的天線接口在底部, 不能直接放在地上,所以想先用小天線頂著用; 結果收到的就只有單頻訊號。
rtcm ntrip 與 ssr 訊息
igs 即時精密星曆除了 15 分鐘發布一次的檔案外, 也有用 ntrip 協議發送。 ntrip 是 rtcm 協議在 http 上運行的版本, rtcm 則是用來傳輸 gnss 訊號的協議。 我印象中 rtcm2 只能用來傳輸 rtk 需要的差分訊號, 而 rtcm3 中定義了 ssr 訊息, 用來表示即時精密星曆。
我有找到一篇文章有提供 rtcm 訊息的意義 , rtkrcv 會顯示收到的訊息, 還有 ntrip source table 也會顯示該 mount point 提供哪些格式訊息, 可以用來粗略判斷運作正不正常。
要收 igs 的 ntrip 協議需要註冊 , 在連接時提供使用者名稱和密碼。 註冊時可以選要申請 igs 或 euref 的, 這個服務似乎很多國家或組織都有提供。
以 igs 來說,在 http://www.igs-ip.net/home 有說明,
而 http://www.igs-ip.net/ 則有以 ntrip 格式提供的
資源列表,
每行是一比記錄,其中以分號分隔不同欄位。
其中以 STR 開頭的記錄是一比可以用 ntrip 連上的站。
例如 STR;NIUM00NIU0;...
,
就表示 www.igs-ip.net 有收集 NIUMOONIUO 站的 ntrip 資料,
可以透過 www.igs-ip.net/NIUMOONIUO
取得 niumooniuo 的資料。
(NIUMOONIUO 稱為 www.igs-ip.net 的一個 mount point。)
igs 下有
http://www.igs-ip.net/
http://mgex.igs-ip.net/
http://products.igs-ip.net/
三個 server。
www 上可以串流所有所有 igs 收集的 gnss 測站資料,
mgex 不知道,
而 products 就是依收集的所有 ntrip 資料,
計算出精密星曆並提供 ssr 訊息的 server。
可以透過 products.igs-ip.net/CLK93
取得即時精密星曆訊息。
ntrip 是以基礎的 http basic authentication 登入, 所以用 http 其實蠻危險的,密碼會以明碼傳送, 雖然多數 server 也提供在 https 上的 ntrip, 但目前 str2str 還不支援 https。 所以建議用 wget 或 curl 代理,再交給 str2str。
wget --user-agent 'NTRIP RTKLIB (wget)' --output-document - \
https://username:password@products.igs-ip.net/CLK93 \
| str2str -out tcpsvr://:5567
curl --user-agent 'NTRIP RTKLIB (curl)' \
https://username:password@products.igs-ip.net/CLK93 \
| str2str -out tcpsvr://:5567
- ntrip server 如果 http 的 user agent 標頭不以
NTRIP
開頭, 就只會吐 http 403 forbidden 錯誤。 - str2str 如果沒有指定
-in
選項,就會從 stdin 讀取, 上面的腳本就是讓 curl 或 wget 把 ntrip 的 rtcm 輸出, 用管道傳到 str2str 的 stdin。 - ntrip 就是 http,所以除了開頭的登入用的 http header, 基本上是單向的協議,就是單方面不停的送二進位資料。 (所以也沒有 content-length 標頭。)
rtkrcv 執行細節
因為我是 raspberry pi,所以是用命令列版本的 rtkrcv 定位, 就寫設定檔後執行,沒有 gui。
我在執行上因為需要比較 rtklib 和後處理的定位結果, 要把 ublox 的原始數據也存成檔案, 所以是用 str2str 從 serial 讀取, 一邊在 tcp 上送給 rtkrcv,另一邊則存成檔案。 ntrip 也可以比照辦理。
執行腳本
igs ntrip 的帳號密碼則寫在檔案 login
裡,
內容就一行帳號密碼,用冒號隔開,
像 username:password
。
有個小問題是 rtkexplorer 版本的 rtkrcv,
-s
選項似乎不能自動執行。
預設 rtkrcv 是只會開啟一個終端,
可以開在 tcp port、指定的 terminal device 或 shell 所在的 tty 上,
要在終端中輸入 start 命令才會開始定位。
所以我加了個 nc 指令,
用來自動連進去後輸入 start 命令。
tcp console 下面的設定檔裡設密碼,
如果手動設為空就可以不用打密碼;
但不設的話會會用預設密碼 admin
。
執行後可以在其它 shell telnet localhost 5564
連進 rtkrcv 的介面,
原本的 shell 則會顯示 str2str 的狀況。
如果要結束,就在原本的 shell 按 ctrl-C,
或直接 kill 掉一開始執行時顯示的 pid。
rtkrcv 的終端中,exit 指令是指離開終端, 要結束 rtkrcv 則是要用 shutdown 指令, 或是直接 kill rtkrcv 程序。 但如果執行時不指定 port 或 terminal device, 就會直接把終端開在現在的終端上, 那就會無法 exit,(否則 exit 了就無法再連上終端了。) 要退出只能直接 shutdown。
#!/bin/sh
ntrip_igs_login=`cat login`
# port
port_real_time_ppp_console=5564 # igs ntrip real time ppp console
port_ublox=5566 # ublox raw observation
port_igs_ssr_rtcm=5567 # igs real time clock orbit
# log=$(date -Is)-run.log
# exec 1>$log 2>&1
echo script pid $$
time_stamp=`date -Is`
str2str -in serial://serial0 \
-out tcpsvr://:$port_ublox \
-out file://$PWD/$time_stamp.ubx &
pid_ublox=$!
curl --user-agent 'NTRIP RTKLIB (curl)' \
https://$ntrip_igs_login@products.igs-ip.net/CLK93 \
| str2str -out tcpsvr://:$port_igs_ssr_rtcm &
pid_ntrip=$!
rtkrcv -o igs-ntrip.conf -p $port_real_time_ppp_console &
pid_ppp=$!
nc -Ct localhost $port_real_time_ppp_console <<CONSOLE
start
exit
CONSOLE
on_exit() {
echo exiting
kill $pid_ublox $pid_ntrip $pid_ppp
mv igs-ntrip.pos $time_stamp.ppp.pos
mv single-dual-frequency.pos
trap - EXIT # prevent calling exit again after term int hup
}
trap on_exit EXIT TERM INT HUP
wait
str2str 從 serial 讀取的 bug
碰到一個問題,用 str2str 把 serial 傳到 tcp 再傳到 rtkrcv 後,收到的資料很多是錯的。 原因大概是單一一支 str2str 程序, 如果同時要讀取 serial、寫入檔案、傳送到 tcp,負擔會太大。 雖然儲存的檔案會是正確的,但 tcp 上會缺資料。 我猜是因為 serial baud 設太高,cpu 來不及, 但也不確定 baud 和 str2str 內部的程式有沒有關係, 我太廢 str2str 的原始碼基本看不懂。
解決方法是啟動二支 str2str 程式, 一支只負責讀 serial 送到 stdout, 另一支再負責儲存到檔案和送到 tcp。
str2str -in serial://serial0#ubx \
| str2str -out file://ublox-f9p.ubx::T \
-out tcpsvr://:5566
只用一支 str2str 同時讀取 serial 並儲存時, 存的 timetag 會變很大,幾乎比原始觀測量還大, 我猜可能是讀取頻率很高,所以要記錄很多次時間戳。 如果用二支 str2str 管道並在第二支 str2str 存, timetag 就比較正常,大小變原始檔的十分之一左右。
選項 logstr 儲存觀測量
原本我是啟動 str2str 和 rtkrcv,
才能同時把資料用來定位也儲存到檔案。
後來發現 rtkrcv 有一個 logstr 選項,
語法就和 str2str 的 -out
一樣,
可以直接把 inpstr 收到資料再轉發出去,
可以直接存成檔案,也可以用 tcp 再傳出去。
但之前用 str2str 讀 serial 同時存檔和 tcp 廣播就很吃力, 如果要用單一支 rtkrcv 做,因為還要定位,可能會更吃力。
之前有一次要在二個站收 network rtk, 本來就直接要了二組 egnss 帳號來連。 後來想到,其實可以只用一個帳號, 然後二個站距離很近,都和同一個 egnss 訊號差分就可以了。 就可以用 logstr 把收到訊號送出去給另一台機器。
network rtk 除了收資料,
還需要把測站所在的大略位置,
用 nmea 格式放在 ntrip 請求的 body 送給伺服器,以內插虛擬觀測量。
(對,就是有 body 的 http get。)
雖然用 str2str -p
選項也可以,
但要先知道大略座標比較麻煩。
如果用 rtkrcv 的話,直接在設定檔裡設
inpstr2-nmeareq=single
ant2-postype=rtcm
,
就會把 sps (single) 的定位結果用 nmea 傳到伺服器,
並把 rtcm 訊息中的座標當基站座標。
kill 終止 str2str 的問題
如果要終止 str2str,直接用 $!
和 kill 即可;
但如果 str2str 還串了管道和一堆有的沒的,
要一次終止就比較麻煩;
可能只能一次終止整個 process group。
詳細可以參考 下一篇專門談終止子程序的文章 。
重播時的時間戳來源
之前提過可以重播記錄的檔案,但在重播 rtcm 時有個問題, rtklib 似乎會解析某些資料的時間戳, 有些則不會,會直接拿現在時間。
我碰到的問題是我的 ublox 資料是 P=4 的, 但 rtcm 是 P=8 的,所以不能二個都在設定檔裡讀。 我就把 ublox 和 rtcm 都改用 str2str 播到 tcp, 然後在 rtkrcv 裡從 tcp 讀。 結果 tcp 讀進來的 ublox 時間是觀測時間, 但 rtcm 讀進來的則變成現在,造成二個不同步。 可能因為 ublox 帶時間戳,而 rtcm 沒有; 或是 rtkrcv 直接假定從 tcp 讀 rtcm 是即時。
總之這個麻煩的問題,我後來是分開讀取來源。
rtcm 直接用 file://ublox-f9p.ubx::T
從檔案讀,就會帶正確的時間戳了;
ublox 則用另一支 str2str 串到 tcp 讀,
觀測量自帶時間戳所以沒問題。
只是這樣要算時差,手動在 str2str 加上去;
而且要用命令一次執行,不能一行一行打,時差會跑掉。
str2str -in file://ublox-f9p.ubx::T::+3600::x300 \
-out tcpsvr://:5567 1>/dev/null 2>&1 &
rtkrcv -o post.conf -s
rtkrcv 自動開始只在終端機連結時啟動
rtkrcv 預設 rtkrcv 只會開啟終端介面,
要在介面裡下 start 命令才會開始讀取資料定位。
所以有設計一個 -s
選項,帶選項的話相當於自動輸入 start 命令。
問題是 s 選項的行為是在開啟終端時會自動執行 start,
如果結合另一個 -p
選項把終端開在 tcp 上,
就不會開啟預設開在 shell tty 上的終端了,
也就要等到有人用 telnet 連到 tcp 上的終端時,
才會 自動開始 定位。
於是就有人在 github issue 上報了這個 自動啟動選項
並不是真的自動啟動的詭異 issue 。
然後建議也五花八門,什麼在腳本內用 python 連進去後送出 start 命令;
我則是直接改原始碼,強制用 stdio 開一個假終端,
在假終端中執行 start 命令。
然後也有人給出另一個比較簡單的解法,
用 -d
選項指定一個終端,這樣就能自動開啟了;
如果沒有終端裝置能指定,指定在 /dev/null
也能自動執行。
設定檔
從 rtkexplorer 的文章 裡改來的。
pos1-posmode
看要設ppp-kine
或ppp-static
都可以。用 ssr ppp 的話,
pos1-sateph
要設成brdc+ssrarp
或brdc+ssrcom
,據文章說法, 二個好像差在對 GNSS 衛星的中心的定位不同? 一個是天線中心、一個是質心。因為在腳本裡用 str2str 把 ublox 和 ntrip 都接到 tcp 上了, 所以輸入都是 tcp。
igs08.atx
是 rtklib 提供的 igs 濾定的天線參數, 網路上可以載到。
# RTKNAVI options (2020/02/09 rtkexplorer/rtklib demo5 gholk)
pos1-posmode =ppp-static # (0:single,1:dgps,2:kinematic,3:static,4:movingbase,5:fixed,6:ppp-kine,7:ppp-static,8:ppp-fixed)
pos1-frequency =l1+l2 # (1:l1,2:l1+l2,3:l1+l2+l5,4:l1+l5)
pos1-soltype =forward # (0:forward,1:backward,2:combined)
pos1-elmask =15 # (deg)
pos1-snrmask_r =off # (0:off,1:on)
pos1-snrmask_b =off # (0:off,1:on)
pos1-snrmask_L1 =0,0,0,0,0,0,0,0,0
pos1-snrmask_L2 =0,0,0,0,0,0,0,0,0
pos1-snrmask_L5 =0,0,0,0,0,0,0,0,0
pos1-dynamics =off # (0:off,1:on)
pos1-tidecorr =off # (0:off,1:on,2:otl)
## important ############################################
pos1-ionoopt =dual-freq # (0:off,1:brdc,2:sbas,3:dual-freq,4:est-stec,5:ionex-tec,6:qzs-brdc,7:qzs-lex,8:stec)
pos1-tropopt =est-ztd # (0:off,1:saas,2:sbas,3:est-ztd,4:est-ztdgrad,5:ztd)
pos1-sateph =brdc+ssrapc # (0:brdc,1:precise,2:brdc+sbas,3:brdc+ssrapc,4:brdc+ssrcom)
pos1-posopt1 =off # (0:off,1:on)
pos1-posopt2 =off # (0:off,1:on)
pos1-posopt3 =off # (0:off,1:on,2:precise)
pos1-posopt4 =off # (0:off,1:on)
pos1-posopt5 =off # (0:off,1:on)
pos1-posopt6 =off # (0:off,1:on)
pos1-exclsats = # (prn ...)
pos1-navsys =1 # (1:gps+2:sbas+4:glo+8:gal+16:qzs+32:comp)
pos2-armode =continuous # (0:off,1:continuous,2:instantaneous,3:fix-and-hold)
pos2-gloarmode =off # (0:off,1:on,2:autocal)
pos2-bdsarmode =off # (0:off,1:on)
pos2-arthres =3
pos2-arthres1 =0.9999
pos2-arthres2 =0.25
pos2-arthres3 =0.1
pos2-arthres4 =0.05
pos2-arlockcnt =0
pos2-arelmask =0 # (deg)
pos2-arminfix =10
pos2-armaxiter =1
pos2-elmaskhold =0 # (deg)
pos2-aroutcnt =5
pos2-maxage =30 # (s)
pos2-syncsol =off # (0:off,1:on)
pos2-slipthres =0.05 # (m)
pos2-rejionno =30 # (m)
pos2-rejgdop =30
pos2-niter =1
pos2-baselen =0 # (m)
pos2-basesig =0 # (m)
out-solformat =llh # (0:llh,1:xyz,2:enu,3:nmea)
out-outhead =off # (0:off,1:on)
out-outopt =off # (0:off,1:on)
out-outvel =off # (0:off,1:on)
out-timesys =gpst # (0:gpst,1:utc,2:jst)
out-timeform =hms # (0:tow,1:hms)
out-timendec =3
out-degform =deg # (0:deg,1:dms)
out-fieldsep =
out-outsingle =off # (0:off,1:on)
out-maxsolstd =0 # (m)
out-height =ellipsoidal # (0:ellipsoidal,1:geodetic)
out-geoid =internal # (0:internal,1:egm96,2:egm08_2.5,3:egm08_1,4:gsi2000)
out-solstatic =all # (0:all,1:single)
out-nmeaintv1 =0 # (s)
out-nmeaintv2 =0 # (s)
out-outstat =off # (0:off,1:state,2:residual)
stats-eratio1 =100
stats-eratio2 =100
stats-errphase =0.003 # (m)
stats-errphaseel =0.003 # (m)
stats-errphasebl =0 # (m/10km)
stats-errdoppler =1 # (Hz)
stats-stdbias =30 # (m)
stats-stdiono =0.03 # (m)
stats-stdtrop =0.3 # (m)
stats-prnaccelh =10 # (m/s^2)
stats-prnaccelv =10 # (m/s^2)
stats-prnbias =0.0001 # (m)
stats-prniono =0.001 # (m)
stats-prntrop =0.0001 # (m)
stats-prnpos =0 # (m)
stats-clkstab =5e-12 # (s/s)
ant1-postype =llh # (0:llh,1:xyz,2:single,3:posfile,4:rinexhead,5:rtcm,6:raw)
ant1-pos1 =90 # (deg|m)
ant1-pos2 =0 # (deg|m)
ant1-pos3 =-6335367.62849036 # (m|m)
ant1-anttype =
ant1-antdele =0 # (m)
ant1-antdeln =0 # (m)
ant1-antdelu =0 # (m)
ant2-postype =llh # (0:llh,1:xyz,2:single,3:posfile,4:rinexhead,5:rtcm,6:raw)
ant2-pos1 =90 # (deg|m)
ant2-pos2 =0 # (deg|m)
ant2-pos3 =-6335367.62849036 # (m|m)
ant2-anttype =
ant2-antdele =0 # (m)
ant2-antdeln =0 # (m)
ant2-antdelu =0 # (m)
ant2-maxaveep =3600
ant2-initrst =on # (0:off,1:on)
misc-timeinterp =off # (0:off,1:on)
misc-sbasatsel =0 # (0:all)
misc-rnxopt1 =
misc-rnxopt2 =
misc-pppopt =
## important ############################################
file-satantfile =igs08.atx
file-rcvantfile =igs08.atx
file-staposfile =
file-geoidfile =
file-ionofile =
file-dcbfile =
file-eopfile =
file-blqfile =
## important ############################################
# set empty password
console-passwd =
file-tempdir =/tmp
file-geexefile =
file-solstatfile =
file-tracefile =
## important ############################################
inpstr1-type =tcpcli # (0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,7:ntripcli,8:ftp,9:http)
inpstr2-type =tcpcli # (0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,7:ntripcli,8:ftp,9:http)
inpstr3-type =off # (0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,7:ntripcli,8:ftp,9:http)
inpstr1-path =localhost:5566
inpstr2-path =localhost:5567
inpstr3-path =
inpstr1-format =ubx # (0:rtcm2,1:rtcm3,2:oem4,3:oem3,4:ubx,5:ss2,6:hemis,7:skytraq,8:gw10,9:javad,10:nvs,11:binex,12:rt17,13:sbf,14:cmr,17:sp3)
inpstr2-format =rtcm3 # (0:rtcm2,1:rtcm3,2:oem4,3:oem3,4:ubx,5:ss2,6:hemis,7:skytraq,8:gw10,9:javad,10:nvs,11:binex,12:rt17,13:sbf,14:cmr,17:sp3)
inpstr3-format =rtcm2 # (0:rtcm2,1:rtcm3,2:oem4,3:oem3,4:ubx,5:ss2,6:hemis,7:skytraq,8:gw10,9:javad,10:nvs,11:binex,12:rt17,13:sbf,14:cmr,17:sp3)
inpstr2-nmeareq =off # (0:off,1:latlon,2:single)
inpstr2-nmealat =0 # (deg)
inpstr2-nmealon =0 # (deg)
outstr1-type =file # (0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,6:ntripsvr)
outstr2-type =off #tcpsvr # (0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,6:ntripsvr)
## important ############################################
outstr1-path =igs-ntrip.pos
outstr2-path =
outstr1-format =llh # (0:llh,1:xyz,2:enu,3:nmea)
outstr2-format =llh # (0:llh,1:xyz,2:enu,3:nmea)
logstr1-type =off # (0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,6:ntripsvr)
logstr2-type =off # (0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,6:ntripsvr)
logstr3-type =off # (0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,6:ntripsvr)
logstr1-path =
logstr2-path =
logstr3-path =
misc-svrcycle =10 # (ms)
misc-timeout =10000 # (ms)
misc-reconnect =10000 # (ms)
misc-nmeacycle =5000 # (ms)
misc-buffsize =32768 # (bytes)
misc-navmsgsel =all # (0:all,1:rover,2:base,3:corr)
misc-proxyaddr =
misc-fswapmargin =30 # (s)