理论
参考1视频 [参考2博客]( // https://zhuanlan.zhihu.com/p/195649092)
先验估计:基于数学模型根据上一时刻状态估计处下一时刻状态的一个结果;
后验估计:模型计算的数据+观测值修正后
每一帧都要执行下边的预测->更新的步骤,而且顺序不能变,且缺一不可。
预测:
前两个是状态与关系预测,预测状态(先验估计)以及状态之间的关系(协方差)。状态在更新,状态之间的关系也在更新。
x
^
k
−
=
A
x
^
k
−
1
−
+
B
u
k
−
1
(1)
\hat{x}^-_{k}=A\hat{x}^-_{k-1}+Bu_{k-1}\tag{1}
x^k−=Ax^k−1−+Buk−1(1)
公式(1)就是根据上一时刻(k-1)的状态,依据数学模型,得到当前时刻的状态(k),本质上要求把两个状态之间的状态转移矩阵写出来,具体矩阵形式可能会有不同,但等式形式类似。
P
k
−
=
A
P
k
−
1
A
T
+
Q
(2)
P_{k}^-=AP_{k-1}A^T+Q\tag{2}
Pk−=APk−1AT+Q(2)
公式(2)中
P
P
P是协方差矩阵,A是状态转移矩阵,Q是噪音矩阵,服从高斯分布,代表一些不可控因素,也就是状态之间的转移除了状态转移矩阵的更新,还有外部条件的影响。因为你观测的状态之间必然是存在一个联系的,用协方差矩阵表示这个联系,一般是一个对角阵,对角线上是方差,非对角线上是两个状态之间的关系。
更新:
K
k
=
P
k
−
H
T
H
P
k
−
H
T
+
R
(3)
K_k=\frac{P^-_kH^T}{HP^-_{k}H^T+R}\tag{3}
Kk=HPk−HT+RPk−HT(3)
公式(3)就是最核心的卡尔曼增益了,可以认为他就是一个权重项,他的目的就是当K取多少时,能让最优估计的不确定性最小。其中P是协方差,R是噪声矩阵(观测值的偏差),H是测量矩阵,(不用管它怎么推导出来的的,会用即可)。
x
^
k
=
x
^
k
−
+
K
k
(
z
k
−
H
x
^
k
−
)
(4)
\hat{x}_k=\hat{x}^-_k+K_k(z_k-H\hat{x}^-_k)\tag{4}
x^k=x^k−+Kk(zk−Hx^k−)(4)
公式(4)就是计算后验估计的方法,其中
x
^
k
\hat{x}_k
x^k是后验估计输出结果,
x
^
k
−
\hat{x}^-_k
x^k−是先验估计结果,
z
k
z_k
zk是观测值;也就是要计算观测值和先验估计之间的差异;我传感器的值你总得借鉴一下,那么借鉴多少呢?就是由
K
K
K决定的
P
k
=
(
I
−
K
k
H
)
P
k
−
(5)
P_k=(I-K_kH)P^-_k\tag{5}
Pk=(I−KkH)Pk−(5)
公式(5)进行协方差矩阵的状态更新。每一帧都不一样,都要更新啊。
实战-以FAST-Dynamic-Vision为例
- 状态有位置 x , y x,y x,y,速度 v x , v y v_{x},v_{y} vx,vy,加速度 a x , a y a_{x},a_{y} ax,ay,其中四个的计算方程如下
x = x + v x d t + 1 2 a x Δ t 2 y = y + v y d t + 1 2 a y Δ t 2 v x = v x + a x Δ t v x = v x + a x Δ t x=x+v_{x}d_t+\frac{1}{2}a_{x}\Delta t^2 \\ y=y+v_{y}d_t+\frac{1}{2}a_{y}\Delta t^2 \\ v_{x}=v_{x}+a_{x}\Delta t \\ v_{x}=v_{x}+a_{x}\Delta t \\ x=x+vxdt+21axΔt2y=y+vydt+21ayΔt2vx=vx+axΔtvx=vx+axΔt
- 因此我们就可以得出他的状态转移方程如下,根据当前状态估计下一时刻状态,其中左侧为时刻t,右侧为时刻t-1,得出的结果叫做先验估计,由上一状态估计出了现在的状态。我们把他叫做 s t a t u s t status_t statust
[ x y v x v y a x a y ] t = [ 1 0 Δ t 0 1 2 a Δ t 2 0 0 1 0 Δ t 0 1 2 a Δ t 2 0 0 1 0 Δ t 0 0 0 0 1 0 Δ t 0 0 0 0 1 0 0 0 0 0 0 1 ] [ x y v x v y a x a y ] t − 1 \begin{bmatrix} x \\ y \\ v_x \\ v_y \\ a_x \\ a_y \\ \end{bmatrix}_t =\ \begin{bmatrix} 1 & 0 & \Delta t & 0 & \frac{1}{2}a\Delta t^2& 0 \\ 0 & 1 & 0 & \Delta t & 0 & \frac{1}{2}a\Delta t^2 \\ 0 & 0 & 1 & 0 & \Delta t & 0 \\ 0 & 0 & 0 & 1 & 0 & \Delta t \\ 0 & 0 & 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 0 & 0 & 1 \\ \end{bmatrix} \begin{bmatrix} x \\ y \\ v_x \\ v_y \\ a_x \\ a_y \\ \end{bmatrix}_{t-1} \\ ⎣⎢⎢⎢⎢⎢⎢⎡xyvxvyaxay⎦⎥⎥⎥⎥⎥⎥⎤t= ⎣⎢⎢⎢⎢⎢⎢⎡100000010000Δt010000Δt010021aΔt20Δt010021aΔt20Δt01⎦⎥⎥⎥⎥⎥⎥⎤⎣⎢⎢⎢⎢⎢⎢⎡xyvxvyaxay⎦⎥⎥⎥⎥⎥⎥⎤t−1
可写为,这就是先验估计
s
t
a
t
u
s
k
=
F
∗
s
t
a
t
u
s
t
−
1
status_k=F*status_{t-1}
statusk=F∗statust−1
其中F如下所示,被叫做状态转移矩阵
F
=
[
1
0
Δ
t
0
1
2
a
Δ
t
2
0
0
1
0
Δ
t
0
1
2
a
Δ
t
2
0
0
1
0
Δ
t
0
0
0
0
1
0
Δ
t
0
0
0
0
1
0
0
0
0
0
0
1
]
F=\ \begin{bmatrix} 1 & 0 & \Delta t & 0 & \frac{1}{2}a\Delta t^2& 0 \\ 0 & 1 & 0 & \Delta t & 0 & \frac{1}{2}a\Delta t^2 \\ 0 & 0 & 1 & 0 & \Delta t & 0 \\ 0 & 0 & 0 & 1 & 0 & \Delta t \\ 0 & 0 & 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 0 & 0 & 1 \\ \end{bmatrix}
F= ⎣⎢⎢⎢⎢⎢⎢⎡100000010000Δt010000Δt010021aΔt20Δt010021aΔt20Δt01⎦⎥⎥⎥⎥⎥⎥⎤
-
那么协方差矩阵P,两个状态之间的联系。一般是个对角阵,对角线单个状态的方差。非对角线上是不同参数之间的关系,它代表**状态之间关系的更新。**Q是一个高斯分布的噪声矩阵。关系分布中有一些不可控因素,一般会初始化一个表示影响,
P t = F P t − 1 F T + Q P_{t}=FP_{t-1}F^T+Q Pt=FPt−1FT+Q其中Q在代码中为dtq。dt为两个时刻之间的时间差
d t = t − p r e t d t q = d t ∗ 100 ∗ Q = d t ∗ 100 ∗ [ 1 0 0 0 0 0 0 1 0 0 0 0 0 0 2 0 0 0 0 0 0 2 0 0 0 0 0 0 4 0 0 0 0 0 0 4 ] dt=t-pre_t \\ dtq=dt*100*Q=dt*100*\ \begin{bmatrix} 1 & 0 & 0 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 & 0 & 0 \\ 0 & 0 & 2 & 0 & 0 & 0 \\ 0 & 0 & 0 & 2 & 0 & 0 \\ 0 & 0 & 0 & 0 & 4 & 0 \\ 0 & 0 & 0 & 0 & 0 & 4 \\ \end{bmatrix} dt=t−pretdtq=dt∗100∗Q=dt∗100∗ ⎣⎢⎢⎢⎢⎢⎢⎡100000010000002000000200000040000004⎦⎥⎥⎥⎥⎥⎥⎤
至此,预测部分就结束了。 -
下面开始更新部分。首先是卡尔曼增益的更新,他在其中把这个公式拆成了两部分
原公式为:
K = ( P C T ) ( C P C T + R ) − 1 K=(PC^T)(CPC^T+R)^{-1} K=(PCT)(CPCT+R)−1
在代码中的表现形式为:
S
=
H
P
H
T
+
R
K
=
P
H
T
∗
S
−
1
S=HPH^T+R \\ K=PH^T*S^{-1}
S=HPHT+RK=PHT∗S−1
其中:
KaTeX parse error: Undefined control sequence: \ at position 73: …atrix} \\ H= \̲ ̲\begin{bmatrix}…
也就是说该卡尔曼增益公式可被展开为如下样式,P的内容见上方,最后卡尔曼增益得到的是一个6*2的矩阵。
K
=
(
P
H
T
)
(
H
P
H
T
+
R
)
−
1
=
(
P
[
1
0
0
1
0
0
0
0
0
0
0
0
]
)
(
[
1
0
0
0
0
0
0
1
0
0
0
0
]
[
1
0
0
0
0
0
0
1
0
0
0
0
0
0
2
0
0
0
0
0
0
2
0
0
0
0
0
0
4
0
0
0
0
0
0
4
]
[
1
0
0
1
0
0
0
0
0
0
0
0
]
+
[
0.5
0
0
0.5
]
)
−
1
K=\ (PH^T)(HPH^T+R)^{-1}=(P \begin{bmatrix} 1 & 0 \\ 0 & 1 \\ 0 & 0 \\ 0 & 0 \\ 0 & 0 \\ 0 & 0 \\ \end{bmatrix}) (\begin{bmatrix} 1 & 0 & 0 & 0 & 0 & 0\\ 0 & 1 & 0 & 0 & 0 & 0 \end{bmatrix} \begin{bmatrix} 1 & 0 & 0 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 & 0 & 0 \\ 0 & 0 & 2 & 0 & 0 & 0 \\ 0 & 0 & 0 & 2 & 0 & 0 \\ 0 & 0 & 0 & 0 & 4 & 0 \\ 0 & 0 & 0 & 0 & 0 & 4 \\ \end{bmatrix} \begin{bmatrix} 1 & 0 \\ 0 & 1 \\ 0 & 0 \\ 0 & 0 \\ 0 & 0 \\ 0 & 0 \\ \end{bmatrix} + \begin{bmatrix} 0.5 & 0 \\ 0 & 0.5 \end{bmatrix})^-1
K= (PHT)(HPHT+R)−1=(P⎣⎢⎢⎢⎢⎢⎢⎡100000010000⎦⎥⎥⎥⎥⎥⎥⎤)([100100000000]⎣⎢⎢⎢⎢⎢⎢⎡100000010000002000000200000040000004⎦⎥⎥⎥⎥⎥⎥⎤⎣⎢⎢⎢⎢⎢⎢⎡100000010000⎦⎥⎥⎥⎥⎥⎥⎤+[0.5000.5])−1
-
然后是状态的更新。
x ^ k = x ^ k − + K k ( Y − H x ^ k − ) \hat{x}_k=\hat{x}^-_k+K_k(Y-H\hat{x}^-_k) x^k=x^k−+Kk(Y−Hx^k−)
这个公式中, Y Y Y是观测到的xy坐标信息(来自相机的测量结果),可以明显的看出, H x ^ k − H\hat{x}^-_k Hx^k−恰好取出了上一状态中的xy坐标信息,得到一个列向量。同样 Y Y Y也是个列向量,做差之后得到2*1的矩阵。再和卡尔曼增益相乘后得到6*1矩阵,就是相应的状态调整值了。然后即可得到后验估计的值。 -
最后是协方差矩阵的更新。
P = ( I − K H ) P P=(I-KH)P P=(I−KH)P
在该公式中, I I I是一个6*6的单位矩阵。
预测:预测状态以及状态之间的关系
卡尔曼增益用来更新状态以及协方差矩阵
卡尔曼增益K:就是个权重项,可大可小可计算