文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

卡尔曼滤波算法包(python)

2023-09-10 16:54

关注

本文写了具有普遍适用性的卡尔曼滤波(Kalman filter)算法程序包,输入参数即可进行运算。

算法可参考资料:

算法推导:

​​​​​​卡尔曼滤波的理解、推导和应用

卡尔曼滤波

 参数理解:

卡尔曼滤波的理解以及参数调整

手把手教你学-卡尔曼滤波(附代码)

\begin{aligned}predict:&\hat{x}'_{k}=A\hat{x}_{k-1}+Bu_{k-1}\\ &P'_{k}=AP_{k-1}A^{T}+Q\\ correct:&K_{k}=P'_{k}H^{T}(HP'H^{T}+R)^{-1}\\ &x_{k}=x_{k}'+K_{k}(Z_{k}-Hx'_{k})\\ &P_{k}=(I-K_{k}H)P'_{k} \end{aligned}

其中Z_{k}=Hx_{k}x_{k}为仪器观测到的状态值

输入参数:

状态矩阵x

状态转移矩阵A

输入控制矩阵B

外界对系统作用矩阵u

初始误差协方差矩阵P

预测噪声协方差矩阵Q

观测矩阵H

观测噪声协方差矩阵R

(可通过调整三个协方差矩阵大小来调整降噪效果)

可复制算法包:

def Kalmanfilter(x):    # 需预先定义以下变量:    # 状态转移矩阵A    # 输入控制矩阵B    # 外界对系统作用矩阵u    # 误差协方差矩阵P    # 预测噪声协方差矩阵Q    # 观测矩阵H    # 观测噪声协方差矩阵R    # import numpy as np    xr = np.shape(x)[0]                     # 调用状态矩阵行数    xc = np.shape(x)[1]                     # 调用状态矩阵列数    X_mat = x.copy()                        # 初始化记录系统优化状态值的矩阵(浅拷贝)    X = x.T[0].T# 抽取预测优化值的初始状态值    Z = H * x    global P    #初始设置为全局变量P    for i in range(1,xc):        # 预测        X_predict = A * X                   # 估算状态变量        if B!=0:            X_predict = A * X + B * u.T[i-1].T        P_predict = A * P * A.T + Q         # 估算状态误差协方差        # 校正        K = P_predict * H.T / (H * P_predict * H.T + R)  # 更新卡尔曼增益        X = X_predict + K * (Z.T[i].T - H * X_predict)  # 更新预测优化值        P = (np.eye(xr) - K * H) * P_predict  # 更新状态误差协方差        # 记录系统的预测优化值        for j in range(xr):            X_mat[j, i] = X[j, 0]    Z_mat = H * X_mat    return Z_matkf = Kalmanfilter(x)

案例:对均加速直线运动的位置进行降噪处理,加速度为1,初始时间为0,初始位置为0,观测时间为7秒,每0.1秒观测一次,设误差为白噪声N(0,1)

方法1

设置时间跳跃系统:(s为位置,v为速度)

x_{k}=Ax_{k-1}+Bu_{k-1}\\ then, \\ s_{k}=(s_{k-1}+\Delta tv_{k-1})+\frac{1}{2}\Delta t^{2}*a\\ v_{k}=(0*s_{k-1}+v_{k-1})+\Delta t*a\\and,\\ Z_{k}=Hx_{k}\\ Z_{k}=1*s_{k}+0*v_{k}

状态矩阵x:

\begin{vmatrix} x_{1} &... &x_{n} \\ v_{1} &... &v_{n} \end{vmatrix}

状态转移矩阵A:

\begin{vmatrix} 1 &\Delta t\\ 0 & 1 \end{vmatrix}

控制矩阵B:

\begin{vmatrix} \frac{1}{2}\Delta t^{2}&0\\ 0& \Delta t \end{vmatrix}

外界对系统作用矩阵u:

\begin{vmatrix} a &... &a \\ a & ...& a \end{vmatrix}

初始误差协方差矩阵P:

\begin{vmatrix} 1 &0 \\ 0& 1 \end{vmatrix}

预测噪声协方差矩阵Q:

\begin{vmatrix} 0.001&0\\ 0&0.001 \end{vmatrix}

观测矩阵H:

\begin{vmatrix} 1\\ 0 \end{vmatrix}

观测噪声协方差矩阵R:

\begin{vmatrix} 1 \end{vmatrix}

import numpy as npimport matplotlib.pyplot as pltdelta_t = 0.1   # 每秒钟采一次样end_t = 7       # 时间长度time_t = end_t * 10                         # 采样次数t = np.arange(0, end_t, delta_t)            # 设置时间数组v_var = 1       # 测量噪声的方差v_noise = np.round(np.random.normal(0, v_var, time_t), 2)# 定义测量噪声a=1             #加速度vn=np.add((1 / 2*a * t ** 2) , v_noise)     # 定义仪器测量的位置v=a*t  #定义速度数组x = np.mat([vn,v])                          # 定义状态矩阵xc = np.shape(x)[1]                         #调用状态矩阵列数u1=np.linspace(a,a,xc)u = np.mat([u1,u1])                         # 定义外界对系统作用矩阵A = np.mat([[1, delta_t], [0, 1]])          # 定义状态转移矩阵B = [[1 / 2 * (delta_t ** 2),0],[0,delta_t]]# 定义输入控制矩阵P = np.mat([[1, 0], [0, 1]])                # 定义初始状态协方差矩阵Q = np.mat([[0.001, 0], [0, 0.001]])        # 定义状态转移(预测噪声)协方差矩阵H = np.mat([1, 0])                          # 定义观测矩阵R = np.mat([1]) # 定义观测噪声协方差矩阵def Kalmanfilter(x):    # 需预先定义以下变量:    # 状态转移矩阵A    # 输入控制矩阵B    # 外界对系统作用矩阵u    # 误差协方差矩阵P    # 预测噪声协方差矩阵Q    # 观测矩阵H    # 观测噪声协方差矩阵R    # import numpy as np    xr = np.shape(x)[0]                     # 调用状态矩阵行数    xc = np.shape(x)[1]                     # 调用状态矩阵列数    X_mat = x.copy()                        # 初始化记录系统优化状态值的矩阵(浅拷贝)    X = x.T[0].T# 抽取预测优化值的初始状态值    Z = H * x    global P    #初始设置为全局变量P    for i in range(1,xc):        # 预测        X_predict = A * X                   # 估算状态变量        if B!=0:            X_predict = A * X + B * u.T[i-1].T        P_predict = A * P * A.T + Q         # 估算状态误差协方差        # 校正        K = P_predict * H.T / (H * P_predict * H.T + R)  # 更新卡尔曼增益        X = X_predict + K * (Z.T[i].T - H * X_predict)  # 更新预测优化值        P = (np.eye(xr) - K * H) * P_predict  # 更新状态误差协方差        # 记录系统的预测优化值        for j in range(xr):            X_mat[j, i] = X[j, 0]    Z_mat = H * X_mat    return Z_matkf=Kalmanfilter(x)plt.rcParams['font.sans-serif'] = ['SimHei']    # 设置正常显示中文plt.plot(t,np.array(kf)[0], "g", label='预测优化值')plt.plot(t,np.array(x[0])[0], "r--", label='测量值')plt.xlabel("时间")   # 设置X轴的名字plt.ylabel("位移")   # 设置Y轴的名字plt.title("卡尔曼滤波示意图")                     # 设置plt.legend()         # 设置图例plt.show()           # 显示图表

 方法2

设置时间跳跃系统:(s为位置,v为速度)

x_{k}=Ax_{k-1}+Bu_{k-1}\\ then, \\ s_{k}=(s_{k-1}+\Delta tv_{k-1}+\frac{1}{2}\Delta t^{2}*a)+0\\ v_{k}=(0*s_{k-1}+v_{k-1}+\Delta t*a)+0\\ a_{k}=(0*s_{k-1}+0*v_{k-1}+a)+0 \\and, \\ Z_{k}=Hx_{k}\\ Z_{k}=1*s_{k}+0*v_{k}+0*a_{k}

状态矩阵x:

\begin{vmatrix} x_{1} &... &x_{n} \\ v_{1} &... &v_{n}\\a&...&a \end{vmatrix}

状态转移矩阵A:

\begin{vmatrix} 1 &\Delta t&\frac{1}{2}\Delta t^{2}\\ 0 & 1& \Delta t\\0&0&1\end{vmatrix}

控制矩阵B:

\begin{vmatrix}0\end{vmatrix}

外界对系统作用矩阵u:

\begin{vmatrix}0\end{vmatrix}

初始误差协方差矩阵P:

\begin{vmatrix} 1 &0 &0\\ 0& 1 &0\\0&0&1\end{vmatrix}

预测噪声协方差矩阵Q:

\begin{vmatrix} 0.001&0&0\\ 0&0.001&0\\0&0&0.001 \end{vmatrix}

观测矩阵H:

\begin{vmatrix} 1\\ 0\\0 \end{vmatrix}

观测噪声协方差矩阵R:

\begin{vmatrix} 1 \end{vmatrix}

import numpy as npimport matplotlib.pyplot as pltdelta_t = 0.1     # 每秒钟采一次样end_t = 7         # 时间长度time_t = end_t * 10                           # 采样次数t = np.arange(0, end_t, delta_t)              # 设置时间数组v_var = 1         # 测量噪声的方差v_noise = np.round(np.random.normal(0, v_var, time_t), 2)# 定义测量噪声a=1               #加速度vn=np.add((1 / 2*a * t ** 2) , v_noise)       # 定义仪器测量的位置v=a*t  #定义速度数组a1=np.linspace(a,a,time_t)x = np.mat([vn,v,a1])                         # 定义状态矩阵u = 0             # 定义外界对系统作用矩阵A = np.mat([[1, delta_t, 1/2*delta_t], [0, 1, delta_t], [0, 0, 1]])          # 定义状态转移矩阵B = 0             # 定义输入控制矩阵P = np.mat([[1, 0,0], [0, 1,0],[0,0,1]])      # 定义初始状态协方差矩阵Q = np.mat([[0.001, 0,0], [0, 0.001,0],[0,0,0.001]])        # 定义状态转移(预测噪声)协方差矩阵H = np.mat([1, 0, 0])                         # 定义观测矩阵R = np.mat([1])   # 定义观测噪声协方差矩阵def Kalmanfilter(x):    # 需预先定义以下变量:    # 状态转移矩阵A    # 输入控制矩阵B    # 外界对系统作用矩阵u    # 误差协方差矩阵P    # 预测噪声协方差矩阵Q    # 观测矩阵H    # 观测噪声协方差矩阵R    # import numpy as np    xr = np.shape(x)[0]                     # 调用状态矩阵行数    xc = np.shape(x)[1]                     # 调用状态矩阵列数    X_mat = x.copy()                        # 初始化记录系统优化状态值的矩阵(浅拷贝)    X = x.T[0].T# 抽取预测优化值的初始状态值    Z = H * x    global P    #初始设置为全局变量P    for i in range(1,xc):        # 预测        X_predict = A * X                   # 估算状态变量        if B!=0:            X_predict = A * X + B * u.T[i-1].T        P_predict = A * P * A.T + Q         # 估算状态误差协方差        # 校正        K = P_predict * H.T / (H * P_predict * H.T + R)  # 更新卡尔曼增益        X = X_predict + K * (Z.T[i].T - H * X_predict)  # 更新预测优化值        P = (np.eye(xr) - K * H) * P_predict  # 更新状态误差协方差        # 记录系统的预测优化值        for j in range(xr):            X_mat[j, i] = X[j, 0]    Z_mat = H * X_mat    return Z_matkf=Kalmanfilter(x)plt.rcParams['font.sans-serif'] = ['SimHei']    # 设置正常显示中文plt.plot(t,np.array(kf)[0], "g", label='预测优化值')plt.plot(t,np.array(x[0])[0], "r--", label='测量值')plt.xlabel("时间")    # 设置X轴的名字plt.ylabel("位移")    # 设置Y轴的名字plt.title("卡尔曼滤波示意图")                      # 设置plt.legend()          # 设置图例plt.show()            # 显示图表

 在合适的协方差矩阵大小设置之下,卡尔曼滤波算法可得到需要的降噪效果,美!!

来源地址:https://blog.csdn.net/weixin_51362945/article/details/131322940

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯