卡尔曼滤波:理论与代码

news2024/9/27 23:30:37

卡尔曼滤波:理论与代码

引言

卡尔曼滤波是一种用于估计系统状态的优化技术,特别适用于含有噪声的测量数据和系统动态变化的情况。本文将简单探讨卡尔曼滤波的理论基础、数学公式的推导,并通过Python代码示例演示其在实际应用中的效果。

一、卡尔曼滤波的基本理论

卡尔曼滤波基于动态系统的模型,通过对系统状态的预测和测量值的融合,提供对系统状态的最优估计。它通过递归地更新估计值,适应系统状态的变化,并考虑测量误差,使得估计更加准确。

二、卡尔曼滤波的基本假设

卡尔曼滤波基于以下两个基本假设:

  1. 线性系统: 系统的动态模型和观测模型必须是线性的。
  2. 高斯噪声: 系统的过程噪声和测量噪声都应该是高斯分布的。

三、卡尔曼滤波的数学公式推导

在这里插入图片描述

1. 预测步骤

1.1 状态预测:

x ^ k − = A x ^ k − 1 + B u k − 1 \begin{equation}\hat{x}_{k}^- = A \hat{x}_{k-1} + B u_{k-1} \end{equation} x^k=Ax^k1+Buk1

其中, x ^ k − \hat{x}_{k}^- x^k是系统状态的先验估计, A A A 是系统矩阵,$\hat{x}_{k-1}$是上一时刻的估计值, B B B 是输入矩阵, u k − 1 u_{k-1} uk1 是系统输入。

1.2 协方差预测:

P k − = A P k − 1 A T + Q \begin{equation} P_{k}^- = A P_{k-1} A^T + Q \end{equation} Pk=APk1AT+Q

其中, P k − P_{k}^- Pk是状态估计的先验协方差矩阵, Q Q Q 是过程噪声协方差。

2. 更新步骤

2.1 卡尔曼增益计算:

K k = P k − H T ( H P k − H T + R ) − 1 \begin{equation}K_{k} = P_{k}^- H^T (H P_{k}^- H^T + R)^{-1} \end{equation} Kk=PkHT(HPkHT+R)1

其中, K k K_{k} Kk是卡尔曼增益, H H H 是测量矩阵, R R R是测量噪声协方差。

2.2 状态更新:

x ^ k = x ^ k − + K k ( z k − H x ^ k − ) \begin{equation}\hat{x}_{k} = \hat{x}_{k}^- + K_{k} (z_{k} - H \hat{x}_{k}^-) \end{equation} x^k=x^k+Kk(zkHx^k)

其中, x ^ k \hat{x}_{k} x^k是系统状态的后验估计, z k z_{k} zk是测量值。

2.3 协方差更新:

P k = ( I − K k H ) P k − \begin{equation}P_{k} = (I - K_{k} H) P_{k}^- \end{equation} Pk=(IKkH)Pk

其中, P k P_{k} Pk 是状态估计的后验协方差矩阵, I I I 是单位矩阵。

四、一维卡尔曼滤波的Python代码示例

以下是一个简单的一维卡尔曼滤波的 Python 代码示例。在这个例子中,我们假设系统是一个匀速运动的目标,我们通过测量得到目标的位置信息。

import numpy as np
import matplotlib.pyplot as plt

# 系统参数
A = np.array([[1]])  # 状态转移矩阵
H = np.array([[1]])  # 观测矩阵
B = np.array([[1]])  # 控制输入矩阵
Q = np.array([[0.01]])  # 过程噪声协方差
R = np.array([[0.1]])   # 观测噪声协方差

# 初始化
x_hat = np.array([0])  # 初始状态估计
P = np.array([1])      # 初始协方差矩阵

# 模拟数据
true_states = np.array([i for i in range(100)])  # 真实状态,匀速增加
measurements = true_states + np.random.normal(0, np.sqrt(R[0, 0]), 100)  # 加入观测噪声

# 卡尔曼滤波
filtered_states = []

for z in measurements:
    # 预测步骤
    x_hat_minus = np.dot(A, x_hat)
    P_minus = np.dot(np.dot(A, P), A.T) + Q

    # 更新步骤
    K = np.dot(np.dot(P_minus, H.T), np.linalg.inv(np.dot(np.dot(H, P_minus), H.T) + R))
    x_hat = x_hat_minus + np.dot(K, (z - np.dot(H, x_hat_minus)))
    P = np.dot((np.eye(1) - np.dot(K, H)), P_minus)

    filtered_states.append(x_hat[0])

filtered_states = np.array(filtered_states)

# 可视化结果
plt.figure(figsize=(12, 6))

plt.plot(true_states, label='True States')
plt.plot(measurements, 'ro', label='Measurements')
plt.plot(filtered_states, label='Filtered States')

plt.title('1D Kalman Filtering')
plt.legend()
plt.show()

在这个例子中,模拟了一个一维系统,其中目标的真实状态是一个匀速增加的序列。观测值通过加入观测噪声生成。卡尔曼滤波器通过预测和更新步骤,对目标的状态进行估计。最终结果显示了真实状态、观测值和卡尔曼滤波估计的对比。

五、二维卡尔曼滤波的Python代码示例

下面是一个简单的二维卡尔曼滤波的Python代码示例。这个例子假设系统是一个匀速运动的目标,通过测量得到位置信息。请注意,这个例子中假设噪声是高斯分布的。

import numpy as np
import matplotlib.pyplot as plt

# 系统参数
dt = 1  # 时间步长
A = np.array([[1, dt],
              [0, 1]])

H = np.array([[1, 0],
              [0, 1]])

B = np.array([[0.5 * dt**2],
              [dt]])

Q = np.array([[0.01, 0],
              [0, 0.01]])  # 过程噪声协方差

R = np.array([[0.1, 0],
              [0, 0.1]])   # 测量噪声协方差

# 初始化
x_hat = np.array([[0],
                  [0]])  # 初始状态估计
P = np.eye(2)  # 初始协方差矩阵

# 模拟数据
true_states = np.array([[i, 2 * i] for i in range(100)])
measurements = true_states + np.random.multivariate_normal([0, 0], R, 100)  # 加入测量噪声

# 卡尔曼滤波
filtered_states = []

for z in measurements:
    # 预测步骤
    x_hat_minus = np.dot(A, x_hat) + np.dot(B, 1)
    P_minus = np.dot(np.dot(A, P), A.T) + Q

    # 更新步骤
    K = np.dot(np.dot(P_minus, H.T), np.linalg.inv(np.dot(np.dot(H, P_minus), H.T) + R))
    x_hat = x_hat_minus + np.dot(K, (z - np.dot(H, x_hat_minus)))
    P = np.dot((np.eye(2) - np.dot(K, H)), P_minus)

    filtered_states.append(x_hat.flatten())

filtered_states = np.array(filtered_states)

# 可视化结果
plt.figure(figsize=(12, 6))

plt.plot(true_states[:, 0], true_states[:, 1], label='True States')
plt.scatter(measurements[:, 0], measurements[:, 1], color='red', marker='o', label='Measurements')
plt.plot(filtered_states[:, 0], filtered_states[:, 1], label='Filtered States', linestyle='dashed')

plt.title('2D Kalman Filtering')
plt.legend()
plt.show()

这个例子中,系统状态是一个二维向量,表示目标在水平和垂直方向上的位置。通过模拟数据生成目标的真实运动轨迹,并在每个时刻添加高斯分布的测量噪声。卡尔曼滤波通过预测和更新步骤,对目标的状态进行估计,最终结果显示了真实状态、测量值和卡尔曼滤波估计的对比。

在实际应用中,系统动态模型 A A A、测量矩阵 H H H、过程噪声协方差 Q Q Q 和测量噪声协方差 R R R都需要根据具体情况进行调整。

六、卡尔曼滤波的应用场景

卡尔曼滤波在许多领域都有广泛的应用,特别适用于需要实时估计的系统,如:

  1. 导航系统: 用于飞行器、汽车等导航系统,通过融合GPS测量和惯性测量,提供准确的位置估计。
  2. 金融领域: 用于股票价格预测和投资组合管理,通过融合历史价格和实时市场数据,提供更稳健的估计。
  3. 机器人技术: 用于移动机器人的自我定位,通过融合传感器测量,提供准确的位置信息。

结论

卡尔曼滤波是一种强大的估计技术,通过有效地融合系统动态模型和测量数据,提供对系统状态的最优估计。本文深入解释了卡尔曼滤波的基本理论、数学公式的推导,并通过Python代码示例演示了其在实际应用中的效果。希望读者通过学习和实践更好地理解和应用卡尔曼滤波技术。

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

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

相关文章

20_GC垃圾回收机制

文章目录 GC如何确定垃圾如何回收垃圾回收垃圾的时机 GC 如何确定垃圾 引用计数算法 给对象添加一个引用计数器,每当一个地方引用它时,计数器加1,每当引用失效时,计数器减少1,当计数器的数值为0时,也就是对…

python,序列的切片

序列的切片就是指从一个序列中取出子序列 语法: 序列[起始下标:结束下标:步长] 步长为1表示一个一个的取元素,步长为2表示每次跳过一个元素的取元素,步长为负数表示反向切片,取元素时取到结束下标&#…

Python如何免费调用微软Bing翻译API

一、引言 现在免费的机器翻译越来越少了,随着有道翻译开始收费,百度降低用户的免费机器翻译额度(目前只有实名认证过的高级用户才能获得100万字符的免费翻译额度),而亚马逊、腾讯等机器翻译调用相对比较麻烦,需要下载各种插件包&…

智能小程序能做什么?

一. 自定义Tab页 涂鸦提供了丰富的场景化、个性化的 ToC 智能服务,不仅可以快速低成本的自由搭建出更多智能服务,还为你提供了基于小程序技术方案的可自主可控的自定义开发链路,为拓展更多品牌化、个性化、差异化智能服务提供生态基础。 我…

Unity之角色控制器

PS:公司终于给我派任务了,最近几天都没学Unity🤧。 一、角色控制器的实现方式 目前小编知道的角色控制器实现方式有三种: 应用商店的角色控制系统Unity自己的角色控制器通过物理系统去做角色控制器 本篇介绍的是第二种Unity自己的角色控制…

【期末不挂科-C++考前速过系列P1】大二C++第1次过程考核(3道简述题&7道代码题)【解析,注释】

前言 大家好吖,欢迎来到 YY 滴C复习系列 ,热烈欢迎! 本章主要内容面向接触过C的老铁 主要内容含: 欢迎订阅 YY滴C专栏!更多干货持续更新!以下是传送门! YY的《C》专栏YY的《C11》专栏YY的《Lin…

vi/vim 编辑器 --基本命令

1 vi/vim编辑器介绍 vi 是visual interface 的简称,是Linux中最经典的文本编辑器 vim是vi的加强版。兼容了vi的所有指令,不仅能编辑文本,而且具有shell程序编辑的功能,可以通过不同颜色的字体辨别语法的正确性,极大…

js中try...catch捕捉错误

文章目录 一、前言二、场景2.1、setTimeout2.2、Promise 三、最后 一、前言 说到try...catch都觉得非常熟悉了,不就是用来捕捉代码块中的错误嘛,平时也用得比较多的 二、场景 try...catch只能捕捉到同步执行代码块中的错误 2.1、setTimeout try {setT…

淘宝商家实现批量上货API接口调用接入说明(淘宝开放平台免申请接入)

API接入详细步骤: 第一步:在淘宝开放平台中选择接口塡写应用申报递交给我司,确认接口是否都有。 第二步:确认接口都有,需交1000元进行测试,可以测试三天,测试数据符合淘宝开放平台接口参数说明&…

Java常用的加密技术

项目结构: 总体代码: package VirtualUtils; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import java.io.UnsupportedEncodingException; import java.security.*; import java.security.sp…

WebServer 跑通/运行/测试(详解版)

👂 椿 - 沈以诚 - 单曲 - 网易云音乐 目录 🎂前言 🌼跑通 (1)系统环境 (2)克隆源码 (3)安装和配置 Mysql (4)写 sql 语句 (5&…

文件操作(一)

目录 一.什么是文件 1.程序文件和数据文件 2.文件名 3,文本文件和二进制文件 二.文件的打开和关闭 1.流和标准流 2.文件指针 3.文件的打开与关闭 三.结尾 一.什么是文件 在我们学习文件操作之前我们先了解一下什么是文件?以及文件为什么使用文件…

【Effective Objective - C】—— 熟悉Objective-C

【Effective Objective - C】—— 熟悉Objective-C 熟悉Objective-C1.oc的起源消息和函数的区别运行期组件和内存管理要点: 2.在类的头文件中尽量少引入其他头文件向前声明要点: 3.多使用字面量语法,少用与之等价的方法字符串字面量字面数值字…

小程序基础学习(导航栏组件)

一&#xff0c;创建组件 二&#xff0c;组件传入参数 三&#xff0c;组件接收参数 四&#xff0c;组件渲染参数 五&#xff0c;组件代码 <!--components/daoHangLan/daoHangLan.wxml--> <view class"titles"><block wx:for"{{titles}}"…

第 3 章 Keepalived 双机热备

技能展示&#xff1a; 会构建双机热备系统 会构建 LVSHA 高可用群集 在这个高度信息化的 IT 时代&#xff0c;企业的生产系统、业务运营、销售和支持&#xff0c;以及日常管理等环节越来越依赖于计算机信息和服务&#xff0c;对高可用&#xff08;HA&#xff09;技术的应用需求…

Python3.5如何打包编译

python3.5怎么打包编译 问题&#xff1a;用Python开发的小工具有时需要编译打包为Windows(*.exe)、Mac等操作系统下的可执行性文件以供非程序员使用。 解决方案&#xff1a; 一、py2exe 目前只支持到Python3.4&#xff0c;暂不支持Python3.5 二、PyInstaller 安装&#x…

C#人力资源管理系统源码

C#人力资源管理系统源码 源码描述&#xff1a; 该系统利用asp.net中mvc,linq搭建开发&#xff0c; 分权限管理 权限级别分为&#xff1a;管理员&#xff0c;经理&#xff0c;专员&#xff0c;员工等 管理员可以管理角色、菜单 经理可以管理 组织规划&#xff0c;员工管理&#…

微信商家转账到零钱,既能单笔又能批量,支持多商户管理

大家好&#xff0c;我是小悟 微信商家转账到零钱的功能大家应该都熟悉吧&#xff0c;为了满足商家向用户微信零钱转账的需求&#xff0c;微信支付推出【商家转账到零钱】服务&#xff0c;方便商户可以一次向单个或多个用户的微信零钱转账。 商家转账到零钱为商户提供了简便、…

【Qt 学习之路】关于C++ Vlc视频播放

文章目录 1、简介2、效果2.1、视频2.2、动态图 3、核心代码3.1、判断视频3.2、视频核心类调用3.3、视频核心类3.3.1、头文件3.3.2、源文件 1、简介 最近有童鞋咨询VLC相关的问题&#xff0c;公布一个 5年前 编写的 VLC示例 代码供参考学习。包括正常对视频各种常用的操作&…

ASP.NET进销存系统源码

ASP.NET进销存系统源码 功能介绍&#xff1a; 财务 销售清单&#xff0c;填写销售单&#xff0c;客户管理&#xff0c;添加客户资料 销售 销售清单&#xff0c;填写销售单&#xff0c;客户管理&#xff0c;添加客户资料 仓库 仓库结存&#xff0c;仓库盘点&#xff0c;盘点结…