卡尔曼滤波器(一维):几种方法?
Kalman filter (one-dimensional): several approaches?
我试图了解卡尔曼滤波器的工作原理,但由于多维变体一开始太令人困惑,所以我从一个一维示例开始。
我找到了 3 个不同的来源来解释温度计的场景,但所有这些场景实现的方程略有不同,我不明白这一点。
我实施了解决方案 2,但我的卡尔曼滤波器并没有真正发挥作用(它高度适应了测量结果,并没有真正考虑到它的噪声)。
所以,在我浪费更多时间尝试解决方案 1 或 3(到目前为止我刚刚阅读)之前:有人可以提供一个清晰的解释 and/or 一维卡尔曼代码示例过滤器?
解决方案 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]
的 "big chunk" 添加到新估计中。如果总是计算当前值,这整个事情不是变得毫无意义吗?
解决方案 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]都没有解释 可以更改为 x 和 p.
解决方案 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_est
(x_est
本身和 x_est_kminus1
)和 p
(p
本身和 p_kminus1
).
是否需要两个列表,否则 p[k] 将被计算两次(在预测和更新步骤中)?
所有这些解都是一般方程的特例,我们必须看看每个解有什么特别之处。
正确的方程式
让我们从适合一维情况的一般方程开始:
# 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
- 测量误差
模型的所有参数(a
、q
、r
、h
)原则上也可以有一个索引 k
和随着系统的发展而变化。但在简单的情况下,它们都可以作为常数。
解与正确方程有何不同
只有解决方案 1 实现了 a
,这很好。 a
告诉您状态如何从一个步骤变为另一个步骤,如果您假设温度是固定的,那么 a == 1
,就像解决方案 2 和 3 一样。
解决方案 1 没有 q
。 q
是我们可以估计过程误差的地方。同样,如果该过程是关于系统静止的 (a == 1
),那么我们可以设置 q = 0
.
None 你的解决方案有一个 h
,这是观察转换(如何从测量到状态)。如果您要根据温度测量值估算温度,则 h = 1
。
h
可能与 1 不同的一个例子是,如果您测量的是您感兴趣的其他东西,例如使用湿度测量来估计温度。那么 h
将是 线性 变换 T(humidity) = h * humidity
。我强调线性是因为以上是线性卡尔曼滤波方程,它们只适用于线性(数学意义上的)系统。
当前和上一步问题
k
与 k - 1
以及 x_est
和 x_est_kminus1
的问题纯粹是一个实现问题。在这方面你所有的解决方案都是一样的。
您对解决方案 1 中 k
和 k - 1
的想法是错误的。只有预测阶段需要考虑当前和上一步(因为它是基于上一步对当前状态的预测),而不是更新步骤。更新步骤作用于预测。
从可读性的角度来看,解决方案 3 最接近数学方程式。原则上,预测步骤还没有给我们 x_est[k]
,但更像是 predicted_x_est[k]
。然后更新步骤在此 predicted_x_est[k]
上运行并为我们提供实际的 x_est[k]
.
然而正如我所说,所有实现都是等效的,因为在对它们进行编程时,您可以看到在预测步骤之后,不再需要过去。因此,您可以安全地为 p
和 x
使用一个变量,而无需保留列表。
关于卡尔曼增益
您写道:
So that for a high Kalman gain kg * (z - x_est[k-1]) a "big chunk" of
the delta z - x_est[k-1] is added to the new estimate. Isn't this whole
thing getting pointless, if one always calculates the current values?
在这些情况下,卡尔曼增益只能在0和1之间。什么时候最大?当 r
(测量误差)为 0 时,这意味着我们无限信任我们的测量。然后等式简化为
x_est = x_est + z - x_est
这意味着我们放弃了我们的预测值(右侧的 x_est
)并将更新后的估计值设置为等于我们的测量值。当我们无限相信我们测量的东西时,这是一件有效的事情。
适应测量
I implemented solution 2 but my kalman filter was not really working (it
highly adapted itself to the measurements and not really considered the
noise on it).
调整卡尔曼滤波器非常棘手,需要深入了解系统并正确估计 q
和 r
。请记住,q
是过程(状态演化)的误差,r
是我们测量的误差。如果您的卡尔曼滤波器过于适应测量结果,则意味着:
q
太大
r
太小了
或两者的结合。您必须尝试使用这些值才能找到有效的值。
我试图了解卡尔曼滤波器的工作原理,但由于多维变体一开始太令人困惑,所以我从一个一维示例开始。
我找到了 3 个不同的来源来解释温度计的场景,但所有这些场景实现的方程略有不同,我不明白这一点。
我实施了解决方案 2,但我的卡尔曼滤波器并没有真正发挥作用(它高度适应了测量结果,并没有真正考虑到它的噪声)。
所以,在我浪费更多时间尝试解决方案 1 或 3(到目前为止我刚刚阅读)之前:有人可以提供一个清晰的解释 and/or 一维卡尔曼代码示例过滤器?
解决方案 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]
的 "big chunk" 添加到新估计中。如果总是计算当前值,这整个事情不是变得毫无意义吗?
解决方案 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]都没有解释 可以更改为 x 和 p.
解决方案 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_est
(x_est
本身和 x_est_kminus1
)和 p
(p
本身和 p_kminus1
).
是否需要两个列表,否则 p[k] 将被计算两次(在预测和更新步骤中)?
所有这些解都是一般方程的特例,我们必须看看每个解有什么特别之处。
正确的方程式
让我们从适合一维情况的一般方程开始:
# 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
- 测量误差
模型的所有参数(a
、q
、r
、h
)原则上也可以有一个索引 k
和随着系统的发展而变化。但在简单的情况下,它们都可以作为常数。
解与正确方程有何不同
只有解决方案 1 实现了 a
,这很好。 a
告诉您状态如何从一个步骤变为另一个步骤,如果您假设温度是固定的,那么 a == 1
,就像解决方案 2 和 3 一样。
解决方案 1 没有 q
。 q
是我们可以估计过程误差的地方。同样,如果该过程是关于系统静止的 (a == 1
),那么我们可以设置 q = 0
.
None 你的解决方案有一个 h
,这是观察转换(如何从测量到状态)。如果您要根据温度测量值估算温度,则 h = 1
。
h
可能与 1 不同的一个例子是,如果您测量的是您感兴趣的其他东西,例如使用湿度测量来估计温度。那么 h
将是 线性 变换 T(humidity) = h * humidity
。我强调线性是因为以上是线性卡尔曼滤波方程,它们只适用于线性(数学意义上的)系统。
当前和上一步问题
k
与 k - 1
以及 x_est
和 x_est_kminus1
的问题纯粹是一个实现问题。在这方面你所有的解决方案都是一样的。
您对解决方案 1 中 k
和 k - 1
的想法是错误的。只有预测阶段需要考虑当前和上一步(因为它是基于上一步对当前状态的预测),而不是更新步骤。更新步骤作用于预测。
从可读性的角度来看,解决方案 3 最接近数学方程式。原则上,预测步骤还没有给我们 x_est[k]
,但更像是 predicted_x_est[k]
。然后更新步骤在此 predicted_x_est[k]
上运行并为我们提供实际的 x_est[k]
.
然而正如我所说,所有实现都是等效的,因为在对它们进行编程时,您可以看到在预测步骤之后,不再需要过去。因此,您可以安全地为 p
和 x
使用一个变量,而无需保留列表。
关于卡尔曼增益
您写道:
So that for a high Kalman gain kg * (z - x_est[k-1]) a "big chunk" of the delta z - x_est[k-1] is added to the new estimate. Isn't this whole thing getting pointless, if one always calculates the current values?
在这些情况下,卡尔曼增益只能在0和1之间。什么时候最大?当 r
(测量误差)为 0 时,这意味着我们无限信任我们的测量。然后等式简化为
x_est = x_est + z - x_est
这意味着我们放弃了我们的预测值(右侧的 x_est
)并将更新后的估计值设置为等于我们的测量值。当我们无限相信我们测量的东西时,这是一件有效的事情。
适应测量
I implemented solution 2 but my kalman filter was not really working (it highly adapted itself to the measurements and not really considered the noise on it).
调整卡尔曼滤波器非常棘手,需要深入了解系统并正确估计 q
和 r
。请记住,q
是过程(状态演化)的误差,r
是我们测量的误差。如果您的卡尔曼滤波器过于适应测量结果,则意味着:
q
太大r
太小了
或两者的结合。您必须尝试使用这些值才能找到有效的值。