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

6

我试图理解卡尔曼滤波器的工作原理。因为多维变量对初学者来说过于复杂,所以我从一个一维示例开始。

我找到了三个不同的来源解释了温度计的场景,但是所有这些情况都实现了略微不同的方程,我没有抓住重点。

我实现了解决方案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

作者在这里只是解释了我们只改变当前值,因为温度计没有必要考虑最后一个值。
所以他简化了以下内容:

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;

这基本上是一样的,但是作者甚至没有解释为什么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]

在这个解决方案中,作者为 x_estx_est本身和x_est_kminus1)以及pp本身和p_kminus1)准备了两个不同的列表。
两个列表是否需要是因为如果不这样做,p[k]会在预测步骤和更新步骤中计算两次吗?
1个回答

17

所有这些解决方案都是一维情况下通用方程的特殊情况,我们需要看到每个方程的特殊之处。

适当的方程式

让我们从一维情况下的适当通用方程开始:

# 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]

以下是需要翻译的内容:
  • x - 状态
  • p - 错误(协方差)
  • a - 状态转移
  • q - 转移误差
  • z - 测量值
  • h - 状态到测量的转换
  • y - 基于预测所期望测量值和实际测量值之间的差异
  • kg - 卡尔曼增益
  • r - 测量误差

模型的所有参数(aqrh)在原则上都可以具有索引k并随系统演变而改变。但在简单情况下,它们都可以视为恒定。

解决方案与正确方程式的不同之处

只有解决方案1实现了一个a,这很好。如果假设温度是稳定的,则a == 1,就像解决方案2和3一样,a告诉您状态从一步到另一步的变化。

解决方案1没有qq是我们可以给出过程误差估计的地方。同样,如果过程是关于系统处于静止状态(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

这意味着我们放弃了预测值(右侧的x_est),并将更新后的估计值设置为等于我们的测量值。当我们无限信任所测量的内容时,这是一种有效的做法。
适应测量值
“我实施了解决方案2,但我的卡尔曼滤波器并没有真正起作用(它高度适应了测量值,而没有真正考虑其中的噪声)。”
调整卡尔曼滤波器很棘手,需要对系统有深入的了解和对qr进行正确估计。请记住,q是过程(状态演化)上的误差,r是我们测量值上的误差。如果您的卡尔曼滤波器过于适应测量值,则意味着:
  1. q太大
  2. r太小
或两者兼而有之。您将不得不尝试不同的值以找到可行的值。

非常感谢!我还有几个问题在阅读时浮现出来。变量 a 是否总是一个常数?如果我有一个传感器检测窗户是否打开...那么我会将 a 重置为负值吗(因为房间现在正在冷却而不是加热)?你能给出一个关于 h 的例子吗?它如何将当前估计状态转换为测量值?你忘记解释 y 了。请添加一个对它的解释好吗?它是一种"未知剩余"吗?或者它是从哪里来的? - daniel451
我们每次迭代都在更新 qr 吗?例如,当我知道温度计测量的噪声随着房间变得越来越热而增加时...或者我会根据先前的知识取一些平均误差,并且永远不会更新 qr 吗? - daniel451
@ascenator 我尝试根据您的后续问题扩展答案 - 检查编辑以获取更改。tldr版本:它们都可以更改,但这使得实现变得更加困难;qr可能是平均误差,也可能取决于状态空间中的位置而进行修改;h是线性变换。 - jepio
我有一个额外的问题:测量误差是绝对值吗?还是应该归一化到某个区间?或者它是标准偏差sigma的近似值,导致测量噪声? - daniel451
@jepio,如果您能看一下这个问题并给予帮助,我将不胜感激。https://dev59.com/06Pia4cB1Zd3GeqPujC5 - Desta Haileselassie Hagos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接