简体   繁体   English

卡尔曼滤波预测t + 2时间步长

[英]kalman filter prediction t+2 timestep

I have a question about using the kalman filter to predict t+2 values. 我有一个关于使用卡尔曼滤波器来预测t + 2值的问题。 As we know, the basic kalman filter has two steps, predict and update. 众所周知,基本的卡尔曼滤波器有两个步骤,即预测和更新。 The predict part can generate xt based on xt-1. 预测部分可以基于xt-1生成xt。 Here are some sample codes I found on the Internet. 这是我在Internet上找到的一些示例代码。

import numpy as np

class KalmanFilter(object):
    def __init__(self, F = None, B = None, H = None, Q = None, R = None, P = None, x0 = None):

        if(F is None or H is None):
            raise ValueError("Set proper system dynamics.")

        self.n = F.shape[1]
        self.m = H.shape[1]

        self.F = F
        self.H = H
        self.B = 0 if B is None else B
        self.Q = np.eye(self.n) if Q is None else Q
        self.R = np.eye(self.n) if R is None else R
        self.P = np.eye(self.n) if P is None else P
        self.x = np.zeros((self.n, 1)) if x0 is None else x0

    def predict(self, u = 0):
        self.x = np.dot(self.F, self.x) + np.dot(self.B, u)
        self.P = np.dot(np.dot(self.F, self.P), self.F.T) + self.Q
        return self.x

    def update(self, z):
        y = z - np.dot(self.H, self.x)
        S = self.R + np.dot(self.H, np.dot(self.P, self.H.T))
        K = np.dot(np.dot(self.P, self.H.T), np.linalg.inv(S))
        self.x = self.x + np.dot(K, y)
        I = np.eye(self.n)
        self.P = np.dot(np.dot(I - np.dot(K, self.H), self.P), 
            (I - np.dot(K, self.H)).T) + np.dot(np.dot(K, self.R), K.T)

def example():
    dt = 1.0/60
    F = np.array([[1, dt, 0], [0, 1, dt], [0, 0, 1]])
    H = np.array([1, 0, 0]).reshape(1, 3)
    Q = np.array([[0.05, 0.05, 0.0], [0.05, 0.05, 0.0], [0.0, 0.0, 0.0]])
    R = np.array([0.5]).reshape(1, 1)

    x = np.linspace(-10, 10, 100)
    measurements = - (x**2 + 2*x - 2)  + np.random.normal(0, 2, 100)

    kf = KalmanFilter(F = F, H = H, Q = Q, R = R)
    predictions = []

    for z in measurements:
        predictions.append(np.dot(H,  kf.predict())[0])
        kf.update(z)

    import matplotlib.pyplot as plt
    plt.plot(range(len(measurements)), measurements, label = 'Measurements')
    plt.plot(range(len(predictions)), np.array(predictions), label = 'Kalman Filter Prediction')
    plt.legend()
    plt.show()

if __name__ == '__main__':
    example()

In this problem, we use the value of t-1 to predict t and update with the value of t. 在此问题中,我们使用t-1的值来预测t并使用t的值进行更新。 If I want to predict the value of t+1 based on t. 如果我想基于t预测t + 1的值。 I changed something accordingly: 我相应地更改了一些内容:

import numpy as np

class KalmanFilter(object):
    def __init__(self, F = None, F_1 = None, B = None, H = None, Q = None, R = None, P = None, x0 = None):

        if(F is None or H is None):
            raise ValueError("Set proper system dynamics.")

        self.n = F.shape[1]
        self.m = H.shape[1]

        self.F = F
        self.F_1 = F_1
        self.H = H
        self.B = 0 if B is None else B
        self.Q = np.eye(self.n) if Q is None else Q
        self.R = np.eye(self.n) if R is None else R       
        self.P = np.eye(self.n) if P is None else P
        self.x = np.zeros((self.n, 1)) if x0 is None else x0

    def predict(self, u = 0):
        self.x = np.dot(self.F, self.x) + np.dot(self.B, u)
        self.P = np.dot(np.dot(self.F, self.P), self.F_1) + self.Q
        return self.x

    def update(self, z):
        y = z - np.dot(self.H, self.x)
        S = self.R + np.dot(self.H, np.dot(self.P, self.H.T))
        K = np.dot(np.dot(self.P, self.H.T), np.linalg.inv(S))
        self.x = self.x + np.dot(K, y)
        I = np.eye(self.n)
        self.P = np.dot(np.dot(I - np.dot(K, self.H), self.P), 
                        (I - np.dot(K, self.H)).T) + np.dot(np.dot(K, self.R), K.T)


def example():
    dt = 1.0/60
    F_0 = np.array([[1, dt, 0], [0, 1, dt], [0, 0, 1]])
    F = np.dot(F_0, F_0)
    F_1 = np.dot(F_0.T, F_0.T)
    H = np.array([1, 0, 0]).reshape(1, 3)
    Q = np.array([[0.05, 0.05, 0.0], [0.05, 0.05, 0.0], [0.0, 0.0, 0.0]])
    R = np.array([0.5]).reshape(1, 1)

    x = np.linspace(-10, 10, 100)
    measurements = - (x**2 + 2*x - 2)  + np.random.normal(0, 2, 100)

    kf = KalmanFilter(F = F, F_1 = F_1, H = H, Q = Q, R = R)
    predictions = []

    for i in range(1, len(measurements), 2):
            predictions.append(np.dot(H,  kf.predict())[0])
            kf.update(measurements[i])

    import matplotlib.pyplot as plt
    plt.plot(range(len(measurements)), measurements, label = 'Measurements')
    plt.plot(range(len(predictions)), np.array(predictions), label = 'Kalman Filter Prediction')
    plt.legend()
    plt.show()

if __name__ == '__main__':
    example()

The major changes are these two: 主要变化是以下两个:

  1. I changed F matrix. 我改变了F矩阵。

  2. I used the value of t+1 timestep to update my result. 我使用了t + 1时间步长的值来更新我的结果。

However, the length of results I got is only half of the original measurements. 但是,我得到的结果的长度仅为原始测量值的一半。 Because of I kind of jumping to update them. 因为我有点跳来更新它们。

I'm a little confused now. 我现在有点困惑。 Does anybody have suggestions or solutions? 有人有建议或解决方案吗? Thank you so much 非常感谢

I see following problems: 我看到以下问题:

  1. The prediction of x(t+1) based on x(t) is actually the same as prediction of x(t) based on x(t-1) . 基于x(t)x(t+1)的预测实际上与基于x(t-1)x(t)的预测相同。 Everything depends on the definition of the time step ( dt ) 一切都取决于时间步长( dt )的定义
  2. You don't need to change your F matrix, it was correct in the first code. 您无需更改F矩阵,这在第一个代码中是正确的。 But it depends on your dt . 但这取决于您的dt
  3. In your second code you replaced self.FT through self.F_1 . 在第二个代码中,您通过self.F_1替换了self.FT But T stands for transpose of F . 但是T代表F transpose It is not good. 不好 That's why probably your result vector has another dimensions. 这就是为什么您的结果向量可能具有另一个维度的原因。

So if you want to predict over some amount of time, only what you need is to know this amount of time. 因此,如果您要预测一段时间,那么仅需要知道此时间即可。 It would be your new dt , which of course will change your F and Q . 这将是您的新dt ,当然会改变您的FQ

If your measurements are taken with a time step dt and you want to see what happens if each second measurement falls off you have two options: 如果您以时间步长dt测量,并且您想查看每秒钟的测量结果下降会发生什么,您有两种选择:

Option 1 选项1

Change dt of the prediction step, so that it equals the time difference between two last measurements and recalculate the F matrix with the new value dt (be aware: in this case you will need to change your Q matrix, because the system gets more uncertainty over a bigger time step). 更改预测步长的dt ,使其等于最后两次测量之间的时间差,并使用新值dt重新计算F矩阵(请注意:在这种情况下,您将需要更改Q矩阵,因为系统会获得更大的不确定性在更大的时间跨度)。

Option 2 选项2

Execute prediction with your original time step dt several times to fill the time period between the measurements. 几次以原始时间步dt执行预测,以填充两次测量之间的时间段。 So if you want to process only each second measurement, your code would look like 因此,如果您只想每秒处理一次,那么您的代码将如下所示

for i in range(1, len(measurements), 2):
    kf.predict()
    kf.predict()
    kf.update(measurements[i])

UPDATE 更新

To your question from the comment: 从评论到您的问题:

i       t      todo

1    0*dt      init
2    1*dt      predict
3    2*dt      predict, update
4    3*dt      predict
5    4*dt      predict, update

Did you mean this case? 你是说这个案子吗

Have a look at this post . 看一下这个帖子 It shows what happens if you predict a lot without new updates. 它显示了如果您预测很多而没有新更新会发生什么。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM