Python 卡尔曼滤波器实现

去年我们在设计一款新产品的时候,由于选用定制开发的一个SoC器件,导致我们在用ADC读取经由这个SoC芯片放大后的信号时,出现了极其不稳定的情况。正常情况下ADC读取出来的信号应当为一条平稳的直线,而现实上读取出来的信号确上下波动极其大,远远超出了我们理论计算水平。

虽然后来通过大量的研究分析,得出时SoC极其容易受到EMI干扰,在添加屏蔽片后成功解决了这个问题,但是在研究过程中我们发现卡尔曼滤波器在处理这种干扰时有着媲美硬件滤波器的结果,还是感到非常惊讶。

下面介绍由Andrew D. Straw提供的基于Python语言的卡尔曼滤波滤波器实现。

#coding:utf-8  
# python3.7
import numpy  
import pylab

def KalmanFilter(z,  n_iter = 20):  
    #这里是假设A=1,H=1的情况  
      
    # intial parameters  
     
    sz = (n_iter,) # size of array   
      
    #Q = 1e-5 # process variance  
    Q = 1e-6 # process variance   
    # allocate space for arrays  
    xhat=numpy.zeros(sz)      # a posteri estimate of x  
    P=numpy.zeros(sz)         # a posteri error estimate  
    xhatminus=numpy.zeros(sz) # a priori estimate of x  
    Pminus=numpy.zeros(sz)    # a priori error estimate  
    K=numpy.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  
    A = 1
    H = 1

    for k in range(1,n_iter):  
        # time update  
        xhatminus[k] = A * xhat[k-1]  #X(k|k-1) = AX(k-1|k-1) + BU(k) + W(k),A=1,BU(k) = 0  
        Pminus[k] = A * P[k-1]+Q      #P(k|k-1) = AP(k-1|k-1)A' + Q(k) ,A=1  
      
        # measurement update  
        K[k] = Pminus[k]/( Pminus[k]+R ) #Kg(k)=P(k|k-1)H'/[HP(k|k-1)H' + R],H=1  
        xhat[k] = xhatminus[k]+K[k]*(z[k]-H * xhatminus[k]) #X(k|k) = X(k|k-1) + Kg(k)[Z(k) - HX(k|k-1)], H=1  
        P[k] = (1-K[k] * H) * Pminus[k] #P(k|k) = (1 - Kg(k)H)P(k|k-1), H=1  
    return xhat

if __name__ == '__main__':
    with open("raw_data.txt", "r", encoding="utf-8") as f:
        text = f.readline().split(",")
    print(text)
    raw_data = list()
    for x in text:
        raw_data.append(int(x))
        print(int(x))

    xhat = KalmanFilter(raw_data, n_iter=len(raw_data))

    pylab.plot(raw_data, 'k-', label='raw measurement')  # 测量值
    pylab.plot(xhat, 'b-', label='Kalman estimate')  # 过滤后的值
    pylab.legend()
    pylab.xlabel('Iteration')
    pylab.ylabel('ADC reading')
    pylab.show()

经过卡尔曼滤波后的数据,基本上就是一条直线,与我们计算结果及我们后来添加的硬件滤波器件相一致,这也反映出卡尔曼滤波器的强大,能从众多大量噪声中找到真值,滤波器能力真不是吹的。

项目后来不用卡尔曼滤波器而大费周折采用成本更高的硬件滤波器,主要还是产品需要一个快速响应输出,而卡尔曼滤波器在这方面有点滞后了,如果对于性能要求不高的产品,这个滤波器是绝佳的利器。

  • 1
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值