ParticleEx5.m
资源名称:work.rar [点击查看]
上传用户:shigeng
上传日期:2017-01-30
资源大小:122k
文件大小:8k
源码类别:
数值算法/人工智能
开发平台:
Matlab
- function [StdErr, EKFErr] = ParticleEx5
- % EKF Particle filter example.
- % Track a body falling through the atmosphere.
- % This system is taken from [Jul00], which was based on [Ath68].
- % Compare the particle filter with the EKF particle filter.
- global rho0 g k dt
- rho0 = 2; % lb-sec^2/ft^4
- g = 32.2; % ft/sec^2
- k = 2e4; % ft
- R = 10^4; % measurement noise variance (ft^2)
- Q = diag([0 0 0]); % process noise covariance
- M = 10^5; % horizontal range of position sensor
- a = 10^5; % altitude of position sensor
- P = diag([1e6 4e6 10]); % initial estimation error covariance
- x = [3e5; -2e4; 1e-3]; % initial state
- xhat = [3e5; -2e4; 1e-3]; % initial state estimate
- N = 200; % number of particles
- % Initialize the particle filter.
- for i = 1 : N
- xhatplus(:,i) = x + sqrt(P) * [randn; randn; randn]; % standard particle filter
- xhatplusEKF(:,i) = xhatplus(:,i); % EKF particle filter
- Pplus(:,:,i) = P; % initial EKF particle filter estimation error covariance
- end
- T = 0.5; % measurement time step
- randn('state',sum(100*clock)); % random number generator seed
- tf = 30; % simulation length (seconds)
- dt = 0.5; % time step for integration (seconds)
- xArray = x;
- xhatArray = xhat;
- xhatEKFArray = xhat;
- for t = T : T : tf
- fprintf('.');
- % Simulate the system.
- for tau = dt : dt : T
- % Fourth order Runge Kutta ingegration
- [dx1, dx2, dx3, dx4] = RungeKutta(x);
- x = x + (dx1 + 2 * dx2 + 2 * dx3 + dx4) / 6;
- x = x + sqrt(dt * Q) * [randn; randn; randn] * dt;
- end
- % Simulate the noisy measurement.
- z = sqrt(M^2 + (x(1)-a)^2) + sqrt(R) * randn;
- % Simulate the continuous-time part of the particle filters (time update).
- xhatminus = xhatplus;
- xhatminusEKF = xhatplusEKF;
- for i = 1 : N
- for tau = dt : dt : T
- % Fourth order Runge Kutta ingegration
- % standard particle filter
- [dx1, dx2, dx3, dx4] = RungeKutta(xhatminus(:,i));
- xhatminus(:,i) = xhatminus(:,i) + (dx1 + 2 * dx2 + 2 * dx3 + dx4) / 6;
- xhatminus(:,i) = xhatminus(:,i) + sqrt(dt * Q) * [randn; randn; randn] * dt;
- xhatminus(3,i) = max(0, xhatminus(3,i)); % the ballistic coefficient cannot be negative
- % EKF particle filter
- [dx1, dx2, dx3, dx4] = RungeKutta(xhatminusEKF(:,i));
- xhatminusEKF(:,i) = xhatminusEKF(:,i) + (dx1 + 2 * dx2 + 2 * dx3 + dx4) / 6;
- xhatminusEKF(:,i) = xhatminusEKF(:,i) + sqrt(dt * Q) * [randn; randn; randn] * dt;
- xhatminusEKF(3,i) = max(0, xhatminusEKF(3,i)); % the ballistic coefficient cannot be negative
- end
- % standard particle filter
- zhat = sqrt(M^2 + (xhatminus(1,i)-a)^2);
- vhat(i) = z - zhat;
- % EKF particle filter
- zhatEKF = sqrt(M^2 + (xhatminusEKF(1,i)-a)^2);
- F = [0 1 0; -rho0 * exp(-xhatminusEKF(1,i)/k) * xhatminusEKF(2,i)^2 / 2 / k * xhatminusEKF(3,i) ...
- rho0 * exp(-xhatminusEKF(1,i)/k) * xhatminusEKF(2,i) * xhatminusEKF(3,i) ...
- rho0 * exp(-xhatminusEKF(1,i)/k) * xhatminusEKF(2,i)^2 / 2; ...
- 0 0 0];
- H = [(xhatminusEKF(1,i) - a) / sqrt(M^2 + (xhatminusEKF(1,i)-a)^2) 0 0];
- Pminus(:,:,i) = F * Pplus(:,:,i) * F' + Q;
- K = Pminus(:,:,i) * H' * inv(H * Pminus(:,:,i) * H' + R);
- xhatminusEKF(:,i) = xhatminusEKF(:,i) + K * (z - zhatEKF);
- zhatEKF = sqrt(M^2 + (xhatminusEKF(1,i)-a)^2);
- vhatEKF(i) = z - zhatEKF;
- end
- % Note that we need to scale all of the q(i) probabilities in a way
- % that does not change their relative magnitudes.
- % Otherwise all of the q(i) elements will be zero because of the
- % large value of the exponential.
- % standard particle filter
- vhatscale = max(abs(vhat)) / 4;
- qsum = 0;
- for i = 1 : N
- q(i) = exp(-(vhat(i)/vhatscale)^2);
- qsum = qsum + q(i);
- end
- % Normalize the likelihood of each a priori estimate.
- for i = 1 : N
- q(i) = q(i) / qsum;
- end
- % EKF particle filter
- vhatscaleEKF = max(abs(vhatEKF)) / 4;
- qsumEKF = 0;
- for i = 1 : N
- qEKF(i) = exp(-(vhatEKF(i)/vhatscaleEKF)^2);
- qsumEKF = qsumEKF + qEKF(i);
- end
- % Normalize the likelihood of each a priori estimate.
- for i = 1 : N
- qEKF(i) = qEKF(i) / qsumEKF;
- end
- % Resample the standard particle filter
- for i = 1 : N
- u = rand; % uniform random number between 0 and 1
- qtempsum = 0;
- for j = 1 : N
- qtempsum = qtempsum + q(j);
- if qtempsum >= u
- xhatplus(:,i) = xhatminus(:,j);
- xhatplus(3,i) = max(0,xhatplus(3,i)); % the ballistic coefficient cannot be negative
- break;
- end
- end
- end
- % The standard particle filter estimate is the mean of the particles.
- xhat = mean(xhatplus')';
- % Resample the EKF particle filter
- Ptemp = Pplus;
- for i = 1 : N
- u = rand; % uniform random number between 0 and 1
- qtempsum = 0;
- for j = 1 : N
- qtempsum = qtempsum + qEKF(j);
- if qtempsum >= u
- xhatplusEKF(:,i) = xhatminusEKF(:,j);
- xhatplusEKF(3,i) = max(0,xhatplusEKF(3,i)); % the ballistic coefficient cannot be negative
- Pplus(:,:,i) = Ptemp(:,:,j);
- break;
- end
- end
- end
- % The EKF particle filter estimate is the mean of the particles.
- xhatEKF = mean(xhatplusEKF')';
- % Save data for plotting.
- xArray = [xArray x];
- xhatArray = [xhatArray xhat];
- xhatEKFArray = [xhatEKFArray xhatEKF];
- end
- close all;
- t = 0 : T : tf;
- figure;
- semilogy(t, abs(xArray(1,:) - xhatArray(1,:)), 'b-'); hold;
- semilogy(t, abs(xArray(1,:) - xhatEKFArray(1,:)), 'r:');
- set(gca,'FontSize',12); set(gcf,'Color','White');
- xlabel('Seconds');
- ylabel('Altitude Estimation Error');
- legend('Standard particle filter', 'EKF particle filter');
- figure;
- semilogy(t, abs(xArray(2,:) - xhatArray(2,:)), 'b-'); hold;
- semilogy(t, abs(xArray(2,:) - xhatEKFArray(2,:)), 'r:');
- set(gca,'FontSize',12); set(gcf,'Color','White');
- xlabel('Seconds');
- ylabel('Velocity Estimation Error');
- legend('Standard particle filter', 'EKF particle filter');
- figure;
- semilogy(t, abs(xArray(3,:) - xhatArray(3,:)), 'b-'); hold;
- semilogy(t, abs(xArray(3,:) - xhatEKFArray(3,:)), 'r:');
- set(gca,'FontSize',12); set(gcf,'Color','White');
- xlabel('Seconds');
- ylabel('Ballistic Coefficient Estimation Error');
- legend('Standard particle filter', 'EKF particle filter');
- figure;
- plot(t, xArray(1,:));
- set(gca,'FontSize',12); set(gcf,'Color','White');
- xlabel('Seconds');
- ylabel('True Position');
- figure;
- plot(t, xArray(2,:));
- title('Falling Body Simulation', 'FontSize', 12);
- set(gca,'FontSize',12); set(gcf,'Color','White');
- xlabel('Seconds');
- ylabel('True Velocity');
- for i = 1 : 3
- StdErr(i) = sqrt((norm(xArray(i,:) - xhatArray(i,:)))^2 / tf / dt);
- EKFErr(i) = sqrt((norm(xArray(i,:) - xhatEKFArray(i,:)))^2 / tf / dt);
- end
- disp(['Standard particle filter RMS error = ', num2str(StdErr)]);
- disp(['EKF particle filter RMS error = ', num2str(EKFErr)]);
- function [dx1, dx2, dx3, dx4] = RungeKutta(x)
- % Fourth order Runge Kutta integration for the falling body system.
- global rho0 g k dt
- dx1(1,1) = x(2);
- dx1(2,1) = rho0 * exp(-x(1)/k) * x(2)^2 / 2 * x(3) - g;
- dx1(3,1) = 0;
- dx1 = dx1 * dt;
- xtemp = x + dx1 / 2;
- dx2(1,1) = xtemp(2);
- dx2(2,1) = rho0 * exp(-xtemp(1)/k) * xtemp(2)^2 / 2 * xtemp(3) - g;
- dx2(3,1) = 0;
- dx2 = dx2 * dt;
- xtemp = x + dx2 / 2;
- dx3(1,1) = xtemp(2);
- dx3(2,1) = rho0 * exp(-xtemp(1)/k) * xtemp(2)^2 / 2 * xtemp(3) - g;
- dx3(3,1) = 0;
- dx3 = dx3 * dt;
- xtemp = x + dx3;
- dx4(1,1) = xtemp(2);
- dx4(2,1) = rho0 * exp(-xtemp(1)/k) * xtemp(2)^2 / 2 * xtemp(3) - g;
- dx4(3,1) = 0;
- dx4 = dx4 * dt;
- return;