boss:整个卡尔曼滤波器的简单案例——估计机器人位置

⭐️ 卡尔曼滤波

卡尔曼滤波(Kalman Filtering)是一种用于状态估计的强大技术,常用于处理具有随机噪声的系统的状态估计问题。在目标跟踪等应用中,卡尔曼滤波常被用来预测目标的位置和速度等状态变量,并根据观测数据进行状态更新,从而实现对目标轨迹的跟踪。

在这里插入图片描述

在目标跟踪中,可能会出现假点(False Positives)的情况,即目标跟踪算法错误地将背景中的噪声或其他物体错误地识别为目标。为了减少假阳性的影响,可以使用卡尔曼滤波器进行假点过滤。下面是卡尔曼滤波的基本原理:

状态模型: 假设目标的状态变量为 x k \mathbf{x}_k xk,包括位置、速度等信息。卡尔曼滤波器会根据系统的动力学模型来预测目标的下一个状态 x ^ k − \hat{\mathbf{x}}_k^- x^k。通常采用线性动力学模型,形式为 x k = F k x k − 1 + B k u k + w k \mathbf{x}_k = \mathbf{F}_k \mathbf{x}_{k-1} + \mathbf{B}_k \mathbf{u}_k + \mathbf{w}_k xk=Fkxk1+Bkuk+wk,其中 F k \mathbf{F}_k Fk 是状态转移矩阵, B k \mathbf{B}_k Bk 是控制输入矩阵, u k \mathbf{u}_k uk 是外部控制输入, w k \mathbf{w}_k wk 是过程噪声(高斯分布)。

观测模型: 卡尔曼滤波器会根据观测数据来更新状态估计值。假设观测数据为 z k \mathbf{z}_k zk,卡尔曼滤波器会根据观测模型 z k = H k x k + v k \mathbf{z}_k = \mathbf{H}_k \mathbf{x}_k + \mathbf{v}_k zk=Hkxk+vk 来估计目标的位置。其中 H k \mathbf{H}_k Hk 是观测矩阵, v k \mathbf{v}_k vk 是观测噪声(高斯分布)。

卡尔曼滤波器更新: 卡尔曼滤波器利用预测值和观测值的差异,结合系统的动力学模型和观测模型,计算出最优的状态估计值。具体来说,卡尔曼滤波器包括两个主要步骤:

预测步骤(Predict): 根据系统的动力学模型,预测目标的状态变量,并计算预测的状态协方差矩阵 P k − \mathbf{P}_k^- Pk

更新步骤(Update): 根据观测模型,计算卡尔曼增益 K k \mathbf{K}_k Kk,并利用观测数据对预测值进行修正,得到最终的状态估计值 x ^ k \hat{\mathbf{x}}_k x^k 和状态协方差矩阵 P k \mathbf{P}_k Pk

整体过程如下图所示:
在这里插入图片描述

卡尔曼的相关资料很多,更详细的知识,读者可以自行搜索,嘻嘻!!!

小编推荐一部著作《Kalman_and_Bayesian_Filters_in_Python》和一位大神的博客 【滤波】设计卡尔曼滤波器,这位大神对前面的著作做了整体的翻译,很牛!!!

⭐️ 设计个卡尔曼滤波器,估计机器人的位置

本文参考《Kalman_and_Bayesian_Filters_in_Python》中的案例,利用函数模拟机器人的位置,然后通过简单卡尔曼滤波器利用测量数据对机器人位置进行估计。

滤波器各个参数设计如下

状态:
在这里插入图片描述

状态转移方程:
在这里插入图片描述

状态转移矩阵:
在这里插入图片描述

观测矩阵:
在这里插入图片描述

初始测量误差协方差矩阵:
在这里插入图片描述

初始状态及其协方差矩阵:
在这里插入图片描述

过程误差协方差矩阵利用白噪声获取。

整体代码如下

from numpy.random import randn
import matplotlib.pyplot as plt
import numpy as np
from filterpy.kalman import KalmanFilter
from scipy.linalg import block_diag
from filterpy.common import Q_discrete_white_noise
from filterpy.stats import plot_covariance_ellipse# 模拟传感器,返回robot的位置信息
class PosSensor(object):def __init__(self, pos=(0, 0), vel=(0, 0), noise_std=1.):self.vel = velself.noise_std = noise_stdself.pos = [pos[0], pos[1]]def read(self):self.pos[0] += self.vel[0]self.pos[1] += self.vel[1]return [self.pos[0] + randn() * self.noise_std,self.pos[1] + randn() * self.noise_std]# 绘制过滤器输出数据
def plot_filter(xs, ys=None, dt=None, c='C0', label='Filter', var=None, **kwargs):if ys is None and dt is not None:ys = xsxs = np.arange(0, len(ys) * dt, dt)if ys is None:ys = xsxs = range(len(ys))lines = plt.plot(xs, ys, color=c, label=label, **kwargs)if var is None:return linesvar = np.asarray(var)std = np.sqrt(var)std_top = ys+stdstd_btm = ys-stdplt.plot(xs, ys+std, linestyle=':', color='k', lw=2)plt.plot(xs, ys-std, linestyle=':', color='k', lw=2)plt.fill_between(xs, std_btm, std_top, facecolor='yellow', alpha=0.2)return lines# 测量误差方差
R_std = 0.35
# 过程误差方差
Q_std = 0.04def tracker():# 创建卡尔曼滤波器tracker = KalmanFilter(dim_x=4, dim_z=2)# 时间步伐dt = 1.0# 状态转移矩阵tracker.F = np.array([[1, dt, 0,  0],[0,  1, 0,  0],[0,  0, 1, dt],[0,  0, 0,  1]])# 过程输入值tracker.u = 0.# 观测矩阵tracker.H = np.array([[1/0.3048, 0, 0, 0],[0, 0, 1/0.3048, 0]])# 测量误差协方差矩阵tracker.R = np.eye(2) * R_std**2# 白噪声q = Q_discrete_white_noise(dim=2, dt=dt, var=Q_std**2)# 过程噪声协方差矩阵tracker.Q = block_diag(q, q)# 初始状态tracker.x = np.array([[0, 0, 0, 0]]).T# 初始状态协方差矩阵tracker.P = np.eye(4) * 500.return tracker# 模拟机器人移动
N = 30
sensor = PosSensor((0, 0), (2, .5), noise_std=R_std)
# 测量数据,位置信息
zs = np.array([sensor.read() for _ in range(N)])# 运行过滤器
robot_tracker = tracker()
# 卡尔曼滤波结果
mu, cov, _, _ = robot_tracker.batch_filter(zs)for x, P in zip(mu, cov):# x 和 y 的协方差cov = np.array([[P[0, 0], P[2, 0]], [P[0, 2], P[2, 2]]])mean = (x[0, 0], x[2, 0])# 绘制卡尔曼滤波器输出的位置信息,包括位置和方差plot_covariance_ellipse(mean, cov=cov, fc='g', std=3, alpha=0.5)# 坐标位置转换为单位米
zs *= .3048
# 绘制测量数据和过滤器输出
plot_filter(mu[:, 0], mu[:, 2])
plt.scatter(zs[:, 0], zs[:, 1], color='k', facecolor='none', lw=2, label='Measurements'),
plt.legend(loc=2)
plt.xlim(0, 20)
plt.show()

运行结果如下
在这里插入图片描述

笔者水平有限,若有不对的地方欢迎评论指正!

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Go并发安全,锁和原子操作

一. 并发安全 有时候在Go代码中可能存在多个goroutine同时操作一个资源(临界区),这种情况会发生竞态问题(数据竞态)。 1.1 互斥锁 互斥锁是一种常见的控制共享资源访问的方法,它能够保证同时只有一个goroutine可以访问共享资源。Go语言中使用sync包的Mut…

uboot大致流程总结

文章目录 一、uboot介绍二、uboot的配置编译过程2.1 make xxx_defconfig2.2 make 一、uboot介绍 uboot是一个bootloader,用于在嵌入式设备中引导linux内核启动,在嵌入式设备中常见的组织结构如下: 芯片内部固化代码 -> bootloader -> …

40+ Node.js 常见面试问题 [2024]

今天就开始你的Node.js生涯。在这里,我们探讨了最佳Node.js面试问题和答案,以帮助应届生和经验丰富的候选人获得理想的工作。 Node.js 是许多大公司技术堆栈的重要组成部分,例如 PayPal、Trello、沃尔玛和 NASA。 根据 ZipRecruiter 的数据&…

算法练习|Leetcode49字母异位词分词 ,Leetcode128最长连续序列,Leetcode3无重复字符的最长子串,sql总结

目录 一、Leetcode49字母异位词分词题目描述解题思路方法:哈希总结 二、Leetcode128最长连续序列题目描述解题思路方法:总结 三、Leetcode3无重复字符的最长子串题目描述解题思路方法:双指针法总结sql总结 一、Leetcode49字母异位词分词 题目描述 给你一个字符串数组&#xf…

模板初阶

泛型编程: 泛型编程:编写与类型无关的通用代码,模板是泛型编程的基础 class Test { public:void Swap(int& left, int& right){int tmp left;left right;right tmp;}void Swap(double& left, double& right){double tmp…

AR HUD_VSLAM+显示技术

智能座舱的一个重要技术方向是表达与展示。HUD可以将驾驶相关的信息,如车速、导航等投射到驾驶员的视线上方,避免驾驶员的目光离开前方道路。这种显示方式可以提供关键信息的实时展示,减少驾驶员的分心。 HUD的技术原理就是通过光学系统将信息…

网络工程师----第十一天

OSPF: 对称加密算法: 也称为私钥加密或单密钥算法,是一种加密方式,其中加密和解密使用相同的密钥。这种算法的优点包括加密解密速度快、计算量小,适用于大量数据的加密。然而,它的缺点是密钥的安全性难以保…

入坑 Node.js 1

原文:https://blog.iyatt.com/?p14717 前言 前面刚刚对 Spring Boot 有了个概念,再来学学 Node.js,顺便当学 JavaScript,为后面入前端做准备。 环境 Node.js 20.12.2 官方 API 文档:https://nodejs.org/docs/lat…

前端CSS基础6(CSS列表与表格的相关属性,边框的样式调整)

前端CSS基础6(CSS列表与表格的相关属性,边框的样式调整) CSS列表相关属性CSS表格相关属性回忆表格边框相关属性单元格边框相关属性回忆单元格的跨行和跨列操作单元格边框的相关属性 CSS列表相关属性 在 CSS 中,列表(L…

多元函数泰勒公式(含黑塞矩阵)

一元函数的泰勒公式: 接下来,由一元函数有关知识,我们有: 注意这里的dxn中,应把dx看作一个整体,即一个微小变量的n次方 我们接下来推导微分算子: 接下来,把一元泰勒公式转为微分形式: 对于二元…

arm架构,django4.2.7适配达梦8数据库

【Python相关包版本信息】 Django 4.2.7 django-dmPython 3.1.7 dmPython 2.5.5 【达梦数据库版本】 DM Database Server 64 V8 DB Version: 0x7000c 适配过程中发现的问题如下: 错误一:d…

OWASP发布十大开源软件安全风险及应对指南

​ 最近爆发的XZ后门事件,尽管未酿成Log4j那样的灾难性后果,但它再次敲响了警钟:软件供应链严重依赖开源软件,导致现代数字生态系统极其脆弱。面对层出不穷的安全漏洞,我们需要关注开源软件 (OSS)风险 ,改进…