📄 kalmdemo.m
字号:
echo on
% This file demonstrates MATLAB's ability to do Kalman filtering.
% Both a steady state filter and a time varying filter are designed
% and simulated below.
echo off
% Copyright (c) 1986-93 by the MathWorks, Inc.
echo on
pause % Press any key to continue ...
% Given the following discrete plant
A=[
1.1269 -0.4940 0.1129
1.0000 0 0
0 1.0000 0];
B = [
-0.3832
0.5919
0.5191];
C=[ 1 0 0];
D=0;
printsys(A,B,C,D)
% Design a Kalman filter to filter out Gaussian noise added to the
% input (i.e sensor noise).
pause % Press any key to continue ...
% Let's do a steady state filter design first using the function
% DLQE. The function DLQE determines the optimal steady state
% filter gain based on the process noise covariance Q, and the
% sensor noise covariance, R.
% For your information the dcgain of this plant is
ddcgain(A,B,C,D)
% and the covariance of the output due to process noise with
% covariance of 1 is:
dcovar(A,B,C,D,1)
% Enter the process noise covariance:
Q = input('Enter a number greater than zero (e.g. 1): ')
% Enter the sensor noise covariance:
R = input('Enter a number greater than zero (e.g. 1): ')
% Now design the steady state filter gain
Lss = dlqe(A,B,C,Q,R)
pause % Press any key to continue ...
% The steady state Kalman filter we have just designed has the
% following update equations:
% - *
% time update: x[n+1] = Ax[n] + Bu[n]
%
% * - -
% observation update: x[n] = x[n] + L(y[n] - Cx[n] - Du[n])
% Since this is a steady state filter we can combine these equations
% into one state model (the Kalman filter)
% - -
% x[n+1] = (A-ALC) x[n] + AL y[n]
%
% * -
% y[n] = (C-CLC) x[n] + CL y[n]
%
% The function DESTIM produces this model (but also includes the
% estimated states as outputs):
[af,bf,cf,df] = destim(A,B,C,D,Lss,[1],[1]);
% Remove est. state outputs
[af,bf,cf,df] = ssdelete(af,bf,cf,df,[],[2:4]);
printsys(af,bf,cf,df,'u y','y*','x1 x2 x3')
pause % Press any key to continue ...
% Let's see how it works by generating some data and comparing the
% filtered response with the true response
% noise noise
% | |
% V V
% u -+->O-->[Plant]-->O--> y --O->[filter]-->y*
% | |
% +-------------------------------+
%
% To simulate the system above, we could generate the response of
% each part separately or we could generate both together. To
% simulate each seperately we would use DLSIM with the plant first
% and then the filter. Below we illustrate how to simulate both
% together.
% First, build one plant that contains the original plant and the
% filter connected as shown in the diagram above. Use PARALLEL and
% CLOOP. Before connecting, add a process noise input to the plant
% that is the same as u and a sensor noise input.
a = A; b=[B,B,zeros(3,1)]; c = C; d=[D,D,1];
% Now connect the original plant input (1) with the known input (1)
% of the filter using PARALLEL.
[at,bt,ct,dt] = parallel(a,b,c,d,af,bf,cf,df,[1],[1],[],[]);
% Put the plant output (1) into the filter sensor input (4)
[at,bt,ct,dt] = cloop(at,bt,ct,dt,[1],[4]);
pause % Press any key to continue ...
% The complete system model now has 4 inputs
% (plant input,process noise,sensor noise,sensor input),
% 2 outputs
% (plant output with noise,filtered output),
% and 6 states.
% Generate a sinusoidal input vector (known)
t = [0:100]';
u = sin(t/5);
% Generate process noise and sensor noise vectors
pnoise = sqrt(Q)*randn(length(t),1);
snoise = sqrt(R)*randn(length(t),1);
pause % Press any key to continue ...
% Now simulate using DLSIM
[y,x] = dlsim(at,bt,ct,dt,[u,pnoise,snoise,zeros(length(t),1)]);
% Generate "true" response
ytrue = y(:,1)-snoise;
% Plot comparison
clg
%subplot(211), plot(t,ytrue,t,y), xlabel('No. of samples'), ylabel('Output')
%subplot(212), plot(t,ytrue-y(:,2)), xlabel('No. of samples'), ylabel('Error')
%pause % Press any key to continue ...
echo off
subplot(211), plot(t,ytrue,t,y), xlabel('No. of samples'), ylabel('Output')
subplot(212), plot(t,ytrue-y(:,2)), xlabel('No. of samples'), ylabel('Error')
pause % Press any key after the plot ...
echo on
% Compute covariance of error
err1 = ytrue-y(:,1);
err1cov = sum(err1.*err1)/length(err1);
err2 = ytrue-y(:,2);
err2cov = sum(err2.*err2)/length(err2);
% Covariance of error before filtering
err1cov
% Covariance of error after filtering
err2cov
pause % Press any key to continue ...
% Now let's form a time varying Kalman filter to perform the same
% task. A time varying Kalman filter is able to perform well even
% when the noise covariance is not stationary. However for this
% demonstration, we will use stationary covariance.
% The time varying Kalman filter has the following update equations
% - *
% time update: x[n+1] = Ax[n] + Bu[n]
% - *
% P[n+1] = AP[n]A' + B*Q*B'
%
% - - -1
% observation update: L[n] = P[n]C'(CP[n]C'+R)
% * - -
% x[n] = x[n] + L[n](y[n] - Cx[n] - Du[n])
% * -
% P[n] = (I-L[n]C)P[n]
% * *
% y[n] = Cx[n] + Du[n]
%
pause % Press any key to continue ...
% Generate the noisy plant response
y = dlsim(A,B,C,D,u+pnoise) + snoise;
% Now filter. We can't use DLSIM here since the system is nonlinear,
% so just implement the above equations in a loop. Use the same inputs
% as before.
P=B*Q*B'; % Guess for initial state covariance
x=zeros(3,1); % Initial condition on the state
yest = zeros(length(t),1);
ycov = zeros(length(t),1);
for i=1:length(t)
yest(i) = C*x + D*u(i);
ycov(i) = C*P*C';
% Time update
x = A*x + B*u(i);
P = A*P*A' + B*Q*B';
% Observation update
L = P*C'/(C*P*C'+R);
x = x + L*(y(i) - C*x - D*u(i));
P = (eye(3)-L*C)*P;
end
% Compare true response with filtered response
clg
%subplot(211), plot(t,y-snoise,t,yest), ylabel('Output')
%subplot(212), plot(t,yest-y+snoise), ylabel('Error'), pause % Press any key
echo off
subplot(211), plot(t,y-snoise,t,yest), ylabel('Output')
subplot(212), plot(t,yest-y+snoise), ylabel('Error'), pause % Press any key
echo on
% The time varying filter also estimates the output covariance
% during the estimation. Let's plot it to see if our filter reached
% steady state (as we would expect with stationary input noise).
subplot(111), plot(t,ycov), ylabel('Covar'), pause % Press any key after plot
% From the covariance plot we see that the output covariance did
% indeed reach a steady state in about 5 samples. From then on,
% our time varying filter has the same performance as the steady
% state version.
% Compute covariance of error
err = y-snoise-yest;
errcov = sum(err.*err)/length(err)
pause % Press any key to continue ...
%Let's compare the final Kalman gain matrices
L,Lss
% So we see that they both obtain the same gain matrix in steady
% state.
echo off
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -