KF-GINS学习笔记
KF-GINS一套基于扩展卡尔曼滤波的GNSS/INS组合导航算法代码,通过松耦合的方式将IMU和GNSS信息进行融合提高定位精度,并且可以在GNSS信号确实的情况下在短时间内提供可靠的定位。
IMU误差补偿
捷联惯性导航算法之前进行误差补偿,补偿当前估计的零偏和比例因子
误差模型:
δ
ω
i
b
b
=
b
g
+
d
i
a
g
(
s
g
)
ω
i
b
b
+
w
g
δ
f
i
b
b
=
b
a
+
d
i
a
g
(
s
a
)
f
i
b
b
+
w
a
\begin{aligned}\delta\boldsymbol{\omega}_{ib}^b&=\boldsymbol{b}_g+diag\left(\boldsymbol{s}_g\right)\boldsymbol{\omega}_{ib}^b+\boldsymbol{w}_g\\\delta\boldsymbol{f}_{ib}^b&=\boldsymbol{b}_a+diag\left(\boldsymbol{s}_a\right)\boldsymbol{f}_{ib}^b+\boldsymbol{w}_a\end{aligned}
δωibbδfibb=bg+diag(sg)ωibb+wg=ba+diag(sa)fibb+wa
误差补偿:
d
i
a
g
(
I
+
s
‾
g
)
−
1
(
ω
~
i
b
b
−
b
ˉ
g
)
=
ω
^
i
b
b
d
i
a
g
(
I
+
s
‾
a
)
−
1
(
f
~
i
b
b
−
b
ˉ
a
)
=
f
^
i
b
b
\begin{aligned}&diag\left(\boldsymbol{I}+\overline{\boldsymbol{s}}_g\right)^{-1}(\tilde{\boldsymbol{\omega}}_{ib}^b-\bar{\boldsymbol{b}}_g)=\hat{\boldsymbol{\omega}}_{ib}^b\\&diag\left(\boldsymbol{I}+\overline{\boldsymbol{s}}_a\right)^{-1}(\tilde{\boldsymbol{f}}_{ib}^b-\bar{\boldsymbol{b}}_a)=\hat{\boldsymbol{f}}_{ib}^b\end{aligned}
diag(I+sg)−1(ω~ibb−bˉg)=ω^ibbdiag(I+sa)−1(f~ibb−bˉa)=f^ibb
INS机械编排
通过IMU发布的信息和过去导航状态推算更新当前导航状态
已知: Δ v k , Δ θ k Δ v k − 1 , Δ θ k − 1 , v e b , k − 1 n , h k − 1 , φ k − 1 , λ k − 1 , q b k − 1 n k − 1 \Delta\boldsymbol{v}_k,\Delta\boldsymbol{\theta}_k\Delta\boldsymbol{v}_{k-1},\Delta\boldsymbol{\theta}_{k-1},\boldsymbol{v}_{eb,k-1}^n,h_{k-1},\varphi_{k-1},\lambda_{k-1},\boldsymbol{q}_{b_{k-1}}^{n_{k-1}} Δvk,ΔθkΔvk−1,Δθk−1,veb,k−1n,hk−1,φk−1,λk−1,qbk−1nk−1
求解: v e b , k n , h k , φ k , λ k , q b k n k \boldsymbol{v}_{eb,k}^n,h_k,\varphi_k,\lambda_k,\boldsymbol{q}_{b_k}^{n_k} veb,kn,hk,φk,λk,qbknk
速度更新
n
n
n系下速度微分方程(站在
n
n
n系角度观测到数值随时间的变换率):
d
v
d
t
∣
n
=
f
−
(
2
ω
i
e
+
ω
e
n
)
×
v
+
g
p
\left.\frac{d\boldsymbol{v}}{dt}\right|_n=\boldsymbol{f}-(2\boldsymbol{\omega}_{ie}+\boldsymbol{\omega}_{en})\times\boldsymbol{v}+\boldsymbol{g}_p
dtdv
n=f−(2ωie+ωen)×v+gp
将向量投影到
n
n
n系(即在n系的坐标值):
d
v
d
t
∣
n
n
=
f
n
−
(
2
ω
i
e
n
+
ω
e
n
n
)
×
v
n
+
g
p
n
=
C
b
n
f
b
−
(
2
ω
i
e
n
+
ω
e
n
n
)
×
v
n
+
g
p
n
\begin{aligned} \left.\frac{d\boldsymbol{v}}{dt}\right|_n^n& =\boldsymbol{f}^n-(2\boldsymbol{\omega}_{ie}^n+\boldsymbol{\omega}_{en}^n)\times\boldsymbol{v}^n+\boldsymbol{g}_p^n \\ &=\mathbf{C}_b^n\boldsymbol{f}^b-(2\boldsymbol{\omega}_{ie}^n+\boldsymbol{\omega}_{en}^n)\times\boldsymbol{v}^n+\boldsymbol{g}_p^n \end{aligned}
dtdv
nn=fn−(2ωien+ωenn)×vn+gpn=Cbnfb−(2ωien+ωenn)×vn+gpn
对其进行离散积分:
Δ
v
f
,
k
n
≡
∫
t
k
−
1
t
k
C
b
n
f
b
d
t
Δ
v
g
/
c
o
r
,
k
n
≡
∫
t
k
−
1
t
k
[
g
p
n
−
(
2
ω
i
e
n
+
ω
e
n
n
)
×
v
n
]
d
t
\begin{gathered}\Delta\boldsymbol{v}_{f,k}^n\equiv\int_{t_{k-1}}^{t_k}\mathbf{C}_b^n\boldsymbol{f}^bdt\\\Delta\boldsymbol{v}_{g/cor,k}^n\equiv\int_{t_{k-1}}^{t_k}\left[\boldsymbol{g}_p^n-(2\boldsymbol{\omega}_{ie}^n+\boldsymbol{\omega}_{en}^n)\times\boldsymbol{v}^n\right]dt\end{gathered}
Δvf,kn≡∫tk−1tkCbnfbdtΔvg/cor,kn≡∫tk−1tk[gpn−(2ωien+ωenn)×vn]dt
速度更新:
v
k
n
=
v
k
−
1
n
+
Δ
v
f
,
k
n
+
Δ
v
g
/
c
o
r
,
k
n
\boldsymbol{v}_k^n=\boldsymbol{v}_{k-1}^n+\Delta\boldsymbol{v}_{f,k}^n+\Delta\boldsymbol{v}_{g/cor,k}^n
vkn=vk−1n+Δvf,kn+Δvg/cor,kn
第二项为比力积分项,第三项为重力/科氏力积分项
对积分进行近似化处理(等效旋转矢量,双子样假设):
Δ
v
g
/
c
o
r
,
k
n
=
[
g
p
n
−
(
2
ω
i
e
n
+
ω
e
n
n
)
×
v
n
]
t
k
−
1
/
2
Δ
t
Δ
v
f
,
k
n
=
[
I
−
1
2
(
ζ
n
(
k
−
1
)
,
n
(
k
)
×
)
]
C
b
(
k
−
1
)
n
(
k
−
1
)
Δ
v
f
,
k
b
(
k
−
1
)
ζ
n
(
k
−
1
)
,
n
(
k
)
=
(
ω
i
e
+
ω
e
n
)
t
k
−
1
/
2
Δ
t
Δ
v
f
,
k
b
(
k
−
1
)
=
Δ
v
k
+
1
2
Δ
θ
k
×
Δ
v
k
+
1
12
(
Δ
θ
k
−
1
×
Δ
v
k
+
Δ
v
k
−
1
×
Δ
θ
k
)
\begin{gathered} \Delta\boldsymbol{v}_{g/cor,k}^n=\left[\boldsymbol{g}_p^n-(2\boldsymbol{\omega}_{ie}^n+\boldsymbol{\omega}_{en}^n)\times\boldsymbol{v}^n\right]_{t_{k-1/2}}\Delta t \\ \Delta\boldsymbol{v}_{f,k}^n=\left[\mathbf{I}-\frac12(\boldsymbol{\zeta}_{n(k-1),n(k)}\times)\right]\mathbf{C}_{b(k-1)}^{n(k-1)}\Delta\boldsymbol{v}_{f,k}^{b(k-1)} \\ \zeta_{n(k-1),n(k)}=\left(\boldsymbol{\omega}_{ie}+\boldsymbol{\omega}_{en}\right)_{t_{k-1/2}}\Delta t \\ \Delta\boldsymbol{v}_{f,k}^{b(k-1)}=\Delta\boldsymbol{v}_k+\frac12\Delta\boldsymbol{\theta}_k\times\Delta\boldsymbol{v}_k+\frac1{12}\left(\Delta\boldsymbol{\theta}_{k-1}\times\Delta\boldsymbol{v}_k+\Delta\boldsymbol{v}_{k-1}\times\Delta\boldsymbol{\theta}_k\right) \end{gathered}
Δvg/cor,kn=[gpn−(2ωien+ωenn)×vn]tk−1/2ΔtΔvf,kn=[I−21(ζn(k−1),n(k)×)]Cb(k−1)n(k−1)Δvf,kb(k−1)ζn(k−1),n(k)=(ωie+ωen)tk−1/2ΔtΔvf,kb(k−1)=Δvk+21Δθk×Δvk+121(Δθk−1×Δvk+Δvk−1×Δθk)
void INSMech::velUpdate(const PVA &pvapre, PVA &pvacur, const IMU &imupre, const IMU &imucur) {
Eigen::Vector3d d_vfb, d_vfn, d_vgn, gl, midvel, midpos;
Eigen::Vector3d temp1, temp2, temp3;
Eigen::Matrix3d cnn, I33 = Eigen::Matrix3d::Identity();
Eigen::Quaterniond qne, qee, qnn, qbb, q1, q2;
// 计算地理参数,子午圈半径和卯酉圈半径,地球自转角速度投影到n系, n系相对于e系转动角速度投影到n系,重力值
// calculate geographic parameters, Meridian and Mao unitary radii,
// earth rotational angular velocity projected to n-frame,
// rotational angular velocity of n-frame to e-frame projected to n-frame, and gravity
Eigen::Vector2d rmrn = Earth::meridianPrimeVerticalRadius(pvapre.pos(0));
Eigen::Vector3d wie_n, wen_n;
wie_n << WGS84_WIE * cos(pvapre.pos[0]), 0, -WGS84_WIE * sin(pvapre.pos[0]);
wen_n << pvapre.vel[1] / (rmrn[1] + pvapre.pos[2]), -pvapre.vel[0] / (rmrn[0] + pvapre.pos[2]),
-pvapre.vel[1] * tan(pvapre.pos[0]) / (rmrn[1] + pvapre.pos[2]);
double gravity = Earth::gravity(pvapre.pos);
// 旋转效应和双子样划桨效应
// rotational and sculling motion
temp1 = imucur.dtheta.cross(imucur.dvel) / 2;
temp2 = imupre.dtheta.cross(imucur.dvel) / 12;
temp3 = imupre.dvel.cross(imucur.dtheta) / 12;
// b系比力积分项
// velocity increment due to the specific force
d_vfb = imucur.dvel + temp1 + temp2 + temp3;
// 比力积分项投影到n系
// velocity increment dut to the specfic force projected to the n-frame
temp1 = (wie_n + wen_n) * imucur.dt / 2;
cnn = I33 - Rotation::skewSymmetric(temp1);
d_vfn = cnn * pvapre.att.cbn * d_vfb;
// 计算重力/哥式积分项
// velocity increment due to the gravity and Coriolis force
gl << 0, 0, gravity;
d_vgn = (gl - (2 * wie_n + wen_n).cross(pvapre.vel)) * imucur.dt;
// 得到中间时刻速度
// velocity at k-1/2
midvel = pvapre.vel + (d_vfn + d_vgn) / 2;
// 外推得到中间时刻位置
// position extrapolation to k-1/2
qnn = Rotation::rotvec2quaternion(temp1);
temp2 << 0, 0, -WGS84_WIE * imucur.dt / 2;
qee = Rotation::rotvec2quaternion(temp2);
qne = Earth::qne(pvapre.pos);
qne = qee * qne * qnn;
midpos[2] = pvapre.pos[2] - midvel[2] * imucur.dt / 2;
midpos = Earth::blh(qne, midpos[2]);
// 重新计算中间时刻的rmrn, wie_e, wen_n
// recompute rmrn, wie_n, and wen_n at k-1/2
rmrn = Earth::meridianPrimeVerticalRadius(midpos[0]);
wie_n << WGS84_WIE * cos(midpos[0]), 0, -WGS84_WIE * sin(midpos[0]);
wen_n << midvel[1] / (rmrn[1] + midpos[2]), -midvel[0] / (rmrn[0] + midpos[2]),
-midvel[1] * tan(midpos[0]) / (rmrn[1] + midpos[2]);
// 重新计算n系下平均比力积分项
// recompute d_vfn
temp3 = (wie_n + wen_n) * imucur.dt / 2;
cnn = I33 - Rotation::skewSymmetric(temp3);
d_vfn = cnn * pvapre.att.cbn * d_vfb;
// 重新计算重力、哥式积分项
// recompute d_vgn
gl << 0, 0, Earth::gravity(midpos);
d_vgn = (gl - (2 * wie_n + wen_n).cross(midvel)) * imucur.dt;
// 速度更新完成
// velocity update finish
pvacur.vel = pvapre.vel + d_vfn + d_vgn;
}
位置更新
大地坐标系下位置微分方程:
φ
˙
=
v
N
R
M
+
h
λ
˙
=
v
E
(
R
N
+
h
)
cos
φ
h
˙
=
−
v
D
\begin{gathered} \dot{\varphi}=\frac{v_{N}}{R_{M}+h} \\ \dot{\lambda}=\frac{v_{E}}{(R_{N}+h)\cos\varphi} \\ \dot{h}=-v_{D} \end{gathered}
φ˙=RM+hvNλ˙=(RN+h)cosφvEh˙=−vD
对积分进行近似化处理:
h
k
=
h
k
−
1
−
1
2
(
v
D
,
k
−
1
+
v
D
,
k
)
(
t
k
−
t
k
−
1
)
φ
k
=
φ
k
−
1
+
v
N
,
k
+
v
N
,
k
−
1
2
(
R
M
,
k
−
1
+
h
ˉ
)
(
t
k
−
t
k
−
1
)
λ
k
=
λ
k
−
1
+
v
E
,
k
+
v
E
,
k
−
1
2
(
R
N
,
k
−
1
/
2
+
h
ˉ
)
cos
φ
ˉ
(
t
k
−
t
k
−
1
)
h_{k}=h_{k-1}-\frac12(v_{D,k-1}+v_{D,k})(t_{k}-t_{k-1})\\ \varphi_{k}=\varphi_{k-1}+\frac{v_{N,k}+v_{N,k-1}}{2(R_{M,k-1}+\bar{h})}(t_{k}-t_{k-1})\\ \lambda_{k}=\lambda_{k-1}+\frac{v_{E,k}+v_{E,k-1}}{2(R_{N,k-1/2}+\bar{h})\cos\bar{\varphi}}(t_{k}-t_{k-1})
hk=hk−1−21(vD,k−1+vD,k)(tk−tk−1)φk=φk−1+2(RM,k−1+hˉ)vN,k+vN,k−1(tk−tk−1)λk=λk−1+2(RN,k−1/2+hˉ)cosφˉvE,k+vE,k−1(tk−tk−1)
其中,
R
N
,
k
−
1
/
2
R_{N,k-1/2}
RN,k−1/2 表示用中间时刻的纬度计算
R
N
,
h
ˉ
=
1
2
(
h
k
+
h
k
−
1
)
,
φ
ˉ
=
1
2
(
φ
k
+
φ
k
−
1
)
R_N,\bar{h}=\frac12(h_k+h_{k-1}),\bar{\varphi}=\frac12(\varphi_k+\varphi_{k-1})
RN,hˉ=21(hk+hk−1),φˉ=21(φk+φk−1)
void INSMech::posUpdate(const PVA &pvapre, PVA &pvacur, const IMU &imupre, const IMU &imucur) {
Eigen::Vector3d temp1, temp2, midvel, midpos;
Eigen::Quaterniond qne, qee, qnn;
// 重新计算中间时刻的速度和位置
// recompute velocity and position at k-1/2
midvel = (pvacur.vel + pvapre.vel) / 2;
midpos = pvapre.pos + Earth::DRi(pvapre.pos) * midvel * imucur.dt / 2;
// 重新计算中间时刻地理参数
// recompute rmrn, wie_n, wen_n at k-1/2
Eigen::Vector2d rmrn;
Eigen::Vector3d wie_n, wen_n;
rmrn = Earth::meridianPrimeVerticalRadius(midpos[0]);
wie_n << WGS84_WIE * cos(midpos[0]), 0, -WGS84_WIE * sin(midpos[0]);
wen_n << midvel[1] / (rmrn[1] + midpos[2]), -midvel[0] / (rmrn[0] + midpos[2]),
-midvel[1] * tan(midpos[0]) / (rmrn[1] + midpos[2]);
// 重新计算 k时刻到k-1时刻 n系旋转矢量
// recompute n-frame rotation vector (n(k) with respect to n(k-1)-frame)
temp1 = (wie_n + wen_n) * imucur.dt;
qnn = Rotation::rotvec2quaternion(temp1);
// e系转动等效旋转矢量 (k-1时刻k时刻,所以取负号)
// e-frame rotation vector (e(k-1) with respect to e(k)-frame)
temp2 << 0, 0, -WGS84_WIE * imucur.dt;
qee = Rotation::rotvec2quaternion(temp2);
// 位置更新完成
// position update finish
qne = Earth::qne(pvapre.pos);
qne = qee * qne * qnn;
pvacur.pos[2] = pvapre.pos[2] - midvel[2] * imucur.dt;
pvacur.pos = Earth::blh(qne, pvacur.pos[2]);
}
姿态更新
姿态的更新计算可用四元数的如下连乘运算来实现:
q
b
(
k
)
n
(
k
)
=
q
n
(
k
−
1
)
n
(
k
)
∘
q
b
(
k
−
1
)
n
(
k
−
1
)
∘
q
b
(
k
)
b
(
k
−
1
)
\boldsymbol q_{b(k)}^{n(k)}=\boldsymbol q_{n(k-1)}^{n(k)}\circ\boldsymbol q_{b(k-1)}^{n(k-1)}\circ\boldsymbol q_{b(k)}^{b(k-1)}
qb(k)n(k)=qn(k−1)n(k)∘qb(k−1)n(k−1)∘qb(k)b(k−1)
q
b
(
k
−
1
)
n
(
k
−
1
)
q_{b(k-1)}^{n(k-1)}
qb(k−1)n(k−1)为上一时刻姿态已知,计算
q
n
(
k
−
1
)
n
(
k
)
q_{n(k-1)}^{n(k)}
qn(k−1)n(k)和
q
b
(
k
)
b
(
k
−
1
)
q_{b(k)}^{b(k-1)}
qb(k)b(k−1)
q
b
(
k
)
b
(
k
−
1
)
=
[
cos
∥
0.5
ϕ
k
∥
sin
∥
0.5
ϕ
k
∥
∥
0.5
ϕ
k
∥
0.5
ϕ
k
]
\boldsymbol{q}_{b(k)}^{b(k-1)}=\begin{bmatrix}\cos\lVert0.5\boldsymbol{\phi}_k\rVert\\\\\frac{\sin\lVert0.5\boldsymbol{\phi}_k\rVert}{\lVert0.5\boldsymbol{\phi}_k\rVert}0.5\boldsymbol{\phi}_k\end{bmatrix}
qb(k)b(k−1)=
cos∥0.5ϕk∥∥0.5ϕk∥sin∥0.5ϕk∥0.5ϕk
等效旋转矢量近似化处理对应(双子样假设):
ϕ
k
=
Δ
θ
k
+
1
12
Δ
θ
k
−
1
×
Δ
θ
k
\phi_{k}=\Delta\boldsymbol{\theta}_{k}+\frac{1}{12}\Delta\boldsymbol{\theta}_{k-1}\times\Delta\boldsymbol{\theta}_{k}
ϕk=Δθk+121Δθk−1×Δθk
q n ( k − 1 ) n ( k ) = [ cos ∥ 0.5 ζ k ∥ − sin ∥ 0.5 ζ k ∥ ∥ 0.5 ζ k ∥ 0.5 ζ k ] \boldsymbol{q}_{n(k-1)}^{n(k)}=\begin{bmatrix}\cos\lVert0.5\boldsymbol{\zeta}_k\rVert\\\\-\frac{\sin\lVert0.5\boldsymbol{\zeta}_k\rVert}{\lVert0.5\boldsymbol{\zeta}_k\rVert}0.5\boldsymbol{\zeta}_k\end{bmatrix} qn(k−1)n(k)= cos∥0.5ζk∥−∥0.5ζk∥sin∥0.5ζk∥0.5ζk
等效旋转矢量对应:
ζ
k
=
∫
t
k
−
1
t
k
[
ω
i
e
n
(
t
)
+
ω
e
n
n
(
t
)
]
d
t
≈
[
ω
i
e
n
(
t
k
−
1
)
+
ω
e
n
n
(
t
k
−
1
)
]
Δ
t
\zeta_{k}=\int_{t_{k-1}}^{t_{k}}\left[\omega_{ie}^{n}(t)+\omega_{en}^{n}(t)\right]dt\approx\left[\omega_{ie}^{n}(t_{k-1})+\omega_{en}^{n}(t_{k-1})\right]\Delta t
ζk=∫tk−1tk[ωien(t)+ωenn(t)]dt≈[ωien(tk−1)+ωenn(tk−1)]Δt
其中,
ω
i
e
n
=
[
ω
e
cos
φ
0
−
ω
e
sin
φ
]
T
ω
e
n
n
=
[
v
E
/
(
R
N
+
h
)
−
v
N
/
(
R
M
+
h
)
−
v
E
tan
φ
/
(
R
N
+
h
)
]
R
M
=
a
(
1
−
e
2
)
(
1
−
e
2
sin
2
φ
)
3
R
N
=
a
1
−
e
2
sin
2
φ
\begin{gathered} \omega_{ie}^{n}=\begin{bmatrix}\omega_{e}\cos\varphi&0&-\omega_{e}\sin\varphi\end{bmatrix}^{\mathrm{T}}\\ \omega_{en}^{n}=\begin{bmatrix}v_{E}/(R_{N}+h)\\-v_{N}/(R_{M}+h)\\-v_{E}\tan\varphi/(R_{N}+h)\end{bmatrix} \\ R_{M}=\frac{a(1-e^{2})}{\sqrt{(1-e^{2}\sin^{2}\varphi)^{3}}} \\ R_{N}=\frac{a}{\sqrt{1-e^{2}\sin^{2}\varphi}} \end{gathered}
ωien=[ωecosφ0−ωesinφ]Tωenn=
vE/(RN+h)−vN/(RM+h)−vEtanφ/(RN+h)
RM=(1−e2sin2φ)3a(1−e2)RN=1−e2sin2φa
式中
φ
\varphi
φ 为纬度(单位弧度),
v
E
v_E
vE,
v
N
v_N
vN 分别为东向和北向速度。
R
M
R_M
RM 和
R
N
R_N
RN 分别为子午圈半径和卯酉圈 半径。
a
a
a 为地球椭球长半轴,$e
为地球椭球模型第一偏心率,对于
C
G
C
S
2000
椭球,
为地球椭球模型第一偏心率,对于 CGCS2000 椭球,
为地球椭球模型第一偏心率,对于CGCS2000椭球,a = 6378137.0m$,
e
=
0.08181919104
e = 0.08181919104
e=0.08181919104
void INSMech::attUpdate(const PVA &pvapre, PVA &pvacur, const IMU &imupre, const IMU &imucur) {
Eigen::Quaterniond qne_pre, qne_cur, qne_mid, qnn, qbb;
Eigen::Vector3d temp1, midpos, midvel;
// 重新计算中间时刻的速度和位置
// recompute velocity and position at k-1/2
midvel = (pvapre.vel + pvacur.vel) / 2;
qne_pre = Earth::qne(pvapre.pos);
qne_cur = Earth::qne(pvacur.pos);
temp1 = Rotation::quaternion2vector(qne_cur.inverse() * qne_pre);
qne_mid = qne_pre * Rotation::rotvec2quaternion(temp1 / 2).inverse();
midpos[2] = (pvacur.pos[2] + pvapre.pos[2]) / 2;
midpos = Earth::blh(qne_mid, midpos[2]);
// 重新计算中间时刻地理参数
// recompute rmrn, wie_n, wen_n at k-1/2
Eigen::Vector2d rmrn;
Eigen::Vector3d wie_n, wen_n;
rmrn = Earth::meridianPrimeVerticalRadius(midpos[0]);
wie_n << WGS84_WIE * cos(midpos[0]), 0, -WGS84_WIE * sin(midpos[0]);
wen_n << midvel[1] / (rmrn[1] + midpos[2]), -midvel[0] / (rmrn[0] + midpos[2]),
-midvel[1] * tan(midpos[0]) / (rmrn[1] + midpos[2]);
// 计算n系的旋转四元数 k-1时刻到k时刻变换
// n-frame rotation vector (n(k-1) with respect to n(k)-frame)
temp1 = -(wie_n + wen_n) * imucur.dt;
qnn = Rotation::rotvec2quaternion(temp1);
// 计算b系旋转四元数 补偿二阶圆锥误差
// b-frame rotation vector (b(k) with respect to b(k-1)-frame)
// compensate the second-order coning correction term.
temp1 = imucur.dtheta + imupre.dtheta.cross(imucur.dtheta) / 12;
qbb = Rotation::rotvec2quaternion(temp1);
// 姿态更新完成
// attitude update finish
pvacur.att.qbn = qnn * pvapre.att.qbn * qbb;
pvacur.att.cbn = Rotation::quaternion2matrix(pvacur.att.qbn);
pvacur.att.euler = Rotation::matrix2euler(pvacur.att.cbn);
}
误差微分方程
姿态误差微分方程(忽略二阶小量):
ϕ
˙
=
−
ω
i
n
n
×
ϕ
+
δ
ω
i
n
n
−
δ
ω
i
b
n
\dot{\phi}=-\omega_{in}^n\times\phi+\delta\boldsymbol{\omega}_{in}^n-\delta\boldsymbol{\omega}_{ib}^n
ϕ˙=−ωinn×ϕ+δωinn−δωibn
展开:
ϕ
˙
N
=
−
ω
e
sin
φ
R
M
+
h
δ
r
N
+
v
E
(
R
N
+
h
)
2
δ
r
D
+
1
R
N
+
h
δ
v
E
−
(
ω
e
sin
φ
+
v
E
tan
φ
R
N
+
h
)
ϕ
E
+
v
N
R
M
+
h
ϕ
D
−
δ
ω
i
b
,
N
n
ϕ
˙
E
=
−
v
N
(
R
M
+
h
)
2
δ
r
D
−
1
R
M
+
h
δ
v
N
+
(
ω
e
sin
φ
+
v
E
tan
φ
R
N
+
h
)
ϕ
N
+
(
ω
e
cos
φ
+
v
E
R
N
+
h
)
ϕ
D
−
δ
ω
i
b
,
E
n
ϕ
˙
D
=
−
[
ω
e
cos
φ
R
M
+
h
+
v
E
sec
2
φ
(
R
M
+
h
)
(
R
N
+
h
)
]
δ
r
N
−
v
E
tan
φ
(
R
N
+
h
)
2
δ
r
D
−
tan
φ
R
N
+
h
δ
v
E
−
v
N
R
M
+
h
ϕ
N
−
(
ω
e
cos
φ
+
v
E
R
N
+
h
)
ϕ
E
−
δ
ω
i
b
,
D
n
\begin{aligned} &\dot{\phi}_{N}= -\frac{\omega_{e}\sin\varphi}{R_{M}+h}\delta r_{N}+\frac{v_{E}}{(R_{N}+h)^{2}}\delta r_{D}+\frac{1}{R_{N}+h}\delta v_{E}-\left(\omega_{e}\sin\varphi+\frac{v_{E}\tan\varphi}{R_{N}+h}\right)\phi_{E} \\ &+\frac{v_N}{R_M+h}\phi_D-\delta\omega_{ib,N}^n \\ &\dot{\phi}_{E}= \begin{aligned}-\frac{v_N}{(R_M+h)^2}\delta r_D-\frac{1}{R_M+h}\delta v_N+\left(\omega_e\sin\varphi+\frac{v_E\tan\varphi}{R_N+h}\right)\phi_N\end{aligned} \\ &+\left(\omega_{e}\cos\varphi+\frac{v_{E}}{R_{N}+h}\right)\phi_{D}-\delta\omega_{ib,E}^{n} \\ &\dot{\phi}_{D}= \begin{aligned}&-\left[\frac{\omega_{e}\cos\varphi}{R_{M}+h}+\frac{v_{E}\sec^{2}\varphi}{(R_{M}+h)(R_{N}+h)}\right]\delta r_{N}-\frac{v_{E}\tan\varphi}{(R_{N}+h)^{2}}\delta r_{D}-\frac{\tan\varphi}{R_{N}+h}\delta v_{E}\end{aligned} \\ &-\frac{v_{N}}{R_{M}+h}\phi_{N}-\left(\omega_{e}\cos\varphi+\frac{v_{E}}{R_{N}+h}\right)\phi_{E}-\delta\omega_{ib,D}^{n} \end{aligned}
ϕ˙N=−RM+hωesinφδrN+(RN+h)2vEδrD+RN+h1δvE−(ωesinφ+RN+hvEtanφ)ϕE+RM+hvNϕD−δωib,Nnϕ˙E=−(RM+h)2vNδrD−RM+h1δvN+(ωesinφ+RN+hvEtanφ)ϕN+(ωecosφ+RN+hvE)ϕD−δωib,Enϕ˙D=−[RM+hωecosφ+(RM+h)(RN+h)vEsec2φ]δrN−(RN+h)2vEtanφδrD−RN+htanφδvE−RM+hvNϕN−(ωecosφ+RN+hvE)ϕE−δωib,Dn
速度误差微分方程(忽略二阶小量):
δ
v
˙
n
=
C
b
n
δ
f
b
+
f
n
×
ϕ
−
(
2
ω
i
e
n
+
ω
e
n
n
)
×
δ
v
n
+
v
n
×
(
2
δ
ω
i
e
n
+
δ
ω
e
n
n
)
+
δ
g
p
n
\delta\dot{\boldsymbol{v}}^n=\mathbf{C}_b^n\delta\boldsymbol{f}^b+\boldsymbol{f}^n\times\boldsymbol{\phi}-(2\boldsymbol{\omega}_{ie}^n+\boldsymbol{\omega}_{en}^n)\times\delta\boldsymbol{v}^n+\boldsymbol{v}^n\times(2\delta\boldsymbol{\omega}_{ie}^n+\delta\boldsymbol{\omega}_{en}^n)+\delta\boldsymbol{g}_p^n
δv˙n=Cbnδfb+fn×ϕ−(2ωien+ωenn)×δvn+vn×(2δωien+δωenn)+δgpn
展开:
δ
v
˙
N
=
−
[
2
v
E
ω
e
cos
φ
R
M
+
h
+
v
E
2
sec
2
φ
(
R
M
+
h
)
(
R
N
+
h
)
]
δ
r
N
+
[
v
N
v
D
(
R
M
+
h
)
2
−
v
E
2
tan
φ
(
R
N
+
h
)
2
]
δ
r
D
+
v
D
R
M
+
h
δ
v
N
−
2
(
ω
e
sin
φ
+
v
E
tan
φ
R
N
+
h
)
δ
v
E
+
v
N
R
M
+
h
δ
v
D
−
f
D
ϕ
E
+
f
E
ϕ
D
+
δ
f
N
δ
v
˙
E
=
=
[
2
ω
e
(
v
N
cos
φ
−
v
D
sin
φ
)
R
M
+
h
+
v
N
v
E
sec
2
φ
(
R
M
+
h
)
(
R
N
+
h
)
]
δ
r
N
+
v
E
v
D
+
v
N
v
E
tan
φ
(
R
N
+
h
)
2
δ
r
D
+
(
2
ω
e
sin
φ
+
v
E
tan
φ
R
N
+
h
)
δ
v
N
+
v
D
+
v
N
tan
φ
R
N
+
h
δ
v
E
+
(
2
ω
e
cos
φ
+
v
E
R
N
+
h
)
δ
v
D
+
f
D
ϕ
N
−
f
N
ϕ
D
+
δ
f
E
δ
v
˙
D
=
2
ω
e
v
E
sin
φ
R
M
+
h
δ
r
N
−
[
v
E
2
(
R
N
+
h
)
2
+
v
N
2
(
R
M
+
h
)
2
−
2
g
p
R
M
R
N
+
h
]
δ
r
D
−
2
v
N
R
M
+
h
δ
v
N
−
2
(
ω
e
cos
φ
+
v
E
R
N
+
h
)
δ
v
E
−
f
E
ϕ
N
+
f
N
ϕ
E
+
δ
f
D
\begin{aligned} &\delta\dot{v}_{N}&& =-\left[\frac{2v_{E}\omega_{e}\cos\varphi}{R_{M}+h}+\frac{v_{E}^{2}\sec^{2}\varphi}{(R_{M}+h)(R_{N}+h)}\right]\delta r_{N}+\left[\frac{v_{N}v_{D}}{(R_{M}+h)^{2}}-\frac{v_{E}^{2}\tan\varphi}{(R_{N}+h)^{2}}\right]\delta r_{D} \\ &&&\begin{aligned}+\frac{v_D}{R_M+h}\delta v_N-2\left(\omega_e\sin\varphi+\frac{v_E\tan\varphi}{R_N+h}\right)\delta v_E+\frac{v_N}{R_M+h}\delta v_D-f_D\phi_E+f_E\phi_D+\delta f_N\end{aligned} \\ &\delta\dot{v}_{E}=&& =\left[\frac{2\omega_{e}(v_{N}\cos\varphi-v_{D}\sin\varphi)}{R_{M}+h}+\frac{v_{N}v_{E}\sec^{2}\varphi}{(R_{M}+h)(R_{N}+h)}\right]\delta r_{N}+\frac{v_{E}v_{D}+v_{N}v_{E}\tan\varphi}{(R_{N}+h)^{2}}\delta r_{D} \\ &&&+\left(2\omega_e\sin\varphi+\frac{v_E\tan\varphi}{R_N+h}\right)\delta v_N+\frac{v_D+v_N\tan\varphi}{R_N+h}\delta v_E+\left(2\omega_e\cos\varphi+\frac{v_E}{R_N+h}\right)\delta v_D \\ &&&+f_{D}\phi_{N}-f_{N}\phi_{D}+\delta f_{E} \\ &\delta\dot{v}_{D}=&& \begin{aligned}\frac{2\omega_{e}v_{E}\sin\varphi}{R_{M}+h}\delta r_{N}-\left[\frac{v_{E}^{2}}{(R_{N}+h)^{2}}+\frac{v_{N}^{2}}{(R_{M}+h)^{2}}-\frac{2g_{p}}{\sqrt{R_{M}R_{N}}+h}\right]\delta r_{D}-\frac{2v_{N}}{R_{M}+h}\delta v_{N}\end{aligned} \\ &&&\begin{aligned}&-2\left(\omega_e\cos\varphi+\frac{v_E}{R_N+h}\right)\delta v_E-f_E\phi_N+f_N\phi_E+\delta f_D\end{aligned} \end{aligned}
δv˙Nδv˙E=δv˙D==−[RM+h2vEωecosφ+(RM+h)(RN+h)vE2sec2φ]δrN+[(RM+h)2vNvD−(RN+h)2vE2tanφ]δrD+RM+hvDδvN−2(ωesinφ+RN+hvEtanφ)δvE+RM+hvNδvD−fDϕE+fEϕD+δfN=[RM+h2ωe(vNcosφ−vDsinφ)+(RM+h)(RN+h)vNvEsec2φ]δrN+(RN+h)2vEvD+vNvEtanφδrD+(2ωesinφ+RN+hvEtanφ)δvN+RN+hvD+vNtanφδvE+(2ωecosφ+RN+hvE)δvD+fDϕN−fNϕD+δfERM+h2ωevEsinφδrN−[(RN+h)2vE2+(RM+h)2vN2−RMRN+h2gp]δrD−RM+h2vNδvN−2(ωecosφ+RN+hvE)δvE−fEϕN+fNϕE+δfD
位置误差微分方程(e系推到转换为n系):
δ
r
˙
n
=
−
ω
e
n
n
×
δ
r
n
+
δ
θ
×
v
n
+
δ
v
n
\begin{aligned} \delta\dot{\boldsymbol{r}}^{n} =-\boldsymbol{\omega}_{en}^n\times\delta\boldsymbol{r}^n+\delta\boldsymbol{\theta}\times\boldsymbol{v}^n+\delta\boldsymbol{v}^n \end{aligned}
δr˙n=−ωenn×δrn+δθ×vn+δvn
展开:
δ
r
˙
N
=
−
v
D
R
M
+
h
δ
r
N
+
v
N
R
M
+
h
δ
r
D
+
δ
v
N
δ
r
˙
E
=
v
E
tan
φ
R
N
+
h
δ
r
N
−
v
D
+
v
N
tan
φ
R
N
+
h
δ
r
E
+
v
E
R
N
+
h
δ
r
D
+
δ
v
E
δ
r
˙
D
=
δ
v
D
\begin{aligned} &\delta\dot{r}_{N} =-\frac{v_{D}}{R_{M}+h}\delta r_{N}+\frac{v_{N}}{R_{M}+h}\delta r_{D}+\delta v_{N} \\ &\delta\dot{r}_{E} =\frac{v_{E}\tan\varphi}{R_{N}+h}\delta r_{N}-\frac{v_{D}+v_{N}\tan\varphi}{R_{N}+h}\delta r_{E}+\frac{v_{E}}{R_{N}+h}\delta r_{D}+\delta v_{E} \\ &\delta\dot{r}_{D} =\delta v_{D} \end{aligned}
δr˙N=−RM+hvDδrN+RM+hvNδrD+δvNδr˙E=RN+hvEtanφδrN−RN+hvD+vNtanφδrE+RN+hvEδrD+δvEδr˙D=δvD
IMU误差微分方程(建模为一阶高斯马尔可夫过程):
b
˙
g
(
t
)
=
−
1
T
q
b
b
g
(
t
)
+
w
g
b
(
t
)
b
˙
a
(
t
)
=
−
1
T
g
b
b
a
(
t
)
+
w
a
b
(
t
)
s
˙
g
(
t
)
=
−
1
T
q
s
s
g
(
t
)
+
w
g
s
(
t
)
s
˙
a
(
t
)
=
−
1
T
a
s
s
a
(
t
)
+
w
a
s
(
t
)
\begin{gathered} \dot{\boldsymbol{b}}_g(t) \begin{aligned}=-\frac{1}{T_{qb}}\boldsymbol{b}_g(t)+\boldsymbol{w}_{gb}(t)\end{aligned} \\ \dot{\boldsymbol{b}}_a(t) =-\frac1{T_{gb}}\boldsymbol{b}_a(t)+\boldsymbol{w}_{ab}(t) \\ \dot{\boldsymbol{s}}_g(t) =-\frac1{T_{qs}}\boldsymbol{s}_g(t)+\boldsymbol{w}_{gs}(t) \\ \dot{\boldsymbol{s}}_a(t) =-\frac1{T_{as}}\boldsymbol{s}_a(t)+\boldsymbol{w}_{as}(t) \end{gathered}
b˙g(t)=−Tqb1bg(t)+wgb(t)b˙a(t)=−Tgb1ba(t)+wab(t)s˙g(t)=−Tqs1sg(t)+wgs(t)s˙a(t)=−Tas1sa(t)+was(t)
GNSS/INS 松组合滤波设计
GNSS/INS 松组合卡尔曼滤波算法设计的关键在于:建立离散时间系统误差状态模型,然后构建 误差状态的线性观测方程。有了系统模型和观测方程则可直接使用卡尔曼滤波的基本方程进行组合导 航解算,即完成了组合导航的算法设计。GNSS/INS 松组合常采用误差状态卡尔曼滤波(间接卡尔曼滤波)进行组合导航解算,以解决系 统的非线性问题。
连续时间误差状态方程
卡尔曼滤波的状态向量包含导航状态误差和传感器误差,定义为:
δ
x
(
t
)
=
[
(
δ
r
n
)
T
(
δ
v
n
)
T
ϕ
T
b
g
T
b
a
T
s
g
T
s
a
T
]
T
\delta\boldsymbol{x}(t)=\begin{bmatrix}(\delta\boldsymbol{r}^n)^T&(\delta\boldsymbol{v}^n)^T&\phi^T&\boldsymbol{b}_g^T&\boldsymbol{b}_a^T&\boldsymbol{s}_g^T&\boldsymbol{s}_a^T\end{bmatrix}^T
δx(t)=[(δrn)T(δvn)TϕTbgTbaTsgTsaT]T
误差状态的连续时间微分方程:
δ
x
˙
(
t
)
=
F
(
t
)
δ
x
(
t
)
+
G
(
t
)
w
(
t
)
\delta\dot{\boldsymbol{x}}(t)=\mathbf{F}(t)\delta\boldsymbol{x}(t)+\mathbf{G}(t)\boldsymbol{w}(t)
δx˙(t)=F(t)δx(t)+G(t)w(t)
根据$ \delta\dot{\boldsymbol{x}}(t)$的表达式,容易写出连续时间系统噪声向量
w
(
t
)
、
\boldsymbol{w}(t)、
w(t)、状态转移矩阵
F
(
t
)
\mathbf{F}(t)
F(t) 和噪声驱动矩阵
G
(
t
)
\mathbf{G}(t)
G(t)。
w
=
[
w
v
T
w
ϕ
T
w
g
b
T
w
a
b
T
w
g
s
T
w
a
s
T
]
T
\boldsymbol w=\begin{bmatrix}\boldsymbol w_v^T&\boldsymbol w_\phi^T&\boldsymbol w_{gb}^T&\boldsymbol w_{ab}^T&\boldsymbol w_{gs}^T&\boldsymbol w_{as}^T\end{bmatrix}^T
w=[wvTwϕTwgbTwabTwgsTwasT]T
G 21 × 18 = [ 0 0 0 0 0 0 C b n 0 0 0 0 0 0 C b n 0 0 0 0 0 0 I 3 × 3 0 0 0 0 0 0 I 3 × 3 0 0 0 0 0 0 I 3 × 3 0 0 0 0 0 0 I 3 × 3 ] \mathbf{G}_{21\times18}=\begin{bmatrix}0&0&0&0&0&0\\\mathbf{C}_b^n&0&0&0&0&0\\0&\mathbf{C}_b^n&0&0&0&0\\0&0&\mathbf{I}_{3\times3}&0&0&0\\0&0&0&\mathbf{I}_{3\times3}&0&0\\0&0&0&0&\mathbf{I}_{3\times3}&0\\0&0&0&0&0&\mathbf{I}_{3\times3}\end{bmatrix} G21×18= 0Cbn0000000Cbn0000000I3×30000000I3×30000000I3×30000000I3×3
F = [ F r r I 3 × 3 0 0 0 0 0 F v r F v v [ ( C b n f b ) × ] 0 C b n 0 C b n d i a g ( f b ) F ϕ r F ϕ v − ( ω h n × ) − C b n 0 − C b n d i a g ( ω h b ) 0 0 0 0 − 1 T g b I 3 × 3 0 0 0 0 0 0 0 − 1 T a b I 3 × 3 0 0 0 0 0 0 0 − 1 T g s I 3 × 3 0 0 0 0 0 0 0 − 1 T a s I 3 × 3 ] \mathbf{F}=\begin{bmatrix}\mathbf{F}_{rr}&\mathbf{I}_{3\times3}&0&0&0&0&0\\\mathbf{F}_{vr}&\mathbf{F}_{vv}&[(\mathbf{C}_{b}^{n}\boldsymbol{f}^{b})\times]&0&\mathbf{C}_{b}^{n}&0&\mathbf{C}_{b}^{n}\mathrm{diag}(\boldsymbol{f}^{b})\\\mathbf{F}_{\phi r}&\mathbf{F}_{\phi v}&-(\boldsymbol{\omega}_{h}^{n}\times)&-\mathbf{C}_{b}^{n}&0&-\mathbf{C}_{b}^{n}\mathrm{diag}(\boldsymbol{\omega}_{h}^{b})&0\\\mathbf{0}&0&0&\frac{-1}{T_{gb}}\mathbf{I}_{3\times3}&0&0&0\\\\0&0&0&0&\frac{-1}{T_{ab}}\mathbf{I}_{3\times3}&\mathbf{0}&0\\\\0&0&0&0&0&\frac{-1}{T_{gs}}\mathbf{I}_{3\times3}&0\\\\0&0&0&0&0&0&\frac{-1}{T_{as}}\mathbf{I}_{3\times3}\end{bmatrix} F= FrrFvrFϕr0000I3×3FvvFϕv00000[(Cbnfb)×]−(ωhn×)000000−CbnTgb−1I3×30000Cbn00Tab−1I3×30000−Cbndiag(ωhb)00Tgs−1I3×300Cbndiag(fb)0000Tas−1I3×3
状态方程离散化
误差状态的离散时间微分方程:
δ
x
k
=
Φ
k
/
k
−
1
δ
x
k
−
1
+
w
k
−
1
\delta x_{k}=\Phi_{k/k-1}\delta x_{k-1}+w_{k-1}
δxk=Φk/k−1δxk−1+wk−1
其中,
Φ
k
/
k
−
1
=
exp
(
∫
t
k
−
1
t
k
F
(
t
)
d
t
)
w
k
−
1
=
∫
t
k
−
1
t
k
Φ
k
/
t
G
(
t
)
w
(
t
)
d
t
\begin{gathered} \Phi_{k/k-1}=\exp\left(\int_{t_{k-1}}^{t_{k}}\mathbf{F}(t)dt\right) \\ \boldsymbol{w}_{k-1}=\int_{t_{k-1}}^{t_{k}}\boldsymbol{\Phi}_{k/t}\mathbf{G}(t)\boldsymbol{w}(t)dt \end{gathered}
Φk/k−1=exp(∫tk−1tkF(t)dt)wk−1=∫tk−1tkΦk/tG(t)w(t)dt
对状态转移矩阵进行近似化处理:
记离散化时间间隔
Δ
t
=
t
k
−
t
k
−
1
\Delta t=t_{k}-t_{k-1}
Δt=tk−tk−1,当
F
(
t
)
\mathbf{F}(t)
F(t) 在较短的积分区间
[
t
k
−
1
,
t
k
]
[t_{k-1},\quad t_{k}]
[tk−1,tk] 内变化不太剧烈时,且 设
F
(
t
k
−
1
)
Δ
t
≪
I
\mathbf{F}(t_{k-1})\Delta t\ll\mathbf{I}
F(tk−1)Δt≪I,则,
Φ
k
/
k
−
1
=
exp
{
F
(
t
k
−
1
)
Δ
t
}
≈
I
+
F
(
t
k
−
1
)
Δ
t
\mathbf{\Phi}_{k/k-1}=\exp\{\mathbf{F}(t_{k-1})\Delta t\}\approx\mathbf{I}+\mathbf{F}(t_{k-1})\Delta t
Φk/k−1=exp{F(tk−1)Δt}≈I+F(tk−1)Δt
预测噪声方差阵:
Q
k
=
∫
l
k
−
1
t
k
Φ
k
/
t
G
(
t
)
q
(
t
)
G
T
(
t
)
Φ
k
/
t
T
d
t
\begin{aligned} \mathbf{Q}_{k}& =\int_{l_{k-1}}^{t_{k}}\boldsymbol{\Phi}_{k/t}\mathbf{G}(t)\mathbf{q}(t)\mathbf{G}^{T}(t)\boldsymbol{\Phi}_{k/t}^{\mathrm{T}}dt \end{aligned}
Qk=∫lk−1tkΦk/tG(t)q(t)GT(t)Φk/tTdt
其中,
q
18
×
18
(
t
)
=
[
V
R
W
2
I
3
×
3
0
0
0
0
0
0
A
R
W
2
I
3
×
3
0
0
0
0
0
0
2
σ
g
b
2
T
g
b
I
3
×
3
0
0
0
0
0
0
2
σ
a
b
2
T
a
b
1
3
×
3
0
0
0
0
0
0
2
σ
g
s
2
T
g
s
I
3
×
3
0
0
0
0
0
0
2
σ
a
s
2
T
a
s
I
3
×
3
]
\mathbf{q}_{18\times18}(t)=\begin{bmatrix}\mathrm{VRW}^2\mathbf{I}_{3\times3}&0&0&0&0&0\\0&\mathrm{ARW}^2\mathbf{I}_{3\times3}&0&0&0&0\\0&0&\frac{2\sigma_{gb}^2}{T_{gb}}\mathbf{I}_{3\times3}&0&0&0\\0&0&0&\frac{2\sigma_{ab}^2}{T_{ab}}\mathbf{1}_{3\times3}&0&0\\0&0&0&0&\frac{2\sigma_{gs}^2}{T_{gs}}\mathbf{I}_{3\times3}&0\\0&0&0&0&0&\frac{2\sigma_{as}^2}{T_{as}}\mathbf{I}_{3\times3}\end{bmatrix}
q18×18(t)=
VRW2I3×3000000ARW2I3×3000000Tgb2σgb2I3×3000000Tab2σab213×3000000Tgs2σgs2I3×3000000Tas2σas2I3×3
当
G
(
t
)
\mathrm{G}(t)
G(t)在较短的积分区间
[
t
k
−
1
,
t
k
]
[t_{k-1},\quad t_k]
[tk−1,tk]内变化不太剧烈时,
Q
k
\mathbf{Q}_{k}
Qk 可简化为梯形积分。
Q
k
≈
1
2
[
Φ
k
/
k
−
1
G
(
t
k
−
1
)
q
(
t
k
−
1
)
G
T
(
t
k
−
1
)
Φ
k
/
k
−
1
T
+
G
(
t
k
)
q
(
t
k
)
G
T
(
t
k
)
]
Δ
t
\mathbf{Q}_k\approx\frac12\left[\boldsymbol{\Phi}_{k/k-1}\mathbf{G}(t_{k-1})\mathbf{q}(t_{k-1})\mathbf{G}^\mathrm{T}(t_{k-1})\boldsymbol{\Phi}_{k/k-1}^\mathrm{T}+\mathbf{G}(t_k)\mathbf{q}(t_k)\mathbf{G}^\mathrm{T}(t_k)\right]\Delta t
Qk≈21[Φk/k−1G(tk−1)q(tk−1)GT(tk−1)Φk/k−1T+G(tk)q(tk)GT(tk)]Δt
离散状态误差预测过程:
x
k
/
k
−
1
=
Φ
k
/
k
−
1
x
k
−
1
\boldsymbol{x}_{k/k-1}=\Phi_{k/k-1}\boldsymbol{x}_{k-1}
xk/k−1=Φk/k−1xk−1
状态协方差矩阵:
P
k
/
k
−
1
=
Φ
k
/
k
−
1
P
k
−
1
Φ
k
/
k
−
1
T
+
Q
k
\boldsymbol{P}_{k/k-1}=\Phi_{k/k-1}\boldsymbol{P}_{k-1}\boldsymbol{\Phi}_{k/k-1}^T+Q_k
Pk/k−1=Φk/k−1Pk−1Φk/k−1T+Qk
// 构造状态转移矩阵
// 位置误差
temp.setZero();
temp(0, 0) = -pvapre_.vel[2] / rmh;
temp(0, 2) = pvapre_.vel[0] / rmh;
temp(1, 0) = pvapre_.vel[1] * tan(pvapre_.pos[0]) / rnh;
temp(1, 1) = -(pvapre_.vel[2] + pvapre_.vel[0] * tan(pvapre_.pos[0])) / rnh;
temp(1, 2) = pvapre_.vel[1] / rnh;
F.block(P_ID, P_ID, 3, 3) = temp;
F.block(P_ID, V_ID, 3, 3) = Eigen::Matrix3d::Identity();
// 速度误差
temp.setZero();
temp(0, 0) = -2 * pvapre_.vel[1] * WGS84_WIE * cos(pvapre_.pos[0]) / rmh -
pow(pvapre_.vel[1], 2) / rmh / rnh / pow(cos(pvapre_.pos[0]), 2);
temp(0, 2) = pvapre_.vel[0] * pvapre_.vel[2] / rmh / rmh - pow(pvapre_.vel[1], 2) * tan(pvapre_.pos[0]) / rnh / rnh;
temp(1, 0) = 2 * WGS84_WIE * (pvapre_.vel[0] * cos(pvapre_.pos[0]) - pvapre_.vel[2] * sin(pvapre_.pos[0])) / rmh +
pvapre_.vel[0] * pvapre_.vel[1] / rmh / rnh / pow(cos(pvapre_.pos[0]), 2);
temp(1, 2) = (pvapre_.vel[1] * pvapre_.vel[2] + pvapre_.vel[0] * pvapre_.vel[1] * tan(pvapre_.pos[0])) / rnh / rnh;
temp(2, 0) = 2 * WGS84_WIE * pvapre_.vel[1] * sin(pvapre_.pos[0]) / rmh;
temp(2, 2) = -pow(pvapre_.vel[1], 2) / rnh / rnh - pow(pvapre_.vel[0], 2) / rmh / rmh +
2 * gravity / (sqrt(rmrn[0] * rmrn[1]) + pvapre_.pos[2]);
F.block(V_ID, P_ID, 3, 3) = temp;
temp.setZero();
temp(0, 0) = pvapre_.vel[2] / rmh;
temp(0, 1) = -2 * (WGS84_WIE * sin(pvapre_.pos[0]) + pvapre_.vel[1] * tan(pvapre_.pos[0]) / rnh);
temp(0, 2) = pvapre_.vel[0] / rmh;
temp(1, 0) = 2 * WGS84_WIE * sin(pvapre_.pos[0]) + pvapre_.vel[1] * tan(pvapre_.pos[0]) / rnh;
temp(1, 1) = (pvapre_.vel[2] + pvapre_.vel[0] * tan(pvapre_.pos[0])) / rnh;
temp(1, 2) = 2 * WGS84_WIE * cos(pvapre_.pos[0]) + pvapre_.vel[1] / rnh;
temp(2, 0) = -2 * pvapre_.vel[0] / rmh;
temp(2, 1) = -2 * (WGS84_WIE * cos(pvapre_.pos(0)) + pvapre_.vel[1] / rnh);
F.block(V_ID, V_ID, 3, 3) = temp;
F.block(V_ID, PHI_ID, 3, 3) = Rotation::skewSymmetric(pvapre_.att.cbn * accel);
F.block(V_ID, BA_ID, 3, 3) = pvapre_.att.cbn;
F.block(V_ID, SA_ID, 3, 3) = pvapre_.att.cbn * (accel.asDiagonal());
// 姿态误差
temp.setZero();
temp(0, 0) = -WGS84_WIE * sin(pvapre_.pos[0]) / rmh;
temp(0, 2) = pvapre_.vel[1] / rnh / rnh;
temp(1, 2) = -pvapre_.vel[0] / rmh / rmh;
temp(2, 0) = -WGS84_WIE * cos(pvapre_.pos[0]) / rmh - pvapre_.vel[1] / rmh / rnh / pow(cos(pvapre_.pos[0]), 2);
temp(2, 2) = -pvapre_.vel[1] * tan(pvapre_.pos[0]) / rnh / rnh;
F.block(PHI_ID, P_ID, 3, 3) = temp;
temp.setZero();
temp(0, 1) = 1 / rnh;
temp(1, 0) = -1 / rmh;
temp(2, 1) = -tan(pvapre_.pos[0]) / rnh;
F.block(PHI_ID, V_ID, 3, 3) = temp;
F.block(PHI_ID, PHI_ID, 3, 3) = -Rotation::skewSymmetric(wie_n + wen_n);
F.block(PHI_ID, BG_ID, 3, 3) = -pvapre_.att.cbn;
F.block(PHI_ID, SG_ID, 3, 3) = -pvapre_.att.cbn * (omega.asDiagonal());
// IMU零偏误差和比例因子误差,建模成一阶高斯-马尔科夫过程
F.block(BG_ID, BG_ID, 3, 3) = -1 / options_.imunoise.corr_time * Eigen::Matrix3d::Identity();
F.block(BA_ID, BA_ID, 3, 3) = -1 / options_.imunoise.corr_time * Eigen::Matrix3d::Identity();
F.block(SG_ID, SG_ID, 3, 3) = -1 / options_.imunoise.corr_time * Eigen::Matrix3d::Identity();
F.block(SA_ID, SA_ID, 3, 3) = -1 / options_.imunoise.corr_time * Eigen::Matrix3d::Identity();
// 系统噪声驱动矩阵
G.block(V_ID, VRW_ID, 3, 3) = pvapre_.att.cbn;
G.block(PHI_ID, ARW_ID, 3, 3) = pvapre_.att.cbn;
G.block(BG_ID, BGSTD_ID, 3, 3) = Eigen::Matrix3d::Identity();
G.block(BA_ID, BASTD_ID, 3, 3) = Eigen::Matrix3d::Identity();
G.block(SG_ID, SGSTD_ID, 3, 3) = Eigen::Matrix3d::Identity();
G.block(SA_ID, SASTD_ID, 3, 3) = Eigen::Matrix3d::Identity();
// 状态转移矩阵
Phi.setIdentity();
Phi = Phi + F * imucur.dt;
// 计算系统传播噪声
Qd = G * Qc_ * G.transpose() * imucur.dt;
Qd = (Phi * Qd * Phi.transpose() + Qd) / 2;
// 传播系统协方差和误差状态
Cov_ = Phi * Cov_ * Phi.transpose() + Qd;
dx_ = Phi * dx_;
GNSS位置观测方程
将IMU中心与GNSS天线相位中心对其:
r
G
=
r
I
+
D
R
−
1
C
b
n
l
b
r_{G}=r_{I}+\mathrm{D}_{R}^{-1}\mathrm{C}_{b}^{n}l^{b}
rG=rI+DR−1Cbnlb
考虑各导航状态的误差:
r
^
G
=
r
^
I
+
D
R
−
1
C
^
b
n
l
b
\hat{r}_{G}=\hat{r}_{I}+\mathrm{D}_{R}^{-1}\hat{\mathrm{C}}_{b}^{n}l^{b}
r^G=r^I+DR−1C^bnlb
引入扰动误差:
r
^
G
=
r
I
+
D
R
−
1
δ
r
n
+
D
R
−
1
[
I
−
(
ϕ
×
)
]
C
b
n
l
b
b
=
r
G
+
D
R
−
1
δ
r
n
+
D
R
−
1
[
(
C
b
n
l
b
)
×
ϕ
]
\begin{gathered} \hat{\boldsymbol{r}}_{G}=\boldsymbol{r}_{I}+\mathbf{D}_{R}^{-1}\delta\boldsymbol{r}^{n}+\mathbf{D}_{R}^{-1}\left[\mathbf{I}-(\boldsymbol{\phi}\times)\right]\mathbf{C}_{b}^{n}\boldsymbol{l}_{b}^{b} \\ =\boldsymbol{r}_{G}+\mathbf{D}_{R}^{-1}\delta\boldsymbol{r}^{n}+\mathbf{D}_{R}^{-1}\left[(\mathbf{C}_{b}^{n}\boldsymbol{l}^{b})\times\phi\right] \end{gathered}
r^G=rI+DR−1δrn+DR−1[I−(ϕ×)]Cbnlbb=rG+DR−1δrn+DR−1[(Cbnlb)×ϕ]
GNSS 定位解算得到的 GNSS 天线相位中心的位置表示为:
r
~
G
=
r
G
−
D
R
−
1
n
r
\tilde{r}_{G}=r_{G}-\mathbf{D}_{R}^{-1}\boldsymbol{n}_{r}
r~G=rG−DR−1nr
观测向量表示为 INS 推算的位置与 GNSS 位置观测之差,
δ
z
r
=
D
R
(
r
^
G
n
−
r
~
G
n
)
≈
δ
r
n
+
(
C
b
n
l
b
)
×
ϕ
+
n
r
\begin{aligned} \delta\boldsymbol{z}_{r}& =\mathbf{D}_{R}\left(\hat{\boldsymbol{r}}_{G}^{n}-\tilde{\boldsymbol{r}}_{G}^{n}\right) \\ &\approx\delta\boldsymbol{r}^{n}+(\mathbf{C}_{b}^{n}\boldsymbol{l}^{b})\times\phi+\boldsymbol{n}_{r} \end{aligned}
δzr=DR(r^Gn−r~Gn)≈δrn+(Cbnlb)×ϕ+nr
改写作如下形式:
δ
z
r
=
H
r
δ
x
+
n
r
\delta\boldsymbol{z}_r=\mathbf{H}_r\delta\boldsymbol{x}+\boldsymbol{n}_r
δzr=Hrδx+nr
观测矩阵为:
H
r
=
[
I
3
0
3
(
C
b
n
l
b
×
)
0
3
0
3
0
3
]
\mathbf{H}_r=\begin{bmatrix}\mathbf{I}_3&\mathbf{0}_3&(\mathbf{C}_b^n\boldsymbol{l}^b\times)&\mathbf{0}_3&\mathbf{0}_3&\mathbf{0}_3\end{bmatrix}
Hr=[I303(Cbnlb×)030303]
测量噪声方差阵为:
R
k
=
n
r
\mathbf{R}_{k}=\boldsymbol{n}_r
Rk=nr
卡尔曼增益:
K
k
=
P
k
/
k
−
1
H
k
T
(
H
k
P
k
/
k
−
1
H
k
T
+
R
k
)
−
1
\boldsymbol{K}_k=\boldsymbol{P}_{k/k-1}H_k^T(H_k\boldsymbol{P}_{k/k-1}H_k^T+R_k)^{-1}
Kk=Pk/k−1HkT(HkPk/k−1HkT+Rk)−1
最优估计状态:
x
k
=
x
k
/
k
−
1
+
K
k
(
z
k
−
H
k
x
k
/
k
−
1
)
\boldsymbol{x}_k=\boldsymbol{x}_{k/k-1}+\boldsymbol{K}_k(z_k-H_k\boldsymbol{x}_{k/k-1})
xk=xk/k−1+Kk(zk−Hkxk/k−1)
更新状态协方差矩阵:
P
k
=
(
I
−
K
k
H
k
)
P
k
/
k
−
1
(
I
−
K
k
H
k
)
T
+
K
k
R
k
K
k
T
\boldsymbol{P}_k=(\boldsymbol{I}-\boldsymbol{K}_kH_k)\boldsymbol{P}_{k/k-1}(\boldsymbol{I}-\boldsymbol{K}_kH_k)^T+\boldsymbol{K}_kR_k\boldsymbol{K}_k^T
Pk=(I−KkHk)Pk/k−1(I−KkHk)T+KkRkKkT
// GNSS位置观测向量
dz = Dr * (antenna_pos - gnssdata.blh);
// 构造GNSS位置观测矩阵
H_gnsspos.setZero();
H_gnsspos.block(0, P_ID, 3, 3) = Eigen::Matrix3d::Identity();
H_gnsspos.block(0, PHI_ID, 3, 3) =
Rotation::skewSymmetric(pvacur_.att.cbn * options_.antlever);
// 位置观测噪声阵
R_gnsspos =
gnssdata.std.cwiseProduct(gnssdata.std).asDiagonal();
kf-gins/gi_engine.cpp/GIEngine::EKFUpdate
// 计算Kalman增益
temp = H * Cov_ * H.transpose() + R;
K = Cov_ * H.transpose() * temp.inverse();
// 更新系统误差状态和协方差
I = I - K * H;
dx_ = dx_ + K * (dz - H * dx_);
Cov_ = I * Cov_ * I.transpose() + K * R * K.transpose();
误差反馈
按照扰动形式进行导航误差反馈,估计的IMU残差更新到IMU误差上
r
=
r
^
−
D
r
δ
r
n
b
‾
g
←
b
‾
g
+
b
g
,
b
‾
a
←
b
‾
a
+
b
a
v
n
=
v
^
n
−
δ
v
n
s
‾
g
←
s
‾
g
+
s
g
,
s
‾
a
←
s
‾
a
+
s
a
C
b
n
=
[
I
+
(
ϕ
×
)
]
C
^
b
n
\begin{aligned}&\boldsymbol{r}=\hat{\boldsymbol{r}}-\boldsymbol{D}_r\delta\boldsymbol{r}^n&&\overline{\boldsymbol{b}}_g\leftarrow\overline{\boldsymbol{b}}_g+\boldsymbol{b}_g,\overline{\boldsymbol{b}}_a\leftarrow\overline{\boldsymbol{b}}_a+\boldsymbol{b}_a\\&\boldsymbol{v}^n=\hat{\boldsymbol{v}}^n-\delta\boldsymbol{v}^n&&\overline{\boldsymbol{s}}_g\leftarrow\overline{\boldsymbol{s}}_g+\boldsymbol{s}_g,\overline{\boldsymbol{s}}_a\leftarrow\overline{\boldsymbol{s}}_a+\boldsymbol{s}_a\\&\boldsymbol{C}_b^n=[\boldsymbol{I}+(\boldsymbol{\phi}\times)]\hat{\boldsymbol{C}}_b^n\end{aligned}
r=r^−Drδrnvn=v^n−δvnCbn=[I+(ϕ×)]C^bnbg←bg+bg,ba←ba+basg←sg+sg,sa←sa+sa
// 位置、速度误差反馈
Eigen::Vector3d delta_r = dx_.block(P_ID, 0, 3, 1);
pvacur_.pos -= Dr_inv * delta_r;
vectemp = dx_.block(V_ID, 0, 3, 1);
pvacur_.vel -= vectemp;
// 姿态误差反馈
vectemp = dx_.block(PHI_ID, 0, 3, 1);
Eigen::Quaterniond qpn = Rotation::rotvec2quaternion(vectemp);
pvacur_.att.qbn = qpn * pvacur_.att.qbn;
// IMU零偏误差反馈
vectemp = dx_.block(BA_ID, 0, 3, 1);
imuerror_.accbias += vectemp;
// 误差状态反馈到系统状态后,将误差状态清零
dx_.setZero();
oldsymbol{s}_a\&\boldsymbol{C}_bn=[\boldsymbol{I}+(\boldsymbol{\phi}\times)]\hat{\boldsymbol{C}}_bn\end{aligned}
$$
// 位置、速度误差反馈
Eigen::Vector3d delta_r = dx_.block(P_ID, 0, 3, 1);
pvacur_.pos -= Dr_inv * delta_r;
vectemp = dx_.block(V_ID, 0, 3, 1);
pvacur_.vel -= vectemp;
// 姿态误差反馈
vectemp = dx_.block(PHI_ID, 0, 3, 1);
Eigen::Quaterniond qpn = Rotation::rotvec2quaternion(vectemp);
pvacur_.att.qbn = qpn * pvacur_.att.qbn;
// IMU零偏误差反馈
vectemp = dx_.block(BA_ID, 0, 3, 1);
imuerror_.accbias += vectemp;
// 误差状态反馈到系统状态后,将误差状态清零
dx_.setZero();
感谢武汉大学卫星导航定位技术研究中心多源智能导航实验室(i2Nav)牛小骥教授团队开源的KF-GINS软件平台