扩展卡尔曼滤波器(EKF):一个面向初学者的交互式教程-翻译
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
扩展卡尔曼滤波器教程
在使用OpenPilot和Pixhawk飞控时,经常遇到扩展卡尔曼滤波(EKF)。从不同的网页和参考论文中搜索这个词,其中大部分都太深奥了。所以我决定创建自己学习教程。本教程从一些简单的例子和标准(线性)卡尔曼滤波器,通过对实际例子来理解卡尔曼滤波器。
Part 1: 一个简单的例子
想象一个飞机准备降落时,尽管我们可能会担心许多事情,像空速、燃料、等等,当然最明显是关注飞机的高度(海拔高度)。通过简单的近似,我们可以认为当前高度是之前的高度失去了一小部分。例如,当每次我们观察飞行高度时,认为飞机失去了2%的高度,那么它的当前高度是上一时刻高度的98%:
altitude current_time=0.98*altitude previous_time
工程上对上面的公式,使用“递归”这个术语进行描述。通过递归前一时刻的值,不断计算当前值。最终我们递归到初始的“基本情况”,比如一个已知的高度。
试着移动上面的滑块,看看飞机针对不同百分比的高度变化。
Part 2:处理噪声
当然, 实际从传感器比如GPS或气压计获得测量高度时,传感器的数据或多或少有所偏差。如果传感器的偏移量为常数,我们可以简单地添加或减去这偏移量来确定我们的高度。不过通常情况下,传感器的偏移量是一个时变量,使得我们所观测到的传感器数据相当于实际高度加上噪声:
observed_altitude current_time=altitude current_time+noise current_time
试着移动上面的滑块看到噪声对观察到的高度的影响。噪音被表示为可观测的海拔范围的百分比。
Part 3:全部考虑
所以现在我们有两个方程描述我们的飞机的状态:
altitude current_time = 0.98 * altitude previous_time
observed_altitude current_time = altitude current_time + noise current_time
这些方程是很容易理解,但他们不够通用处理一般系统,除了我们上面所举的例子。更一般的方程,工程上采用熟悉的像x、y和z为变量,a和b为常量,下标k代表时间。所以我们的方程变成:
x是我们系统的当前状态,xk−1是其先前的状态,a是一常数(在我们的示例中是0.98),zk 是我们当前的观测变量,vk是当前的测量噪声。卡尔曼滤波如此受欢迎的原因之一是,通过给定的观测量zk,常量a以及整体的测量噪声vk,它可以让我们得到一个对当前状态的准确的估计值xk。
我们还应该考虑到,飞机实际的高度变化可能没有描述的那么光滑。飞机通常在下降过程中是会经历一定的动荡的。这种动荡是通过定义的噪声来描述,可视为另一个噪声信号:
altitude current_time = 0.98 * altitude previous_time +turbulence current_time
一般表述为
Wk表示过程噪声,比如飞机下降过程的动荡,这是一个固有模型的一部分,而不是观测量或测量值。为了方便其他问题的讨论,我们将忽略过程噪声一段时间,但我们将在传感器融合一节继续讨论它。
Part 4:状态估计
这里再次(忽略过程噪声)列出我们的两个方程,来描述我们正在观察的系统状态:
因为我们的目标是从观测量z获得状态量x,我们可以重写第二个方程为:
当然,问题是我们不知道当前的噪声vk,理论上它是不可预测的。幸运的是,卡尔曼滤波器能够使我们通过考虑当前的观测值和先前的估计值来估计当前的状态值。工程上在变量上
面使用“^”帽子符号表示估计值。所以表示当前状态的估计值。然后我们可以用先前的估计值和当前观测值的权重来表示当前的估计值。
这里的g表示权重值的增益。这个方程用红色突出显示,是因为这就是我们直接使用的卡尔曼滤波器。
现在,这一切看起来相当复杂,想象一下如果gk的取极值会如何?当gk = 0时,我们得到:
也就是说增益为0时,观测值对状态估计没有影响,当前状态级先前的状态估计值。当gk=1时,我们得到:
也就是说,当增益为1时,前面的状态估计值并不重要,我们所获取的当前状态估计完全跟当前的观测值有关。当然,实际的增益值可能介于这两种极端情况之间。试着移动下面的滑块,看到增益对获得当前状态估计的影响:
Part 5:计算增益
所以现在我们有一个公式,可以根据先前的估计值,当前的观测量,当前的增益
来计算当前状态估计。
那么,我们如何计算增益呢?答案是:间接地从噪声获得。回想下,每一个观测值都与一个特定的噪声值有关:
我们不知道每一个观测量的单独的噪声值,但我们通常能知道噪声的平均值。比如:一个传感器所发布的精度能告诉我们大概的输出的噪声值。称这个变量为r,r没有下标值,因为r不随时间而变化,与传感器的性能有关。我们可以根据r计算当前增益gk:
这里的pk是一个用于递归计算的预测误差:
让我们思考之前这两个公式是什么意思。
假设我们之前预测的误差是零。然后我们获得当前的增益为,这样下一个状态估计与当前的状态估计没有不同。这是有道理的,因为当预测值准确的时候,
我们不应该调整状态估计。在另一个极端,如果预测误差是1。然后将获得。如
果r是零,或者传感器的噪声很小,那我们的增益为1。新的状态估计与观测值有很大关系。但随着r增大,增益越来越小,换句话说,当传感器的噪声太大,则忽略一个糟糕的预测值。
第三个公式,递归地从它的前一个值pk−1和当前增益gk计算预测误差pk?当,我
们得到。所以,对于状态估计,0增益表示没有更新的预测误差。当,
我们得到。因此,增益的最大值也就是没有预测误差,当前的观测值直接用于更新当前状态。
Part 6:预测与更新
我们现在基本可以运行卡尔曼滤波器,并看到一些结果。首先,你可能会思考常量a在我们的原始方程中有什么作用:
似乎在我们的状态估计方程中消失了:
答案是,我们需要这两个方程一起来估计状态。事实上,这两个方程基于不同类型的信息,表示状态的估计。我们的原始方程表示预测状态应该是什么,第二个方程表示基于观测值的更新预测。所以我们重写原始方程:
最后,我们使用常数a表示预测误差:
这两个红色公式表示我们的卡尔曼滤波器的预测阶段。周期预测/更新的思路是,预测/更新,……重复等尽可能多的时间步长。
Part 7:运行滤波器