卡尔曼滤波器行为

4 投票
1 回答
1055 浏览
提问于 2025-04-18 23:01

我使用了这里实现的卡尔曼滤波器:https://gist.github.com/alexbw/1867612

我对它的理解非常基础。这是我写的测试代码:

import matplotlib.pyplot as plt
import numpy as np
from Kalman import Kalman

n = 50    
d = 5

xf = np.zeros(n - d)
yf = np.zeros(n - d)

xp = np.zeros(d)
yp = np.zeros(d)

x = np.zeros(n)
y = np.zeros(n)

for i in range(n):

    if i==0:
        x[i] = 05
        y[i] = 20
        KLF = Kalman(6, 2)

    elif i< (n - d):
        xf[i], yf[i] = KLF.predict()  
        x[i] = x[i-1] + 1
        y[i] = y[i-1] + np.random.random() * 10
        NewPoint = np.r_[x[i], y[i]]
        KLF.update(NewPoint)
    else:
        x[i] = x[i-1] + 1
        y[i] = y[i-1] + np.random.random() * 10
        xp[n - i -1], yp[n - i -1] = KLF.predict()  
        NewPoint = np.r_[x[i] , yp[n - i -1]]
        KLF.update(NewPoint)

plt.figure(1)
plt.plot(x, y, 'ro') #original
plt.plot(xp, yp, 'go-') #predicted kalman
plt.plot(xf, yf, 'b') #kalman filter
plt.legend( ('Original', 'Prediction', 'Filtered') ) 
plt.show()

enter image description here

我的问题是,为什么卡尔曼滤波器的起始值是0,而我的数据是从x=5,y=20开始的?这是某种标准行为吗?

谢谢

1 个回答

8

当前的卡尔曼实例状态存储在 x 属性中:

In [48]: KLF = Kalman(6, 2)

In [49]: KLF.x
Out[49]: 
matrix([[ 0.],
        [ 0.],
        [ 0.],
        [ 0.],
        [ 0.],
        [ 0.]])

这六个部分代表了位置、速度和加速度。所以默认情况下,卡尔曼实例的起始位置是 (0,0),速度和加速度都是零。

在创建了 KLF 之后,当 i=1 时,第一次对 xfyf 的修改是通过调用 KLF.predict 来实现的:

xf[i], yf[i] = KLF.predict()

这里有两个问题。首先,xf[0], yf[0] 从来没有被更新,所以它们仍然保持在 (0, 0)。因此,蓝线是从 (0, 0) 开始的。

第二个问题是,由于卡尔曼类的定义,KLF.x 的当前状态默认是 (0, 0)。如果你想让 KLF 实例的起始位置是 (5, 20),那么你需要自己修改 KLF.x

另外,请记住,卡尔曼滤波器的工作流程是先进行 观察,然后再进行 预测。这一点在类的文档说明中有提到。

现在我不太明白你代码的意图,所以不打算去理清 update 应该在 predict 之前的逻辑,但关于设置初始状态,你可以使用这个:

if i==0:
    x[i] = 5
    y[i] = 20
    KLF = Kalman(6, 2)
    KLF.x[:2] = np.matrix((x[0], y[0])).T
    xf[i], yf[i] = KLF.predict()  

这样会得到

enter image description here

撰写回答