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

前言

标题里的EKF、UKF、CKF、PF分别为:扩展卡尔曼滤波、无迹卡尔曼滤波、容积卡尔曼滤波、粒子滤波。

EKF是扩展卡尔曼滤波,计算快,最常用于非线性状态方程或观测方程下的卡尔曼滤波。

但是EKF应对强非线性的系统时,估计效果不如UKF。

UKF是无迹卡尔曼滤波/无味卡尔曼滤波,使用UT变换产生多个sigma点,对点的预测和加权求和来模拟非线性的转移,精度较高、计算量也比较大。

但是UKF的UT变换理论依据不明确,且实际运行时容易出现矩阵奇异的情况,因此提出来CKF

CKF是容积卡尔曼滤波,容积变换理论意义更明确、运行更稳定。

PF通常使用大量的粒子来进行计算,要想达到UKF或CKF的精度,计算量往往很大,不过通过增加粒子数量也能获得更高的定位效果。

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

程序结构

程序背景是组合导航下的卡尔曼滤波,三维状态量可以理解成三维的位置,也可以理解成三维的速度。相应的,三维的输入量可以理解成三维的速度,也可以理解成三维的加速度,比较灵活。

程序结构如下:

初始化→运动模型建立→滤波参数设置→EKF→UKF→CKF→PF→误差计算→结果绘制

程序运行结果

状态量的真值、各方法估计值对比:

放大后得到如下图像:

误差图像如下:

其中,"未滤波"表示纯INS计算的结果。

会自动计算当前各方法计算的误差统计特性(误差最大值、平均值),如下:

只有一个m文件,方便调试和学习。

部分代码

matlab 复制代码
% 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迭代
相关推荐
DevRay6 小时前
Java 21虚拟线程深度实战:告别线程池焦虑,百万并发吞吐量直接翻倍(原理+代码+避坑)
java·开发语言
free-elcmacom6 小时前
C++学习<1>程序分区
开发语言·c++
醉颜凉6 小时前
Java 必看:如何彻底避免 HashMap 多线程死循环问题?
java·开发语言
默 语6 小时前
Java新手入门:从零开始安装JDK并配置环境变量
java·开发语言·python·mysql·group by·1024程序员节·数据去重
Brilliantwxx7 小时前
【STM32】 I2C_EEPROM_test 工程(实战篇)
开发语言·stm32·单片机·嵌入式硬件·ecmascript
清水白石0087 小时前
Python 异步编程深度解析:Cancellation 到底是异常还是控制信号?从 asyncio 取消机制到企业级事务设计最佳实践
开发语言·python
kolyle7 小时前
万级 QPS 下的 Token 分发系统架构:从 0 到 1 跑通 AI 时代的“水电煤“
开发语言·人工智能·系统架构·token·qps·极智词元·大模型私有化部署
caoerzhong7 小时前
JeeWMS 开源仓库管理系统 GPL-3.0 合规指南:Java WMS 二次开发前必须弄清的授权边界
java·开发语言·开源·vue
Patrick在香港7 小时前
Python 审计香港开放数据目录:两个端点差 10 倍,只有 9.3% 的资源标了「最后修改时间」
开发语言·数据库·python·数据分析·api·数据治理·开放数据
Sylvia33.7 小时前
火星数据体育API|一站式接入足球篮球电竞等18+项目实时数据
java·开发语言·python·websocket·游戏