卡尔曼滤波简单笔记整理
摘要
本文笔记根据b站DR_CAN博主的卡尔曼滤波器视频和另一位博主scoutee的滤波笔记一:卡尔曼滤波(Kalman Filtering)详解整理。并在章节5中贴上了自己使用stm32对陀螺仪数据进行滤波的代码,可以根据代码进行拓展使用。
章节1:递归算法
卡尔曼滤波器(Kalman Filter)实际上是一种Optimal Recursive Data Processing Algorithm(最优递归数字处理算法)
章节1.1:例子
假设我用一把尺子测量一个硬币的直径
Z
k
Z_k
Zk,如下图所示 。
当需要估计真实值的时候,我们很自然会想到取平均,那么有硬币直径的估计值
X
^
k
\hat{X}_k
X^k:
X
^
k
=
1
k
(
Z
1
+
Z
2
+
⋯
+
Z
k
)
=
1
k
(
Z
1
+
Z
2
+
⋯
+
Z
k
−
1
)
+
1
k
Z
k
=
k
−
1
k
1
k
−
1
(
Z
1
+
Z
2
+
⋯
+
Z
k
−
1
)
+
1
k
Z
k
=
k
−
1
k
X
^
k
−
1
+
1
k
Z
k
=
X
^
k
−
1
+
1
k
(
Z
k
−
X
^
k
−
1
)
(1)
\begin{aligned} &\hat{X}_k = \dfrac{1}{k}(Z_1+Z_2+\dots+Z_k) \\ & \ \ \ \ \ = \dfrac{1}{k}(Z_1+Z_2+\dots+Z_{k-1}) +\dfrac{1}{k}Z_k \\ & \ \ \ \ \ = \dfrac{k-1}{k}\dfrac{1}{k-1}(Z_1+Z_2+\dots+Z_{k-1}) +\dfrac{1}{k}Z_k \\ & \ \ \ \ \ = \dfrac{k-1}{k}\hat{X}_{k-1} +\dfrac{1}{k}Z_k \\ & \ \ \ \ \ = \hat{X}_{k-1} +\dfrac{1}{k}(Z_k- \hat{X}_{k-1}) \\ \tag{1} \end{aligned}
X^k=k1(Z1+Z2+⋯+Zk) =k1(Z1+Z2+⋯+Zk−1)+k1Zk =kk−1k−11(Z1+Z2+⋯+Zk−1)+k1Zk =kk−1X^k−1+k1Zk =X^k−1+k1(Zk−X^k−1)(1)
我们可以看到随着k的增大,1/k趋向于0
, 有
X
^
k
→
X
^
k
−
1
\hat{X}_k \rightarrow \hat{X}_{k-1}
X^k→X^k−1。也就是说:随着测量次数的增多,测量值
Z
k
Z_k
Zk的值变得越来越不重要,因为我们已经得到较为准确的估计值
X
^
k
\hat{X}_k
X^k。同理如果测量次数k比较小,那么每次测量得到的结果对估计值相当重要。例如,当k=1时,
X
^
k
=
Z
1
\hat{X}_k={Z}_{1}
X^k=Z1。
令
K
k
=
1
k
K_k=\dfrac{1}{k}
Kk=k1,那么可以得到:
X
^
k
=
X
^
k
−
1
+
K
k
(
Z
k
−
X
^
k
−
1
)
(2)
\textcolor{blue}{\hat{X}_k= \hat{X}_{k-1} +K_k(Z_k- \hat{X}_{k-1})} \tag{2}
X^k=X^k−1+Kk(Zk−X^k−1)(2)
该公式的理解为:当前的估计值 = 上一次的估计值 + 系数 *(当前的测量值-上一次的估计值)
也就是说当前的估计值与上次估计值相关,上次估计值又与上上次有关。所以这种算法是一种递归算法
,其中
K
k
K_k
Kk被称为卡尔曼系数/增益
。但同时卡尔曼滤波器又不需要很多数据,仅需要上次的数据即可,这也是卡尔曼滤波器的优势之一。
章节1.2:误差与卡尔曼增益
-
误差和卡尔曼增益的计算关系:
-
估计误差(Estimate Error): e E S T e_{EST} eEST
-
测量误差(Measurement Error): e M E A e_{MEA} eMEA
-
根据测量误差和估计误差,可以得到
卡尔曼增益
: K k = e E S T k − 1 e E S T k − 1 + e M E A k K_k=\dfrac{e_{EST}^{k-1}}{e_{EST}^{k-1}+e_{MEA}^{k}} Kk=eESTk−1+eMEAkeESTk−1 -
估计误差更新: e E S T = ( 1 − K k ) e E S T k − 1 e_{EST} = (1-K_k)e_{EST}^{k-1} eEST=(1−Kk)eESTk−1
我们分析一下:
卡尔曼增益 = 上一次估计误差 上一次估计误差 + 这次测量误差 卡尔曼增益=\dfrac{上一次估计误差}{上一次估计误差+这次测量误差} 卡尔曼增益=上一次估计误差+这次测量误差上一次估计误差- 假若 e E S T k − 1 ⋙ e M E A k e_{EST}^{k-1} \ggg e_{MEA}^{k} eESTk−1⋙eMEAk,那么 K k → 1 K_k \rightarrow 1 Kk→1,有 X ^ k = X ^ k − 1 + 1 ∗ ( Z k − X ^ k − 1 ) = Z k \hat{X}_k= \hat{X}_{k-1} +1*(Z_k- \hat{X}_{k-1})=\textcolor{blue}{Z_k} X^k=X^k−1+1∗(Zk−X^k−1)=Zk,也就是说当第k-1次估计误差远大于第k次测量误差时候,我们会更相信测量值。
- 假若 e E S T k − 1 ⋘ e M E A k e_{EST}^{k-1} \lll e_{MEA}^{k} eESTk−1⋘eMEAk,那么 K k → 0 K_k \rightarrow 0 Kk→0,有 X ^ k = X ^ k − 1 + 0 ∗ ( Z k − X ^ k − 1 ) = X ^ k − 1 \hat{X}_k= \hat{X}_{k-1} +0*(Z_k- \hat{X}_{k-1})=\textcolor{blue}{\hat{X}_{k-1}} X^k=X^k−1+0∗(Zk−X^k−1)=X^k−1,我们此时更相信上一次估计值。
-
-
举个例子:
假设实际长度50cm,测量值为51cm,测量误差是3cm(测量仪器的固有参数,整个过程保持不变),即实际长度在47-53之间。假设初始估计值是48cm(在我的理解中,第一次的估计值按照测量值来算好了),初始估计误差为3cm。如表所示为递归结果。
章节2:数据融合算法
章节2.1:例子
假设有两个秤去测量同一个东西,两个秤测量结果服从正态分布。
- Z 1 = 30 g Z_1=30g Z1=30g,标准差为 σ Z 1 = 2 g \sigma_{Z_1}=2g σZ1=2g
-
Z
2
=
32
g
Z_2=32g
Z2=32g,标准差为
σ
Z
2
=
3
g
\sigma_{Z_2}=3g
σZ2=3g
那么其分布结果如图所示:
根据两个秤的结果估算实际重量 Z ^ \hat{Z} Z^,那么直觉来看,结果肯定位于 Z 1 Z_1 Z1和 Z 2 Z_2 Z2这两个值之间。并且,由于第一个秤的标准差更小,结果应该会更靠近第一个秤。融合方式为:
Z ^ = Z 1 + K k ( Z 2 − Z 1 ) , K k ∈ [ 0 , 1 ] (3) \textcolor{blue}{\hat{Z} = Z_1+K_k(Z_2-Z_1),K_k \in [0,1] }\tag{3} Z^=Z1+Kk(Z2−Z1),Kk∈[0,1](3)
其中, K k K_k Kk为卡尔曼增益。要使 Z ^ \hat{Z} Z^最准确,即要使 Z ^ \hat{Z} Z^的方差最小,那么有:
σ z ^ 2 = V a r ( Z 1 + K k ( Z 2 − Z 1 ) ) = V a r ( ( 1 − K k ) Z 1 + Z 2 ) (4) \begin{aligned} &\sigma_{\hat{z}} ^2=Var(Z_1+K_k(Z_2-Z_1)) \\ &\ \ \ \ \ =Var((1-K_k)Z_1+Z_2) \\ \end{aligned} \tag{4} σz^2=Var(Z1+Kk(Z2−Z1)) =Var((1−Kk)Z1+Z2)(4)
由于两个秤的结果 Z 1 Z_1 Z1和 Z 2 Z_2 Z2是相互独立的
,所以:
σ z ^ 2 = V a r ( ( 1 − K k ) Z 1 + Z 2 ) = V a r ( ( 1 − K k ) Z 1 ) + V a r ( Z 2 ) = ( 1 − K k ) 2 σ Z 1 2 + σ Z 2 2 (5) \begin{aligned} &\sigma_{\hat{z}} ^2=Var((1-K_k)Z_1+Z_2) \\ &\ \ \ \ \ =Var((1-K_k)Z_1)+Var(Z_2) \\ &\ \ \ \ \ =\textcolor{blue}{(1-K_k)^2\sigma_{Z_1}^2+\sigma_{Z_2}^2 }\\ \end{aligned} \tag{5} σz^2=Var((1−Kk)Z1+Z2) =Var((1−Kk)Z1)+Var(Z2) =(1−Kk)2σZ12+σZ22(5)
公式 5 5 5对 K k K_k Kk求导,并令其为0: d σ z ^ 2 d K k = 0 \dfrac{d\sigma_{\hat{z}} ^2}{dK_k}=0 dKkdσz^2=0,求解得到: K k = σ Z 1 2 σ Z 1 2 + σ Z 2 2 = 2 2 2 2 + 3 2 = 4 13 K_k = \dfrac{\sigma_{Z_1}^2}{\sigma_{Z_1}^2+\sigma_{Z_2}^2}=\dfrac{2^2}{2^2+3^2}=\dfrac{4}{13} Kk=σZ12+σZ22σZ12=22+3222=134
代回公式 3 3 3中可得最优值
: Z ^ = 30 + 4 13 ( 32 − 30 ) = 30.615 \hat{Z} =30+\dfrac{4}{13}(32-30)=30.615 Z^=30+134(32−30)=30.615,代回公式 5 5 5中可得标准差: σ z ^ = 1.583 \sigma_{\hat{z}}=1.583 σz^=1.583。可以看到,经过数据融合之后的数据方差是要小于两个秤的方差的。我对此的理解是两个不确定的结果融合之后可以增加数据的可信度,就好像俗话说:三个臭皮匠顶个诸葛亮。也就是说任何事情在自己不确定的情况下,找个人讨论讨论就可以增加结果的成功性。嘿嘿\dog
章节3:协方差矩阵和状态空间方程
章节3.1:协方差矩阵
协方差矩阵可以同时将方差和协方差体现出来描述变量之间的联动性。
- 举个例子:
球队中各球员的信息如下表格所示:
球员 | 身高 x | 体重 y | 年龄 z |
---|---|---|---|
张三 | 182 | 80 | 29 |
李四 | 180 | 77 | 26 |
王五 | 193 | 86 | 29 |
平均值 | 185 | 81 | 28 |
-
那么可以计算:
-
身高方差为 σ x 2 = 1 3 [ ( 182 − 185 ) 2 + ( 180 − 185 ) 2 + ( 193 − 185 ) 2 ] = 32.67 \sigma_x^2=\dfrac{1}{3}[(182-185)^2+(180-185)^2+(193-185)^2]=32.67 σx2=31[(182−185)2+(180−185)2+(193−185)2]=32.67
-
体重方差为 σ y 2 = 1 3 [ ( 80 − 81 ) 2 + ( 77 − 81 ) 2 + ( 86 − 81 ) 2 ] = 14 \sigma_y^2=\dfrac{1}{3}[(80-81)^2+(77-81)^2+(86-81)^2]=14 σy2=31[(80−81)2+(77−81)2+(86−81)2]=14
-
年龄方差为 σ z 2 = 1 3 [ ( 29 − 28 ) 2 + ( 26 − 28 ) 2 + ( 29 − 28 ) 2 ] = 2 \sigma_z^2=\dfrac{1}{3}[(29-28)^2+(26-28)^2+(29-28)^2]=2 σz2=31[(29−28)2+(26−28)2+(29−28)2]=2
-
协方差为(协方差为正,代表两变量具有正相关性 ):
- σ x σ y = 1 3 [ ( 182 − 185 ) ( 80 − 81 ) + ( 180 − 185 ) ( 77 − 81 ) + ( 193 − 185 ) ( 86 − 81 ) ] = 21 = σ y σ x \sigma_x \sigma_y=\dfrac{1}{3}[(182-185)(80-81)+(180-185)(77-81)+(193-185)(86-81)]=21=\sigma_y \sigma_x σxσy=31[(182−185)(80−81)+(180−185)(77−81)+(193−185)(86−81)]=21=σyσx
- σ x σ z = 1 3 [ ( 182 − 185 ) ( 29 − 28 ) + ( 180 − 185 ) ( 26 − 28 ) + ( 193 − 185 ) ( 29 − 28 ) ] = 5 = σ z σ x \sigma_x \sigma_z=\dfrac{1}{3}[(182-185)(29-28)+(180-185)(26-28)+(193-185)(29-28)]=5=\sigma_z \sigma_x σxσz=31[(182−185)(29−28)+(180−185)(26−28)+(193−185)(29−28)]=5=σzσx
- σ y σ z = 1 3 [ ( 80 − 81 ) ( 29 − 28 ) + ( 77 − 81 ) ( 26 − 28 ) + ( 86 − 81 ) ( 29 − 28 ) ] = 4 = σ z σ y \sigma_y \sigma_z=\dfrac{1}{3}[(80-81)(29-28)+(77-81)(26-28)+(86-81)(29-28)]=4=\sigma_z \sigma_y σyσz=31[(80−81)(29−28)+(77−81)(26−28)+(86−81)(29−28)]=4=σzσy
因此协方差矩阵为 P = [ σ x 2 σ x σ y σ x σ z σ y σ x σ y 2 σ y σ z σ z σ x σ z σ y σ z 2 ] = [ 32.67 21 5 21 14 4 5 4 2 ] P=\begin{bmatrix} \sigma_x^2 & \sigma_x \sigma_y & \sigma_x \sigma_z \\ \sigma_y \sigma_x & \sigma_y^2 & \sigma_y \sigma_z \\ \sigma_z \sigma_x & \sigma_z \sigma_y & \sigma_z^2 \end{bmatrix}=\begin{bmatrix} 32.67 & 21 &5 \\ 21&14 & 4 \\ 5 &4& 2 \end{bmatrix} P= σx2σyσxσzσxσxσyσy2σzσyσxσzσyσzσz2 = 32.6721521144542
-
-
利用矩阵直接计算
协方差矩阵
:- 已知 [ x 1 y 1 z 1 x 2 y 2 z 2 x 3 y 3 z 3 ] = [ 182 80 29 180 77 26 193 86 29 ] \begin{bmatrix} x_1 & y_1 & z_1 \\ x_2 & y_2 & z_2 \\ x_3 & y_3 & z_3 \end{bmatrix}=\begin{bmatrix} 182 & 80 & 29 \\ 180 & 77 & 26 \\ 193 & 86 & 29 \end{bmatrix} x1x2x3y1y2y3z1z2z3 = 182180193807786292629
- 令a= [ x 1 y 1 z 1 x 2 y 2 z 2 x 3 y 3 z 3 ] − 1 3 [ 1 1 1 1 1 1 1 1 1 ] [ x 1 y 1 z 1 x 2 y 2 z 2 x 3 y 3 z 3 ] \begin{bmatrix} x_1 & y_1 & z_1 \\ x_2 & y_2 & z_2 \\ x_3 & y_3 & z_3 \end{bmatrix}-\dfrac{1}{3}\begin{bmatrix} 1 & 1 & 1 \\ 1 & 1 & 1 \\ 1 & 1 & 1 \end{bmatrix}\begin{bmatrix} x_1 & y_1 & z_1 \\ x_2 & y_2 & z_2 \\ x_3 & y_3 & z_3 \end{bmatrix} x1x2x3y1y2y3z1z2z3 −31 111111111 x1x2x3y1y2y3z1z2z3
- 那么
协方差矩阵
为: P = 1 3 a T a P=\dfrac{1}{3}a^Ta P=31aTa
章节3.2:状态空间方程
-
举个例子:通过弹簧振动阻尼系统学习装填空间方程的表达形式
已知弹簧胡克系数是k,阻尼系数是B,向右移动的距离是x,向右的力是F,物体质量为m。那么有动态状态方程:
m x ¨ + B x ˙ + k x = F (7) m\ddot{x}+B\dot{x}+kx=F \tag{7} mx¨+Bx˙+kx=F(7)
其中, x ¨ = d 2 x d t 2 = a \ddot{x}=\dfrac{d^2x}{dt^2}=a x¨=dt2d2x=a(加速度) , x ˙ = d x d t = v \dot{x}=\dfrac{dx}{dt}=v x˙=dtdx=v(速度),F又可以视为系统输入u 。该系统中,系统状态变量为:
x 1 = x , x 2 = x ˙ (8) x_1 =x,x_2 =\dot{x} \tag{8} x1=x,x2=x˙(8)
那么有:运动状态方程
:
x 1 ˙ = x 2 x 2 ˙ = x ¨ = ( F − B x ˙ − k x ) / m = 1 m u − B m x 2 − k m x 1 (9) \begin{aligned} &\dot{x_1} =x_2 \\ &\dot{x_2} =\ddot{x}=(F-B\dot{x}-kx)/m = \dfrac{1}{m}u-\dfrac{B}{m}x_2-\dfrac{k}{m}x_1 \end{aligned} \tag{9} x1˙=x2x2˙=x¨=(F−Bx˙−kx)/m=m1u−mBx2−mkx1(9)测量方程为
:
z 1 = x = x 1 , ( 位置 ) z 2 = x ˙ = x 2 , ( 加速度 ) (10) \begin{aligned} &z_1 =x=x_1,(位置) \\ &z_2=\dot{x}=x_2,(加速度) \end{aligned} \tag{10} z1=x=x1,(位置)z2=x˙=x2,(加速度)(10)
因此
状态空间
的表达形式为:
[ x 1 ˙ x 2 ˙ ] = [ 0 1 − k m − B m ] [ x 1 x 2 ] + [ 0 1 m ] u (11) \begin{bmatrix} \dot{x_1} \\ \dot{x_2} \end{bmatrix} =\begin{bmatrix} 0&1 \\ -\dfrac{k}{m}& -\dfrac{B}{m}\end{bmatrix}\begin{bmatrix} x_1 \\ x_2 \end{bmatrix}+\begin{bmatrix} 0\\ \dfrac{1}{m}\end{bmatrix}u \tag{11} [x1˙x2˙]=[0−mk1−mB][x1x2]+[0m1]u(11)
[ z 1 z 2 ] = [ 1 0 0 1 ] [ x 1 x 2 ] (12) \begin{bmatrix} {z_1} \\ {z_2} \end{bmatrix} =\begin{bmatrix} 1&0 \\ 0& 1\end{bmatrix}\begin{bmatrix} x_1 \\ x_2 \end{bmatrix} \tag{12} [z1z2]=[1001][x1x2](12)
其中公式 11 11 11代表运动状态方程
,公式 12 12 12代表测量方程
。
理想情况下状态空间时间连续的表达形式为
:
X ˙ ( t ) = A x ( t ) + B u ( t ) Z = H x ( t ) (13) \begin{aligned} &\dot{X}(t)=Ax(t)+Bu(t) \\&Z=Hx(t) \end{aligned} \tag{13} X˙(t)=Ax(t)+Bu(t)Z=Hx(t)(13)状态空间时间离散的表达形式为
:
x k = A x k − 1 + B u k − 1 z k = H x k (14) \begin{aligned} &x_k=Ax_{k-1}+Bu_{k-1} \\&z_k=Hx_k \end{aligned} \tag{14} xk=Axk−1+Buk−1zk=Hxk(14)
实际情况下,由于存在噪声影响,状态空间表达方式修正如下:
状态空间时间连续的表达形式为
:
X ˙ ( t ) = A x ( t ) + B u ( t ) + w ( t ) Z = H x ( t ) + v ( t ) (15) \begin{aligned} &\dot{X}(t)=Ax(t)+Bu(t)+\textcolor{red}{w(t)} \\&Z=Hx(t) +\textcolor{red}{v(t)}\end{aligned} \tag{15} X˙(t)=Ax(t)+Bu(t)+w(t)Z=Hx(t)+v(t)(15)状态空间时间离散的表达形式为
:
x k = A x k − 1 + B u k − 1 + w k − 1 z k = H x k + v k (16) \begin{aligned} &x_k=Ax_{k-1}+Bu_{k-1}+\textcolor{red}{w_{k-1}} \\&z_k=Hx_k+\textcolor{red}{v_k} \end{aligned} \tag{16} xk=Axk−1+Buk−1+wk−1zk=Hxk+vk(16)
-
如何通过状态空间方程得到相对准确的估计值
由于现实条件下,存在噪声影响,导致模型( x k x_k xk)和测量( z k z_k zk)均不准确,那么如何在不准确的情况下估计相对准确的 x ^ k \hat{x}_k x^k?这就是卡尔曼滤波器
要解决的问题。还记得我们在章节2提到的
数据融合
算法吗,实际上卡尔曼滤波器就是实现数据融合,即:
章节4:卡尔曼增益公式推导和误差协方差矩阵公式推导
章节4.1:卡尔曼增益公式推导
-
如公式 16 16 16所示,我们认为 x k x_k xk是
状态变量
, A A A是状态转换矩阵
, B B B是控制转换矩阵
, H H H是量测矩阵
, u k − 1 u_{k-1} uk−1是k-1刻的系统输入
, w k − 1 w_{k-1} wk−1和 v k v_{k} vk分别为过程噪声
和测量噪声
,并且我们认为噪声均服从高斯分布( P ( w ) ∼ ( 0 , Q ) , P ( v ) ∼ ( 0 , R ) P(w)\sim(0,Q),P(v)\sim(0,R) P(w)∼(0,Q),P(v)∼(0,R)),但过程噪声是不可测的。因此,下一步为了方便建模,我们忽视掉噪声的影响。也是因为少了噪声这一项,所以下面的结果都是估计值
,而不像公式15,16中是真实值。 -
通过计算,已知 先验估计 :
x ~ ^ k = A x ^ k − 1 + B u k − 1 (17) \hat{\tilde{x}}_k = A\hat{x}_{k-1}+Bu_{k-1} \tag{17} x~^k=Ax^k−1+Buk−1(17)
由于 测量值 z k z_k zk可以由仪器直接测量得到,因此根据公式 14 14 14,可以得到估计值: x ^ k m e a = H − 1 z k \hat{x}_k^{mea}=H^{-1}z_k x^kmea=H−1zk。那么根据计算得到的不准确先验估计值
x ~ ^ k \hat{\tilde{x}}_k x~^k和测量得到的不准确估计值
x ^ k m e a \hat{x}_k^{mea} x^kmea融合之后得到最优估计值,即 后验估计值 :
x ^ k = x ~ ^ k + G ( x ^ k m e a − x ~ ^ k ) = x ~ ^ k + G ( H − 1 z k − x ~ ^ k ) (18) \begin{aligned} &\hat{{x}}_k =\hat{\tilde{x}}_k +G(\hat{x}_k^{mea}-\hat{\tilde{x}}_k )\\ & \ \ \ \ =\hat{\tilde{x}}_k +G(H^{-1}z_k-\hat{\tilde{x}}_k ) \end{aligned} \tag{18} x^k=x~^k+G(x^kmea−x~^k) =x~^k+G(H−1zk−x~^k)(18)
简单起见,令 G = K k H G=K_kH G=KkH,那么公式 18 18 18可以化简得到最终的卡尔曼滤波公式
:
x ^ k = x ~ ^ k + K k ( z k − H x ~ ^ k ) , K k ∈ [ 0 , H − 1 ] (19) \hat{{x}}_k =\hat{\tilde{x}}_k +K_k(z_k-H\hat{\tilde{x}}_k ),K_k \in[0,H^{-1}]\tag{19} x^k=x~^k+Kk(zk−Hx~^k),Kk∈[0,H−1](19)
为了使结果更可信,我们必须要寻找最优
K k K_k Kk,使得 x ^ k \hat{{x}}_k x^k更加趋向于真实值 x k {x}_k xk。因此,接下来的过程就类似于章节2的推导过程。 -
首先引入
误差
: e k = x k − x ^ k \textcolor{red}{e_k =x_k-\hat{x}_k} ek=xk−x^k,由于服从高斯分布的变量经过线性组合后仍服从高斯分布,因此 e ∼ ( 0 , p ) e \sim(0,p) e∼(0,p)。 p p p是协方差矩阵。
实际上,当估计结果越准确
, e k e_k ek的方差是越小的
。由于协方差主对角线上元素相加值是该矩阵的迹,因此我们的优化目标
就是让 p p p的迹最小!!!- 计算
e
k
e_k
ek的协方差矩阵:
p
k
=
E
[
e
k
e
k
T
]
=
E
[
(
x
k
−
x
^
k
)
(
x
k
−
x
^
k
)
T
]
p_k =E[e_ke_k^T]=E[(x_k-\hat{x}_k)(x_k-\hat{x}_k)^T]
pk=E[ekekT]=E[(xk−x^k)(xk−x^k)T],将公式
16
16
16和
19
19
19代入可得:
x k − x ^ k = x k − x ~ ^ k − K k ( z k − H x ~ ^ k ) = x k − ( I − K k H ) x ~ ^ k − K k z k = x k − ( I − K k H ) x ~ ^ k − K k ( H x k + v k ) = ( I − K k H ) ( x k − x ~ ^ k ) − K k v k (20) \begin{aligned} &x_k-\hat{x}_k=x_k-\hat{\tilde{x}}_k -K_k(z_k-H\hat{\tilde{x}}_k )\\ &\ \ \ \ \ \ \ \ \ \ \ \ \ \ =x_k -(I-K_kH )\hat{\tilde{x}}_k-K_kz_k\\ &\ \ \ \ \ \ \ \ \ \ \ \ \ \ =x_k -(I-K_kH )\hat{\tilde{x}}_k-K_k(Hx_k+{v_k} )\\ &\ \ \ \ \ \ \ \ \ \ \ \ \ \ =(I-K_kH )(x_k -\hat{\tilde{x}}_k)-K_k{v_k} \\ \end{aligned} \tag{20} xk−x^k=xk−x~^k−Kk(zk−Hx~^k) =xk−(I−KkH)x~^k−Kkzk =xk−(I−KkH)x~^k−Kk(Hxk+vk) =(I−KkH)(xk−x~^k)−Kkvk(20)
定义先验误差
: e ~ k = x k − x ~ ^ k \textcolor{red}{\tilde{e}_k =x_k -\hat{\tilde{x}}_k} e~k=xk−x~^k,有 e ~ ∼ ( 0 , p ~ ) \tilde{e}\sim(0,\tilde{p}) e~∼(0,p~)那么
p k = E [ ( x k − x ^ k ) ( x k − x ^ k ) T ] = E { [ ( I − K k H ) e ~ k − K k v k ] [ ( I − K k H ) e ~ k − K k v k ] T } = E { [ ( I − K k H ) e ~ k − K k v k ] [ e ~ k T ( I − K k H ) T − v k T K k T ] } = E { ( I − K k H ) e ~ k e ~ k T ( I − K k H ) T − ( I − K k H ) e ~ k v k T K k T − K k v k e ~ k T ( I − K k H ) T + K k v k v k T K k T } = E { ( I − K k H ) e ~ k e ~ k T ( I − K k H ) T } − E { ( I − K k H ) e ~ k v k T K k T } − E { K k v k e ~ k T ( I − K k H ) T } + E { K k v k v k T K k T } (21) \begin{aligned} &p_k=E[(x_k-\hat{x}_k)(x_k-\hat{x}_k)^T] \\ &\ \ \ \ = E\{[(I-K_kH )\tilde{e}_k-K_k{v_k}] [(I-K_kH )\tilde{e}_k-K_k{v_k}]^T\}\\ &\ \ \ \ = E\{[(I-K_kH )\tilde{e}_k-K_k{v_k}] [\tilde{e}_k^T(I-K_kH )^T-v_k^TK_k^T]\}\\ &\ \ \ \ = E\{(I-K_kH )\tilde{e}_k \tilde{e}_k^T(I-K_kH )^T-(I-K_kH )\tilde{e}_kv_k^TK_k^T-K_k{v_k}\tilde{e}_k^T(I-K_kH )^T+K_k{v_k}v_k^TK_k^T\}\\ &\ \ \ \ = E\{(I-K_kH )\tilde{e}_k \tilde{e}_k^T(I-K_kH )^T\}-E\{(I-K_kH )\tilde{e}_kv_k^TK_k^T\}-E\{K_k{v_k}\tilde{e}_k^T(I-K_kH )^T\}+E\{K_k{v_k}v_k^TK_k^T\}\\ \end{aligned} \tag{21} pk=E[(xk−x^k)(xk−x^k)T] =E{[(I−KkH)e~k−Kkvk][(I−KkH)e~k−Kkvk]T} =E{[(I−KkH)e~k−Kkvk][e~kT(I−KkH)T−vkTKkT]} =E{(I−KkH)e~ke~kT(I−KkH)T−(I−KkH)e~kvkTKkT−Kkvke~kT(I−KkH)T+KkvkvkTKkT} =E{(I−KkH)e~ke~kT(I−KkH)T}−E{(I−KkH)e~kvkTKkT}−E{Kkvke~kT(I−KkH)T}+E{KkvkvkTKkT}(21)
方便起见,先但看第二项
: E { ( I − K k H ) e ~ k v k T K k T } E\{(I-K_kH )\tilde{e}_kv_k^TK_k^T\} E{(I−KkH)e~kvkTKkT},由于 ( I − K k H ) (I-K_kH ) (I−KkH), K k T K_k^T KkT是常数,因此:
E { ( I − K k H ) e ~ k v k T K k T } = ( I − K k H ) E { e ~ k v k T } K k T E\{(I-K_kH )\tilde{e}_kv_k^TK_k^T\}=(I-K_kH )E\{\tilde{e}_kv_k^T\}K_k^T E{(I−KkH)e~kvkTKkT}=(I−KkH)E{e~kvkT}KkT。
将公式17和先验误差代入,有:
E { e ~ k v k T } = E { ( x k − x ^ k ) v k T } = E { ( A x k − 1 + B u k − 1 + w k − 1 − A x ^ k − 1 − B u k − 1 ) v k T } E\{\tilde{e}_kv_k^T\}=E\{(x_k -\hat{x}_k) v_k^T\}=E\{(Ax_{k-1}+Bu_{k-1}+\textcolor{red}{w_{k-1}} -A\hat{x}_{k-1}-Bu_{k-1}) v_k^T\} E{e~kvkT}=E{(xk−x^k)vkT}=E{(Axk−1+Buk−1+wk−1−Ax^k−1−Buk−1)vkT},这其中, x ^ k − 1 \hat{x}_{k-1} x^k−1, x k − 1 {x}_{k-1} xk−1, w k − 1 w_{k-1} wk−1和 v k T v_k^T vkT是非同一时刻
的变量,因此,这两者相互独立互不影响,即: E { e ~ k v k T } = E [ A x k − 1 + w k − 1 − A x ^ k − 1 ] E [ v k T ] E\{\tilde{e}_kv_k^T\}=E[Ax_{k-1}+\textcolor{red}{w_{k-1}} -A\hat{x}_{k-1}]E[v_k^T] E{e~kvkT}=E[Axk−1+wk−1−Ax^k−1]E[vkT],因为 E [ v k T ] = 0 E[v_k^T]=0 E[vkT]=0,故第二项值为0
。同理可得第三项值为0
。因此:
p k = E { ( I − K k H ) e ~ k e ~ k T ( I − K k H ) T } + E { K k v k v k T K k T } = ( I − K k H ) E { e ~ k e ~ k T } ( I − K k H ) T + K k E { v k v k T } K k T = ( I − K k H ) p ~ k ( I − K k H ) T + K k R K k T = ( p ~ k − K k H p ~ k ) ( I − H T K k T ) + K k R K k T = p ~ k − p ~ k H T K k T − K k H p ~ k + K k H p ~ k H T K k T + K k R K k T (22) \begin{aligned} &p_k= E\{(I-K_kH )\tilde{e}_k \tilde{e}_k^T(I-K_kH )^T\}+E\{K_k{v_k}v_k^TK_k^T\}\\ &\ \ \ \ = (I-K_kH )E\{\tilde{e}_k \tilde{e}_k^T\}(I-K_kH )^T+K_kE\{{v_k}v_k^T\}K_k^T\\ &\ \ \ \ = (I-K_kH )\tilde{p}_k(I-K_kH )^T+K_kRK_k^T\\ &\ \ \ \ = (\tilde{p}_k-K_kH\tilde{p}_k )(I-H^T K_k^T)+K_kRK_k^T\\ &\ \ \ \ = \tilde{p}_k-\tilde{p}_kH^T K_k^T-K_kH\tilde{p}_k+K_kH\tilde{p}_kH^T K_k^T+K_kRK_k^T\\ \end{aligned} \tag{22} pk=E{(I−KkH)e~ke~kT(I−KkH)T}+E{KkvkvkTKkT} =(I−KkH)E{e~ke~kT}(I−KkH)T+KkE{vkvkT}KkT =(I−KkH)p~k(I−KkH)T+KkRKkT =(p~k−KkHp~k)(I−HTKkT)+KkRKkT =p~k−p~kHTKkT−KkHp~k+KkHp~kHTKkT+KkRKkT(22)
回到我们的原始目的,我们的
优化目标
就是让 p p p的迹最小,那么:
t r ( p k ) = t r ( p ~ k ) − t r ( p ~ k H T K k T ) − t r ( K k H p ~ k ) + t r ( K k H p ~ k H T K k T ) + t r ( K k R K k T ) = t r ( p ~ k ) − t r ( ( K k H p ~ k T ) T ) − t r ( K k H p ~ k ) + t r ( K k H p ~ k H T K k T ) + t r ( K k R K k T ) = t r ( p ~ k ) − 2 t r ( K k H p ~ k ) + t r ( K k H p ~ k H T K k T ) + t r ( K k R K k T ) ( 转置不改变对角位置数据 ) (23) \begin{aligned} &tr(p_k)= tr(\tilde{p}_k)-tr(\tilde{p}_kH^T K_k^T) - tr(K_kH\tilde{p}_k) + tr(K_kH\tilde{p}_kH^T K_k^T) + tr(K_kRK_k^T)\\ &\ \ \ \ \ \ \ \ \ \ \ = tr(\tilde{p}_k)-tr((K_kH\tilde{p}_k^T)^T) - tr(K_kH\tilde{p}_k) + tr(K_kH\tilde{p}_kH^T K_k^T) + tr(K_kRK_k^T)\\ &\ \ \ \ \ \ \ \ \ \ \ = tr(\tilde{p}_k)- 2tr(K_kH\tilde{p}_k) + tr(K_kH\tilde{p}_kH^T K_k^T) + tr(K_kRK_k^T)(转置不改变对角位置数据)\\ \end{aligned} \tag{23} tr(pk)=tr(p~k)−tr(p~kHTKkT)−tr(KkHp~k)+tr(KkHp~kHTKkT)+tr(KkRKkT) =tr(p~k)−tr((KkHp~kT)T)−tr(KkHp~k)+tr(KkHp~kHTKkT)+tr(KkRKkT) =tr(p~k)−2tr(KkHp~k)+tr(KkHp~kHTKkT)+tr(KkRKkT)(转置不改变对角位置数据)(23)
对公式23进行求导:
d t r ( p k ) d K k = d t r ( p ~ k ) d K k − 2 d t r ( K k H p ~ k ) d K k + d t r ( K k H p ~ k H T K k T ) d K k + d t r ( K k R K k T ) d K k = 0 − 2 ( H p ~ k ) T + 2 K k H p ~ k H T + 2 K k R (24) \begin{aligned} &\dfrac{dtr(p_k)}{dK_k}= \dfrac{dtr(\tilde{p}_k)}{dK_k} - 2\dfrac{dtr(K_kH\tilde{p}_k)}{dK_k} + \dfrac{dtr(K_kH\tilde{p}_kH^T K_k^T)}{dK_k} + \dfrac{dtr(K_kRK_k^T)}{dK_k}\\ &\ \ \ \ \ \ \ \ \ \ \ \ \ \ = 0- 2(H\tilde{p}_k)^T+2K_kH\tilde{p}_kH^T+2K_kR\\ \end{aligned} \tag{24} dKkdtr(pk)=dKkdtr(p~k)−2dKkdtr(KkHp~k)+dKkdtr(KkHp~kHTKkT)+dKkdtr(KkRKkT) =0−2(Hp~k)T+2KkHp~kHT+2KkR(24)
令公式24为0,得到 卡尔曼滤增益的最优取值(核心公式) :
K k = p ~ k H T H p ~ k H T + R (25) K_k= \dfrac{\tilde{p}_kH^T}{H\tilde{p}_kH^T+R} \tag{25} Kk=Hp~kHT+Rp~kHT(25)
从公式25可以看出,当测量噪声R很大,卡尔曼增益为0,代入公式19,得: x ^ k = x ~ ^ k \hat{{x}}_k =\hat{\tilde{x}}_k x^k=x~^k,即此时结果全部相信先验估计值。当R很小的时候,可以忽略不计,则: x ^ k = H − 1 z k \hat{{x}}_k =H^{-1}z_k x^k=H−1zk。该结果同样符合我们在章节2中得到的规律。
根据公式22和25,可以得到 后验估计误差 e k e_k ek协方差的更新公式:
p k = p ~ k − p ~ k H T K k T − K k H p ~ k + K k H p ~ k H T K k T + K k R K k T = p ~ k ( I − H T K k T ) − K k H p ~ k + K k ( H p ~ k H T + R ) K k T = p ~ k ( I − H T K k T ) − K k H p ~ k + p ~ k H T H p ~ k H T + R ( H p ~ k H T + R ) K k T = p ~ k ( I − H T K k T ) − K k H p ~ k + p ~ k H T K k T = p ~ k ( I − H T K k T ) − K k H p ~ k + ( K k H p ~ k ) T = p ~ k ( I − H T K k T ) (26) \begin{aligned} &p_k= \tilde{p}_k-\tilde{p}_kH^T K_k^T-K_kH\tilde{p}_k+K_kH\tilde{p}_kH^T K_k^T+K_kRK_k^T\\ &\ \ \ \ = \tilde{p}_k(I-H^T K_k^T)-K_kH\tilde{p}_k+K_k(H\tilde{p}_kH^T +R)K_k^T\\ &\ \ \ \ = \tilde{p}_k(I-H^T K_k^T)-K_kH\tilde{p}_k+ \dfrac{\tilde{p}_kH^T}{H\tilde{p}_kH^T+R}(H\tilde{p}_kH^T +R)K_k^T\\ &\ \ \ \ = \tilde{p}_k(I-H^T K_k^T)-K_kH\tilde{p}_k+ {\tilde{p}_kH^T}K_k^T\\ &\ \ \ \ = \tilde{p}_k(I-H^T K_k^T)-K_kH\tilde{p}_k+ {(K_kH\tilde{p}_k)}^T\\ &\ \ \ \ = \tilde{p}_k(I-H^T K_k^T)\\ \end{aligned} \tag{26} pk=p~k−p~kHTKkT−KkHp~k+KkHp~kHTKkT+KkRKkT =p~k(I−HTKkT)−KkHp~k+Kk(Hp~kHT+R)KkT =p~k(I−HTKkT)−KkHp~k+Hp~kHT+Rp~kHT(Hp~kHT+R)KkT =p~k(I−HTKkT)−KkHp~k+p~kHTKkT =p~k(I−HTKkT)−KkHp~k+(KkHp~k)T =p~k(I−HTKkT)(26) - 计算
e
k
e_k
ek的协方差矩阵:
p
k
=
E
[
e
k
e
k
T
]
=
E
[
(
x
k
−
x
^
k
)
(
x
k
−
x
^
k
)
T
]
p_k =E[e_ke_k^T]=E[(x_k-\hat{x}_k)(x_k-\hat{x}_k)^T]
pk=E[ekekT]=E[(xk−x^k)(xk−x^k)T],将公式
16
16
16和
19
19
19代入可得:
章节4.2:误差的协方差矩阵公式推导
在上一节中,我们推导出来四个公式:
- 先验估计 :
x ~ ^ k = A x ^ k − 1 + B u k − 1 (27) \hat{\tilde{x}}_k = A\hat{x}_{k-1}+Bu_{k-1} \tag{27} x~^k=Ax^k−1+Buk−1(27) - 后验估计 :
x ^ k = x ~ ^ k + K k ( z k − H x ~ ^ k ) , K k ∈ [ 0 , H − 1 ] (28) \hat{{x}}_k =\hat{\tilde{x}}_k +K_k(z_k-H\hat{\tilde{x}}_k ),K_k \in[0,H^{-1}]\tag{28} x^k=x~^k+Kk(zk−Hx~^k),Kk∈[0,H−1](28) - 卡尔曼滤增益 :
K k = p ~ k H T H p ~ k H T + R (29) K_k= \dfrac{\tilde{p}_kH^T}{H\tilde{p}_kH^T+R} \tag{29} Kk=Hp~kHT+Rp~kHT(29) - 后验估计误差
e
k
e_k
ek协方差:
p k = p ~ k ( I − H T K k T ) (30) \begin{aligned} &p_k = \tilde{p}_k(I-H^T K_k^T)\\ \end{aligned} \tag{30} pk=p~k(I−HTKkT)(30)
四个公式中存在未知量先验估计误差协方差
: p ~ k \tilde{p}_k p~k,根据先验估计误差定义: e ~ k = x k − x ~ ^ k \tilde{e}_k=x_k-\hat{\tilde{x}}_k e~k=xk−x~^k。将公式16( x k x_k xk定义)和27( x ~ ^ k \hat{\tilde{x}}_k x~^k定义)代入,可以得到:
e ~ k = x k − x ~ ^ k = A x k − 1 + B u k − 1 + w k − 1 − A x ^ k − 1 − B u k − 1 = A ( x k − 1 − x ^ k − 1 ) + w k − 1 = A e k − 1 + w k − 1 (31) \begin{aligned} & \tilde{e}_k=x_k-\hat{\tilde{x}}_k \\ &\ \ \ \ =Ax_{k-1}+Bu_{k-1}+\textcolor{red}{w_{k-1}}-A\hat{x}_{k-1}-Bu_{k-1} \\ &\ \ \ \ =A(x_{k-1}-\hat{x}_{k-1})+{w_{k-1}}\\ &\ \ \ \ =Ae_{k-1}+{w_{k-1}} \end{aligned} \tag{31} e~k=xk−x~^k =Axk−1+Buk−1+wk−1−Ax^k−1−Buk−1 =A(xk−1−x^k−1)+wk−1 =Aek−1+wk−1(31)
因此先验估计误差协方差为:
p
~
k
=
E
[
e
~
k
e
~
k
T
]
=
E
[
(
A
e
k
−
1
+
w
k
−
1
)
(
A
e
k
−
1
+
w
k
−
1
)
T
]
=
E
[
A
e
k
−
1
e
k
−
1
T
A
T
+
A
e
k
−
1
w
k
−
1
T
+
w
k
−
1
e
k
−
1
T
A
T
+
w
k
−
1
w
k
−
1
T
]
(32)
\begin{aligned} & \tilde{p}_k=E[\tilde{e}_k\tilde{e}_k^T] \\ & \ \ \ \ \ =E[(Ae_{k-1}+{w_{k-1}})(Ae_{k-1}+{w_{k-1}})^T]\\ & \ \ \ \ \ =E[Ae_{k-1}e_{k-1}^TA^T+Ae_{k-1}w_{k-1}^T+w_{k-1}e_{k-1}^TA^T+w_{k-1}w_{k-1}^T]\\ \end{aligned} \tag{32}
p~k=E[e~ke~kT] =E[(Aek−1+wk−1)(Aek−1+wk−1)T] =E[Aek−1ek−1TAT+Aek−1wk−1T+wk−1ek−1TAT+wk−1wk−1T](32)
类似于我们在处理公式21的方式,式中第二项:
E
[
A
e
k
−
1
w
k
−
1
T
]
=
A
E
{
(
x
k
−
1
−
x
^
k
−
1
)
w
k
−
1
T
}
=
E
{
(
A
x
k
−
2
+
B
u
k
−
2
+
w
k
−
2
−
A
x
^
k
−
2
−
B
u
k
−
2
)
w
k
−
1
T
}
E[Ae_{k-1}w_{k-1}^T]=AE\{(x_{k-1} -\hat{x}_{k-1}) w_{k-1}^T\}=E\{(Ax_{k-2}+Bu_{k-2}+\textcolor{red}{w_{k-2}} -A\hat{x}_{k-2}-Bu_{k-2}) w_{k-1}^T\}
E[Aek−1wk−1T]=AE{(xk−1−x^k−1)wk−1T}=E{(Axk−2+Buk−2+wk−2−Ax^k−2−Buk−2)wk−1T}。
由于
w
k
−
1
w_{k-1}
wk−1和
w
k
−
2
w_{k-2}
wk−2,
x
k
−
2
x_{k-2}
xk−2,
x
^
k
−
2
\hat{x}_{k-2}
x^k−2处于非同一时刻
,因此
e
k
−
1
e_{k-1}
ek−1和
w
k
−
1
T
w_{k-1}^T
wk−1T相互独立
。那么:
E
[
A
e
k
−
1
w
k
−
1
T
]
=
E
[
A
e
k
−
1
]
E
[
w
k
−
1
T
]
=
0
E[Ae_{k-1}w_{k-1}^T]=E[Ae_{k-1}]E[w_{k-1}^T]=0
E[Aek−1wk−1T]=E[Aek−1]E[wk−1T]=0,同理第三项也是0。因此可以得到:
- 先验估计误差协方差的计算公式(更新公式) :
p ~ k = E [ e ~ k e ~ k T ] = E [ A e k − 1 e k − 1 T A T + A e k − 1 w k − 1 T + w k − 1 e k − 1 T A T + w k − 1 w k − 1 T ] = E [ A e k − 1 e k − 1 T A T + w k − 1 w k − 1 T ] = A p k − 1 A T + Q (33) \begin{aligned} & \tilde{p}_k=E[\tilde{e}_k\tilde{e}_k^T] \\ & \ \ \ \ \ =E[Ae_{k-1}e_{k-1}^TA^T+Ae_{k-1}w_{k-1}^T+w_{k-1}e_{k-1}^TA^T+w_{k-1}w_{k-1}^T]\\ & \ \ \ \ \ =E[Ae_{k-1}e_{k-1}^TA^T+w_{k-1}w_{k-1}^T]\\ & \ \ \ \ \ =Ap_{k-1}A^T+Q\\ \end{aligned} \tag{33} p~k=E[e~ke~kT] =E[Aek−1ek−1TAT+Aek−1wk−1T+wk−1ek−1TAT+wk−1wk−1T] =E[Aek−1ek−1TAT+wk−1wk−1T] =Apk−1AT+Q(33)
章节5:卡尔曼滤波器对数据进行处理
根据第四章节,我们可以得到卡尔曼滤波器对数据进行处理的步骤( 五个核心公式)为:
- 首先,在预测阶段:
- 根据状态空间方程对数据进行 先验估计 : x ~ ^ k = A x ^ k − 1 + B u k − 1 \hat{\tilde{x}}_k = A\hat{x}_{k-1}+Bu_{k-1} x~^k=Ax^k−1+Buk−1
- 更新 先验估计误差协方差 : p ~ k = A p k − 1 A T + Q \tilde{p}_k=Ap_{k-1}A^T+Q p~k=Apk−1AT+Q
- 然后,根据测量值校正预测值:
- 计算 卡尔曼增益: K k = p ~ k H T H p ~ k H T + R K_k= \dfrac{\tilde{p}_kH^T}{H\tilde{p}_kH^T+R} Kk=Hp~kHT+Rp~kHT
- 更新 后验估计误差协方差 : p k = p ~ k ( I − H T K k T ) p_k = \tilde{p}_k(I-H^T K_k^T) pk=p~k(I−HTKkT)
- 根据数据融合算法,得到 后验估计: x ^ k = x ~ ^ k + K k ( z k − H x ~ ^ k ) \hat{{x}}_k =\hat{\tilde{x}}_k +K_k(z_k-H\hat{\tilde{x}}_k ) x^k=x~^k+Kk(zk−Hx~^k)
个人理解,为了使用卡尔曼滤波器,需要初始化 x ^ 0 \hat{x}_0 x^0和 p 0 p_0 p0。一般情况下我会将测量值的第一个值初始化为 x ^ 0 \hat{x}_0 x^0, p 0 p_0 p0也采用测量仪器测量误差协方差。
代码示例
使用方式示例:
- 先定义一个卡尔曼指针:Kalman_t p;
- 调用KalmanCreate()创建并初始化该卡尔曼滤波器;
- 读取传感器数据,然后调用KalmanFilter()滤波。
Kalman p; // 定义卡尔曼滤波器结构体
float SersorData; // 传感器数据
KalmanCreate(&p,1,10); // 初始化卡尔曼滤波器
while(1)
{
SersorData = sersor(); // 获取传感器数据
SersorData = KalmanFilter(&p,SersorData); // 传感器数据滤波
}
/**
* @name Kalman_t struct
* @brief 卡尔曼滤波器的结构体
* @param 见内部的标注
*
* @retval none
* @attention 注意,由于此代码创建时只用于陀螺仪单轴数据滤波,因此所有的变量结构没有定义成矩阵格式。如果需要可以使用stm32FPU开启矩阵计算。
*/
typedef struct {
float X_last; //上一时刻的后验估计值:\hat{X}_{k-1}
float X_pre; //当前时刻的先验估计值:\hat{\tilde{X}}_k
float X_now; //当下时刻的后验估计值: \hat{X}_k
float P_mid; //当前时刻先验估计误差协方差: \tilde{p}_k
float P_now; //当前时刻后验估计误差协方差: p_k
float P_last; //上一时刻后验估计误差协方差:p_{k-1}
float Kk; //卡尔曼增益
float A; //状态转换矩阵
float B; //控制转换矩阵
float Q; //系统噪声误差(协方差)
float R; //测量噪声误差(协方差)
float H; //量测矩阵
}Kalman_t;
/**
* @name kalmanCreate
* @brief 创建卡尔曼滤波器
* @param p: 滤波器结构体
* T_Q:系统噪声误差(协方差)
* T_R:测量噪声误差(协方差)
*
* @retval none
*/
void KalmanCreate(Kalman_t *p,float T_Q,float T_R)
{
p->X_last = (float)0;
p->P_last = 0;
p->Q = T_Q;
p->R = T_R;
p->A = 1;
p->B = 0;
p->H = 1;
p->X_mid = p->X_last;
}
/**
* @name KalmanFilter
* @brief 卡尔曼滤波器
* @param p: 滤波器的结构体变量
* dat: 要滤波的数据
* @retval 返回滤波后的数据
* @attention
* A=1 B=0 H=1 I=1 W(K) V(k)是白噪声,叠加在测量值上了,可以忽略不计
* 该函数对应我们本章总结的五个核心公式
*/
float KalmanFilter(Kalman_t* p,float dat)
{
p->X_mid =p->A*p->X_last; //先验估计
p->P_mid = p->A*p->P_last+p->Q; //先验估计误差
p->Kk = p->P_mid/(p->P_mid+p->R); //卡尔曼增益
p->X_now = p->X_mid+p->kg*(dat-p->X_mid); //后验估计(数据融合)
p->P_now = (1-p->Kk)*p->P_mid; //后验估计误差
p->P_last = p->P_now; //更新上一时刻后验估计误差
p->X_last = p->X_now; //更新上一时刻后验估计
return p->X_now; //返回滤波后数据值
}
章节6:拓展卡尔曼滤波器-Extended Kalman Filter(EKF)
拓展卡尔曼滤波的作用就是对非线性测量系统进行滤波,但是由于我们前面讨论的都是针对线性系统的。而且原来服从高斯分布的变量经过非线性系统之后,不再服从高斯分布。所以,为了解决这问题,我们就要想办法把非线性系统通过近似的方式转化为线性系统。这个利器就是:泰勒展开
。(等待后续增加)