Kalman滤波器的原理与实现

卡尔曼滤波器(Kalman Filter)是一个十分强大滤波器,虽然叫做滤波器,卡尔曼滤波器其实可以起到到两个作用,即预测与更新,这与我们在其运行时所关注的环节有关。当我们关注预测状态量这一步时,我们可以通过卡尔曼滤波器获取状态量的超前预测值,预测的值取决于滤波对象的运动建模。而当我们关注更新来获取最优估计状态时,我们关心的是如何通过卡尔曼增益以及测量量估计量来获取当前的最优估计状态,这时卡尔曼滤波就像一个正常的滤波器。本篇是看完Dr_Can博士对于卡尔曼滤波的讲解后的小笔记。

链接在这Dr_Can的卡尔曼滤波器讲解

一些参数明确

在解释卡尔曼滤波之前,需要先明确一些参数,如下

\(x_k\) 为\(k\)时刻的状态量的真实值\(\\\)

\(\hat{x}_k^-\) 为\(k\)时刻的状态量的先验预测值\(\\\)

\(\hat{x}_{k-1}\) 为\(k-1\)时刻的状态量的最优后验估计值\(\\\)

\(z_k\) 为\(k\)时刻的测量量\(\\\)

\(u\) 为外部输入的控制量\(\\\)

\(B\) 为控制量矩阵\(\\\)

\(A\) 为状态转移矩阵\(\\\)

\(P^-\) 为误差协方差矩阵的先验预测值\(\\\)

\(P\) 为误差协方差矩阵\(\\\)

\(H\) 为观测转移矩阵\(\\\)

\(Q\) 为状态噪声协方差矩阵\(\\\)

\(R\) 为测量噪声协方差矩阵\(\\\)

\(K_k\) 为卡尔曼增益\(\\\)

例子引出

给出一个匀速运动模型的例子来引出卡尔曼滤波。这也是一个经典的例子。

给出一个做匀速直线运动的小球,其速度为\(V\),其相对于某坐标系的位置为\(x\),根据运动学相关的知识,可以写出小球的运动方程\(x_{t} = x_{t-1} + V_x * t\)。假设小球不仅在\(x\)方向上有运动,在\(y\)方向上也有同样的匀速直线运动,其\(y\)方向的运动方程为\(y_{t} = y_{t-1} + V_y * t\)。即我们现在有了描述小球运动的两个方程,再加上速度的两个方程\(V_{xt} = V_{xt-1}\)以及\(V_{yt} = V_{yt - 1}\)。我们称物体的以上的变量为物体的状态量,也就是我们想要获得一些量。

\[x_{t} = x_{t-1} + V_{xt-1} t \\
y_{t} = y_{t-1} + V_{yt-1} t \\
V_{xt} = V_{xt-1} \\
V_{yt} = V_{yt - 1}
\]

不妨写为矩阵相乘的形式

\[\begin{bmatrix}
x_t \\
y_t \\
V_{xt} \\
V_{yt}
\end{bmatrix} =
\begin{bmatrix}
1&0&t&0 \\
0&1&0&t \\
0&0&1&0 \\
0&0&0&1
\end{bmatrix}
\begin{bmatrix}
x_{t-1} \\
y_{t-1} \\
V_{xt-1} \\
V_{yt-1}
\end{bmatrix}
\]

倘若假设采样时间为1即\(t = 1\),可以写成

\[\begin{bmatrix}
x_t \\
y_t \\
V_{xt} \\
V_{yt}
\end{bmatrix} =
\begin{bmatrix}
1&0&1&0 \\
0&1&0&1 \\
0&0&1&0 \\
0&0&0&1
\end{bmatrix}
\begin{bmatrix}
x_{t-1} \\
y_{t-1} \\
V_{xt-1} \\
V_{yt-1}
\end{bmatrix}
\]

可以看出,\(t\)时刻物体的状态量可以由\(t-1\)时刻物体的状态量来推算出来。此时我们将上式记为

\[x_{t} = Ax_{t-1}
\]

显然有时物体并不会一直线性运动,假设此时物体被外部因素赋予(输入)一个加速度\(a\),则物体此时的运动方程变为

\[x_{t} = x_{t-1} + V_{xt-1} t + \frac{1}{2}at^2\\
V_{xt} = V_{xt-1} + at
\]

则矩阵形式的方程变为

\[\begin{bmatrix}
x_t \\
y_t \\
V_{xt} \\
V_{yt}
\end{bmatrix} =
\begin{bmatrix}
1&0&t&0 \\
0&1&0&t \\
0&0&1&0 \\
0&0&0&1
\end{bmatrix}
\begin{bmatrix}
x_{t-1} \\
y_{t-1} \\
V_{xt-1} \\
V_{yt-1}
\end{bmatrix} +
\begin{bmatrix}
0&\frac{1}{2}t^2 \\
0&\frac{1}{2}t^2 \\
0&t\\
0&t
\end{bmatrix}
\begin{bmatrix}
a_x \\
a_y
\end{bmatrix}
\]

不妨记为

\[x_{t} = Ax_{t-1} + Bu
\]

这样我们就得出了如何使用前一时刻或者说前一次的状态量来获得预测当前的状态量。不难看出,预测的准不准,取决于对观测物体运动建模的准确性。

倘若模型不准确,根据该模型推理出的数据是有噪声干扰和误差的,我们将这个噪声干扰叫做\(w_i\)。并假设噪声的概率分布符合期望为0的正态分布(这是卡尔曼滤波的重要假设之一),即\(P(w_i)\sim N(0,Q)\)。加上这个误差后的公式为

\[x_{t} = Ax_{t-1} + Bu + w_i
\]

需要注意的是\(w_i\)也为一个矩阵,同理\(Q\)也为一个协方差矩阵,这是一个多元正态分布。

此时我们再来考虑更多一种情况。倘若我们不仅可以通过模型对状态量进行预测得出当前时刻的状态量,同时还可以通过一些测量仪器来获得物体的当前状态的测量值。

在这个例子中可以认为有一个雷达来检测物体每一时刻的位置信息以及速度信息。这些测量值统称为\(z_k\),为一个矩阵。注意测量量的维度并不要求与状态量相同。考虑到有时测量量与状态量可能需要些许转换,如测量电阻时我们总是使用电压处以电流(\(R = \frac{U}{I}\))的转换,我们将这种转换关系使用一个矩阵\(H\)表示,\(H\)就表示状态量可以通过某个公式或者关系转换到测量量。在上面的例子中,\(H\)为单位矩阵。综上,可以得出以下式子。

\[z_k = H x_k
\]

当然,考虑到测量仪器测量时的各种噪声以及误差,我们将其记为\(v_i\),并假设其概率分布也满足正态分布,即\(P(v_i)\sim N(0,R)\)。

最终得出

\[z_k = Hx_k + v_i
\]

最后,我们好像得出了观测物体的两个值,一个是通过不太精确的模型得出的预测值,另一个是通过不太准确的仪器测出的当前的测量值。我们所有的信息只有这两个值。那么如何在一些合理的假设下,通过这两个不太准确的值,获得最接近物体真实值的最优解呢?这便是这便是卡尔曼滤波所要做的事情,通过两个不准确值来估计出最接近真实值的最优解。

写在题外:这两个公式实质上的严格数学推导是由现代控制理论里的状态空间表达式的离散形式得出的,想要了解更多的推导请看Dr_Can的卡尔曼滤波器讲解,讲的非常详细易懂!

卡尔曼滤波简单推导

下面对卡尔曼滤波的一些思想和公式进行简单的说明

数据融合

考虑最简单的均值滤波,对于物体的某一属性(如上述的位置\(x\))我们已经有\(k-1\)个已经测量到的值,以及当前第\(k\)次的测量值。为了利用当前这些数据获取接近真实值的值,我们最容易想到的就是均值滤波,也就是从1到\(k\)的测量取均值。

\[\hat{x_k} = \frac{1}{k}\sum_{i = 1}^kx_i
\]

不妨将其做以下变换

\[\hat{x_k} = \frac{1}{k}(x_1 + ... + x_{k-1} + x_k) \\
\hat{x_k} = \frac{1}{k}\sum_{i=1}^{k-1}x_i + \frac{1}{k}x_{k}\\
\hat{x_k} = \frac{k-1}{k}\frac{1}{k-1}\sum_{i=1}^{k-1}x_i + \frac{1}{k}x_{k} \\
记\frac{1}{k-1}\sum_{i=1}^{k-1}x_i = \hat{x_{k-1}} \\
\hat{x_k} = \frac{k-1}{k} \hat{x_{k-1}} + \frac{1}{k}x_k = \hat{x_{k-1}} + \frac{1}{k}(\hat{x_{k-1}} - x_k)
\]

最终我们得出了这个式子

\[\hat{x_k} = \hat{x_{k-1}} + \frac{1}{k}(x_k - \hat{x_{k-1}})
\]

不难看出,当前\(k\)时刻的估计值由\(x_{k-1}\)时刻的估计值\(\hat{x_{k-1}}\)以及\(k\)时刻的测量值\(x_k\)来共同决定,而\(\frac{1}{k}\)这个系数决定了这两者的占比。我们不妨令\(\frac{1}{k} = G\),这里姑且称其为卡尔曼增益。且\(\hat{x_{k-1}}\)可以视为基于前\(k-1\)次的数据对第\(k\)次的数据的一个预测或者说估计。不妨即为\(\hat{x_k}^-\)

利用这个思想,对于小球的例子中,\(x_{k}\)时刻的预测值可以由运动方程给出

\[\hat{x_k}^- = A\hat{x_{k-1}} + Bu_{k-1}
\]

且\(k\)时刻的测量量满足以下

\[z_k = Hx_k \\
x_k = H^-z_k
\]

利用上述思想,得出\(k\)时刻的估计值为

\[\hat{x_k} = \hat{x_k}^- + G(x_k -\hat{x_k}^- ) = \hat{x_k}^- + G( H^-z_k - \hat{x_k}^-)
\]

不妨假设\(G = K_kH\),带入得出

\[\hat{x_k} = \hat{x_k}^- + K_k(z_k - H\hat{x_k}^-)
\]

这便是卡尔曼滤波的核心公式之一,我们使用这个公式来估计当前状态量的最优值。至于为何为最优,后续会给出简单说明。

协方差矩阵

这部分是概率统计的知识。对于随机变量\(X\),我们可以用期望\(E(x)\)来描述它的平均水平或者一个趋势,同时可以使用方差\(D(x)\)或者\(Var(x)\)来描述其波动情况。同时我们定义这样一个式子

\[Cov(X,Y) = E((X - E(X))(Y - E(Y)))
\]

称\(Cov(X,Y)\)为两个随机变量的协方差。不难看出,协方差描述了两个变量之间的相关程度,具体可以看这个通俗理解协方差。当两个变量相互独立时,其协方差为0,说明彼此毫无关系,互不影响。

对于两个随机变量\(X\)和\(Y\),可以给出一个矩阵来描述其各个变量之间的关系

\[P = \begin{bmatrix}
\sigma_{xx}&\sigma_{xy} \\
\sigma_{yx}&\sigma_{yy}
\end{bmatrix}
\]

这样使用协方差矩阵就可以记录出2个以及多个随机变量之间的关系。

对于\(e = [e_1\quad e_2]\)假设随机变量\(e_1,e_2\)符合正态分布\((0,\sigma)\)(基本上卡尔曼滤波就是建立在所有误差都是正态分布这个假设上的),其各个元素协方差矩阵可以这样求

\[E[e *e^T]
\]

展开即为

\[\begin{bmatrix}
E(e_1e_1)&E(e_1e_2) \\
E(e_2e_1)&E(e_2e_2)
\end{bmatrix}
\]

已知方差的计算式有\(D(x) = E(x^2) - E^2(x)\),且我们已知符合期望为0的正态分布,则\(E(x) = 0\),故有\(D(x) = E(x^2)\),同理对于协方差的计算式\(Cov(X,Y) = E(XY) - E(X)E(Y)\),应用如上条件变为\(Cov(X,Y) = E(XY)\),这两个公式应用于上式有

\[\begin{bmatrix}
E(e_1^2)&E(e_1e_2) \\
E(e_2e_1)&E(e_2^2)
\end{bmatrix}
=
\begin{bmatrix}
\sigma_{e_1e_1}&\sigma_{e_1e_2} \\
\sigma_{e_2e_1}&\sigma_{e_2e_2}
\end{bmatrix}
\]

这个公式在推导卡尔曼增益的计算式时会用到。

卡尔曼公式简单推导

先给出卡尔曼滤波的五个核心公式,然后对其做一些说明

\[\hat{x_k}^- = A\hat{x_{k-1}} + Bu_{k-1}\qquad [1] \\
P_k^- = AP_{k-1}A^T + Q \qquad[2]\\
K_k = P_k^-H^T/(HP^-_kH^T + R) \qquad [3]\\
\hat{x_k} = \hat{x_k}^- + K_k(z_k - H\hat{x_k}^-) \qquad [4] \\
P_k = P_k^- - K_k HP_k^-或者(I - K_kH)P_k^- \qquad [5]
\]

[1]式

\[\hat{x_k}^- = A\hat{x_{k-1}} + Bu_{k-1}
\]

对于1式,我们将上一部分推断的公式写到这里

\[x_{k} = Ax_{k-1} + Bu_{k-1} + w_i
\]

估计时,误差已经融入估计的计算,也就是误差与噪声是包含在模型本身中的,无法像上面一样直接提出来一个\(w_i\),因此我们将这个带有误差与噪声的预测值记为\(\hat{x_k}^-\),代表着状态量的先验预测值。这样我们就得出来第一个公式

\[\hat{x_k} = A\hat{x_{k-1}} + Bu_{k-1}
\]

[4]式

\[\hat{x_k} = \hat{x_k}^- + K_k(z_k - H\hat{x_k}^-)
\]

对于4式,我们可以看到出现了当前的最优估计值\(\hat{x_{k}}\)以及先验预测值\(\hat{x_{k}}^-\)和测量量\(z_k\)。还有一个新的量\(K_k\),我们称之为卡尔曼增益。卡尔曼增益是卡尔曼滤波中最为灵魂最为重要的一个量。

不难看出,当\(K_k = 0\)时(实际上是一个全0矩阵),\(x\)在\(k\)时刻的最优估计值\(\hat{x_k}\)就为\(k\)时刻的先验预测值\(\hat{x_{k}}^-\),当\(K_k = H\)时,\(\hat{x_k}\)就为测量值\(H^-z_k\)(这是由测量量\(z_k = Hx_k\)两边同乘\(H^-\)得\(x_k = H^-z
_k\))。因此\(K_k\)这个参数决定了测量量与预测量对于最优估计值的贡献程度。

利用上面中数据融合的思想可以知道,为了求出当前状态下最优的估计值,我们唯一不知道的量就是\(K_k\)。而衡量最优的条件是什么呢?显然在概率统计中,方差越小,数据围绕真实值越集中。因此我们此时的目标就是寻找一个\(K_k\)的计算式,这样的\(K_k\)使得\(
x_k -\hat{x_k}\)的方差(多元数据使用协方差矩阵的迹)最小。

[3]式

\[K_k = P_k^-H^T/(HP^-_kH^T + R)
\]

再讲这个式子之前,我们不妨给出一个真实状态量与后验最优估计量之间的误差的量化。

\[e_k = x_k - \hat{x_k}
\]

同理,假设\(e_k\)的误差也符合正态分布\(P(e_k)\sim{N(0,P)}\)。与噪声的方差一样,\(P\)也是一个协方差矩阵,反映了\(e_k\)的各个状态之间的关系以及误差。以匀速运动的物体为例,我们仅关注其位置为状态量。

\[P =
\begin{bmatrix}
\sigma_{xx} & \sigma_{xy} \\
\sigma_{xy} & \sigma_{yy}
\end{bmatrix}
\]

因此当前的目的就是寻求一个\(K_k\),使得\(e_k\)的误差最小,也就是协方差矩阵的迹最小(迹上的元素描述的是各个变量相对于其真实值的误差,而其他元素描述的是各个变量之间的相关性)。我们依旧认为\(e_k\)符合正态分布\((0,P)\),由上述协方差矩阵的计算式可知

\[P = E(e_ke_k^T)\\
\]

带入\(e_k\)

\[P = E((x_k - \hat{x_k})(x_k - \hat{x_k})^T)\\
\]

又已知\(\hat{x_k}\)的表达式为

\[\hat{x_k} = \hat{x_k}^- + K_k(z_k - H\hat{x_k}^-)
\]

将其带入计算P的式子,这样\(K_k\)就引入进来了。接着只需要应用一些线性代数的技巧化简即可。最后对得到的式子求导取极值可以得到\(K_k\)的计算式

\[K_k = P_k^-H^T/(HP^-_kH^T + R)
\]

其中

\[P_k^- = E(e_k^-{e_k^-}^T)
\]

[2]式

对于[2]式,是由\(k-1\)次的误差协方差矩阵推算出\(k\)次的先验误差协方差矩阵的过程。使用了计算公式\(D(AX) = AD(X)A^T\),外加上噪声矩阵Q的测量噪声,可以得出[2]式

\[P_k^- = AP_{k-1}A^T + Q
\]

这是很不严谨的推理,算不上推导,推导请看Dr_Can的卡尔曼滤波讲解

[5]式

最后,我们要更新误差协方差矩阵,得出根据\(\hat{x_k}\)计算出的最新的误差协方差矩阵。直接使用公式

\[P = E((x_k - \hat{x_k})(x_k - \hat{x_k})^T)
\]

带入求出表达式即可。最终得出

\[P_k = P_k^- - K_k HP_k^-或者(I - K_kH)P_k^-
\]

综上,[1][2]式用来根据模型进行当前状态的预测,[3][4][5]式用来对当前状态进行最优估计,这两部分不断循环执行,一个卡尔曼滤波器就开始工作了。

相对于简单的均值滤波,我们可以看到卡尔曼滤波并不太依赖于之前的一些数据与状态,本次的更新仅取决于上一次的数据,而且可以取得不错的效果。而均值的话非常依赖之前的样本数量,样本数量少的话会导致本次的估计不太准确

至此,卡尔曼滤波的黄金五式就解释完啦,知识水平有限,讲的很粗糙,有错误的话记得提醒我。

简单扩展Kalman滤波器

显然,kalman滤波器的预测的第一个式子

\[\hat{x_k}^- = A\hat{x_{k-1}} + Bu_{k-1}
\]

注定了卡尔曼滤波只能使用与线性系统,且系统的各种误差与噪声均符合期望为0的正态分布。那么,对于非线性系统,怎么才可以使用卡尔曼滤波呢?答案是线性化。

对于一个使用非线性模型描述的系统(即包含\(sinx,cosx,e^x\)),我们可以通过泰勒展开的方式将其线性化。通过非线性函数在上一次最优估计\(\hat{x_{k-1}}\)处的一阶泰勒展开,将其化为多项式的形式。对于一些矩阵如A,B,H等,可以利用矩阵求导的知识将其化为对应的雅可比矩阵来求解。

也就是说扩展卡尔曼滤波与卡尔曼滤波的不同之处仅在于预测这一步中的模型是非线性系统线性化后的模型,其他的步骤与普通而卡尔曼滤波一模一样。

Kalman滤波器的原理与实现的更多相关文章

  1. Kalman滤波器从原理到实现

    Kalman滤波器的历史渊源 We are like dwarfs on the shoulders of giants, by whose grace we see farther than the ...

  2. Kalman滤波器原理和实现

    Kalman滤波器原理和实现 kalman filter Kalman滤波器的直观理解[1] 假设我们要测量一个房间下一刻钟的温度.据经验判断,房间内的温度不可能短时大幅度变化,也就是说可以依经验认为 ...

  3. 【计算机视觉】基于Kalman滤波器的进行物体的跟踪

    预估器 我们希望能够最大限度地使用測量结果来预计移动物体的运动. 所以,多个測量的累积能够让我们检測出不受噪声影响的部分观測轨迹. 一个关键的附加要素即此移动物体运动的模型. 有了这个模型,我们不仅能 ...

  4. 终于成功仿了一次Kalman滤波器

    终于成功仿了一次Kalman滤波器 首先是测试了从网上down的一段代码 % KALMANF - updates a system state vector estimate based upon a ...

  5. 想了解SAW,BAW,FBAR滤波器的原理?看这篇就够了!

    想了解SAW,BAW,FBAR滤波器的原理?看这篇就够了!   很多通信系统发展到某种程度都会有小型化的趋势.一方面小型化可以让系统更加轻便和有效,另一方面,日益发展的IC**技术可以用更低的成本生产 ...

  6. 运动目标跟踪中kalman滤波器的使用

    目标跟踪的kalman滤波器介绍 Kalman滤波器是通过前一状态预测当前状态,并使用当前观测状态进行校正,从而保证输出状态平稳变化,可有效抵抗观测误差.因此在运动目标跟踪中也被广泛使用.在视频处理的 ...

  7. FIR滤波器工作原理(算法)以及verilog算法实现(包含与IIR的一些对比)

    滤波器在2017年IC前端的笔试中,出现频率十分的高.不论今后是否会涉及,还是要记住一些会比较好.接下来就将从这四个方面来讲解,FIR数字滤波器的工作原理(算法)与verilog实现. ·什么是FIR ...

  8. kalman滤波器公式的推导

    卡尔曼滤波的使用范围: 该系统要有如下关系: 计算步骤: PART0:INI PART1:Time update 迭代的目标:从X(K-1)+ 求得X(K) + 因此,先有X(K-1)+,已知F,G. ...

  9. 扩展卡尔曼滤波(MRPT)

    EKF relies on a linearisation of the evolution and observation functions which are good approximatio ...

  10. 卡尔曼滤波器 Kalman Filter (转载)

    在学习卡尔曼滤波器之前,首先看看为什么叫“卡尔曼”.跟其他著名的理论(例如傅立叶变换,泰勒级数等等)一样,卡尔曼也是一个人的名字,而跟他们不同的是,他是个现代人! 卡 尔曼全名Rudolf Emil ...

随机推荐

  1. [python]将多张图片合并为单个pdf文件

    前言 最近有个个人需求是要把多个图片文件合并为一个PDF文件,这样方便用PDF阅读器连续看,避免界面点一下,只会图片放大.(比如看漫画) 主要思路是先把单张图片转换成单个PDF文件,然后把PDF文件进 ...

  2. 一: Mysql字符集问题

    ## Mysql 字符集问题 1 修改MySQL5.7字符集 1.1 修改步骤 在MySQL 8.0版本之前,默认字符集为 latin1 ,utf8字符集指向的是 utf8mb3 .网站开发人员在数据 ...

  3. Java //100以内的质数的输出(从2开始,到这个数-1结束为止,都不能被这个数本身整除)+优化

    1 //100以内的质数的输出(从2开始,到这个数-1结束为止,都不能被这个数本身整除) 2 boolean isFlag = true; //标识i是否被j除尽,修改其值 3 4 for(int i ...

  4. c语言四则运算小程序

    本文源程序代码来源于csdn一位博主: 文章链接:http://t.csdnimg.cn/L29fs 原程序简洁凝练,以简短的代码写出了一个加法运算器. 以下是运行结果(本文全程用visual stu ...

  5. [VueJsDev] 基础知识 - Button的全局节流

    [VueJsDev] 目录列表 https://www.cnblogs.com/pengchenggang/p/17037320.html Button的全局节流 ::: details 目录 目录 ...

  6. 基于ads1299的可穿戴脑电信号采集之性能调试总结

    一 前言 问题背景: 最近做项目,遇到了一个问题,就是采集的信号有噪声,在这里做了很多尝试.   二 测试步骤 A 内部方波信号质量,通过测试发现内部方波信号质量特别好.这个说明了软件和存储这块,没啥 ...

  7. day03-应用线程01

    JavaGUI-坦克大战03 7.线程的应用01 7.1坦克子弹发射思路 在坦克大战2.0基础上添加如下功能:当玩家按下 j 键,就发射一颗子弹. 思路: 当发射一颗子弹后,就等于启动了一个线程 He ...

  8. 01.Android线程池实践基础

    目录介绍 01.实际开发问题 02.线程池的优势 03.ThreadPoolExecutor参数 04.ThreadPoolExecutor使用 05.线程池执行流程 06.四种线程池类 07.exe ...

  9. 记录--开局一张图,构建神奇的 CSS 效果

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 假设,我们有这样一张 Gif 图: 利用 CSS,我们尝试来搞一些事情. 图片的 Glitch Art 风 在这篇文章中 --CSS 故障 ...

  10. C# OpenCv DNN 人脸检测

    using OpenCvSharp; using OpenCvSharp.Dnn; using System; using System.Collections.Generic; using Syst ...