运动模型非线性测量非线性扩展卡尔曼跟踪融合滤波算法(Matlab仿真)

        卡尔曼滤波的原理和理论在CSDN已有很多文章,这里不再赘述,仅分享个人的理解和Matlab仿真代码。

        之前的博文运动模型非线性扩展卡尔曼跟踪融合滤波算法(Matlab仿真)-CSDN博客使用扩展卡尔曼滤波算法将非线性的运动模型线性化,但测量值仍旧是线性的,不需要雅可比矩阵。这里考虑测量值也为非线性的情况,并用Matlab做仿真。

      如果估计值为[x,y,v,theta,w],测量值为[x,y,v,theta],则它们为线性关系,状态观测矩阵可以用下面的矩阵表示。

        

        这里考虑估计值为[x,y,v,theta,w],但测量值为[x,y,vx,vy],两者为非线性关系,则需要使用下表中的h(x)和线性化的雅可比矩阵 进行滤波计算。

        由估计值和测量值的关系可以得到

         ​​​​​​​

        也即h(x)函数,写为测量的预测则为

% 扩展卡尔曼滤波的测量模型
function Z_pred = EKF_measure(x)Z_pred = x(1:4);v = x(3);theta = x(4);Z_pred(3) = v*cos(theta);Z_pred(4) = v*sin(theta);
end

        而对于测量的雅可比矩阵 ​​​​​​​,则可以通过下式获得

        根据公式计算,得到测量的雅可比矩阵为

        

        再带入H矩阵中可以得到扩展卡尔曼滤波的结果。将上述公式用matlab编程即可得到滤波结果。

% 匀速转弯运动模型的扩展卡尔曼滤波算法仿真
% 摄像头和雷达的测量值为x,y,vx,vy,有J_H
clc;clear;close all;% 匀速转弯运动的初始值
x0 = 0;                                     % 目标的初始横向位置
y0 = 0;                                     % 目标的初始纵向位置
v = 3;                                      % 目标的速度
theta = 0;                                  % 目标的偏航角(目标在当前坐标系下和x轴的夹角)
omga = 0.1;                                 % 目标的偏航角速度
N = 150;                                    % 数据量
dt = 0.2;                                   % 单帧时间
t = dt*(1:1:N);                             % 时间轴% 更新超参数
sigma_q_x = 0.2;                            % 纵向距离的过程噪声标准差
sigma_q_y = 0.2;                            % 横向距离的过程噪声标准差
sigma_q_v = 0.2;                            % 目标速度的过程噪声标准差
sigma_q_theta = 0.01;                        % 目标偏航角的过程噪声标准差
sigma_q_ogma = 0.01;                         % 目标偏航角速度的过程噪声标准差
Q_matrix_ctrv = diag([sigma_q_x^2, sigma_q_y^2, sigma_q_v^2, sigma_q_theta^2, sigma_q_ogma^2]);% 设置测量噪声协方差矩阵R,噪声来自测量的误差
sigma_r_x = 0.2;
sigma_r_y = 0.2; 
sigma_r_vx = 0.1; 
sigma_r_vy = 0.1;
R_matrix_ctrv = diag([sigma_r_x^2, sigma_r_y^2, sigma_r_vx^2, sigma_r_vy^2]);% 卡尔曼滤波器初始化参数
X_ctrv = zeros(5,N);                                    % 初始化目标运动真值
W_cv = mvnrnd(zeros(1,5), Q_matrix_ctrv)';              % 过程噪声向量
X_ctrv(:,1) = EKF_predict([x0;y0;v;theta;omga], dt);    % 根据运动模型得到当前时刻状态
X_ctrv(:,1) = X_ctrv(:,1) + W_cv;                       % 加过程噪声,也可不加
Z_ctrv = zeros(4,N);                                    % 初始化目标测量值
V_ctrv = mvnrnd(zeros(1,4), R_matrix_ctrv)';            % 观测误差矩阵
Z_ctrv(:,1) = EKF_measure(X_ctrv(:,1)) + V_ctrv;
Xest_ekf = zeros(5,N);                                  % 卡尔曼滤波估计值
Xest_ekf(:,1) = X_ctrv(:,1);                            % 第一帧无法滤波,用测量值初始化
P_ekf = zeros(5,5,N);                                   % 状态估计协方差矩阵
P_ekf(:,:,1) = eye(5);                                  % 初始化状态估计协方差矩阵,常用单位矩阵% 扩展卡尔曼滤波的核心算法
for i = 2:N% 状态更新X_ctrv(:,i) = EKF_predict(X_ctrv(:,i-1), dt);W_ctrv = mvnrnd(zeros(1,5), Q_matrix_ctrv)';        % 过程噪声向量X_ctrv(:,i) = X_ctrv(:,i) + W_ctrv;                 % 加过程噪声% 预测步骤X_pre = EKF_predict(Xest_ekf(:,i-1), dt);F_ctrv = EKF_Jacobian_F(Xest_ekf(:,i-1), dt);P_pre = F_ctrv * P_ekf(:,:,i-1) * F_ctrv' + Q_matrix_ctrv;% 测量模型更新V_ctrv = mvnrnd(zeros(1,4), R_matrix_ctrv)';            % 观测误差矩阵Z_ctrv(:,i) = EKF_measure(X_ctrv(:, i)) + V_ctrv;% 更新步骤H_ctrv = EKF_Jacobian_H(X_ctrv(:, i));K_ekf = P_pre * H_ctrv' / (H_ctrv * P_pre * H_ctrv' + R_matrix_ctrv);Xest_ekf(:,i) = X_pre + K_ekf * (Z_ctrv(:,i) - EKF_measure(X_pre));P_ekf(:,:,i) = (eye(5) - K_ekf * H_ctrv) * P_pre; 
end% 绘图部分保持不变
figure;
size = 10;
width = 2;
% 位置曲线图
subplot(2,2,1);
plot(Z_ctrv(1,:),'.g','MarkerSize',size); hold on;              % 画出测量值
plot(Xest_ekf(1,:),'b','LineWidth',width);hold on;              % 画出最优估计值
plot(X_ctrv(1,:),'r','LineWidth',width);                        % 画出实际状态值
title('X位置状态曲线');
legend('位置测量值', '位置最优估计值', '实际位置');% 位置曲线图
subplot(2,2,2);
plot(Z_ctrv(2,:),'.g','MarkerSize',size);hold on;               % 画出测量值
plot(Xest_ekf(2,:),'b','LineWidth',width);hold on;              % 画出最优估计值
plot(X_ctrv(2,:),'r','LineWidth',width);                        % 画出实际状态值
title('Y位置状态曲线');
legend('位置测量值', '位置最优估计值', '实际位置');X_vx_ctrv = X_ctrv(3,:).*cos(X_ctrv(4,:));
X_vy_ctrv = X_ctrv(3,:).*sin(X_ctrv(4,:));
Xest_vx_ekf = Xest_ekf(3,:).*cos(Xest_ekf(4,:));
Xest_vy_ekf = Xest_ekf(3,:).*sin(Xest_ekf(4,:));
% 速度曲线图
subplot(2,2,3);
plot(Z_ctrv(3,:),'.g','MarkerSize',size); hold on;                 % 画出测量值
plot(Xest_vx_ekf,'b','LineWidth',width); hold on;             % 画出最优估计值
plot(X_vx_ctrv,'r','LineWidth',width);                        % 画出实际状态值
title('X速度状态曲线');
legend('速度测量值', '速度最优估计值', '实际速度');% 偏航角曲线图
subplot(2,2,4);
plot(Z_ctrv(4,:),'.g','MarkerSize',size); hold on;                 % 画出测量值
plot(Xest_vy_ekf,'b','LineWidth',width); hold on;             % 画出最优估计值
plot(X_vy_ctrv,'r','LineWidth',width);                        % 画出实际状态值
title('Y速度状态曲线');
legend('速度测量值', '速度最优估计值', '实际速度');% 位置平面图
% figure;
% plot(Z_ctrv(1,:),Z_ctrv(2,:));hold on;          % 画出测量值
% plot(Xest_ekf(1,:),Xest_ekf(2,:));              % 画出最优估计值
% plot(X_ctrv(1,:),X_ctrv(2,:));hold on;          % 画出实际值
% title('目标运动曲线');
% legend('位置测量值', '位置最优估计值', '实际位置');% 扩展卡尔曼滤波的预测模型
function X_pred = EKF_predict(x, dt)% CTRV模型的预测模型v = x(3);theta = x(4);omega = x(5);if omega == 0 % 避免除以0dx = v * cos(theta) * dt;dy = v * sin(theta) * dt;elsedx = v/omega * (sin(theta + omega * dt) - sin(theta));dy = v/omega * (-cos(theta + omega * dt) + cos(theta));enddtheta = omega * dt;X_pred = x + [dx; dy; 0; dtheta; 0]; % 速度和转向率的变化假设为0
end% 扩展卡尔曼滤波预测模型的雅可比矩阵
function F = EKF_Jacobian_F(x, dt)v = x(3);theta = x(4);omega = x(5);F = eye(5);if omega == 0 % 避免除以0F(1, 3) = -v * sin(theta) * dt;F(1, 4) = cos(theta) * dt;F(2, 3) = v * cos(theta) * dt;F(2, 4) = sin(theta) * dt;elseF(1, 3) = 1/omega * (sin(theta + omega * dt) - sin(theta));F(1, 4) = v/omega * (cos(theta + omega * dt) - cos(theta));F(1, 5) = v/omega^2 * (sin(theta) - sin(theta + omega * dt)) + v * dt * cos(theta + omega * dt)/omega;F(2, 3) = v/omega * (sin(theta + omega * dt) - sin(theta));F(2, 4) = 1/omega * (-cos(theta + omega * dt) + cos(theta));F(2, 5) = v/omega^2 * (-cos(theta) + cos(theta + omega * dt)) + v * dt * sin(theta + omega * dt)/omega;endF(4, 5) = dt;
end% 扩展卡尔曼滤波的测量模型
function Z_pred = EKF_measure(x)Z_pred = x(1:4);v = x(3);theta = x(4);Z_pred(3) = v*cos(theta);Z_pred(4) = v*sin(theta);
end% 扩展卡尔曼滤波观测模型的雅可比矩阵
function H = EKF_Jacobian_H(x)H = zeros(4,5);v = x(3);theta = x(4);cos_theta = cos(theta);sin_theta = sin(theta);H(1, 1) = 1;H(2, 2) = 1;H(3, 3) = cos_theta;H(3, 4) = -v*sin_theta;H(4, 3) = sin_theta;H(4, 4) = v*cos_theta;
end

        下图是仿真运行的结果,可以看到匀速转弯运动目标通过扩展卡尔曼滤波算法得到了高精度的跟踪轨迹。

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

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

相关文章

我的年终总结2023

As a DBA 从2023年初开始,我就给自己定下了23年的主要任务——学习PostgreSQL数据库。虽然没有定下细致的计划,但总体的目标是把PG的一些基础知识学完。后来发现我想简单了,学习PG的成本比我想象的多的多,导致23年这个目标没有完…

葡萄酒术语“干”是什么意思呢?

一个初学品酒的人常常会感到力不从心,有如此多的术语,如甜、干、单宁、酒体等等,很容易让人迷失。嗯,就像情人眼里出西施一样,“好酒”因人而异。虽然品尝各种不同的葡萄酒是了解你喜欢什么的最好方法,但我…

3D渲染农场的优势体现在哪里?点进来,CG Magic小编告诉您!

目前,渲染的涉及也是越来越广的,无论是通过本地渲染还是云渲染,都是为了3D渲染效率更高。 渲染农场工作原理就是提升制作效率与降低成本的利器。无论大型制作公司还是小型工作室,甚至是个人用户,都会借助于3d渲染农场…

LLM:Scaling Laws for Neural Language Models (上)

论文:https://arxiv.org/pdf/2001.08361.pdf 发表:2020 摘要1:损失与模型大小、数据集大小以及训练所用计算量成比例,其中一些趋势跨越了七个量级以上。 2:网络宽度或深度等其他架构细节在很大范围内影响较小。3&…

探索Python数据结构与算法:解锁编程的无限可能

文章目录 一、引言1.1 数据结构与算法对于编程的重要性1.2 Python作为实现数据结构与算法的强大工具 二、列表和元组2.1 列表:创建列表、索引、切片和常用操作2.2 元组:不可变序列的特性和使用场景 三、字符串操作和正则表达式3.1 字符串的常见操作和方法…

windows编译TensorFlowServing

概述 整个编译打包过程的总体思路,是参照在linux下的编译流程,配置环境,执行编译命令,根据编译器/链接器反馈的错误,修改相应的源码或者相关库文件的存放路径,编译出windows平台下静态库和二进制执行文件。…

BuildRoot配置RTL8822CE WIFIBT模块(WIFI部分)

TinkerBoard2主板自带的无线模块为RTL8822CE,PCIe接口 之前在风火轮下载的Linux源码编译出来的BuildRoot根文件系统没有相关的驱动文件 [rootrk3399:/]# find . -name *.ko [rootrk3399:/]# lsmod Module Size Used by Not tainted [rootrk33…

Dicom Tag: Image Position,Image Orientation和Patient Position

文章目录 Image Position,Image Orientation和Patient PositionImage Position (0020,0032):Image Orientation (0020,0037):Patient Position(0018,5100): Image Position,Image Orientation和Patient Position 在DICOM图像中,I…

栈(顺序存储、链式存储)

栈的定义 栈(Stack)是只允许在一端进行插入或删除操作的线性表 栈的操作特性是后进先出LIFO(Last In First Out) 顺序存储 链式存储

三款非常实用的图片转换格式工具

BMP是一种常见的位图图像格式,而JPG则是互联网上广泛使用的图像格式。有时,为了满足特定的需求或更好的兼容性,我们需要将BMP格式转换为JPG格式。今天,我们将为您推荐三款实用的软件,帮助您轻松完成这一转换。 水印云…

QT 原生布局和QML的区别

一、QML 与 Qt Quick的区别 1.1 从概念上区分 为了更精确地对两者进行说明,先看助手对 QML 的描述: QML is a user interface specification and programming language. QML 是一种用户界面规范和标记语言,允许开发人员和设计师创建高性能、流…

端智能在大众点评搜索重排序的应用实践

1 引言 随着大数据、人工智能等信息技术的快速发展,云计算已经无法满足特定场景对数据隐私、高实时性的要求。借鉴边缘计算的思想,在终端部署 AI 能力逐渐步入大众的视野,“端智能”的概念应运而生。相比于传统的云计算,在智能手…

【Maven】008-Maven 私服搭建与使用

【Maven】008-Maven 私服搭建与使用 文章目录 【Maven】008-Maven 私服搭建与使用一、概述1、简介2、建立私服后依赖查找和下载逻辑第一步:请求本地仓库第二步:请求 Maven 私服第三步:请求外部远程仓库(远程中央仓库等&#xff09…

动态路由协议

一、动态路由协议 动态路由协议,用在多个 Router 之间定期的、自动的、互相交换 Routes(路由信息,包含了网段信息、可达性信息、路径信息等),动态生成 Routing Table Entries,并最终达到全网的路由收敛&am…

近4w字吐血整理!只要你认真看完【C++编程核心知识】分分钟吊打面试官(包含:内存、函数、引用、类与对象、文件操作)

🌈个人主页:godspeed_lucip 🔥 系列专栏:C从基础到进阶 🏆🏆关注博主,随时获取更多关于C的优质内容!🏆🏆 C核心编程🌏1 内存分区模型&#x1f384…

力扣hot100 颜色分类 双指针 滚动赋值

Problem: 75. 颜色分类 文章目录 思路解题方法复杂度Code💖 超简洁版 思路 解题方法 描述你的解题方法 复杂度 时间复杂度: O ( n ) O(n) O(n) 空间复杂度: O ( 1 ) O(1) O(1) Code class Solution { public void sortColors(int[] nums){int n nums.length…

Relation-Aware Graph Transformer for SQL-to-Text Generation

Relation-Aware Graph Transformer for SQL-to-Text Generation Abstract SQL2Text 是一项将 SQL 查询映射到相应的自然语言问题的任务。之前的工作将 SQL 表示为稀疏图,并利用 graph-to-sequence 模型来生成问题,其中每个节点只能与 k 跳节点通信。由…

Qt超简单实现贪吃蛇

文章目录 常量Snake类GameController类GUI显示游戏简图 为了能够最简单地完成程序,所以没有用类的继承等知识。感兴趣的朋友可以改写一下。 常量 const int FILE_SIZE 30; //地图方格大小 const int FPS 5000 / 33; //游戏运行帧率 enum Item{empty, wall, food…

Netty通信中的粘包半包问题(三)

之前我们介绍了用特殊分隔符来分割每个报文,但是如果传输的数据中恰好有个特殊分隔符,它将会被拆分成多个,于是,为了进一步避免这个问题,还有一种解决方案是在两端的channelPipeline中用一个固定长度来区分&#xff0c…

K8s(一)Pod资源——Pod介绍、创建Pod、Pod简单资源配额

目录 Pod概述 pod网络 pod存储 pod和容器对比 创建pod的方式 pod运行方式分类 Pod的创建 Pod的创建过程 通过kubectl run来创建pod 通过yaml文件创建,yaml文件简单写法 Pod简单操作 Pod的标签labels Pod的资源配额resource 测试 Pod概述 Kubernetes …