1 準備知識
rtklib中相對定位部分使用擴展卡爾曼濾波實現。所以,要真正搞懂rtklib中載波相位差分定位的部分,最好先看一下kalman濾波的知識(當然點開這篇文章,想必對GNSS領域的domain knowledge是已經很熟悉的了_)。不需要很精通,以筆者10幾年斷斷續續卡爾曼濾波相關的工作經驗來看,我覺得卡爾曼濾波最好能理解以下內容
:
- 會應用卡爾曼濾波五公式解決基本問題
- 感性的認識到卡爾曼濾波的本質其實是模型與量測的加權
- 能知道什麼是時間更新,什麼是量測更新
- 給定狀態與量測能自己建立模型,即求A陣和C陣(有的書上叫F陣和 H 陣)
關於最後這一點,其實每個行業或者業務領域需要的domain knowledge千差萬別,有些很簡單比如估計個溫度,電量等等,稍微複雜一點的比如本篇文章中的ekf,當然這個複雜是相對的,其與組合導航領域的數據融合來說真是小巫見大巫了。
2 狀態向量與觀測向量的選取
卡爾曼濾波中第一步也是最重要的便是選擇狀態向量和觀測向量。只要這兩組向量確定出來了,那麼卡爾曼濾波模型就“基本”確定了。
2.1 狀態向量
量測向量x的定義如下:
x=[rr,vr,B1,B2,B5]
其中,rr,vr分別爲三維位置向量和速度向量。Bi是m維單差模糊度,m是觀測到的衛星個數。即:
Bi=[Brb,i1,Brb,i2,...,Brb,im]
使用單差模糊度是爲了規避曆元間參考衛星可能改變的問題。
2.2 量測向量
量測向量y的定義如下:
y=[ϕ1,ϕ2,ϕ5,P1,P2,P5]
其中,ϕi,Pi分別爲雙差載波相位和雙差僞距。
3 定義卡爾曼濾波模型
3.1 時間更新模型
以下爲運動學方程,比較簡單,就是位置是上一時刻的位置加速度乘以時間間隔,速度認爲不變,單差模糊度恆定不變。
rr(k+1)=rr(k)+vr(k)∗dt
vr(k+1)=vr(k)
Bi(k+1)=Bi(k)
其中dt爲曆元間隔,通過以上關係我們很容易得到狀態轉移矩陣A
A=⎣⎡I3,303,303m,3I3,3∗dtI3,303m,303,3m03,3mI3m,3m⎦⎤
從上面的結果可以看出A是一個常值矩陣,這個是很不錯的,這不僅省去了線性化的工作。更有意思的是如果量測矩陣也是一個常值矩陣,那麼這個系統就是一個線性定常系統,對於線性定常系統卡爾曼濾波的增益矩陣(通常記爲K陣)無需在線計算,可以提前計算出來,系統中直接應用即可。
線性定常系統的K陣最後收斂爲一個常值矩陣,不熟悉卡爾曼濾波的可以通過卡爾曼濾波五公式自己體會。
3.2 量測更新模型
量測模型略複雜,從下邊的式子可以容易看出是非線性的,所以系統並不是線性定常系統。
ϕrbjk=ρrbjk+λ(Brbj−Brbk)
Prbjk=ρrbjk
若記y=h(x),則我們需要求解h的雅克比矩陣。
觀測模型可以通過matlab或者python的sympy推導出來,以下以四顆衛星爲例給出結果。
⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡(rx−xs1)2+(ry−ys1)2+(rz−zs1)2rx−xs1−(rx−xs2)2+(ry−ys2)2+(rz−zs2)2rx−xs2(rx−xs1)2+(ry−ys1)2+(rz−zs1)2rx−xs1−(rx−xs3)2+(ry−ys3)2+(rz−zs3)2rx−xs3(rx−xs1)2+(ry−ys1)2+(rz−zs1)2rx−xs1−(rx−xs4)2+(ry−ys4)2+(rz−zs4)2rx−xs4(rx−xs1)2+(ry−ys1)2+(rz−zs1)2rx−xs1−(rx−xs2)2+(ry−ys2)2+(rz−zs2)2rx−xs2(rx−xs1)2+(ry−ys1)2+(rz−zs1)2rx−xs1−(rx−xs3)2+(ry−ys3)2+(rz−zs3)2rx−xs3(rx−xs1)2+(ry−ys1)2+(rz−zs1)2rx−xs1−(rx−xs4)2+(ry−ys4)2+(rz−zs4)2rx−xs4(rx−xs1)2+(ry−ys1)2+(rz−zs1)2rx−xs1−(rx−xs2)2+(ry−ys2)2+(rz−zs2)2rx−xs2(rx−xs1)2+(ry−ys1)2+(rz−zs1)2rx−xs1−(rx−xs3)2+(ry−ys3)2+(rz−zs3)2rx−xs3(rx−xs1)2+(ry−ys1)2+(rz−zs1)2rx−xs1−(rx−xs4)2+(ry−ys4)2+(rz−zs4)2rx−xs4(rx−xs1)2+(ry−ys1)2+(rz−zs1)2rx−xs1−(rx−xs2)2+(ry−ys2)2+(rz−zs2)2rx−xs2(rx−xs1)2+(ry−ys1)2+(rz−zs1)2rx−xs1−(rx−xs3)2+(ry−ys3)2+(rz−zs3)2rx−xs3(rx−xs1)2+(ry−ys1)2+(rz−zs1)2rx−xs1−(rx−xs4)2+(ry−ys4)2+(rz−zs4)2rx−xs4(rx−xs1)2+(ry−ys1)2+(rz−zs1)2rx−xs1−(rx−xs2)2+(ry−ys2)2+(rz−zs2)2rx−xs2(rx−xs1)2+(ry−ys1)2+(rz−zs1)2rx−xs1−(rx−xs3)2+(ry−ys3)2+(rz−zs3)2rx−xs3(rx−xs1)2+(ry−ys1)2+(rz−zs1)2rx−xs1−(rx−xs4)2+(ry−ys4)2+(rz−zs4)2rx−xs4(rx−xs1)2+(ry−ys1)2+(rz−zs1)2rx−xs1−(rx−xs2)2+(ry−ys2)2+(rz−zs2)2rx−xs2(rx−xs1)2+(ry−ys1)2+(rz−zs1)2rx−xs1−(rx−xs3)2+(ry−ys3)2+(rz−zs3)2rx−xs3(rx−xs1)2+(ry−ys1)2+(rz−zs1)2rx−xs1−(rx−xs4)2+(ry−ys4)2+(rz−zs4)2rx−xs4(rx−xs1)2+(ry−ys1)2+(rz−zs1)2ry−ys1−(rx−xs2)2+(ry−ys2)2+(rz−zs2)2ry−ys2(rx−xs1)2+(ry−ys1)2+(rz−zs1)2ry−ys1−(rx−xs3)2+(ry−ys3)2+(rz−zs3)2ry−ys3(rx−xs1)2+(ry−ys1)2+(rz−zs1)2ry−ys1−(rx−xs4)2+(ry−ys4)2+(rz−zs4)2ry−ys4(rx−xs1)2+(ry−ys1)2+(rz−zs1)2ry−ys1−(rx−xs2)2+(ry−ys2)2+(rz−zs2)2ry−ys2(rx−xs1)2+(ry−ys1)2+(rz−zs1)2ry−ys1−(rx−xs3)2+(ry−ys3)2+(rz−zs3)2ry−ys3(rx−xs1)2+(ry−ys1)2+(rz−zs1)2ry−ys1−(rx−xs4)2+(ry−ys4)2+(rz−zs4)2ry−ys4(rx−xs1)2+(ry−ys1)2+(rz−zs1)2ry−ys1−(rx−xs2)2+(ry−ys2)2+(rz−zs2)2ry−ys2(rx−xs1)2+(ry−ys1)2+(rz−zs1)2ry−ys1−(rx−xs3)2+(ry−ys3)2+(rz−zs3)2ry−ys3(rx−xs1)2+(ry−ys1)2+(rz−zs1)2ry−ys1−(rx−xs4)2+(ry−ys4)2+(rz−zs4)2ry−ys4(rx−xs1)2+(ry−ys1)2+(rz−zs1)2ry−ys1−(rx−xs2)2+(ry−ys2)2+(rz−zs2)2ry−ys2(rx−xs1)2+(ry−ys1)2+(rz−zs1)2ry−ys1−(rx−xs3)2+(ry−ys3)2+(rz−zs3)2ry−ys3(rx−xs1)2+(ry−ys1)2+(rz−zs1)2ry−ys1−(rx−xs4)2+(ry−ys4)2+(rz−zs4)2ry−ys4(rx−xs1)2+(ry−ys1)2+(rz−zs1)2ry−ys1−(rx−xs2)2+(ry−ys2)2+(rz−zs2)2ry−ys2(rx−xs1)2+(ry−ys1)2+(rz−zs1)2ry−ys1−(rx−xs3)2+(ry−ys3)2+(rz−zs3)2ry−ys3(rx−xs1)2+(ry−ys1)2+(rz−zs1)2ry−ys1−(rx−xs4)2+(ry−ys4)2+(rz−zs4)2ry−ys4(rx−xs1)2+(ry−ys1)2+(rz−zs1)2ry−ys1−(rx−xs2)2+(ry−ys2)2+(rz−zs2)2ry−ys2(rx−xs1)2+(ry−ys1)2+(rz−zs1)2ry−ys1−(rx−xs3)2+(ry−ys3)2+(rz−zs3)2ry−ys3(rx−xs1)2+(ry−ys1)2+(rz−zs1)2ry−ys1−(rx−xs4)2+(ry−ys4)2+(rz−zs4)2ry−ys4(rx−xs1)2+(ry−ys1)2+(rz−zs1)2rz−zs1−(rx−xs2)2+(ry−ys2)2+(rz−zs2)2rz−zs2(rx−xs1)2+(ry−ys1)2+(rz−zs1)2rz−zs1−(rx−xs3)2+(ry−ys3)2+(rz−zs3)2rz−zs3(rx−xs1)2+(ry−ys1)2+(rz−zs1)2rz−zs1−(rx−xs4)2+(ry−ys4)2+(rz−zs4)2rz−zs4(rx−xs1)2+(ry−ys1)2+(rz−zs1)2rz−zs1−(rx−xs2)2+(ry−ys2)2+(rz−zs2)2rz−zs2(rx−xs1)2+(ry−ys1)2+(rz−zs1)2rz−zs1−(rx−xs3)2+(ry−ys3)2+(rz−zs3)2rz−zs3(rx−xs1)2+(ry−ys1)2+(rz−zs1)2rz−zs1−(rx−xs4)2+(ry−ys4)2+(rz−zs4)2rz−zs4(rx−xs1)2+(ry−ys1)2+(rz−zs1)2rz−zs1−(rx−xs2)2+(ry−ys2)2+(rz−zs2)2rz−zs2(rx−xs1)2+(ry−ys1)2+(rz−zs1)2rz−zs1−(rx−xs3)2+(ry−ys3)2+(rz−zs3)2rz−zs3(rx−xs1)2+(ry−ys1)2+(rz−zs1)2rz−zs1−(rx−xs4)2+(ry−ys4)2+(rz−zs4)2rz−zs4(rx−xs1)2+(ry−ys1)2+(rz−zs1)2rz−zs1−(rx−xs2)2+(ry−ys2)2+(rz−zs2)2rz−zs2(rx−xs1)2+(ry−ys1)2+(rz−zs1)2rz−zs1−(rx−xs3)2+(ry−ys3)2+(rz−zs3)2rz−zs3(rx−xs1)2+(ry−ys1)2+(rz−zs1)2rz−zs1−(rx−xs4)2+(ry−ys4)2+(rz−zs4)2rz−zs4(rx−xs1)2+(ry−ys1)2+(rz−zs1)2rz−zs1−(rx−xs2)2+(ry−ys2)2+(rz−zs2)2rz−zs2(rx−xs1)2+(ry−ys1)2+(rz−zs1)2rz−zs1−(rx−xs3)2+(ry−ys3)2+(rz−zs3)2rz−zs3(rx−xs1)2+(ry−ys1)2+(rz−zs1)2rz−zs1−(rx−xs4)2+(ry−ys4)2+(rz−zs4)2rz−zs4(rx−xs1)2+(ry−ys1)2+(rz−zs1)2rz−zs1−(rx−xs2)2+(ry−ys2)2+(rz−zs2)2rz−zs2(rx−xs1)2+(ry−ys1)2+(rz−zs1)2rz−zs1−(rx−xs3)2+(ry−ys3)2+(rz−zs3)2rz−zs3(rx−xs1)2+(ry−ys1)2+(rz−zs1)2rz−zs1−(rx−xs4)2+(ry−ys4)2+(rz−zs4)2rz−zs4000000000000000000000000000000000000000000000000000000l1l1l1000000000000000−l1000000000000000000−l1000000000000000000−l1000000000000000000l2l2l2000000000000000−l2000000000000000000−l2000000000000000000−l2000000000000000000l5l5l5000000000000000−l5000000000000000000−l5000000000000000000−l5000000000⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤
可以抽象成以下形式,
C=
⎣⎢⎢⎢⎢⎢⎢⎡−DE−DE−DE−DE−DE−DE000000λ1D000000λ2D000000λ5D000⎦⎥⎥⎥⎥⎥⎥⎤
其中,
D=
⎣⎢⎢⎡11...1−10...00−1...0............00...−1⎦⎥⎥⎤
4 小結
到此,想必您對rtkpos的關鍵算法已經“很”瞭解了,當然其中還有很多細節,比如共視星選取,周跳探測,不同動態模型下的F陣或者A陣選取,Q陣和R陣的確定,整週模糊度的確定算法等,這些細節將會接下來結合代碼詳細講解。