- 本文转载于Bzarg所写博客,点击这里可以查看原文!
我忍不住想和您分享一些关于卡尔曼滤波器的事情,因为它的作用实在是太不可思议了。出乎意料的是,几乎没有软件工程师和科学家对此有所了解,这让我感到很难过,因为它真的是在不确定情况下组合信息的通用且强大的工具。有时,它提取准确信息的能力、几乎是神奇的——如果听起来我讲的太多了,那么请看一下以前发布的视频,其中我演示了通过观察自由浮标的速度,借助卡尔曼滤波器来确定其方向的例子。
它是什么?
您可以在不确定某个动态系统信息的任何情况下使用卡尔曼滤波器,并且可以对系统接下来将要做什么做出有根据的猜测。即使现实状况出现了混乱并干扰了您所猜测的预期运动,卡尔曼滤波器通常也可以很好地弄清楚实际发生了什么。同时,它可以充分利用您可能不会想到的疯狂现象之间的相关性!
卡尔曼滤波器是不断变化的系统的理想选择。他们有这样做的好处是它们在内存上比较轻便(除了保留以前的状态,它们不需要保留任何历史记录),而且它们非常快,非常适合实时问题和嵌入式系统。
在Google上的大多数地方,用于实现Kalman过滤器的数学运算看起来都很恐怖且不透明。这是一种糟糕的情况,因为如果您以正确的方式看待卡尔曼滤波器,实际上它非常简单易懂。因此,它是一个很好的文章主题,我将尝试用许多清晰,漂亮的图片和颜色来阐明它。前提很简单;您只需要对概率和矩阵有基本的了解。
我将从卡尔曼滤镜可以解决的问题的一个简单的例子开始,但是如果您想了解闪亮的图片和数学,请随时前进。
卡尔曼滤波器能做什么?
让我们举一个玩具示例:您已经构建了一个可以在树林中四处游荡的小型机器人,并且该机器人需要确切地知道它在哪里,以便它可以导航。

我们会说我们的机器人处于状态xk,这只是位置和速度:
xk=(p,v)请注意,状态只是有关系统基础配置的数字列表。可能是任何东西。在我们的示例中,它是位置和速度,但它可能是有关油箱中的油量,汽车发动机的温度,用户手指在触摸板上的位置或需要跟踪的任何数量的数据。
我们的机器人还具有一个GPS传感器,该传感器的精确度约为10米,这很好,但是它需要比10米更精确地知道其位置。这些树林中有许多沟壑和悬崖,如果机器人错了几英尺,它可能会掉下悬崖。因此GPS本身还不够好。

我们可能还对机器人的移动方式有所了解:它知道发送给轮式电动机的命令,并且知道如果机器人朝一个方向前进,并且没有任何干扰,那么在下一瞬间它可能会沿着同一方向前进。但是当然,它并不完全了解其运动:它可能会受到风的冲击,车轮可能会打滑一点,或者在崎bump不平的地形上翻滚。因此轮子转动的数量可能无法完全代表机器人实际行驶的距离,因此预测也不是完美的。
GPS 传感器告诉我们有关状态的信息,但只能间接地告诉我们,并且存在一些不确定性或不准确性。我们的预测告诉我们有关机器人如何运行的信息,但仅是间接的,并且存在一定的不确定性或不准确性。
但是,如果我们使用所有可用的信息,是否能获得比任何一种估计本身都能提供的更好的答案?当然答案是肯定的,这就是卡尔曼滤波器的目的。
卡尔曼滤波器如何看待您的问题
让我们看一下我们要解释的风景。我们将继续一个仅具有位置和速度的简单状态。
x=[pv]我们不知道实际的位置和速度是多少。可能存在的位置和速度组合的范围很广,但其中某些组合比其他组合更有可能:

卡尔曼滤波器假设两个变量(在我们的示例中为位置和速度)都是随机的且呈高斯分布。每个变量都具有平均值,这是随机分布(及其最可能的状态)的中心,和一个方差,这是不确定性:μσ2

在上图中,位置和速度是不相关的,这意味着一个变量的状态不会告诉您其他变量的含义。
下面的示例显示了一些更有趣的内容:位置和速度相关。观察特定位置的可能性取决于您的速度:

例如,如果我们基于旧职位来估计新职位,则可能会出现这种情况。如果我们的速度很高,我们可能会走得更远,所以我们的位置会更远。如果我们走得很慢,我们就不会走得太远。
保持这种关系真的很重要,因为它可以为我们提供更多信息:一种度量可以告诉我们一些其他信息。这就是卡尔曼滤波器的目标,我们希望从不确定的测量中尽可能多地获取信息!
这种相关性被称为协方差矩阵的东西捕获。简而言之,矩阵Σij每个元素是第i个状态变量和第j个状态变量之间的相关程度。(您也许可以猜测协方差矩阵是对称的,这意味着您交换i和j都没关系)。协方差矩阵通常标记为"Σ",因此我们将它们的元素称为"Σij"。

用矩阵描述问题
我们将关于状态的知识建模为高斯Blob,因此在k时刻, 我们需要两条信息:我们将最佳估计称为x^k(平均值,在其他地方称为μ)及其协方差矩阵Pk。
x^kPk=[positionvelocity]=[ΣppΣvpΣpvΣvv]
(当然,这里我们仅使用位置和速度,但是记住状态可以包含任意数量的变量并表示您想要的任何值很有用)。
接下来,我们需要某种方式查看当前状态(在时间k-1)并预测在时间k的下一个状态。请记住,我们不知道哪个状态是“真实”状态,但是我们的预测功能并不在乎。它仅适用于所有这些,并为我们提供了新的发行版:

我们可以用矩阵表示此预测步骤:Fk

它占用了我们原始估计中的每个点,并将其移动到新的预测位置,如果原始估计是正确的,则系统将在该位置移动。
让我们应用这个。我们如何使用矩阵来预测未来下一时刻的位置和速度?我们将使用一个非常基本的运动学公式:
pkvk=pk−1+Δtvk−1=vk−1
换句话说:
x^k=[10Δt1]x^k−1=Fkx^k−1
现在,我们有了一个预测矩阵,该矩阵提供了我们的下一个状态,但是我们仍然不知道如何更新协方差矩阵。
这是我们需要另一个公式的地方。如果我们将分布中的每个点乘以矩阵A,那么其协方差矩阵Σ会发生什么?
好吧,这很容易。我只是给你一个标识:
Cov(x)Cov(Ax)=Σ=AΣAT
因此,将方程(4)与(3)结合:
x^kPk=Fkx^k−1=FkPk−1FkT
外部影响
但是,我们还没有捕获所有内容。可能会有一些与国家本身无关的变化-外界可能正在影响系统。
例如,如果状态模拟火车的运动,则火车操作员可能会推油门,从而导致火车加速。同样,在我们的机器人示例中,导航软件可能会发出使车轮转动或停止的命令。如果我们知道有关世界动态的其他信息,则可以将其填充到名为uk,对其进行处理,然后将其添加到我们的预测作为更正。
假设我们知道由于油门设置或控制命令而产生的预期加速度a。从基本运动学中,我们可以得到:以矩阵形式:
pkvk=pk−1+Δt=vk−1+vk−1+21aΔt2aΔt
以矩阵形式:
x^k=Fkx^k−1+[2Δt2Δt]a=Fkx^k−1+Bkuk
Bk被称为控制矩阵,uk被称为控制向量。(对于没有外部影响的非常简单的系统,可以忽略这些)。
让我们再添加一个细节。如果我们的预测不是实际情况的100%准确模型,会发生什么?
外部不确定性
如果状态基于其自身的属性而发展,则一切都很好。一切都还是好的,如果基于外部力量,状态演变,只要我们知道这些外力。
但是我们不知道的力量呢?例如,如果我们要跟踪四轴飞行器,它可能会随风摇晃。如果我们跟踪的是轮式机器人,则车轮可能会打滑,或者地面上的颠簸可能会使其减速。我们无法跟踪这些事情,如果发生任何此类情况,我们的预测可能会落空,因为我们没有考虑这些额外的力量。
通过在每个预测步骤之后添加一些新的不确定性,我们可以对与“世界”相关的不确定性(即我们不跟踪的事物)进行建模:

在我们原来的估计每个状态可能已经移动到一个范围状态。因为我们非常喜欢高斯blobs,所以我们会说x^k−1中的每一个点以协方差Qk移动到高斯Blob内的某个位置。换句话说,我们将未跟踪的影响视为具有协方差的噪声Qk。

这将产生一个新的高斯斑点,其协方差不同(但均值相同):

我们可以通过简单地添加Qk来获得扩展的协方差 为预测步骤提供完整的表达方式:
x^kPk=Fkx^k−1+Bkuk=FkPk−1FkT+Qk
换句话说,新的最佳估计是根据先前的最佳估计做出的预测,加上对已知外部影响的校正。
而新的不确定性的预测从旧的不确定性,一些从环境额外的不确定性。
好吧,这很容易。我们对系统可能的位置有一个模糊的估计,在预先给定x^k和Pk的前提下。当我们从传感器中获取一些数据时会发生什么?
通过测量完善估算
我们可能有几个传感器,这些传感器可以向我们提供有关系统状态的信息。就目前而言,衡量什么并不重要。也许一个读取位置,另一个读取速度。每个传感器都告诉我们有关状态的一些间接信息,换句话说,传感器在状态下运行并产生一组读数。

请注意,读数的单位和小数位可能与我们跟踪的状态的单位和小数位不同。您也许可以猜到这是怎么回事:我们将使用矩阵Hk对传感器进行建模。

我们可以用通常的方式找出我们希望看到的传感器读数的分布:
μexpectedΣexpected=Hkx^k=HkPkHkT
卡尔曼滤波器的优点之一是处理传感器噪声。换句话说,我们的传感器至少有些不可靠,并且我们原始估计中的每个状态都可能导致一定范围的传感器读数。

从我们观察到的每次阅读中,我们可能会猜测我们的系统处于特定状态。但是由于存在不确定性,因此某些州比其他州更可能产生我们看到的读数:

我们称这种不确定性(即传感器噪声)的协方差Rk。分布的平均值等于我们观察到的读数,我们将其称为zk。
因此,现在有两个高斯斑点:一个围绕我们的转换预测的平均值,另一个围绕我们获得的实际传感器读数。

我们必须设法使基于预测状态(粉红色)的读数推测与基于实际观察到的传感器读数(绿色)的推测有所不同。
那么,我们最可能的新状态是什么?对于任何可能的传感器读数(z1,z2),我们有2个相关的概率:
(1). 传感器zk读数是(z1,z2)的(错误)测量量的概率
(2). 我们预先的估计认为(z1,z2)正是我们应该看到的读数的概率
如果我们有两个概率,并且我们想知道两个概率都为真的机会,则将它们相乘。因此,我们采用两个高斯斑点并将它们相乘:

我们剩下的就是overlap,这两个斑点都是亮的/可能的区域。而且比我们之前的任何一个估计都精确得多。这种分布的均值是最可能出现两种估计的配置,因此,鉴于我们拥有的所有信息,它是对真实配置的最佳猜测。
嗯 这看起来像另一个高斯斑点。

事实证明,当你乘两个高斯斑点具有独立的手段和协方差矩阵,你会得到一个新的高斯斑点与它自己的均值和方差矩阵!也许您可以看到进展:必须有一个公式可以从旧参数中获取这些新参数!
结合高斯
让我们找到那个公式。在一维中首先看这是最简单的。期望为μ方差为σ2的一维高斯分布曲线被定义如下:
N(x,μ,σ)=σ2π1e−2σ2(x–μ)2
我们想知道将两个高斯曲线相乘会发生什么。下面的蓝色曲线表示两个高斯总体的(未归一化)交集:

N(x,μ0,σ0)⋅N(x,μ1,σ1)=?N(x,μ’,σ’)
您可以将方程式(9)替换掉(10)中,然后进行一些数学简化(需要注意的是重新进行归一化,然后使得总的概率和为1),然后得到:
μ’σ’2=μ0+σ02+σ12σ02(μ1–μ0)=σ02–σ02+σ12σ04
我们可以通过删除一小部分并将其命名为k来简化 :
kμ’σ’2=σ02+σ12σ02=μ0+k(μ1–μ0)=σ02–kσ02
请注意如何进行以前的估算并添加一些内容以进行新的估算。看看这个公式有多简单!
但是矩阵版本呢?好吧,让我们重新编写方程式(12)和(13)以获得矩阵形式。如果Σ是高斯Blob的协方差矩阵,且μ是其沿着每个轴的均值(期望),那么:
Kμ’Σ’=Σ0(Σ0+Σ1)−1=μ0+K(μ1–μ0)=Σ0–KΣ0
K是一个称为Kalman增益的矩阵,我们将在稍后使用它。
简单!我们快完成了!
放在一起
我们有两个分布:
预测的测量分布——(μ0,Σ0)=(Hkx^k,PkHkHkT);
观测的测量分布——(μ1,Σ1)=(zk,Rk);
将二者插入等式(15)可以得到他们的重叠部分:
Hkx^k’HkPk’HkT=Hkx^k=HkPkHkT+–K(zk–Hkx^k)KHkPkHkT
从等式(14)中计算得到的卡尔曼增益为:
K=HkPkHkT(HkPkHkT+Rk)−1
观察到有一个Hk隐含在K中,因此我们可以从(16)、(17)的每个式子中去掉开头的Hk,然后在计算Pk’的公式两边去掉尾端的HkT。
x^k’Pk’=x^k=Pk+–K’(zk–Hkx^k)K’HkPk
K’=PkHkT(HkPkHkT+Rk)−1
…为我们提供了更新步骤的完整方程式。
就是这样!x^k’是我们新的最佳估算值,我们可以继续反馈它(以及Pk’)返回到我们希望的另一轮预测或更新中。

总结一下
在上述所有数学中,您需要实现的只是方程式(7)、(18)和(19)(或者,如果您忘记了这些内容,则可以从方程式(4)、(15)中重新推导一切)。
这将使您能够准确地对任何线性系统建模。对于非线性系统,我们使用扩展的卡尔曼滤波器,该滤波器通过简单地线性化预测和测量值的均值来工作。(将来我可能会对EKF进行第二次撰写)。
如果我做得很好,希望外面的人会意识到这些东西有多酷,并想出一个意想不到的新地方将它们付诸实践。
最后
感谢Bzarg写的这篇博客,读起来确实是非常通俗易懂,让人感觉学习是一种享受。