您的位置:首页 > 编程语言 > MATLAB

kalman 滤波器及其MATLAB实现

2017-11-11 21:47 197 查看
卡尔曼滤波是一个很常用的滤波算法,与维纳滤波相比有很多长处。这里我们把Kalman Filter简称为KF。KF的基本思想是:采用信号、噪声、状态空间模型,利用前一时刻的状态最优估计值及其误差方差估计和现时刻的量测值来更新对状态变量的估计,求出现在时刻的最优估计值。
说白点就是对现在时刻的估计(可能是同时估计好几个变量)是取决于前一时刻估计误差和现在时刻的某个观测值。通过不断的预测和实测来修正自己的估计值,最后达到一个理想的平稳状态。

卡尔曼滤波的具体原理和推导过程,有点复杂。某些细节我也没弄明白,不过这并不影响我们写程序和使用它。如果你看了我写的这个小分享,表明你对卡尔曼滤波有一定的了解了,否则你也不会看这种玩意。如果真的不了解,那可以查找下相关资料。

卡尔曼滤波的5大公式:



这五个公式公式可要注意他们的下标了,下面我们从上至下依次说下这五个公式的意思
第一个公式就是说我们研究的变量在这一时刻与上一时刻的具体关系。那个Fai矩阵就是系数对应关系。可以看到这里就把卡尔曼滤波的使用范围限定在线性系统中了,基本的卡尔曼滤波器是不能用于非线性系统的。
第二个公式叫方差先验估计,说的这么文艺,其实就是计算估计值和实际值的方差大小,以评估现在的估计的误差是不是合适。
第三个公式叫增益矩阵,前面已经说过,卡尔曼滤波根据当前观测变量的变化趋势来估计一时刻变量的值,这个增益矩阵就是指我们定的这个变化的“度”的大小。
第四个就是求要估计的值了。
第五个是修正估计值与实际值的方差。
这5个公式是卡尔曼滤波的关键,下面就结合一个实例在说下卡尔曼滤波的程序如何写~交大的同学,如果你们选了最优估计这门课,然后看到这个,嘿嘿,便宜你们了。

应用:卡尔曼滤波在目标测量中的应用

某火箭在空中沿直线做匀加速飞行,加速度为  ,发动机推力的波动一定会引起加速度波动,雷达以间隔时间不断测量该火箭距离远点的距离  ,由于雷达的测量噪声使得火箭距离测量值   中含有噪声。现在欲通过雷达对火箭距离的测量数据求得火箭的真实距离、速度和加速度。 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 设置初始化信息
% N:设置卡尔曼滤波器追踪点数
% r:设置估计变量个数,这里r=3
% s:被追踪的火箭的距离,初始值为1000m
% v:火箭的速度,初始值为50m/s
% a:火箭的加速度,初始值为20m/s2,此时加速度默认为不变
% T: 雷达的扫描间隔,此时设为1秒
% wt: 系统噪声,方差为20
% vt: 量测噪声,方差为16
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clear all;
close all;
N = 100;
r = 3;
t = 1:1:N;
T = 1;
s = zeros(1,N);
v = zeros(1,N);
a = zeros(1,N);
a(t) = 20;
s0 = 1000;
v0 = 50;
for n = 1:N
v(n) = v0 + a(n)*n;
s(n) = 1000+v0*n+0.5*a(n)*n*n;
end
4000

wt = randn(1,N);
wt = sqrt(4)*wt./std(wt);
s = s + wt;
v = v + wt;
a(t) = a(t) + wt(t);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 卡尔曼滤波部分,继承之前初始化变量
% A:转移矩阵
% H:量测矩阵
% Qk:系统噪声矩阵
% Rk:量测噪声矩阵
% P0:均方误差矩阵初始值
% Y:火箭的状态矩阵,由k_s,k_v,k_a组成
% Y0:状态矩阵的初始值
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Y0 = [900 0 0]';
Y = [Y0 zeros(r,N-1)];
A = [1 1 0;0 1 1;0 0 1];
H = [1 0 0];
Qk = [0 0 0;0 0 0;0 0 20];
Rk = 16;
P0 = [30 0 0;0 20 0;0 0 10];
P1 = P0;
P2 = zeros(r,r);
for k = 1:N
Y(:,k) = A*Y(:,k);
P2 = A*P1*A'+Qk;
Kk = P2*H'*inv(H*P2*H'+Rk);
Y(:,k+1) = Y(:,k)+Kk*(s(:,k)-H*Y(:,k));
P1 = (eye(r,r)-Kk*H)*P2;
end
k_s = Y(1,:);
k_v = Y(2,:);
k_a = Y(3,:);
subplot(3,1,1);
plot(t,s(t),'-',t,k_s(t),'o');
title('距离');
legend('实际值','估计值');
xlabel('t');
ylabel('s');
subplot(3,1,2);
plot(t,v(t),t,k_v(t),'+');
title('速度');
legend('实际值','估计值');
xlabel('t');
ylabel('v');
subplot(3,1,3);
plot(t,a(t),t,k_a(t),'-x');
title('加速度');
legend('实际值','估计值');
xlabel('t');
ylabel('a');
axis([0,N,0,30]); 具体细节不讲了。运行后,就得到我们想要的结果了~



一个小总结,希望对你有帮助。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: