从贝叶斯滤波理论到容积卡尔曼滤波算法(CKF)详细推导及编程实现常转弯率模型估计。(matlab)

容积卡尔曼滤波(CKF)是由加拿大学者Arasaratnam和Haykin在2009年提出的。该算法的核心思想是针对非线性高斯系统,通过三阶球面径向容积准则来近似状态的后验均值和协方差,以保证在理论上以三阶多项式逼近任何非线性高斯状态的后验均值和方差。

  • 贝叶斯滤波
  • 球面-径向容积规则
  • 容积卡尔曼滤波算法
  • matlab实现"Cubature Kalman Filters"论文中常转弯率例子

贝叶斯滤波:

由于容积卡尔曼滤波是基于贝叶斯滤波理论框架的次优滤波,所以我们先来了解一下贝叶斯滤波。

在解决滤波问题时,如果我们能求出状态的后验概率密度函数,就可以通过状态的概率密度函数描述非线性系统的统计特性,再通过各种估计准则和近似方法就能得到不同的滤波算法。
系统状态后验概率密度决定了系统的多种统计特性。因此如何求得系统状态的后验概率密度函数成为关键。而贝叶斯估计的优点是给出了状态后验概率密度函数的递推求解方法,成为众多滤波算法的核心思想。

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

上面两个式子就组成了贝叶斯递推公式,我们可以看出贝叶斯滤波从理论上实现了非线性滤波的最优估计。

2
在这里插入图片描述
2
3
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
1
下图为贝叶斯滤波框图。在这里插入图片描述在这里插入图片描述

球面-径向容积规则:

由上一部分的贝叶斯滤波,我们很难直接求解上述积分。我们将上述积分变形为:
在这里插入图片描述

n维球坐标变换

在这里插入图片描述

由n维球坐标变换定理可将上面积分转换成球面径向积分:
在这里插入图片描述
在这里插入图片描述
将上面积分分解成球面积分径向积分
在这里插入图片描述
在这里插入图片描述
上述球面积分和径向积分都是通过容积规则来实现,容积规则是将一系列点集D用非线性函数进行传递,然后根据加权求和来近似非线性函数的后验均值和方差。
*

点集D有如下定义: 在这里插入图片描述

在这里插入图片描述在这里插入图片描述
所以球面积分就变成了:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
所以容积点可选取单位球的球面与其坐标系相交的点。
所以球面积分可近似为:
在这里插入图片描述
径向积分:
在这里插入图片描述在这里插入图片描述在这里插入图片描述
将球面积分的近似带入到径向积分中可得:
在这里插入图片描述
在这里插入图片描述
上面式子就是三阶球面径向容积规则的近似规则。
接下来我们将容积规则与高斯分布的积分相结合:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
上面式子就是容积卡尔曼滤波使用的三阶球面径向容积规则
在这里插入图片描述

接下来我们来看一下CKF算法的流程:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
常转弯率模型CKF滤波估计(matlab):
在这里插入图片描述

程序如下:

CKF函数:
function [Pk,Xjian]=CKF(Pk,n,Xjian,y,Q,R)
m = 2*n;  %n为状态维数
T=1;%时间
kesai=sqrt(m/2) * [eye(n),-eye(n)];
[S1]=chol(Pk)';%分解成AT*A(下三角*上三角)取下三角
Xr=S1*kesai+repmat(Xjian,1,m);%计算容积点,repmat()把元素复制m行n列
for i=1:m
    omiga = Xr(5,i);
    fai= [1,     sin(omiga*T)/omiga, 0, -(1-cos(omiga*T))/omiga, 0;
          0,           cos(omiga*T), 0,           -sin(omiga*T), 0;
          0, (1-cos(omiga*T))/omiga, 1,      sin(omiga*T)/omiga, 0;
          0,           sin(omiga*T), 0,            cos(omiga*T), 0;
          0,                      0, 0,                       0, 1];
    Xcr(:,i) = fai*Xr(:,i);  %传播容积点                                 
end 
Xpr=(1/m).*sum(Xcr,2);%状态量预测值
Ppr=(1/m).*(Xcr*Xcr')-Xpr*Xpr'+ Q;%误差协方差
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[S2]=chol(Ppr)';
Xp=S2*kesai+repmat(Xpr,1,m);
yr=[sqrt(Xp(3,:).^2+Xp(1,:).^2);atan2(Xp(3,:),Xp(1,:))];%传播

Ypre = (1/m).*sum(yr,2);%计算量测预测值
Pyy=(1/m)*yr*yr'-Ypre*Ypre'+R;%协方差
Pxy=(1/m)*Xp*yr'-Xpr*Ypre';%互协方差

K = Pxy*inv(Pyy); %增益                             
Xjian=Xpr+K*(y-Ypre);  % 状态估计                       
Pk=Ppr-K*Pyy*K';  %估计误差协方差
主函数:
clear all;
clc;
bushu=100;
omiga=-3;
T=1;
q1=0.1,q2=1.75*10^(-4);
or=10,oo=sqrt(10);
M=[(1/3)*T^2 (1/2)*T^2;(1/2)*T^2 T]
R=diag([(or)^2 (oo)^2]);
randn('seed',36);     w1=sqrt(q1*M)*randn(2,2);
randn('seed',32);     w2=sqrt(q1*M)*randn(2,2);
randn('seed',29);     w3=sqrt(q2*T)*randn(1,1);
Q=zeros(5,5);
Q(1,1)=w1(1,1),Q(1,2)=w1(1,2),Q(2,1)=w1(2,1),Q(2,2)=w1(2,2);
Q(3,3)=w2(1,1),Q(3,4)=w2(1,2),Q(4,3)=w2(2,1),Q(4,4)=w2(2,2);
Q(5,5)=w3;

 x(:,1) =[1000;300;1000;0;-3];
 Pk(:,:,1) =diag([100,10,100,10,100]); 
Xjian(:,1)=[1000;300;1000;0;-3];
n=5;
    randn('seed', 5);  
    w=sqrt(Q)*randn(5,bushu);
    randn('seed', 2);
    v=sqrt(R)*randn(2,bushu);
 for k = 2 : bushu
    omiga=x(5,k-1);
    fai=[1,    sin(omiga*T)/omiga,      0,    -(1-cos(omiga*T))/omiga,     0;
         0,    cos(omiga*T),            0,    -sin(omiga*T),               0;
         0,    (1-cos(omiga*T))/omiga,  1,    sin(omiga*T)/omiga,          0;
         0,    sin(omiga*T),            0,    cos(omiga*T),                0;
         0,    0,                       0,    0,                           1];
 
    x(:,k) = fai * x(:,k-1) +w(:,k-1);      %状态值 
    z(:,k) = [sqrt(x(1,k).^2+x(3,k).^2);atan2(x(3,k),x(1,k))] + v(:,k) %观测值
     
    [Pk(:,:,k),Xjian(:,k)]=CKF(Pk(:,:,k-1),n,Xjian(:,k-1),z(:,k),Q,R);
 end

t=2:bushu;
figure(1)
subplot(2,2,1)
plot(t,x(3,t),'b',t,Xjian(3,t),'r');  
xlabel('时间'); 
ylabel('水平位置');
subplot(2,2,2)
plot(t,x(2,t),'b',t,Xjian(2,t),'r');
xlabel('时间'); 
ylabel('水平速度');
subplot(2,2,3)
plot(t,x(3,t),'b',t,Xjian(3,t),'r');  
xlabel('时间'); 
ylabel('竖直位置');
subplot(2,2,4)
plot(t,x(4,t),'b',t,Xjian(4,t),'r');
xlabel('时间'); 
ylabel('竖直速度');
figure(2)
plot(t,x(5,t),'b',t,Xjian(5,t),'r');
legend('真值','估值'); 
xlabel('时间'); 
ylabel('转弯率');
figure(3)
plot(x(1,t),x(3,t),'b',Xjian(1,t),Xjian(3,t),'r');
 

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

补充说明:

1,因为在这个例子中系数fai是变化的,所以在编CKF函数的程序时要将fai的变化也体现出来(看第一段程序)。 2,看最后一张图我们发现估值跟的效果不是特别好可能是因为初始值过大,程序中随机数种子的选取(种子的选取不同结果也不相同,主要改变一下w3的种子)。

Help
最后本人在找关于CKf 文章中常转弯率模型的推导尤其是其中M的详细推导过程,希望大家多多分享,万分感谢!请收下小弟的膝盖,哈哈哈

  • 62
    点赞
  • 323
    收藏
    觉得还不错? 一键收藏
  • 28
    评论
### 回答1: 卡尔曼滤波(Kalman Filter)和平方根容积卡尔曼滤波(Square Root Cubature Kalman Filter)是用的估计滤波算法,主要应用于状态估计和系统辨识问题。下面我将分别介绍其Matlab实验代码。 卡尔曼滤波Matlab实验代码如下所示: ```matlab % 定义系统模型 A = [1 0.1; 0 1]; % 状态转移矩阵 B = [0.005; 0.1]; % 控制输入矩阵 H = [1 0]; % 观测矩阵 Q = [0.01 0; 0 0.01]; % 过程噪声协方差矩阵 R = 1; % 观测噪声方差 % 初始化滤波器状态 x_k = [0; 0]; % 状态向量 P_k = [1 0; 0 1]; % 状态协方差矩阵 % 初始化观测数据 y_k = [10; 8]; % 观测向量 % 迭代更新滤波器 for i = 1:length(y_k) % 预测步骤 x_k1 = A * x_k; P_k1 = A * P_k * A' + B * Q * B'; % 更新步骤 K_k = P_k1 * H' / (H * P_k1 * H' + R); x_k = x_k1 + K_k * (y_k(i) - H * x_k1); P_k = (eye(2) - K_k * H) * P_k1; end % 输出滤波结果 disp(x_k) ``` 平方根容积卡尔曼滤波Matlab实验代码如下所示: ```matlab % 定义系统模型 A = [1 0.1; 0 1]; % 状态转移矩阵 B = [0.005; 0.1]; % 控制输入矩阵 H = [1 0]; % 观测矩阵 Q = [0.01 0; 0 0.01]; % 过程噪声协方差矩阵 R = 1; % 观测噪声方差 % 初始化滤波器状态 x_k = [0; 0]; % 状态向量 P_k = [1 0; 0 1]; % 状态协方差矩阵 % 初始化观测数据 y_k = [10; 8]; % 观测向量 % 迭代更新滤波器 for i = 1:length(y_k) % 预测步骤 x_k1 = A * x_k; P_k1 = A * P_k * A' + B * Q * B'; % 更新步骤 K_k = P_k1 * H' / (H * P_k1 * H' + R); x_k = x_k1 + K_k * (y_k(i) - H * x_k1); P_k = (eye(2) - K_k * H) * P_k1; % 平方根容积卡尔曼滤波的特殊步骤 [U, S, V] = svd(P_k); S_sqrt = sqrtm(S); P_k = U * S_sqrt * V'; end % 输出滤波结果 disp(x_k) ``` 这是一个简单的卡尔曼滤波和平方根容积卡尔曼滤波Matlab实验代码,用于对给定观测数据进行状态估计。根据实际需求,你可以对系统模型和参数进行相应的调整和修改。 ### 回答2: 卡尔曼滤波(Kalman Filter)和平方根容积卡尔曼滤波 (Square Root Cubature Kalman Filter)是两种见的滤波算法。以下是一个使用MATLAB实现的简单示例代码。 卡尔曼滤波MATLAB实验代码: ```matlab % 定义系统模型 A = [1 1; 0 1]; % 状态转移矩阵 B = [0.5; 1]; % 输入转移矩阵 C = [1 0]; % 观测矩阵 Q = [0.01 0; 0 0.01]; % 状态过程噪声协方差矩阵 R = 1; % 观测噪声协方差矩阵 % 初始化滤波器 x = [0; 0]; % 状态估计初始值 P = [1 0; 0 1]; % 状态估计误差协方差矩阵 % 定义观测数据 Y = [1.2; 2.1; 3.7; 4.3]; % 观测数据 % 开始滤波 for i = 1:length(Y) % 预测状态 x = A * x + B * 0; % 无输入 P = A * P * A' + Q; % 更新状态 K = P * C' / (C * P * C' + R); x = x + K * (Y(i) - C * x); P = (eye(size(A)) - K * C) * P; % 输出状态估计值 disp(['第', num2str(i), '次观测的状态估计值为:']); disp(x); end ``` 平方根容积卡尔曼滤波MATLAB实验代码: ```matlab % 定义系统模型 A = [1 1; 0 1]; % 状态转移矩阵 B = [0.5; 1]; % 输入转移矩阵 C = [1 0]; % 观测矩阵 Q = [0.01 0; 0 0.01]; % 状态过程噪声协方差矩阵 R = 1; % 观测噪声协方差矩阵 % 初始化滤波器 x = [0; 0]; % 状态估计初始值 P = [1 0; 0 1]; % 状态估计误差协方差矩阵 % 定义观测数据 Y = [1.2; 2.1; 3.7; 4.3]; % 观测数据 % 开始滤波 for i = 1:length(Y) % 预测状态 x = A * x + B * 0; % 无输入 P = sqrtm(A * P * A' + Q); % 更新状态 G = P * C' / (C * P * C' + R); x = x + G * (Y(i) - C * x); P = sqrtm((eye(size(A)) - G * C) * P * (eye(size(A)) - G * C)' + G * R * G'); % 输出状态估计值 disp(['第', num2str(i), '次观测的状态估计值为:']); disp(x); end ``` 以上是一个简单的卡尔曼滤波和平方根容积卡尔曼滤波MATLAB实验代码示例。这些代码用于实现两种滤波算法,并使用预定义的系统模型和观测数据进行状态估计。实际应用中,需要根据具体问题进行参数调整和适应性修改。 ### 回答3: 卡尔曼滤波(Kalman Filter)和平方根容积卡尔曼滤波(Square Root Cubature Kalman Filter)都是用于状态估计滤波算法卡尔曼滤波是一种最优线性估计算法,基于状态空间模型,在系统的观测和模型误差服从高斯分布的条件下,通过使用先验信息和测量更新,来估计系统的状态。卡尔曼滤波的基本原理是通过不断地对先验状态和先验协方差进行更新和修正,得到最优估计。 平方根容积卡尔曼滤波是对传统卡尔曼滤波的改进算法之一,主要用于解决非线性系统的状态估计问题。相比于传统的卡尔曼滤波,平方根容积卡尔曼滤波使用了卡尔曼滤波的根协方差表示,通过对根协方差进行传输和修正,避免了传统卡尔曼滤波中协方差矩阵计算的数值不稳定问题,提供了更好的数值精度和计算效。 以下是MATLAB实验代码的伪代码示例: ``` % 卡尔曼滤波 % 初始化状态和观测噪声的协方差矩阵 Q = ... % 状态噪声的协方差矩阵 R = ... % 观测噪声的协方差矩阵 % 初始化状态和协方差矩阵 x = ... % 状态向量 P = ... % 状态协方差矩阵 for k = 1:N % 预测步骤 x_hat = ... % 先验状态估计 P_hat = ... % 先验协方差估计 % 更新步骤 K = P_hat * C' / (C * P_hat * C' + R) % 卡尔曼增益 x = x_hat + K * (z - C * x_hat) % 后验状态估计 P = (eye(size(K,1)) - K * C) * P_hat % 后验协方差估计 end % 平方根容积卡尔曼滤波 % 初始化状态和观测噪声的协方差矩阵 Q = ... % 状态噪声的协方差矩阵 R = ... % 观测噪声的协方差矩阵 % 初始化状态和根协方差矩阵 x = ... % 状态向量 S = ... % 根协方差矩阵 for k = 1:N % 预测步骤 x_hat = ... % 先验状态估计 S_hat = ... % 先验根协方差估计 % 更新步骤 y = z - H * x_hat % 观测残差 K = S_hat * H' / (H * S_hat * H' + R) % 平方根卡尔曼增益 x = x_hat + K * y % 后验状态估计 S = (eye(size(K,1)) - K * H) * S_hat % 后验根协方差估计 end ``` 注意,在实际应用中,需要根据具体问题的状态模型和观测模型进行相应的参数设置和代码实现。以上代码仅为伪代码示例,具体的实现方式可能有所不同。可根据实际需求和问题进行算法选择和代码编写。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 28
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值