无人驾驶卡尔曼滤波

news2024/12/24 9:22:49

无人驾驶卡尔曼滤波(行人检测)
x k = a x k − 1 + w k x_k = ax_{k-1} + w_k xk=axk1+wk
w k w_k wk:过程噪声

状态估计

估计飞行器状态(高度)
x k = z k − v k x_k = z_k - v_k xk=zkvk
卡尔曼滤波通过同时考虑上一状态值和当前的测量值来获得对当前状态值的估计,对状态 x x x的估计: x ^ \hat{x} x^
x ^ k = x ^ k − 1 + g k ( z k − x ^ k − 1 ) \hat{x}_k = \hat{x}_{k-1} + g_k(z_k - \hat{x}_{k-1}) x^k=x^k1+gk(zkx^k1)
g k g_k gk:卡尔曼增益:指之前的估计和当前测量对当前估计的影响的分配权重,如果为0,说明非常不信任当前的测量,直接保留了上一次的估计作为当前状态的估计;增益为 1,认为当前的测量非常可信,彻底接受它作为我当前状态的估计

计算卡尔曼增益

那么如何计算卡尔曼增益呢?我们使用一种间接的方法,我们虽然不知道测量噪声 v k v_k vk的值,但是我们知道它的均值,前面我们提到,测量噪声来自传感器本身,并且符合高斯分布,所以我们能够从传感器厂商那里获得测量噪声的均值 r r r,那么 g k g_k gk可以表示为:

g k = p k − 1 ( p k − 1 + r ) g_k = \frac{p_{k-1}}{(p_{k-1} + r)} gk=(pk1+r)pk1

p k p_k pk:预测误差

p k = ( 1 − g k ) p k − 1 p_k = \frac{(1 - g_k)}{p_{k-1}} pk=pk1(1gk)

那么假设前一次的预测误差 $ p_{k-1} = 0$,那么根据公式,当前的增益 g k = 0 g_k = 0 gk=0,一维着舍弃掉当前的测量而完全采用上一个时刻的估计,如果 p k − 1 = 1 p_{k-1} = 1 pk1=1 那么增益变成 1 / ( 1 + r r r ) 通常$ r $ 是个很小的数值,所以增益为1,所以完全接受这一次的测量作为我们的估计(因为上一次的的预测误差太大了,为1,所以一旦拿到了新的测量,如获至宝,就干脆把不准确的上次的估计舍弃掉了)
对于下面的公式的分析是一样的,我们考虑极端的例子,当增益为 0, p k = p k − 1 p_k = p_{k-1} pk=pk1 ,因为我们彻底舍弃掉了本次的测量,所以本次的预测误差只能接受上一次的。

预测和更新

得到两个公式:

x k = a x k − 1 x_k = ax_{k-1} xk=axk1

x ^ k = x ^ k − 1 + g k ( z k − x ^ k − 1 ) \hat{x}_k = \hat{x}_{k-1} + g_k(z_k - \hat{x}_{k-1}) x^k=x^k1+gk(zkx^k1)

第一个公式我们称之为预测,是基于一些先验的知识(比如说运动模型,牛顿力学等等)觉得我们的状态应该是这样的,而第二个公式呢,就是我们基于我们“不完美的”的传感器的测量数据来更新我们对状态的估计。另为,预测,理论上只考虑了一个固定的过程模型和过程噪声,但是由于我们现在是对机械的状态进行估计,在预测过程中需要对机械本身的控制建模, 我们在预测部分再新增一个控制信号,我们用 b u k bu_k buk表示。实际的传感器测量除了会有测量噪声 v k v_k vk 以外,还会存在一定的关于真实状态的缩放,因此我们使用 x k x_k xk 表示测量时通常还会在其前面加一个缩放系数 c c c 。 结合这写我们就可以得到卡尔曼滤波预测和更新过程了:

预测

x ^ k = a x ^ k − 1 + b u k \hat{x}_k = a\hat{x}_{k-1} + bu_k x^k=ax^k1+buk

p k = a p k − 1 a p_k = ap_{k-1}a pk=apk1a

卡尔曼滤波更新的过程为:

g k = p k c c p k c + r g_k = \frac{p_kc}{cp_kc + r} gk=cpkc+rpkc

x ^ k ← x ^ k + g k ( z k − c x ^ k ) \hat{x}_k←\hat{x}_k + g_k(z_k - c\hat{x}_k) x^kx^k+gk(zkcx^k)

p k ← ( 1 − g k c ) p k p_k←(1 - g_kc)p_k pk(1gkc)pk

线性代数方法

预测

x ^ k = A x ^ k − 1 + B u k \hat{x}_k = A\hat{x}_{k-1} + Bu_k x^k=Ax^k1+Buk

P k = A P k − 1 A P_k = AP_{k-1}A Pk=APk1A

卡尔曼滤波更新的过程为:

G k = P k C c P k C + R G_k = \frac{P_kC}{cP_kC + R} Gk=cPkC+RPkC

x ^ k ← x ^ k + G k ( z k − C x ^ k ) \hat{x}_k←\hat{x}_k + G_k(z_k - C\hat{x}_k) x^kx^k+Gk(zkCx^k)

P k ← ( 1 − G k C ) P k P_k←(1 - G_kC)P_k Pk(1GkC)Pk

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
from sympy import Symbol, Matrix
from sympy.interactive import printing

x = np.mat([[0.0, 0.0, 0.0, 0.0]]).T
print(x, x.shape)
P = np.diag([1000.0, 1000.0, 1000.0, 1000.0])
print(P, P.shape)

dt = 0.1
F = np.mat([[1.0, 0.0, dt, 0.0],  # 预测矩阵
              [0.0, 1.0, 0.0, dt],
              [0.0, 0.0, 1.0, 0.0],
              [0.0, 0.0, 0.0, 1.0]])

print(F, F.shape)

H = np.mat([[0.0, 0.0, 1.0, 0.0],  # 测量矩阵
              [0.0, 0.0, 0.0, 1.0]])
print(H, H.shape)

ra = 0.09

R = np.mat([[ra, 0.0],
              [0.0, ra]])
print(R, R.shape)

I = np.eye(4)
print(I, I.shape)

sv = 0.5
G = np.mat([[0.5*dt**2],  # 卡尔曼增益
              [0.5*dt**2],
              [dt],
              [dt]])
Q = G*G.T*sv**2   # 过程噪声的协方差矩阵
print(G, G.shape)
print(Q, Q.shape)

printing.init_printing()
dts = Symbol('dt')
Qs = Matrix([[0.5*dts**2], [0.5*dts**2], [dts], [dts]])
Qs*Qs.T

m = 200
vx = 20
vy = 10

mx = np.array(vx + np.random.randn(m))
my = np.array(vy + np.random.randn(m))
measurements = np.vstack((mx, my))

print(measurements.shape)
print('Standard Deviation of Acceleration Measurements=%.2f' % np.std(mx))
print('You assumed %.2f in R.' % R[0, 0])

# fig = plt.figure(figsize=(16, 5))
# plt.step(range(m), mx, label='$\dot x$')
# plt.step(range(m), my, label='$\dot y$')
# plt.ylabel('Velocity $m/s$')
# plt.title('Measurements')
# plt.legend(loc='best', prop={'size': 18})

xt = []
yt = []
dxt = []
dyt = []
Zx = []
Zy = []
Px = []
Py = []
Pdx = []
Pdy = []
Rdx = []
Rdy = []
Kx = []
Ky = []
Kdx = []
Kdy = []

def savestates(x, Z, P, R, K):
    xt.append(float(x[0]))
    yt.append(float(x[1]))
    dxt.append(float(x[2]))
    dyt.append(float(x[3]))
    Zx.append(float(Z[0]))
    Zy.append(float(Z[1]))
    Px.append(float(P[0, 0]))
    Py.append(float(P[1, 1]))
    Pdx.append(float(P[2, 2]))
    Pdy.append(float(P[3, 3]))
    Rdx.append(float(R[0, 0]))
    Rdy.append(float(R[1, 1]))
    Kx.append(float(K[0, 0]))
    Ky.append(float(K[1, 0]))
    Kdx.append(float(K[2, 0]))
    Kdy.append(float(K[3, 0]))

for n in range(len(measurements[0])):
    x = F * x
    P = F * P * F.T + Q
    S = (H * P * H.T) + R
    K = (P * H.T) * np.linalg.pinv(S)

    Z = measurements[:, n].reshape(2, 1)
    y = Z - (H * x)
    x = x + (K * y)

    P = (I - (K * H)) * P

    savestates(x, Z, P, R, K)

def plot_x():
    fig = plt.figure(figsize=(16, 9))
    plt.step(range(len(measurements[0])), dxt, label='$estimateVx$')
    plt.step(range(len(measurements[0])), dyt, label='$estimateVy$')

    plt.step(range(len(measurements[0])), measurements[0], label='$measurementVx$')
    plt.step(range(len(measurements[0])), measurements[1], label='$measurementVy$')

    plt.axhline(vx, color='#999999', label='$trueVx$')
    plt.axhline(vy, color='#999999', label='$trueVy$')

    plt.xlabel('Filter Step')
    plt.title('Estimate (Elements from State Vector $X$)')
    plt.legend(loc='best', prop={'size': 11})
    plt.ylim([0, 30])
    plt.ylabel('Velocity')
    plt.show()

def plot_xy():
    fig = plt.figure(figsize=(16, 16))
    plt.scatter(xt, yt, s=20, label='State', c='k')
    plt.scatter(xt[0], yt[0], s=100, label='Start', c='g')
    plt.scatter(xt[-1], yt[-1], s=100, label='Goal', c='r')

    plt.xlabel('x')
    plt.ylabel('y')
    plt.title('Position')
    plt.legend(loc='best')
    plt.axis('equal')
    plt.show()

if __name__ == '__main__':
    plot_xy()

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

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

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

相关文章

OpenAI 是如何一步一步把RAG做到98%的准确性得

参考OpenAI的官方演讲,如何做好RAG。本文整理的内容,均来源于此演讲内容。 【OpenAI演讲-自制中文字幕】干货-如何提升大模型表现?-提示工程、RAG与Fine-Tuning技巧详解_哔哩哔哩_bilibili 45% 的准确性 普通搜索不做任何处理的效果&#x…

人工智能_机器学习091_使用三维瑞士卷数据_KMeans聚类算法进行瑞士卷数据聚类---人工智能工作笔记0131

然后我们首先来构建一下数据 准备瑞士卷数据: import numpy as np 导入数学计算包 import matplotlib.pyplot as plt 导入画图包 #自底向上聚类 from sklearn.cluster import AgglceerativeClustering 导入分层聚类模型 from sklearn.datasets import make_swiss_roll # 瑞士卷…

给自己创建的GPTs添加Action(查天气)

前言 在这篇文章中,我将分享如何利用ChatGPT 4.0辅助论文写作的技巧,并根据网上的资料和最新的研究补充更多好用的咒语技巧。 GPT4的官方售价是每月20美元,很多人并不是天天用GPT,只是偶尔用一下。 如果调用官方的GPT4接口&…

Linux 下查看内存使用情况方法总结

在做Linux系统优化的时候,物理内存是其中最重要的一方面。自然的,Linux也提供了非常多的方法来监控宝贵的内存资源的使用情况。下面的清单详细的列出了Linux系统下通过视图工具或命令行来查看内存使用情况的各种方法。 1./proc/meminfo 查看RAM使用情况…

【C语言】TCP测速程序

一、服务端 下面是一个用 C 语言编写的测试 TCP 传输速度的基本程序示例。 这只是一个简单示例&#xff0c;没有做详细的错误检查和边缘情况处理。在实际应用中&#xff0c;可能需要增加更多的功能和完善的异常处理机制。 TCP 服务器 (server.c): #include <stdio.h> #…

Centos7 手动更改系统时间

文章目录 1.更改系统时间2.写入系统时间3.查看是否写入成功 1.更改系统时间 date -s "2017-12-18 09:40:00"2.写入系统时间 hwclock -w3.查看是否写入成功 timedatectl

vue中鼠标拖动触发滚动条的移动

前言 在做后端管理系统中&#xff0c;像弹窗或大的表单时&#xff0c;经常会有滚动条的出现&#xff0c;但有些时候如流程、图片等操作时&#xff0c;仅仅使用鼠标拖动滚动条操作不太方便&#xff0c;如果使用鼠标拖拽图片或容器来触发滚动条的移动就比较方便了 功能设计 如…

用python提取word中的所有图片

使用word中提取的方式图片会丢失清晰度&#xff0c;使用python写一个脚本&#xff0c;程序运行将弹出对话框选择一个word文件&#xff0c;然后在弹出一个对话框选择一个文件夹保存word中的文件。将该word中的所有图片都保存成png格式&#xff0c;并命名成image_i的样式。 程序…

模型容器与AlexNet构建

一、模型容器——Containers nn.Sequential 是 nn.module的容器&#xff0c;用于按顺序包装一组网络层 Sequential 容器 nn.Sequential 是 nn.module的容器&#xff0c;用于按顺序包装一组网络层 • 顺序性&#xff1a;各网络层之间严格按照顺序构建 • 自带forward()&#xf…

nodejs版本管理工具nvm的安装与使用

提示&#xff1a;nodejs版本管理工具nvm的安装与使用 文章目录 前言一、安装二、淘宝镜像配置三、安装所需版本的nodejs四、切换nodejs版本五、参考文档总结 前言 需求&#xff1a;新建一个vue3项目&#xff0c;&#xff0c;提示写法错误 查原因为node版本过低 随着技术更新迭…

6个提升Python编程能力的PyCharm插件

大家好&#xff0c;PyCharm作为一款强大的集成开发环境&#xff0c;本身已经提供了许多功能&#xff0c;但一些插件将进一步扩展和增强PyCharm的能力。通过使用这些插件&#xff0c;大家能够更快速地编写代码、提高代码质量、进行调试和优化&#xff0c;并将开发体验提升到一个…

Python 面向对象之元类

Python 面向对象之元类 【一】一切皆对象 【1】元类 元类&#xff08;metaclass&#xff09;是Python中用于创建类的类。在Python中&#xff0c;类是对象&#xff0c;而元类就是类的类它们控制类的创建过程&#xff0c;允许你定制类的行为Python中内置的默认元类是type我们用…

SpringMVC概述、SpringMVC 的入门

1.MVC介绍 MVC是一种设计模式&#xff0c;将软件按照模型、视图、控制器来划分&#xff1a; M&#xff1a;Model&#xff0c;模型层&#xff0c;指工程中的JavaBean&#xff0c;作用是处理数据 JavaBean分为两类&#xff1a; 一类称为数据承载Bean&#xff1a;专门存储业务数据…

12、DolphinScheduler

1、DolphinScheduler简介 1.1、 DolphinScheduler概述 Apache DolphinScheduler是一个分布式、易扩展的可视化DAG工作流任务调度平台。致力于解决数据处理流程中错综复杂的依赖关系&#xff0c;使调度系统在数据处理流程中开箱即用。 1.2、 DolphinScheduler核心架构 Dolph…

Unity 踩坑记录 AnyState 切换动画执行两次

AnySate 切换动画 Can Transition To Self 将这个勾选去掉&#xff01;&#xff01;&#xff01;

九州金榜如何让孩子在家庭教育中更优秀

​ 每个人在出生时就有上天恩赐的两份礼物&#xff0c;一份是血脉相连的亲情&#xff0c;一份是家庭的关爱与教育。 最早接触的人就是父母&#xff0c;最早接触的教育就是家庭教育&#xff0c;这对孩子的影响极为深远。 这种家庭教育相比较学校教育&#xff0c;不仅有言传教…

springCould中的Config-从小白开始【10 】

目录 &#x1f32d;1.spring cloud Config是什么&#x1f636;‍&#x1f32b;️&#x1f636;‍&#x1f32b;️&#x1f636;‍&#x1f32b;️ &#x1f953;2.能干什么&#x1f636;‍&#x1f32b;️&#x1f636;‍&#x1f32b;️&#x1f636;‍&#x1f32b;️ &am…

借用GitHub将typora图片文件快速上传CSDN

前情概要 众所周知&#xff0c;程序员大佬们喜欢用typora软件写代码笔记&#xff0c;写了很多笔记想要放到CSDN上给其他大佬分享&#xff0c;但是在往csdn上搬运的时候&#xff0c;图片总是上传出错&#xff0c;一张一张搞有很麻烦&#xff0c;咋如何搞&#xff1f; 废话不多…

conda新建、配置python3.8虚拟环境,torch-cuda1.8,torchtext0.9.0,huggingface安装transformers库

起因是我在用bert的时候&#xff0c;导包报错 Python 环境缺少 importlib.metadata 模块。importlib.metadata 是 Python 3.8 引入的模块&#xff0c;而我的环境中使用的 Python 版本为 3.7。所以我得重新配置一个python3.8的环境 准备工作 在开始菜单找到anaconda prompt(an…

唠一唠Java线程池

第1章&#xff1a;引言 大家好&#xff0c;我是小黑&#xff0c;咱们今天来聊聊Java线程池&#xff0c;如果没有线程池&#xff0c;每个线程都需要手动创建和销毁线程&#xff0c;那将是多么低效和耗资源啊&#xff01; 线程池的核心作用就是复用已创建的线程&#xff0c;减少…