KALMAN过滤器不响应更改

时间:2017-05-19 18:52:06

标签: filter filtering kalman-filter pykalman

我是第一次实现卡尔曼滤波器来从源获取电压值。它起作用并稳定在源电压值但如果那时源改变了电压,则滤波器不适应新值。

我使用了3个步骤:

  1. 获得卡尔曼增益

    KG = previous_error_in_estimate / ( previous_error_in_estimate + Error_in_measurement )
    
  2. 获取当前估算值

    Estimation = previous_estimation + KG*[measurement - previous_estimation]
    
  3. 计算估算误差

    Error_in_estimate = [1-KG]*previous_error_in_estimate
    
  4. 事实是,当0< = KG< = 1时,Error_in_estimate越来越少,这使得KG也越来越少( error_in_measurement 是一个常数),所以最后估算仅取决于先前的估算,并且不考虑当前的测量

    这可以防止过滤器适应测量变化。

    我该如何做到这一点?

    由于

    编辑:

    回答Claes:

    我不确定卡尔曼滤波器是否对我的问题有效,因为我没有系统模型,我只是从一个非常嘈杂的传感器中读取一堆读数来测量一个不太可预测的变量。

    为了简单起见,想象一下读取用户改变的电位器(可变电阻器),就无法预测或模拟用户的行为。

    我已经实现了一个非常基本的SMA(简单移动平均)算法,我想知道是否有更好的方法来实现它。

    卡尔曼滤波器对这样的问题有效吗?

    如果没有,你会建议什么?

    2ND EDIT

    感谢Claes提供了这样一个有用的信息

    我一直在MathLab中进行一些数值测试(还没有真正的数据),用高斯滤波器进行卷积似乎可以得到最准确的结果。

    Kalman measurement variance R=0.1^2 Bad result

    使用卡尔曼滤波器我不知道如何估计过程和测量方差,有什么方法吗?只有当我减少了相当多的测量方差时,卡尔曼滤波器才能适应。在先前的图像中,测量方差是R = 0.1 ^ 2(原始示例中的那个)。这是与R = 0.01 ^ 2

    相同的测试

    Kalman measurement variance R=0.01^2 Better result

    当然,这些是没有实际数据的MathLab测试。明天我将尝试使用真实数据在真实系统中实现此过滤器,看看我是否可以获得类似的结果

1 个答案:

答案 0 :(得分:1)

简单的MA过滤器可能足以满足您的示例。如果您想使用卡尔曼滤波器,SciPy cookbook

就有一个很好的例子

我修改了代码以包含步骤更改,以便您可以看到收敛。

# Kalman filter example demo in Python
# A Python implementation of the example given in pages 11-15 of "An
# Introduction to the Kalman Filter" by Greg Welch and Gary Bishop,
# University of North Carolina at Chapel Hill, Department of Computer
# Science, TR 95-041,
# http://www.cs.unc.edu/~welch/kalman/kalmanIntro.html

# by Andrew D. Straw

import numpy as np
import matplotlib.pyplot as plt

plt.rcParams['figure.figsize'] = (10, 8)

# intial parameters
n_iter = 400
sz = (n_iter,) # size of array
x1 = -0.37727*np.ones(n_iter/2) # truth value 1
x2 = -0.57727*np.ones(n_iter/2) # truth value 2
x = np.concatenate((x1,x2),axis=0)
z = x+np.random.normal(0,0.1,size=sz) # observations (normal about x, sigma=0.1)

Q = 1e-5 # process variance

# allocate space for arrays
xhat=np.zeros(sz)      # a posteri estimate of x
P=np.zeros(sz)         # a posteri error estimate
xhatminus=np.zeros(sz) # a priori estimate of x
Pminus=np.zeros(sz)    # a priori error estimate
K=np.zeros(sz)         # gain or blending factor

R = 0.1**2 # estimate of measurement variance, change to see effect

# intial guesses
xhat[0] = 0.0
P[0] = 1.0

for k in range(1,n_iter):
    # time update
    xhatminus[k] = xhat[k-1]
    Pminus[k] = P[k-1]+Q

    # measurement update
    K[k] = Pminus[k]/( Pminus[k]+R )
    xhat[k] = xhatminus[k]+K[k]*(z[k]-xhatminus[k])
    P[k] = (1-K[k])*Pminus[k]

plt.figure()
plt.plot(z,'k+',label='noisy measurements')
plt.plot(xhat,'b-',label='a posteri estimate')
plt.plot(x,color='g',label='truth value')
plt.legend()
plt.title('Estimate vs. iteration step', fontweight='bold')
plt.xlabel('Iteration')
plt.ylabel('Voltage')

输出是: enter image description here