首页 > 其他分享 >EKF+UKF+CKF+PF的效果对比|三维非线性滤波|MATLAB例程

EKF+UKF+CKF+PF的效果对比|三维非线性滤波|MATLAB例程

时间:2024-07-03 19:30:51浏览次数:21  
标签:CKF 例程 EKF 卡尔曼滤波 滤波 i1 length UKF

前言

标题里的EKF、UKF、CKF、PF分别为:扩展卡尔曼滤波、无迹卡尔曼滤波、容积卡尔曼滤波、粒子滤波。
EKF是扩展卡尔曼滤波,计算快,最常用于非线性状态方程或观测方程下的卡尔曼滤波。
但是EKF应对强非线性的系统时,估计效果不如UKF。
UKF是无迹卡尔曼滤波/无味卡尔曼滤波,使用UT变换产生多个sigma点,对点的预测和加权求和来模拟非线性的转移,精度较高、计算量也比较大。
但是UKF的UT变换理论依据不明确,且实际运行时容易出现矩阵奇异的情况,因此提出来CKF
CKF是容积卡尔曼滤波,容积变换理论意义更明确、运行更稳定。
PF通常使用大量的粒子来进行计算,要想达到UKF或CKF的精度,计算量往往很大,不过通过增加粒子数量也能获得更高的定位效果。

以上方法没有谁好谁不好的说法,必须结合使用场景、精度要求、滤波量的类型等因素来确定,所以这里给出以上四个方法估计同一种状态的MATLAB代码,用于对比。

程序结构

程序背景是组合导航下的卡尔曼滤波,三维状态量可以理解成三维的位置,也可以理解成三维的速度。相应的,三维的输入量可以理解成三维的速度,也可以理解成三维的加速度,比较灵活。
程序结构如下:
初始化→运动模型建立→滤波参数设置→EKF→UKF→CKF→PF→误差计算→结果绘制
请添加图片描述

程序运行结果

状态量的真值、各方法估计值对比:
在这里插入图片描述
放大后得到如下图像:
在这里插入图片描述
误差图像如下:
在这里插入图片描述
其中,“未滤波”表示纯INS计算的结果。
会自动计算当前各方法计算的误差统计特性(误差最大值、平均值),如下:
在这里插入图片描述
只有一个m文件,方便调试和学习。

部分代码

% EKF+UKF+CKF+PF,四个滤波效果对比
% author:Evand©2024
% date: 2024-06-29/Ver1
clear;clc;close all;
rng(0);
%% 滤波模型初始化
t = 1:1:1000;% 定义时间序列
Q = 1*diag([1,1,1]);% 过程噪声协方差矩阵和过程噪声
w = sqrt(Q)*randn(size(Q,1),length(t));
% 观测噪声协方差矩阵和观测噪声
R = 1*diag([1,1,1]);
v = sqrt(R)*randn(size(R,1),length(t));
P0 = 1*eye(3);% 初始状态估计协方差矩阵
X = zeros(3,length(t));% 初始化状态向量
% 初始化扩展卡尔曼滤波状态向量
X_ekf = zeros(3,length(t));
X_ekf(1,1) = X(1,1);
% 初始化观测值格式
Z = zeros(3,length(t));
% 定义初始观测值
Z(:,1) = [X(1,1)^2/20;X(2,1);X(3,1)] + v(:,1);

%% 运动模型
% 初始化未滤波的状态向量
X_ = zeros(3,length(t));
X_(:,1) = X(:,1);
% 运动模型迭代
for i1 = 2:length(t)
    % 计算真实状态值
    X(:,i1) = [X(1,i1-1) + (2.5 * X(1,i1-1) / (1 + X(1,i1-1).^2)) + 8 * cos(1.2*(i1-1));
               X(2,i1-1) + 1;
               X(3,i1-1)];
    % 计算未滤波的状态值
    X_(:,i1) = [X_(1,i1-1) + (2.5 * X_(1,i1-1) / (1 + X_(1,i1-1).^2)) + 8 * cos(1.2*(i1-1));
                X_(2,i1-1) + 1;
                X_(3,i1-1)] + w(:,i1-1);
    % 计算观测值
    Z(:,i1) = [X(1,i1).^2 / 20;X(2,i1);X(3,i1)] + v(i1);
end

%% EKF
% 初始化EKF协方差矩阵
P = P0;
fprintf('完整内容下载链接:https://gf.bilibili.com/item/detail/1105727012')
% 生成EKF过程噪声
w_ekf = sqrt(Q)*randn(size(Q,1),length(t));
% EKF迭代

标签:CKF,例程,EKF,卡尔曼滤波,滤波,i1,length,UKF
From: https://blog.csdn.net/callmeup/article/details/140086656

相关文章

  • 【STM32F1例程10】UCOSII系统实验
      那么这个实验,从项目的工程结构来看,其实稍微稍微有一丢丢,有一丢丢比之前几个实验复杂,但是还是老话,既然能读到这篇文章,证明能力还是得到认可的。实验简介  那么在STM32上进行uC/OS-II系统实验是一种常见的实践,可以帮助大家了解和应用实时操作系统(RTOS)在嵌入式系统开......
  • 【《视觉十四讲》例程运行记录】——运行ch9后端优化CeresBA和g2o求解BA的实践例程
    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录一、运行ch9的例程代码1.MeshLab安装2.编译例程代码前的修改3.编译例程二可能的报错:c++:internalcompilererror:已杀死(programcclplus)1.问题描述2.原因分析3.解决总结一、运行ch9......
  • NRF52840DK PCA10056 BLE Mesh Light例程记录
    1.创建项目在打开的VSCode窗口,打开nRFConnect选项卡,"Createanewapplication" 选择"Copyasample" 输入"light", 选择"BluetoothMeshlight". 选择copy后,保存的路径。 键盘"Enter"一下。 点击"AddBuildConfiguration&qu......
  • 基于EKF算法估计电动汽车蓄电池的SOC
    电动汽车(EV)作为未来汽车的一大发展方向,其动力源——动力锂电池组的荷电状态(SOC)估计显得尤为重要。SOC直接反应了电池组剩余容量的多少,是预测EV行驶里程、使用和维护电池组的重要依据。然而,由于电动汽车电池组在使用过程中的高度非线性特性,准确估计SOC面临巨大挑战。扩展Kalman......
  • 【STM32F1例程2】GPIO外部中断输入
    1.实验说明无需连外部杜邦线,下载程序,全速运行,按右边按键看到LEDD1(PB4引脚驱动)亮暗能变化一次2.主要代码先上main.c#include"delay.h"#include"sys.h"//外部中断0配置,PA0脚产生外部中断是外部中断0voidEXTI0_Config(void){ EXTI_InitTypeDefEXTI_InitStructur......
  • 【STM32F1例程3】ADC实验
    1.实验说明 PA4口作为ADC采集口,PA4口接地或者接3.3V。下载运行程序,PA4口接地,会发现VolDta值为0,然后把PA4口接3.3V,会发现VolDta值为33002.主要程序直接上main.c#include"delay.h"#include"sys.h"//ADC配置,ADC1通道4voidADC_Config_Init(void){ ADC_InitTypeDef......
  • 《DX12龙书》-第一个例程出现的报错:error: 应用程序请求的操作依赖于已缺失或不匹配的
    《DX12龙书》|《Introductionto3DGameProgrammingwithDirectX12》|《DirectX123D游戏开发实践》个人电脑环境Window11;VisualStudio2022出现问题主要原因:书中代码的环境是:Windows10;VS2015,在不同环境上运行难免会出现一些错误。问题一:C2102&要求左值错......
  • @Transactional(rollbackFor = Exception.class) 事务失效 A加了@Transactional注解
    @Transactional(rollbackFor=Exception.class)事务失效,一个方法A上加了这个注解,在方法A中调用了B方法,A方法中有数据库操作,B方法中也有,现在问题是,B方法中事务失效了,怎么保证不失效 在Spring框架中,使用@Transactional注解可以很方便地管理事务,但是如果你在方法A中调用了方法B,......
  • Python-使用OpenCV(二)_第一个示例程序
    1、创建项目2、创建代码importcv2#加载图片image=cv2.imread("C:\\Users\\Administrator\\Pictures\\Screenshots\\20240311220733.png")#显示图片cv2.imshow("Image",image)#等待任意键被敲击cv2.waitKey(0)#关闭所有窗口cv2.destroyAllWindows()3、结......
  • @Transactional(rollbackFor = Exception.class)注解的方法A,此方法A中插入成功,再调用
    当你在一个带有@Transactional注解的方法中插入数据成功,然后调用另一个方法(无论该方法是否也带有@Transactional注解),但发现第二个方法中的插入语句没有实际插入数据,但打印出了insert语句,这通常意味着事务没有按预期执行或事务被提前提交了。这里有几个可能的原因和解决方案:自......