前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >1,Kalman滤波器参数如何选取

1,Kalman滤波器参数如何选取

原创
作者头像
雷科
修改于 2020-02-17 03:53:27
修改于 2020-02-17 03:53:27
3K0
举报

新冠居家封闭期间,对参考文献中估计常数的例子,初次使用python的NumPy库进行仿真,深入理解Kalman滤波器的参数对滤波性能的影响。

设计5组参数,生成图片的如下

模拟数据直方图统计.png
模拟数据直方图统计.png
状态.png
状态.png
滤波值的方差.png
滤波值的方差.png
新息的统计距离.png
新息的统计距离.png
新息的统计距离的统计信息.png
新息的统计距离的统计信息.png

结论

1.1,增加Q,增益增加,即观测值在状态更新方程中的权重变大,滤波器更加灵敏,反之亦然。

1.2,增加R,增益减小,即观测值在状态更新方程中的权重变小,滤波器反应迟钝,反之亦然。

2.1,参数R表示观测值的方差,应尽可能准确。

2.2,综合考虑滤波器在随机性和惯性等方面的表现,参数Q的取值在r/9 - r/4 较合适?

心得

Matlab真心不好下载不好用,Python确实好用多了。

代码如下

代码语言:txt
AI代码解释
复制
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
'''=========================================================================================================
@Project -> File   :active -> kalmanEstimateConstant
@IDE    :PyCharm
@Author :Mr. Ddc
@Date   :2020/2/12 15:34
@Desc   :对参考文献中的例子(估计一个常数)进行仿真,深入理解Kalman滤波器的参数对滤波性能的影响。
@Ref    :Welch & Bishop, An Introduction to the Kalman Filter, UNC-Chapel Hill, TR 95-041, July 24, 2006
=========================================================================================================='''

import sys
import traceback
import getopt
import numpy as np
import matplotlib.pyplot as plt


# 模拟观测数据
def simData(xTruth, sigma, N):
    data = np.random.normal(xTruth, sigma, N)
    # np.savetxt("SimData.txt", data)  # 数据存盘
    return data

# 1维数据滤波
def filter1D(z, Q, R):
    x = np.zeros(z.shape)  # 滤波值
    pkk = np.zeros(z.shape)  # 滤波协方差
    dis = np.zeros(z.shape)  # 新息统计距离

    # 初始化
    x[0] = z[0]
    pkk[0] = R

    for i in range(1, z.size):
        xki = x[i-1]  # 状态的一步预测
        pki = pkk[i-1] + Q  # 协方差的一步预测
        v = z[i] - xki  # 新息
        S =  pki + R  # 新息的协方差
        K = pki / S  # 增益
        x[i] = xki + K * v  # 状态的更新
        # pkk[i] = pki - K*S*K  # 协方差的更新  # 两者是相同的
        pkk[i] = (1 - K) * pki  # 协方差的更新
        dis[i] = v / S * v  # 新息统计距离

    return x, pkk, dis

# 画图
def display(Q, R, xTruth, z, x, pkk, dis, ivSta):
    N = z.size

    # 颜色表
    colors = []
    colors.append('b')  # 参数1
    colors.append('g')  # 参数2
    colors.append('r')  # 参数3
    colors.append('y')  # 参数4
    colors.append('c')  # 参数5
    colors.append('m')  # 观测值用
    colors.append('orange')  # 真值用

    # markers
    markers = []
    markers.append('o')  # 参数1
    markers.append('v')  # 参数2
    markers.append('d')  # 参数3
    markers.append('x')  # 参数4
    markers.append('+')  # 参数5

    # 画 真值、观测值、滤波值
    title = '状态'
    plt.figure(title)
    plt.plot(np.arange(N) + 1, xTruth * np.ones(N), color = colors[len(colors)-1], label = '真值')  # plot
    plt.plot(np.arange(N) + 1, z, '.-', color = colors[len(colors)-2], label = '观测值')  # plot
    for i in range(0, len(R)):
        plt.plot(np.arange(N) + 1, x[i, :], 'o-',
                 marker = markers[i], color = colors[i], label = f'({i+1}):Q = {Q[i]: .6f}, R = {R[i]:.4f}')  # plot

    plt.legend()
    plt.xlabel('时间')  # 设置x轴标签
    plt.ylabel('电压')  # 设置y轴标签
    # plt.title(title)
    plt.savefig(title)

    # 画 滤波值的方差
    title = '滤波值的方差'
    fig = plt.figure(title)
    # 主图 ax1
    left, bottom, width, height = 0.15, 0.11, 0.8, 0.8
    ax1 = fig.add_axes([left, bottom, width, height])
    for i in range(0, len(R)):
        ax1.plot(np.arange(N)+1, pkk[i], '.-',
                 marker = markers[i], color = colors[i], label = f'({i+1}):Q = {Q[i]: .6f}, R = {R[i]:.4f}')  # plot

    ax1.legend(loc = 'upper right')
    ax1.grid()
    ax1.set_ylabel('方差')  # 设置y轴标签  斜体
    ax1.set_xlabel('时间')  # 设置x轴标签
    # ax1.set_ylabel('$\mathregular{Voltage^2}$')  # 设置y轴标签 去除斜体
    ax1.set_ylim([-0.002, 0.02])
    # ax1.set_title(title)
    # 子图,由于参数3对应的方差太大,用子图另画
    left, bottom, width, height = 0.25, 0.6, 0.25, 0.25
    ax2 = fig.add_axes([left, bottom, width, height])
    ax2.plot(np.arange(N)+1, pkk[3], '.-', marker = markers[3],  color = colors[3])
    ax2.grid()
    ax2.set_ylabel('方差', fontsize = 'small')  # 设置y轴标签
    ax2.set_xlabel('时间', fontsize = 'small')  # 设置x轴标签
    ax2.set_title('参数4', fontsize = 'small')
    ax2.patch.set_visible(False)  # 设置子图透明
    plt.savefig(title)

    # 画 新息的统计距离
    title = '新息的统计距离'
    fig = plt.figure(title)
    # 主图 ax1
    left, bottom, width, height = 0.12, 0.11, 0.8, 0.8
    ax1 = fig.add_axes([left, bottom, width, height])
    for i in range(0, len(R)):
        ax1.plot(np.arange(N)+1, dis[i, :], '.-',
                 marker = markers[i], color = colors[i], label = f'({i+1}):Q = {Q[i]: .6f}, R = {R[i]:.4f}')  # plot

    ax1.legend(loc = 'upper right')
    ax1.set_xlabel('时间')  # 设置x轴标签
    ax1.set_ylabel('统计距离')  # 设置y轴标签
    ax1.set_ylim([-0.1, 7])
    ax1.grid()
    # 子图,由于参数4对应的方差太大,用子图另画
    left, bottom, width, height = 0.23, 0.6, 0.25, 0.25
    ax2 = fig.add_axes([left, bottom, width, height])
    ax2.plot(np.arange(N)+1, dis[4], '.-', marker = markers[4], color = colors[4])
    ax2.set_xlabel('时间', fontsize = 'small')  # 设置x轴标签
    ax2.set_ylabel('统计距离', fontsize = 'small')  # 设置y轴标签
    ax2.grid()
    ax2.set_title('参数5', fontsize = 'small')
    ax2.patch.set_visible(False)  # 设置子图透明
    plt.savefig(title)

    # 画 新息的统计距离的统计信息
    txt = ('最小值', '最大值', '平均值', '标准差')
    title = '新息的统计距离的统计信息'
    fig = plt.figure(title)
    # 主图 ax1
    left, bottom, width, height = 0.12, 0.11, 0.8, 0.8
    ax1 = fig.add_axes([left, bottom, width, height])
    for i in range(0, ivSta.shape[1]):
        ax1.plot(np.arange(ivSta.shape[0])+1, ivSta[:, i], '.-', label = txt[i])  # plot

    ax1.legend(loc = 'upper right')
    ax1.set_xticks(np.arange(ivSta.shape[0])+1)
    ticks = []
    for i in range(ivSta.shape[0]):
        ticks.append('参数' + str(i+1))
    ax1.set_xticklabels(ticks)
    ax1.set_ylim([-0.3, 9])
    ax1.grid()
    # 子图,由于参数4对应的值太大,用子图另画
    left, bottom, width, height = 0.23, 0.6, 0.25, 0.25
    ax2 = fig.add_axes([left, bottom, width, height])
    ax2.bar(range(0, 3), ivSta[-1, 1:], alpha = 0.5)
    ax2.set_xticks(range(0, 3))
    ax2.set_xticklabels(txt[1:], rotation = 30, fontsize = 'small')
    ax2.patch.set_visible(False)  # 设置子图透明
    # for item in [fig, ax2]:  # 设置子图透明
    #     item.patch.set_visible(False)
    ax2.grid()
    ax2.set_title('参数5', fontsize = 'small')
    plt.savefig(title)

    plt.show()

# Works 实现主要功能
def Works():
    N = 100  # 观测次数
    xTruth = -0.37727  # 真值
    sigma = 0.1  # 叠加正态分布噪声的标准差
    r = sigma ** 2  # 观测方差

    # 1,模拟一次数据
    # simData(xTruth, sigma, N)  # 模拟观测数据
    # z = np.loadtxt("SimData.txt")  # 从硬盘读取数据
    z = simData(xTruth, sigma, N)  # 模拟观测数据

    plt.figure("模拟数据直方图统计")
    count, bins, ignored = plt.hist(z, z.size)
    plt.plot(bins, 1 / (sigma * np.sqrt(2 * np.pi)) * np.exp( - (bins - xTruth)**2 / (2 * sigma**2) ), linewidth = 2, color = 'r')
    plt.savefig("模拟数据直方图统计")

    # 五组参数
    R = [r,     r,      r,      r*100,  r/100]
    Q = [1e-5,  r/9,    2*r,    1e-5,   1e-5]
    x = np.zeros((len(R), z.size))  # 滤波值,各行依次对应一组参数
    pkk = np.zeros((len(R), z.size))  # 滤波协方差,各行依次对应一组参数
    dis = np.zeros((len(R), z.size))  # 新息统计距离,各行依次对应一组参数

    for idxR in range(0, len(R)):
        r = R[idxR]
        q = Q[idxR]
        x[idxR, :], pkk[idxR, :], dis[idxR, :] = filter1D(z, q, r)  # 滤波

    # 统计新息的最小值/最大值/平均值/标准差
    ivSta = np.zeros((len(R), 4))  # 各行依次对应一组参数
    for idxR in range(0, len(R)):
        ivSta[idxR, :] = (np.min(dis[idxR, :]), np.max(dis[idxR, :]), np.mean(dis[idxR, :]), np.std(dis[idxR, :], ddof = 1) )

    display(Q, R, xTruth, z, x, pkk, dis, ivSta)  # 画图

    return 0


# 异常处理函数
class Usage(Exception):
    def __init__(self, msg):
        self.msg = msg


# main()函数
def main(argv=None):
    if argv is None:
        argv = sys.argv
    try:
        try:
            opts, args = getopt.getopt(argv[1:], "h", ["help"])
        except(getopt.error, msg):
            raise (Usage(msg))

        # 使plt支持中文
        plt.rcParams['font.sans-serif'] = ['SimHei']
        plt.rcParams['axes.unicode_minus'] = False

        # Works 实现主要功能
        Works()
    except Usage as err:  # 待处理新增代码中的异常
        print(sys.stderr, err.msg)
        print(sys.stderr, "for help use --help")
        return 1
    except Exception as e:
        print("print_exception()")
        exc_type, exc_value, exc_tb = sys.exc_info()
        print('the exc type is:', exc_type)
        print('the exc value is:', exc_value)
        print('the exc tb is:', exc_tb)
        traceback.print_exception(exc_type, exc_value, exc_tb)
    finally:
        print('exit main')


# 直接运行的入口
if "__main__" == __name__:
    sys.exit(main())

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
2 用kalman滤波器估计一维匀速直线运动目标的状态
本例参考 参考 何友. 雷达数据处理 第二章中对于一维匀速直线运动使用kalman滤波器的例子进行仿真
雷科
2020/03/07
1.3K0
python学习之matplot
import matplotlib.pyplot as plt import numpy as np import pandas as pd from mpl_toolkits.mplot3d import Axes3D import matplotlib.gridspec as gridspec from matplotlib import animation
py3study
2020/01/08
7910
Python可视化 | 三维图形迁移
在前面推送中我们提到了通过collection功能而在3D地图中添加地图的方法,也短暂提到了栅格与填色两种图形样式的降维方法。但是从matplotlib这两个函数的底层有一定的局限性,比如下面这两张图的侧面填色就无法绘出:
郭好奇同学
2021/05/28
1.9K0
Python可视化 | 三维图形迁移
深度学习基础之matplotlib,一文搞定各个示例
Matplotlib 是 Python 的绘图库。它可与 NumPy 一起使用 ,Matplotlib也是深度学习的常用绘图库,主要是将训练的成果进行图形化,因为这样更直观,更方便发现训练中的问题,今天来学习下,走起!!
香菜聊游戏
2021/10/19
1.5K0
深度学习基础之matplotlib,一文搞定各个示例
Matplotlib绘制的27个常用图(附对应代码实现)
https://nbviewer.jupyter.org/github/matplotlib/AnatomyOfMatplotlib/blob/master/AnatomyOfMatplotlib-Part2-Plotting_Methods_Overview.ipynb
double
2019/11/14
9640
气象编程 | Python基础地图构建
---- Python-basemap-中国南海小地图:‍ import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.basemap import Basemap import cmaps import shapefile from matplotlib.path import Path from matplotlib.patches import PathPatch import os import maskout2 f
气象学家
2020/12/18
2.2K0
气象编程 | Python基础地图构建
python可视化 | contour、contourf、cartopy补充
三个问题都是一些历史遗留问题,专门留待这一节来解决。包括画指定的等值线(如588)、如何在一个子图里绘制多个contourf、cartopy的刊误。
郭好奇同学
2021/03/25
5.6K0
python可视化 | contour、contourf、cartopy补充
Python基础(十二) | 还不会python绘图?两万字博文教你Matplotlib库(超详细总结)
https://matplotlib.org/api/_as_gen/matplotlib.pyplot.plot.html#matplotlib.pyplot.plot
timerring
2022/10/08
2.5K0
Python基础(十二) | 还不会python绘图?两万字博文教你Matplotlib库(超详细总结)
【数据可视化】Matplotlib 从入门到精通学习笔记
如果将文本数据与图表数据相比较,人类的思维模式更适合于理解后者,原因在于图表数据更加直观且形象化,它对于人类视觉的冲击更强,这种使用图表来表示数据的方法被叫做数据可视化。
小小程序员
2022/11/22
5.4K0
【数据可视化】Matplotlib 从入门到精通学习笔记
Python绘制气象实用地图(附代码和测试数据)
前面的推文对于常用的Python绘图工具都有了一些介绍,在这里就不赘述了。本文主要就以下几个方面:“中国区域绘图”、“包含南海”、“兰伯特投影带经纬度标签”、“基于salem的mask方法”、“进阶中国区域mask方法”、“进阶省份mask方法”。对日常的实用需求能够在一定程度上满足。后续就Python在气象常用的统计方法(显著性检验)、合成分析、多变量叠加绘图再进行推送,敬请期待!
MeteoAI
2019/08/12
16.1K3
Python绘制气象实用地图(附代码和测试数据)
Matplotlib使用笔记
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
村雨遥
2019/09/09
5650
Python3快速入门(十六)——Mat
Matplotlib是 Python 2D-绘图领域使用最广泛的套件,可以简易地将数据图形化,并且提供多样化的输出格式。 matplotlib有两个接口,一个是状态机层的接口,通过pyplot模块来进行管理;一个是面向对象的接口,通过pylab模块将所有的功能函数全部导入其单独的命名空间内。
py3study
2020/01/03
1.3K0
Matplotlib 1.4W+字基础教程来了(收藏吃灰去吧~~)
参考:Rougier N P, Droettboom M, Bourne P E, et al. Ten Simple Rules for Better Figures[J]. PLOS Computational Biology【IF 4.7】, 2014, 10(9).感兴趣戳:https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4161295/pdf/pcbi.1003833.pdf
DataCharm
2021/02/22
1.5K0
Matplotlib 1.4W+字基础教程来了(收藏吃灰去吧~~)
视觉Transformers中的位置嵌入 - 研究与应用指南
自从 2017 年推出《Attention is All You Need》以来,Transformer 已成为自然语言处理 (NLP) 领域最先进的技术。 2021 年,An Image is Worth 16x16 Words² 成功地将 Transformer 应用于计算机视觉任务。从那时起,人们提出了许多基于Transformer的计算机视觉架构。
数据科学工厂
2024/03/12
2030
视觉Transformers中的位置嵌入 - 研究与应用指南
matplotlib 入门使用指南
1. pyplot模块 1.1. color的值 blue 1.2. Marker的值 point marker 1.3. LineStyles的值 solid line style 例子: 'b' # blue markers with default shape 'ro' # red circles 'g-' # green solid line '--' # dashed line with default color 'k^:' # black triangle_up mark
syy
2020/04/07
9720
python绘图及可视化备课
于刊老师担心我准备的内容不够讲两节课的,如果我讲完这一章的内容还没有结束的话我就讲一讲我最近捣鼓的东西
十二惊惶
2024/02/28
3700
python绘图及可视化备课
Python空间绘图-Colorbar详解
在我们绘制有色阶的图片时,多会用到colorbar这个关联利器,色条可以直接将数值与颜色连接在一起。常用的scatter、contourf是非常适合使用的。第一节我们来简要谈谈常用的colorbar参数,以后例子都基于contourf命令。
DataCharm
2021/02/22
20.8K0
Python空间绘图-Colorbar详解
Matplotlib 基础
Matplotlib 是一个 Python 绘图库,可以跨平台生成各种硬拷贝格式和交互式环境的出版品质数据。
iOSDevLog
2019/05/28
2K0
【Python】 【绘图】plt.figure()的使用
figure(num=None, figsize=None, dpi=None, facecolor=None, edgecolor=None, frameon=True)
全栈程序员站长
2022/09/07
1.2K0
matplotlib安装及使用
matplotlib是基于python语言的开源项目,旨在为python提供一个数据绘图包。我将在这篇文章中介绍matplotlib API的核心对象,并介绍如何使用这些对象来实现绘图。实际上,matplotlib的对象体系严谨而有趣,为使用者提供了巨大的发挥空间。用户在熟悉了核心对象之后,可以轻易的定制图像。matplotlib的对象体系也是计算机图形学的一个优秀范例。即使你不是python程序员,你也可以从文中了解一些通用的图形绘制原则。matplotlib使用numpy进行数组运算,并调用一系列其他的python库来实现硬件交互。matplotlib的核心是一套由对象构成的绘图API。
狼啸风云
2023/10/07
4920
matplotlib安装及使用
相关推荐
2 用kalman滤波器估计一维匀速直线运动目标的状态
更多 >
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档