How a Kalman filter works, in pictures


本文是一个学习笔记,内容的 原文

What is it?

卡尔曼滤波是一种通用的强大的信息融合(combining information)工具(但是因为最原始卡尔曼滤波是一种线性的,对严重的非线性无法很好的估计,所以有后续的扩展卡尔曼滤波,后续更新),可以在任何有不确定信息(uncertain information)的地方使用,即使系统又很大的干扰也可以得到不错的结果,并且可以利用到你想象不到的相关性。

卡尔曼滤波非常适合这些不断变化的系统。它们具有的优点是:轻量级存储(它们不需要保存上一状态以外的任何历史数据),计算快速,这使得它们非常适合于实时问题和嵌入式系统。

What we do with a Kalman filter?

看一个小栗子:有一个机器人在深林里漫步,她需要知道自己哪里可以走
robot
假设她在状态 x k ⃗ \vec{x_k} xk ,包含有位置和速度信息: x k ⃗ = ( p ⃗ , v ⃗ ) \vec{x_k} = (\vec{p}, \vec{v}) xk =(p ,v )

状态就是你系统基本配置(configuration)的数字列表;它可以是任何变量。在这个例子中,状态就是位置和速度,但是它可以是油罐中液体的总量数据、引擎的温度、用户手指在平板上的位置,或者任何你想要观察的数据。

我们的机器人有一个 GPS,精确约为10米,正常工作,但是我们对机器人定位的精度要求高于10米。树林里有很多沟和崖,如果机器人走错几英尺,就可能跌落悬崖。所以仅有 GPS 是不够的。
掉下悬崖
我们还知道机器人如何移动的一些信息:她发送给轮子的指令,她的头的朝向以及没有障碍,下一步,它可能就沿着这个方向前进。当然,它不可能知道运动过程中的所有状况:它可能被风刮倒,车轮可能打滑,或者在颠簸的路面侧翻;所以轮子的转角并不能精确的表示机器人走了多远,这个预测不是完美的。
GPS告诉我们一些状态信息,但是不直接的,有一些不确定性和不准确性。我们的预测是告诉我们机器人如何移动,但也是不直接的,有一些不确定性和不准确性。
如果我们能利用所有可用的信息,能给我们跟好的估计结果,这既是卡尔曼滤波的精髓

How a Kalman filter sees your problem

继续刚才的问题,我们还是使用简单的状态,只有位置和速度的情况:
x ⃗ = [ p v ] \vec{x} = \begin{bmatrix} p\\ v \end{bmatrix} x =[pv]
我们不知道实际的位置和速度,有一系列可能的位置与速度的组合,但是其中的一些可能性更高:

高斯0,
上图是一个二维高斯分布的投影图片,卡尔曼滤波假设两个变量(位置和速度,在我们的case中)是随机高斯分布的。每个变量都有均值 μ \mu μ(随机分布的中心)和方差 σ 2 \sigma^2 σ2(表示不确定性)。

在这里插入图片描述
上图表示的是位置和速度是不相关的,相关性的概念在概率论里有讲。大概意思就是一个变量不会告诉你另一个变量的信息。

下面的例子中:位置和速度是相关的。一个指定位置的可能观测值取决于速度:

高斯3
这种情况用于利用上旧的状态估计下一个状态,速度越大跑的越远。

这种关系在跟踪定位时非常重要,因为这会提供更多信息:一个测量值告诉我们其他测量值的可能范围。这就是卡尔曼滤波器的目标,我们希望从不确定的测量值中得到尽可能多的信息

这种关系由协方差矩阵给出。简单来说,协方差矩阵的每个元素 Σ i j \Sigma_{ij} Σij都是第 i i i个状态变量和第 j j j个状态变量的相关程度。(所以协方差矩阵是对称的,交换 i i i j j j并不影响)协方差矩阵通常用“ Σ \Sigma Σ”表示,所以将其元素称为“ Σ i j \Sigma_{ij} Σij”。

高斯2

Describing the problem with matrices

我们要建模需要在时间 k k k上的Gaussian blob,需要两条信息,最优估计 x ^ k \mathbf{\hat{x}_k} x^k(也称为均值 μ \mu μ)和协方差矩阵 P k \mathbf{P_k} Pk
x ^ k = [ position velocity ] P k = [ Σ p p Σ p v Σ v p Σ v v ] (1) \begin{aligned} \mathbf{\hat{x}}_k &= \begin{bmatrix} \text{position}\\ \text{velocity} \end{bmatrix}\\ \mathbf{P}_k &= \begin{bmatrix} \Sigma_{pp} & \Sigma_{pv} \\ \Sigma_{vp} & \Sigma_{vv} \\ \tag{1} \end{bmatrix} \end{aligned} x^kPk=[positionvelocity]=[ΣppΣvpΣpvΣvv](1)
(这里只用到了位置和速度,但记得状态可以包括许多变量你想要的都可以呈现上去)

接下来我们需要在当前状态(current state) k − 1 k-1 k1 时刻去预测在在 k k k 时刻的下一个状态。记得我们并不知道哪个状态是真实的,但是预测方程并不关心。它根据所有可能状态,给出一个新的分布:

高斯7

我们可以用矩阵 F k \mathbf{F_k} Fk 表示该预测步骤:
高斯8
把我们原始估计(original estimate)的每一个点移动到新的预测点,如果原始估计是对的话,这些预测点就是系统可能移动的地方。(注:这里的原始估计就是上图中蓝色的框框的区域,是 k − 2 k-2 k2时刻估计出来的)
我们用基本的运动学方程来表示这个估计:
p k = p k − 1 + Δ t v k − 1 v k = v k − 1 \begin{aligned} \color{deeppink}{p_k} &= \color{royalblue}{p_{k-1}} + \Delta t &\color{royalblue}{v_{k-1}} \\ \color{deeppink}{v_k} &= &\color{royalblue}{v_{k-1}} \end{aligned} pkvk=pk1+Δt=vk1vk1
用矩阵表示:

x ^ k = [ 1 Δ t 0 1 ] x ^ k − 1 = F k x ^ k − 1 (2) \begin{aligned} \color{deeppink}{\mathbf{\hat{x}}_k} &= \begin{bmatrix} 1 & \Delta t \\ 0 & 1 \end{bmatrix} \color{royalblue}{\mathbf{\hat{x}}_{k-1}}\\ &= \mathbf{F}_k \color{royalblue}{\mathbf{\hat{x}}_{k-1}} \tag{2} \end{aligned} x^k=[10Δt1]x^k1=Fkx^k1(2)
我们现在有了预测下一状态的预测矩阵,但是仍然不知道怎样更新协方差矩阵。

我们需要另一个方程。如果我们对分布中的每一个点乘以一个矩阵 A \color{firebrick}{\mathbf{A}} A,那么协方差矩阵 Σ \Sigma Σ这比较简单,我将直接给出:

C o v ( x ) = Σ C o v ( A x ) = A Σ A T (3) \begin{aligned} Cov(x) &= \Sigma\\ Cov(\color{firebrick}{\mathbf{A}}x) &= \color{firebrick}{\mathbf{A}} \Sigma \color{firebrick}{\mathbf{A}}^T \end{aligned} \tag{3} Cov(x)Cov(Ax)=Σ=AΣAT(3)
结合(2)和(3):
x ^ k = F k x ^ k − 1 P k = F k P k − 1 F k T (4) \begin{aligned} \color{deeppink}{\mathbf{\hat{x}}_k} &= \mathbf{F}_k \color{royalblue}{\mathbf{\hat{x}}_{k-1}} \\ \color{deeppink}{\mathbf{P}_k} &= \mathbf{F_k} \color{royalblue}{\mathbf{P}_{k-1}} \mathbf{F}_k^T \end{aligned} \tag{4} x^kPk=Fkx^k1=FkPk1FkT(4)

External influence

我们没有利用到所有信息,外部世界的某些变化可能跟状态没有关系,但是会影响到系统。例如列车员推动气阀会使车的速度变化,同样我们的机器人会发送指令给轮子走或停。如果我们知道更多的关于真实世界的信息,我们可以将这些写成一个向量叫做 u k ⃗ \color{darkorange}{\vec{\mathbf{u}_k}} uk ,加入到我们的预测作为一种修正。
例如我们知道加速度 a \color{darkorange}{a} a表示控制指令,从基础的运动学公式:
p k = p k − 1 + Δ t v k − 1 + 1 2 a Δ t 2 v k = v k − 1 + a Δ t \begin{aligned} \color{deeppink}{p_k} &= \color{royalblue}{p_{k-1}} + {\Delta t} &\color{royalblue}{v_{k-1}} + &\frac{1}{2} \color{darkorange}{a} {\Delta t}^2 \\ \color{deeppink}{v_k} &= &\color{royalblue}{v_{k-1}} + & \color{darkorange}{a} {\Delta t} \end{aligned} pkvk=pk1+Δt=vk1+vk1+21aΔt2aΔt
矩阵形式:
x ^ k = F k x ^ k − 1 + [ Δ t 2 2 Δ t ] a = F k x ^ k − 1 + B k u k ⃗ (5) \begin{aligned} \color{deeppink}{\mathbf{\hat{x}}_k} &= \mathbf{F}_k \color{royalblue}{\mathbf{\hat{x}}_{k-1}} + \begin{bmatrix} \frac{\Delta t^2}{2} \\ \Delta t \end{bmatrix} \color{darkorange}{a} \\ &= \mathbf{F}_k \color{royalblue}{\mathbf{\hat{x}}_{k-1}} + \mathbf{B}_k \color{darkorange}{\vec{\mathbf{u}_k}} \end{aligned} \tag{5} x^k=Fkx^k1+[2Δt2Δt]a=Fkx^k1+Bkuk (5)
B k \mathbf{B}_k Bk叫控制矩阵(control matrix), u k ⃗ \color{darkorange}{\vec{\mathbf{u}_k}} uk 叫控制向量(control vector),如果没有外界控制影响可以忽略他们。

External uncertainty

如果状态只根据自身的属性变化,则没有问题。如果状态同时根据外部作用变化,只要我们知道外部作用力是啥,也没有问题。原文举例这里不解释了。

我们关于“世界”(我们没有keep track的)的不确定性建模,每一步预测都添加一点新的不确定性:

高斯9
在原始估计中的每一个状态都能够转移到一定状态范围。因为高斯斑,可以说,在 x ^ k − 1 \color{royalblue}{\mathbf{\hat{x}}_{k-1}} x^k1的每一个点,都移动到了一个协方差为 Q k \color{mediumaquamarine}{\mathbf{Q}_k} Qk的高斯斑中。换一种说法就是,我们将不确定的影响看作是协方差 Q k \color{mediumaquamarine}{\mathbf{Q}_k} Qk的噪声。

高斯10a
(注:增加了不确定性以后,原来的一个点转移到下一时刻就是根据方程算出来对应的某处,但是增加了不确定性以后,可能在新的区域绿色框框内的某处了)

这会产生一个新的高斯斑,有新的协方差(相同的期望):

高斯10b
这个扩展的协方差通过加 Q k \color{mediumaquamarine}{\mathbf{Q}_k} Qk得到,所以完整的预测表达式:
x ^ k = F k x ^ k − 1 + B k u k ⃗ P k = F k P k − 1 F k T + Q k \begin{aligned} \color{deeppink}{\mathbf{\hat{x}}_k} &= \mathbf{F}_k \color{royalblue}{\mathbf{\hat{x}}_{k-1}} + \mathbf{B}_k \color{darkorange}{\vec{\mathbf{u}_k}} \\ \color{deeppink}{\mathbf{P}_k} &= \mathbf{F_k} \color{royalblue}{\mathbf{P}_{k-1}} \mathbf{F}_k^T + \color{mediumaquamarine}{\mathbf{Q}_k} \end{aligned} x^kPk=Fkx^k1+Bkuk =FkPk1FkT+Qk
也就是说,新的最优估计是由上一时刻的最优估计进行预测,加上已知外部影响的修正得到的。

新的不确定性是由上一时刻的不确定性进行预测,加上一些环境中额外的不确定性

这就简单了,我们有了系统当前状态的模糊估计( x ^ k , P k \color{deeppink}{\mathbf{\hat{x}}_k},\color{deeppink}{\mathbf{P}_k} x^k,Pk)。接下来看看从传感器获取数据时发生了什么。

Refining the estimate with measurements(测量值矫正估计)

系统有一些传感器,间接给一些状态信息,换句话说就是:传感器在某一状态,给出一系列读数。

在这里插入图片描述
读数的单位和量程可能与状态的不同,我们用矩阵 H k \mathbf{H}_k Hk对传感器建模。

在这里插入图片描述
我们能够得到传感器读数的分布:
μ ⃗ expected = H k x ^ k Σ expected = H k P k H k T \begin{aligned} \vec{\mu}_{\text{expected}} &= \color{deeppink}\mathbf{H}_k \color{deeppink}{\mathbf{\hat{x}}_k} \\ \mathbf{\Sigma}_{\text{expected}} &= \color{deeppink}\mathbf{H}_k \color{deeppink}{\mathbf{P}_k} \mathbf{H}_k^T \end{aligned} μ expectedΣexpected=Hkx^k=HkPkHkT
卡尔曼滤波适合于处理传感器的噪声。也就是说,传感器多少都会有些不可靠性,原始估计中的每一个状态的传感器读数都会是一个范围值。

高斯14
从我们观测到的每一个读数,我们可能猜测系统在一个特定的状态。但是因为存在不确定性,观测到的数据中某些状态的可能性会比较高。(眼见不一定为实,某些数据偏高了)

高斯11
称这个不确定性(传感器噪声)的协方差为 R k \color{mediumaquamarine}{\mathbf{R}_k} Rk。该分布的期望和观测到的读数相同 ,称为 z k ⃗ \color{yellowgreen}{\vec{\mathbf{z}_k}} zk

现在,我们得到两个高斯斑:一个表示系统状态预测;一个表示传感器读数。

高斯4
接下来就是要协调预测值和传感器读数值。

所以哪个更接近真实的状态呢?我们认为观测的是错误的,预测值是我们想看到的。如果我们有两个概率,想知道两个概率都是真的(重叠)只要把他们乘起来(概率论的知识)。

高斯6a
重叠的部分就是最有可能的部分,就是根据已有的新的的最好估计。看起来像另一个高斯斑(gaussian blob)。

高斯6

Combining Gaussians

(注:这节前面就是一些概率论的知识,两个高斯函数相乘的分布等等,不会的就补数学知识咯)
先假设一维的高斯分布相乘: N ( x , μ 0 , σ 0 ) ⋅ N ( x , μ 1 , σ 1 ) = ? N ( x , μ ’ , σ ’ ) \begin{aligned} \mathcal{N}(x, \color{fuchsia}{\mu_0}, \color{deeppink}{\sigma_0}) \cdot \mathcal{N}(x, \color{yellowgreen}{\mu_1}, \color{mediumaquamarine}{\sigma_1}) \stackrel{?}{=} \mathcal{N}(x, \color{royalblue}{\mu’}, \color{mediumblue}{\sigma’}) \end{aligned} N(x,μ0,σ0)N(x,μ1,σ1)=?N(x,μ,σ) 结果:
μ ’ = μ 0 + σ 0 2 ( μ 1 – μ 0 ) σ 0 2 + σ 1 2 σ ’ 2 = σ 0 2 – σ 0 4 σ 0 2 + σ 1 2 \begin{aligned} \color{royalblue}{\mu’} &= \mu_0 + \frac{\sigma_0^2 (\mu_1 – \mu_0)} {\sigma_0^2 + \sigma_1^2}\\ \color{mediumblue}{\sigma’}^2 &= \sigma_0^2 – \frac{\sigma_0^4} {\sigma_0^2 + \sigma_1^2} \end{aligned} μσ2=μ0+σ02+σ12σ02(μ1μ0)=σ02σ02+σ12σ04
简单分解出一个因子 k \color{purple}{\mathbf{k}} k
k = σ 0 2 σ 0 2 + σ 1 2 \begin{aligned} \color{purple}{\mathbf{k}} = \frac{\sigma_0^2}{\sigma_0^2 + \sigma_1^2} \end{aligned} k=σ02+σ12σ02

μ ’ = μ 0 + k ( μ 1 – μ 0 ) σ ’ 2 = σ 0 2 – k σ 0 2 \begin{aligned} \color{royalblue}{\mu’} &= \mu_0 + &\color{purple}{\mathbf{k}} (\mu_1 – \mu_0)\\ \color{mediumblue}{\sigma’}^2 &= \sigma_0^2 – &\color{purple}{\mathbf{k}} \sigma_0^2 \end{aligned} μσ2=μ0+=σ02k(μ1μ0)kσ02
我们把上式写成高维的形式: Σ \Sigma Σ表示高斯斑的协方差矩阵, μ ⃗ \vec{\mu} μ 表示每个轴的均值:
K = Σ 0 ( Σ 0 + Σ 1 ) − 1 \begin{aligned} \color{purple}{\mathbf{K}} = \Sigma_0 (\Sigma_0 + \Sigma_1)^{-1} \end{aligned} K=Σ0(Σ0+Σ1)1
K \color{purple}{\mathbf{K}} K称为卡尔曼增益矩阵。

Putting it all together

我们有两个分布:预估测量 ( μ 0 , Σ 0 ) = ( H k x ^ k , H k P k H k T ) (\color{fuchsia}{\mu_0}, \color{deeppink}{\Sigma_0}) = (\color{fuchsia}{\mathbf{H}_k \mathbf{\hat{x}}_k}, \color{deeppink}{\mathbf{H}_k \mathbf{P}_k \mathbf{H}_k^T}) (μ0,Σ0)=(Hkx^k,HkPkHkT)和观测测量 ( μ 1 , Σ 1 ) = ( z k ⃗ , R k ) (\color{yellowgreen}{\mu_1}, \color{mediumaquamarine}{\Sigma_1}) = (\color{yellowgreen}{\vec{\mathbf{z}_k}}, \color{mediumaquamarine}{\mathbf{R}_k}) (μ1,Σ1)=(zk ,Rk),把他们弄到一起:
H k x ^ k ’ = H k x ^ k + K ( z k ⃗ – H k x ^ k ) H k P k ’ H k T = H k P k H k T – K H k P k H k T \begin{aligned} \mathbf{H}_k \color{royalblue}{\mathbf{\hat{x}}_k’} &= \color{fuchsia}{\mathbf{H}_k \mathbf{\hat{x}}_k} & + & \color{purple}{\mathbf{K}} ( \color{yellowgreen}{\vec{\mathbf{z}_k}} – \color{fuchsia}{\mathbf{H}_k \mathbf{\hat{x}}_k} ) \\ \mathbf{H}_k \color{royalblue}{\mathbf{P}_k’} \mathbf{H}_k^T &= \color{deeppink}{\mathbf{H}_k \mathbf{P}_k \mathbf{H}_k^T} & – & \color{purple}{\mathbf{K}} \color{deeppink}{\mathbf{H}_k \mathbf{P}_k \mathbf{H}_k^T} \end{aligned} Hkx^kHkPkHkT=Hkx^k=HkPkHkT+K(zk Hkx^k)KHkPkHkT
卡尔曼增益是:
K = H k P k H k T ( H k P k H k T + R k ) − 1 \begin{aligned} \color{purple}{\mathbf{K}} = \color{deeppink}{\mathbf{H}_k \mathbf{P}_k \mathbf{H}_k^T} ( \color{deeppink}{\mathbf{H}_k \mathbf{P}_k \mathbf{H}_k^T} + \color{mediumaquamarine}{\mathbf{R}_k})^{-1} \end{aligned} K=HkPkHkT(HkPkHkT+Rk)1
H k x ^ k ’ \mathbf{H}_k \color{royalblue}{\mathbf{\hat{x}}_k’} Hkx^k H k \mathbf{H}_k Hk 去掉,把 H k P k ’ H k T \mathbf{H}_k \color{royalblue}{\mathbf{P}_k’} \mathbf{H}_k^T HkPkHkT 的左右两边都去掉,怎么去就是 线性代数的基本问题了,得到:
x ^ k ’ = x ^ k + K ’ ( z k ⃗ – H k x ^ k ) P k ’ = P k – K ’ H k P k \begin{aligned} \color{royalblue}{\mathbf{\hat{x}}_k’} &= \color{fuchsia}{\mathbf{\hat{x}}_k} & + & \color{purple}{\mathbf{K}’} ( \color{yellowgreen}{\vec{\mathbf{z}_k}} – \color{fuchsia}{\mathbf{H}_k \mathbf{\hat{x}}_k} ) \\ \color{royalblue}{\mathbf{P}_k’} &= \color{deeppink}{\mathbf{P}_k} & – & \color{purple}{\mathbf{K}’} \color{deeppink}{\mathbf{H}_k \mathbf{P}_k} \end{aligned} x^kPk=x^k=Pk+K(zk Hkx^k)KHkPk

K ’ = P k H k T ( H k P k H k T + R k ) − 1 \begin{aligned} \color{purple}{\mathbf{K}’} = \color{deeppink}{\mathbf{P}_k \mathbf{H}_k^T} ( \color{deeppink}{\mathbf{H}_k \mathbf{P}_k \mathbf{H}_k^T} + \color{mediumaquamarine}{\mathbf{R}_k})^{-1} \end{aligned} K=PkHkT(HkPkHkT+Rk)1
得到了完整的更新步骤。

x ^ k ’ \color{royalblue}{\mathbf{\hat{x}}_k’} x^k是校正后的最优估计,我们可以继续,将其与 P k ’ \color{royalblue}{\mathbf{P}_k’} Pk投入下一轮的预测、更新。
flow

后记

后记是我在看这篇intro的时候学到的一些知识点。感觉对一些参数有更深刻的理解或者解开了一些疑惑吧。

  1. 首先对于参数 A A A ,就是上面写的 F k F_k Fk k − 1 k-1 k1 k k k 的关系矩阵,实际过程中可能是个变化量,这个值跟现控里面的状态空间表达式那个有点类似吧(这个我个人感觉,还不太确定待求证); B B B 是和输入相关的矩阵; H H H 是测量状态到测量值 z k z_k zk 的变换矩阵,实际过程也可能是变换的,有时候假设不变。
  2. 测量误差协方差 R k R_k Rk 通常都是经验值,我们也可以使用一些off-line sample measurements去计算,但是怎么算,概率论只学了一维的协方差计算,还没学习高维的,以后可能会学到。
  3. 过程噪声协方差 Q k Q_k Qk 通常更难确定,因为我们没有能力去直接观察我们estimating的过程,但是通常简单的过程模型就能产生不错的结果了,如果过于复杂就会给系统认为“injects”不确定性。
  4. 通常我们就手动调参,理论上能获的更好的结果,如果需要先验地算出这两个参数,就需要系统辨识(system identification)的知识,我表示不会。
  5. 通常在 Q Q Q R R R 是固定的常数下, P k P_k Pk K k K_k Kk 可以快速地收敛并保持不变,这种情况下我们就可以off-line地估计出这两个数。
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值