手写卡尔曼滤波

news2024/11/14 20:31:58

形象图

里面的my_Kalman.ipynb 和ppt就是了,其他的是原始资料和 辅助函数
链接:https://pan.baidu.com/s/1J1nA–oqoj8OvgbrA3LfbQ?pwd=1264
提取码:1264

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
# 定义卡尔曼滤波器类
class KalmanFilter:
    def __init__(self, dt, sigma_a, sigma_z):
        self.dt = dt  # 时间步长
        self.sigma_a = sigma_a  # 过程噪声的标准差
        self.sigma_z = sigma_z  # 观测噪声的标准差
        self.A = np.array([[1, 0, dt, 0],
                           [0, 1, 0, dt],
                           [0, 0, 1, 0],
                           [0, 0, 0, 1]])  # 状态转移矩阵
        self.Q = np.array([[dt**4/4, 0, dt**3/2, 0],
                           [0, dt**4/4, 0, dt**3/2],
                           [dt**3/2, 0, dt**2, 0],
                           [0, dt**3/2, 0, dt**2]]) * sigma_a**2  # 过程噪声协方差矩阵
        self.H = np.array([[1, 0, 0, 0],
                           [0, 1, 0, 0]])  # 观测矩阵
        self.R = np.array([[sigma_z**2, 0],
                           [0, sigma_z**2]])  # 观测噪声协方差矩阵
        self.mu = np.zeros((4, 1))  # 状态向量
        self.sigma = np.eye(4)  # 状态协方差矩阵
    
    # 预测状态和协方差
    def predict(self):
        self.mu = self.A @ self.mu
        self.sigma = self.A @ self.sigma @ self.A.T + self.Q
    
    # 更新状态和协方差
    def update(self, z):
        K = self.sigma @ self.H.T @ np.linalg.inv(self.H @ self.sigma @ self.H.T + self.R)
        self.mu = self.mu + K @ (z - self.H @ self.mu)
        self.sigma = (np.eye(4) - K @ self.H) @ self.sigma
    
    # 获取当前状态向量
    def get_state(self):
        return self.mu.flatten()[:2]
    
# 初始化参数
dt = 0.1  # 时间步长
sigma_a = 0.5  # 过程噪声的标准差
sigma_z = 1  # 观测噪声的标准差
u = np.array([1, 0.5, 0, 0])  # 物体的速度和加速度
x_real = np.array([0, 0])  # 物体的真实位置
kf = KalmanFilter(dt, sigma_a, sigma_z)  # 初始化卡尔曼滤波器

# 绘制预测结果的动态可视化
fig, ax = plt.subplots()
xdata_real, ydata_real = [], []
xdata_pred, ydata_pred = [], []
line_real, = ax.plot([], [], 'o', color='blue')
line_pred, = ax.plot([], [], '-', color='red')

def init():
    ax.set_xlim(-10, 10)
    ax.set_ylim(-10, 10)
    return line_real, line_pred

def update(frame):
    global x_real, u, kf
    # 更新物体的真实位置
    x_real = x_real + u[:2] * dt
    # 产生观测值
    z = x_real + np.random.randn(2) * sigma_z
    # 进行预测和更新
    kf.predict()
    kf.update(z)
    # 绘制真实位置和预测位置
    xdata_real.append(x_real[0])
    ydata_real.append(x_real[1])
    line_real.set_data(xdata_real, ydata_real)
    x_pred, y_pred = kf.get_state()
    xdata_pred.append(x_pred)
    ydata_pred.append(y_pred)
    line_pred.set_data(xdata_pred, ydata_pred)
    return line_real, line_pred

ani = FuncAnimation(fig, update, frames=range(100), init_func=init, blit=True)

# 保存动态图为gif文件
ani.save('kalman_filter_prediction.gif', writer='pillow')

请添加图片描述

我们定义了一个KalmanFilter类来实现卡尔曼滤波器。在update函数中,我们首先更新物体的真实位置,然后生成观测值,接着使用卡尔曼滤波器进行预测和更新,并将真实位置和预测位置绘制在图像上。同时,我们使用FuncAnimation函数将预测结果进行动态可视化,并使用ani.save函数将动态图保存为gif文件。

执行代码后,会在当前工作目录下生成名为kalman_filter_prediction.gif的文件,其中包含了绘制的动态图。您可以使用任何支持gif格式的图像查看器打开它。

卡尔曼滤波器是一种算法,它利用随时间观测到的一系列测量来估计系统的状态。它被广泛应用于许多不同的工程和科学领域,包括控制系统、信号处理和机器人学。

在高层次上,卡尔曼滤波器通过组合两个信息流来工作:关于系统当前状态的预测和系统实际状态的测量。滤波器使用这两个信息流来迭代更新其对系统状态的估计,并计算该估计的不确定性(或协方差)。

更具体地说,卡尔曼滤波器遵循一个递归过程,其中包括以下步骤:

  1. 预测:滤波器根据先前对状态的估计和系统的动态(即状态随时间的演变)预测系统的当前状态。这个预测是基于一个状态转移模型,描述了状态随时间的演变,以及一个过程噪声模型,考虑了任何预测中的不确定性或误差。

  2. 更新:滤波器将系统的新测量(即观测值)纳入其中,并根据预测状态与观测状态之间的差异更新其对状态的估计。这个更新是基于一个测量模型,描述了测量与系统状态的关系,以及一个测量噪声模型,考虑了测量中的任何不确定性或误差。

  3. 重复:滤波器重复执行这些步骤,使用更新后的状态估计作为下一个时间步的预测,并纳入新的测量来改进其估计。

卡尔曼滤波器旨在最小化估计状态和系统真实状态之间的均方误差。它通过使用一组数学方程最小化估计状态和真实状态之间的期望平方误差,给定可用的测量和预测来实现这一点。

总体而言,卡尔曼滤波器是一种在存在不确定性和噪声的情况下估计系统状态的强大工具。它被广泛应用于许多不同的领域,并已被证明在广泛的应用中是有效的。

ssshttps://www.bilibili.com/video/BV1GB4y1D7P1/?spm_id_from=333.788&vd_source=569ef4f891360f2119ace98abae09f3f

什么是卡尔曼滤波

卡尔曼滤波(Kalman Filter)是一种用于估计状态空间模型中状态变量的算法,它可以通过系统的动态方程和观测方程,递归地计算和更新状态的估计值和误差协方差矩阵。卡尔曼滤波算法最初是由R.E. Kalman在1960年提出来的,后来被广泛应用于控制、信号处理、航空航天、无线通信、机器人等领域。

卡尔曼滤波的基本思想是:通过对系统状态及其误差的估计,结合观测数据对系统状态进行更新,从而提高对系统状态的估计精度。具体来说,卡尔曼滤波算法包含以下几个步骤:

  1. 预测:根据系统的动态方程,利用前一时刻的状态估计值和误差协方差矩阵,预测当前时刻的状态估计值和误差协方差矩阵。

  2. 更新:根据观测方程,利用当前时刻的观测数据和预测的状态估计值,计算当前时刻的状态估计值和误差协方差矩阵。

  3. 递归:重复进行预测和更新,逐步逼近真实的系统状态。

卡尔曼滤波算法的优点是可以对系统状态进行实时估计,同时考虑了系统的动态特性和观测噪声。它可以在噪声较大、观测数据存在缺失等情况下,仍然能够对系统状态进行较为准确的估计。缺点是需要对系统的动态方程和观测方程进行建模,对模型的准确性和参数的选择有一定要求。
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述 如果火箭被遮挡住了怎么办?
跟踪运动,也称为运动跟踪,是指在视频或图像序列中自动或半自动地跟踪目标的位置和运动。跟踪运动可以用于许多应用程序,如视频监控、自动驾驶、机器人导航、运动分析等。

跟踪运动的目标通常是一个或多个运动中的物体,如人、车、球等。跟踪运动的过程通常涉及以下步骤:

  1. 目标检测:在视频或图像序列中检测出目标物体的位置和大小。

  2. 特征提取:提取目标物体的特征,如颜色、纹理、形状等。

  3. 相似度度量:计算目标物体在相邻帧中的相似度,以确定目标的运动方向和速度。

  4. 目标跟踪:根据目标物体在前几帧中的位置和运动信息,估计目标在当前帧中的位置和运动信息。

跟踪运动是一项复杂的任务,需要应用计算机视觉和机器学习等技术来实现。常用的跟踪算法包括Kalman滤波器、粒子滤波器、相关滤波器、光流法等。
什么叫跟踪运动?
观测
预测
观测
在这里插入图片描述
在这里插入图片描述

运动建模

在这里插入图片描述在这里插入图片描述在这里插入图片描述高斯分布

由于狗狗运动的不确定性所以对狗狗进行建模,使用高斯分布进行建模
在这里插入图片描述高斯分布仅仅用两个变量进行描述,均值和方差
在这里插入图片描述
在这里插入图片描述
高斯分布进行相加和相乘之后依然是高斯分布的
在这里插入图片描述
绿色虚线是由蓝色和黄色相加生成的
新的高斯分布均值在原来两个均值之间
方差变小,变得更加高瘦

高斯分布下的运动预测

基于原始的数据所建立的一个模型
在这里插入图片描述非完美的运动学模型的方差会更大一下,因为他的不确定性更大
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述用观测矫正误差

优化算法:使用优化算法,如扩展卡尔曼滤波器(EKF)、无迹卡尔曼滤波器(UKF)等,对机器人或车辆的位置和运动进行优化。这些算法可以通过对测量结果和模型进行联合估计,减少误差累积,并提高位置和运动的准确性。

卡尔曼滤波(Kalman Filter)是一种用于估计系统状态的算法,可以用于矫正机器人或车辆等移动系统中的位置和运动误差。卡尔曼滤波的基本原理是通过对系统状态的预测和测量结果的融合,估计系统的真实状态,并降低其估计误差。

以下是使用卡尔曼滤波矫正位置和运动误差的一般步骤:

  1. 确定状态变量:确定系统的状态变量,例如机器人或车辆的位置、速度、加速度等。

  2. 建立状态转移模型:建立状态转移模型,描述系统状态在时间上的变化。例如,可以使用运动学模型描述机器人或车辆的运动行为。

  3. 建立观测模型:建立观测模型,描述系统状态和测量结果之间的关系。例如,可以使用传感器测量机器人或车辆的位置和运动,建立观测模型。

  4. 初始化:初始化系统状态和卡尔曼滤波器的状态。通常,将系统状态设置为初始位置和速度,并将卡尔曼滤波器的状态设置为初始状态。

  5. 预测:使用状态转移模型,预测系统的状态和协方差矩阵。预测的状态和协方差矩阵将作为下一步的输入。

  6. 测量更新:使用观测模型和测量结果,对系统状态和协方差矩阵进行更新。根据卡尔曼滤波的原理,测量结果将用于校正预测的状态和协方差矩阵。

  7. 循环迭代:重复执行步骤5和6,直到达到预设条件或满足精度要求。

通过这些步骤,可以使用卡尔曼滤波矫正移动系统中的位置和运动误差,并提高其位置和运动的准确性。需要注意,卡尔曼滤波的效果受到状态转移模型和观测模型的准确性和精度的影响,因此需要根据具体情况进行调整和优化。

手写高斯分布的运动预测代码

#namedtuple
#先写一个高斯类
#导入命名元组
from collections import namedtuple 
#gaussian表示一个高斯分布mean表示均值,var表示方差
gaussian = namedtuple("Gaussian",["mean","var"])
#打印出属性
gaussian.__repr__ = lambda s:f"N(mean={s[0]:.3f},var ={s[1]:.3f})"
g1 = gaussian(3.4,10.1)
g2 = gaussian(mean = 4.5, var = 0.2**2)
print(g1)
print(g2)
g1.mean,g2.var
N(mean=3.400,var =10.100)
N(mean=4.500,var =0.040)

在这里插入图片描述

#高斯相加
def predict(pos,movement):
#均值相加,方差相加
	return gaussian(pos.mean+movement.mean,pos.var+movement.var)
	

在这里插入图片描述

高斯分布下的预测

在这里插入图片描述在这里插入图片描述取两个高斯的交集

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码演示

#高斯相乘的函数
def gaussian_multiply(g1,g2):
	mean = (g1.var*g2.mean+g2.var*g1.mean)/(g1.var+g2.mean)
	variance = (g1.var*g2.var)/(g1.var+g2.var)
	return gaussian(mean,variance)
#更新
def update(likelihood,prior)
	posterior = gaussian_multiply(likelihood,prior)
	return posterior
predicted_pos = gaussian(10.0,0.2**2)
measured_pos = gaussian(11.0,0.1**2)
estimated_pos = update(predicted_pos,measured_pos)
print(measured_pos)
print(predicted_pos)
print(estimated_pos)

在这里插入图片描述当我们将观测结果和预测结果结合起来,我们会发现方差变小了
将多个数据源进行加权平均之后,会更加确定

你的第一个卡尔曼滤波器

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述蓝色和红色都是数据源
绿色是过滤掉噪声之后的

import numpy as np
from numpy.random import randn
from math import sqrt
import matplotlib.pyplot as plt
def print_result(predict,update,z,epoch):
    #predicted_pos,updated_posclear,measured_pos
    predict_template = '{:3.0f} {:7.3f} {:8.3f}'
    update_template = '\t{:.3f}\t{:7.3f}{:7.3f}'
    print(predict_template.format(epoch,predict[0],predict[1],end='\t'))
    print(update_templatre.format(z,update[0],update[1]))
def plot_result(epochs,prior_list,x_list,z_list):
    epoch_list = np.arrange(epochs)
    plt.plot(epoch_list,prior_list,linestyle = ':',color = 'r',label = "prior/predicted_pos",lw=2)
    plt.plot(epoch_list,z_list,linestyle = ":",color = 'b',label = "posterior/updated_pos",lw =2)
    plt.plot(epoch_list,z_list,linestyle=":",color = 'b',label = "likelihood.measurement",lw = 2)
    plt.legent(loc = "center left",bbox_to_anchor=(1,0.5))
#1.一些初始的状态和变量的赋值
motion_var= 1.0#人的运动运动方差
sensor_var= 2.0 #GPS的运动方差
x = gaussian(0,20**2)
velocity = 1.0
dt = 1 #时间单位的最小刻度
motion_model = gaussian(velocity,motion_var)
#2.生成数据
zs = []
current_x = x.mean
for _ in range(10):#我们让小明周10s,每走1s,就看看gps进行矫正并且把这些数据存起来
    #先生成我们的运动数据
    v = velocity + randn()*motion_var
    current_x += v*dt #将上一秒的位移加到这一秒
    #生成观测数据
    measurement = current_x + randn()*sensor_var#gps观测也有一定误差
    zs.append(measurement)

zs

[1.7745837204798636,
 0.7238059161348066,
 2.2738223282592034,
 5.1347547337355195,
 5.692724470550488,
 5.01630210516077,
 7.273752372058138,
 10.711965916869577,
 8.341629923352198,
 10.715059361392347]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/498848.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

物理验证LVS对bulk(体)的理解和处理技巧

对于物理验证中的LVS,需要对各种物理器件进行SpiceVsGDS的比对,基于现在流行的std-cell的库的设计方法,LVS需要对CMOS器件多相应的处理,这里会涉及到一些具体的物理库的知识和小的技巧,这里结合具体的物理设计和CDL形态…

网络安全战略:如何应对不断变化的威胁环境?

网络安全一直是大家所关注的重点。在如今的数字化时代,网络安全问题日益严峻,网络攻击者使用更加复杂和高级的攻击方式,企图从各种角度入侵和危害我们的计算机网络。因此,我们必须制定一套完善的网络安全战略,以便更好…

LeetCode 牛客单链表OJ题目分享

目录 链表的回文结构相交链表环形链表I环形链表II 链表的回文结构 链接: link 题目描述: 题目思路: 本题思路是找到每一条链表的中间节点,之后逆置中间节点之后的链表,定义两个指针,分别指向逆置后链表的头部的链表的…

8年资深测试总结,性能测试基础知识(大全)你的进阶之路...

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 性能测试&#xf…

力扣sql中等篇练习(十七)

力扣sql中等篇练习(十七) 1 计算布尔表达式的值 1.1 题目内容 1.1.1 基本题目信息1 1.1.2 基本题目信息2 1.1.3 示例输入输出 a 示例输入 b 示例输出 1.2 示例sql语句 # 使用SELECT子句中的子查询查询到对应的值 SELECT t1.left_operand,t1.operator,t1.right_operand,cas…

Obsidian templater日记模板添加一个随机问题

Obsidian templater日记模板添加一个随机问题 简介 每天日记里写同样的东西,感觉有点无聊,想问自己一些问题,每天不同。 查到有插件random structural diary,我想要的功能就是这样,但是没懂这个插件怎么放进templat…

【Android入门到项目实战-- 9.3】—— 加速度传感器的详细使用教程

基础知识 加速度传感器可以返回x、y、z三轴的加速度数值,该数值受地心引力的影响。 将手机平放桌面上,x、y、z轴默认为9.81;手机向下z轴为-9.81。 将手机向左倾斜,x轴为正,向右倾斜,x为负; 将手…

Windows11安装hadoop-3.3.0

一、安装Java 1. 下载Java 进入下载页面Java Archive Downloads - Java SE 8 Java SE Development Kit 8u191中 选择适合操作系统的下载文件 在安装好的路径下,将Java目录复制到C:\根目录下,形成C:\Java\jdk1.8.0_191目录结构 2. 设置环境变量 二、…

Docker虚拟化概念

Docker虚拟化概念 1、虚拟化技术的概念 虚拟化技术主要是将物理资源转变为逻辑上可以管理的资源;用以打破物理资源结构之间的壁垒;让计算的原件运行在虚拟的基础之上;而不是直接运行在硬件设备资源上; 说白了就是硬件资源转变成…

大数据开会记录【NiFi数据集成、AllData数据中台管理系统、RuoYi】

今天上午和下午开了个小会,上午说了一下Nifi,下午具体说了一下nifi和ruoyi。 目录 上午 下午 上午 三个人开会。 上次说的挖掘平台,您这边是否有技术人员对nifi比较熟悉,并且能够将相关功能集成到数据中台系统中。 现在结构化的…

不收费的电脑数据恢复软件EasyRecovery16

EasyRecovery是一款操作安全、恢复性比较高的数据恢复工具,小伙伴们可以使用EasyRecovery恢复各种各样被删除的文件、视频、图片等。EasyRecovery还可以支持恢复被格式化的媒体文件,只是使用EasyRecovery恢复时时间较久。如果小伙伴们有误删除的文件需要…

【Qt 从入门到入土】上篇

【Qt 从入门到入土】下篇 一个非常好的学习 Qt 的视频 本文目录 1. Qt 概述1.1 什么是 Qt1.2 Qt 的发展史1.3 支持的平台1.4 Qt 的版本1.5 Qt 的优点1.6 成功案例 2. 创建 Qt 项目2.1 使用向导创建2.2 手动创建2.3 .pro文件2.4 一个最简单的 Qt 应用程序2.5 Qt 命名规范和常用…

【Java入门合集】第三章面向对象编程(下)

【Java入门合集】第三章面向对象编程(下) 博主:命运之光 专栏:JAVA入门 学习目标 理解面向对象三大主要特征; 掌握类与对象的区别与使用; 掌握类中构造方法以及构造方法重载的概念及使用; 掌握包…

已做过算法题总结

217、存在重复元素(easy) 输入:nums [1,2,3,1] 输出:true 输入:nums [1,2,3,4] 输出:false 输入:nums [1,1,1,3,3,4,3,2,4,2] 输出:true 给你一个整数数组 nums 。如果任一值在数组中出现 至少两次 &…

【2106. 摘水果】

来源:力扣(LeetCode) 描述: 在一个无限的 x 坐标轴上,有许多水果分布在其中某些位置。给你一个二维整数数组 fruits ,其中 fruits[i] [positioni, amounti] 表示共有 amounti 个水果放置在 positioni 上…

Android平台播放透明视频

Android平台播放透明视频 思路 设计一种特殊的视频,它的一半内容存储alpha信息,另一半内容存储rgb信息,接着通过OpenGL获取每个像素点的alpha值和rgb值进行混合,最后出来的画面就是带有透明效果的视频了。 可以上下的分&#xf…

【疯狂造轮子-iOS】JSON转Model系列之二

1. 前言 上一篇《【疯狂造轮子-iOS】JSON转Model系列之一》实现了一个简陋的JSON转Model的库,不过还存在很多问题。下面我会尝试一个个去解决。 2. 存在问题及解决思路 2.1 没有考虑JSON数据并不一定是NSDictionary类型 有时候JSON并不一定是NSDictionary类型&…

【医学影像数据处理】2D/3D patch的crop和merge操作汇总

在做3D分割任务中,多数的方法多采用整体缩放,或裁剪成一个个小的patch操作,这样做的一个主要原因是内存问题。 相较于整体缩放,采用裁剪成patch的方法,对于小目标会更加的鲁棒,这也是大多数3D分割任务中常…

Leetcode448. 找到所有数组中消失的数字

Every day a leetcode 题目来源:448. 找到所有数组中消失的数字 解法1:STL set set 是一个集合类型的容器,里面的元素具有唯一性,并且所有元素都会根据元素的键值自动被排序,以红黑树为底层数据结构。 我们使用集合…

git上传大大大文件项目好折磨人

本来想把unity项目的源码上传上gitee啊,但是那个项目有1个多G,还是个半成品,要是写完,都不知道行不行 正常的上传 所用到的命令: 1、 git init 初始化,创建本地仓库 2、 git add . 添加到本地仓库 3、 git…