卡尔曼滤波器(一维):几种方法?

dan*_*451 3 python algorithm filtering kalman-filter

我试着理解卡尔曼滤波器是如何工作的,因为多维变体在一开始就太混乱了,我开始用一维的例子.

我找到了3个不同的资料来解释温度计的情景,但所有这些情景实现了略微不同的方程式,我不明白这一点.

我实现了解决方案2,但我的卡尔曼滤波器并没有真正起作用(它非常适合测量,而不是真正考虑它上面的噪声).

所以,在我浪费更多时间尝试解决方案1或3之前(我刚才读过):有人能为一维卡尔曼滤波器提供干净的解释和/或代码示例吗?


解决方案1

// x_est: current estimate;           p: current estimate error;
// a:     constant of the system;    kg: kalman gain
// z:     current observation; 

// Predict
x_est   =   a * x_est
p       =   a * p * a

// Update
kg      =   p  / (p  + r)
x_est   =   x_est + kg * (z - x_est)
p       =   (1 - kg) * p
Run Code Online (Sandbox Code Playgroud)

作者(这里)只解释我们只更改当前值,因为不需要温度计来考虑最后一个值.

所以他简化了:

p[k] = (1 - kg) * p[k-1] p = (1 - kg) * p

x_est[k] = x_est[k-1] + kg * (z - x_est[k-1]) x_est = x_est + kg * (z - x_est)

...等等...

我不明白为什么这是可能的.我认为卡尔曼滤波器的一个主要部分是考虑当前观测z是否有用(通过卡尔曼增益).因此,对于高卡尔曼增益,增量kg * (z - x_est[k-1])的"大块" z - x_est[k-1]被添加到新估计中.如果总是计算当前值,这整件事情是否变得毫无意义?


解决方案2

# q: process variance / process noise
# r: error in measurement

x_est = x_est
p     = p + q;

k     = p / (p + r);
x_est = x_est + k * (z – x_est);
p     = (1 – k) * p;
Run Code Online (Sandbox Code Playgroud)

这几乎是一样的,但作者甚至没有解释为什么x [k-1]p [k-1]可以改为xp.


解决方案3

# Q: process variance / process noise
# R: error in measurement

# prediction
x_est_kminus1[k] = x_est[k - 1]
p_kminus1[k]        = p[k - 1] + Q

# update
kg[k]     = p_kminus1[k] / (p_kminus1[k] + R)
x_est[k] = x_est_kminus1[k] + kg[k] * (z[k] - x_est_kminus1[k])
p[k]     = (1 - kg[k]) * p_kminus1[k]
Run Code Online (Sandbox Code Playgroud)

在这个解决方案中,作者有两个不同的列表x_est(x_est本身和x_est_kminus1)和p(p本身和p_kminus1).

是否需要两个列表,否则p [k]将被计算两次(在预测和更新步骤中)?

jep*_*pio 13

所有这些解决方案都是一般方程的特例,我们必须看看每个方程的特殊之处.

适当的方程式

让我们从1D案例的适当通用方程开始:

# prediction
x[k] = a * x[k - 1]
p[k] = a * p[k - 1] * a + q
# update
y = z - h * x[k]
kg = p * h / (h * p * h + r)
x[k] = x[k] + kg * y
p[k] = (1 - kg * h) * p[k]
Run Code Online (Sandbox Code Playgroud)
  • x - 国家
  • p - 错误(协方差)
  • a - 国家转型
  • q - 过渡错误
  • z - 测量
  • h - 状态到测量的转换
  • y - 根据预测和我们实际测量的结果,我们预期测量的差异
  • kg - 卡尔曼获益
  • r - 测量误差

所有的模型(的参数a,q,r,h)可在主也有一个索引k作为系统的发展和变化.但在简单的情况下,它们都可以被视为不变的.

解决方案与正确的方程式有何不同

只有解决方案1实现了一个a,这很好.a告诉你状态如何从一步变为另一步,如果你假设温度是静止的那么a == 1,就像在解决方案2和3中一样.

解决方案1没有q.q是我们可以估算过程错误的地方.同样,如果过程是关于系统静止(a == 1)那么我们可以设置q = 0.

您的解决方案都没有h,这是观察转换(如何从测量到状态).如果您正在估算温度,则根据温度的测量结果h = 1.

一个例子h可能与1不同,如果你测量的东西比你感兴趣的估计,例如使用湿度测量来估算温度.然后h线性变换T(humidity) = h * humidity.我强调线性,因为上面是线性卡尔曼滤波器方程,它们只适用于线性(在数学意义上)系统.

当前和上一步的问题

的问题,kk - 1具有x_estx_est_kminus1纯粹是执行的问题.在这方面,您的所有解决方案都是相同的.

您对解决方案1的思考kk - 1解决方案已经完成.只有预测阶段需要考虑当前和前一步骤(因为它是基于前一步骤的当前状态的预测),而不是更新步骤.更新步骤作用于预测.

从可读性的观点来看,解3最接近数学方程.原则上,预测步骤还没有给我们x_est[k],但更像是predicted_x_est[k].然后更新步骤在此运行,predicted_x_est[k]并提供我们的实际x_est[k].

然而正如我所说,所有实现都是等效的,因为当它们被编程时,您可以看到在预测步骤之后,不再需要过去.因此,您可以安全地使用一个变量,px无需保留列表.

关于卡尔曼获益

你写了:

因此,对于高卡尔曼增益kg*(z-x_est [k-1]),将delta z-x_est [k-1]的"大块"添加到新估计.如果总是计算当前值,这整件事情是否变得毫无意义?

在这些情况下,卡尔曼增益只能在0和1之间.什么时候最大?当r(测量误差)为0时,这意味着我们无限地信任我们的测量.然后该等式简化为

x_est = x_est + z - x_est
Run Code Online (Sandbox Code Playgroud)

这意味着我们放弃了我们的预测值(x_est在右侧)并将我们的更新估算值设置为与我们的测量值相等.当我们无限地信任我们衡量的东西时,这是有效的事情.

适应测量

我实现了解决方案2,但我的卡尔曼滤波器并没有真正起作用(它非常适合测量,而不是真正考虑它上面的噪声).

调整卡尔曼滤波器很棘手,需要深入了解系统和正确估计qr.请记住,这q是过程中的错误(状态演变),r是我们测量的错误.如果您的卡尔曼滤波器过于适应测量,则意味着:

  • q 太大了
  • r 太小

或两者的结合.您必须使用值来查找有效的值.