MHT billiard demo.
This models billiard balls that can bounce of the walls of an enclosure. The model is two double integrators but because of the bounce there is considerable model uncertainty in position and velocity. The sensor outputs the x and y position of each ball with noise. See also KFBilliardsDemo which demonstrates the filter by itself.
The state vector is [x;vX;y;vY].
The demo uses the Kalman Filter (KF).
------------------------------------------------------------------------- See also BilliardCollision, RHSBilliards, ScanToTrackBilliards -------------------------------------------------------------------------
Contents
-------------------------------------------------------------------------
% Copyright (c) 2013 Princeton Satellite Systems, Inc. % All rights reserved. % -------------------------------------------------------------------------
Initialize
-----------
% Control screen output %---------------------- printHypotheses = 1; printTrackUpdates = 0; makePlots = 1; % Set the seed for the random number generators. % If the seed is not set each run will be different. %--------------------------------------------------- seed = 45198; rng(seed); % The number of balls and the random initial position and velocity %----------------------------------------------------------------- d.nBalls = 2; sigP = 0.4; sigV = 1; sigMeas = 0.00000001; % Enclosure limits %----------------- d.xLim = [-1 1]; d.yLim = [-1 1]; % Time step setup %---------------- dT = 0.1; tEnd = 8; % Set the initial state %---------------------- x = zeros(4*d.nBalls,1); rN = rand(4*d.nBalls,1); for k = 1:d.nBalls j = 4*k-3; x(j ,1) = sigP*(rN(j ) - 0.5); x(j+1,1) = sigV*(rN(j+1) - 0.5); x(j+2,1) = sigP*(rN(j+2) - 0.5); x(j+3,1) = sigV*(rN(j+3) - 0.5); end % For initializing the Kalman Filter %----------------------------------- x0 = x; % Set the number of time steps %----------------------------- n = ceil(tEnd/dT); % Plotting %--------- xP = zeros(length(x),n);
Simulate
---------
fprintf(1,'\nRunning the simulation...'); % Sensor measurements %-------------------- nM = 2*d.nBalls; y = zeros(nM,n); iY = zeros(nM,1); for k = 1:d.nBalls j = 2*k-1; iY(j ) = 4*k-3; iY(j+1) = 4*k-1; end for k = 1:n % Collisions %----------- x = BilliardCollision( x, d ); % Plotting %--------- xP(:,k) = x; % Integrate %---------- x = RK4(@RHSBilliards, x, dT, 0, d ); % Measurements %------------- y(:,k) = x(iY) + sigMeas*randn(nM,1); end fprintf(1,'DONE.\n'); % Plot the simulation results %---------------------------- hB = NewFig( 'Billiard Balls' ); c = 'bgrcmyk'; kX = 1; kY = 3; s = cell(1,d.nBalls); l = []; for k = 1:d.nBalls plot(xP(kX,1),xP(kY,1),['o',c(k)]) hold on l(k) = plot(xP(kX,:),xP(kY,:),c(k)); kX = kX + 4; kY = kY + 4; s{k} = sprintf('Ball %d',k); end XLabelS('x (m)'); YLabelS('y (m)'); set(gca,'ylim',d.yLim,'xlim',d.xLim); legend(l,s) grid
Running the simulation...DONE.
Implement MHT
--------------
% Covariances %------------ r0 = sigMeas^2*[1;1]; % Measurement covariance q0 = [1;60;1;60]; % The baseline plant covariance diagonal p0 = [0.1;1;0.1;1]; % Initial state covariance matrix diagonal % Plant model %------------ a = [1 dT;0 1]; b = [dT^2/2;dT]; zA = zeros(2,2); zB = zeros(2,1); % Create the Kalman Filter data structures %----------------------------------------- for k = 1:d.nBalls kf(k) = KFInitialize( 'kf', 'm', x0(4*k-3:4*k), 'x', x0(4*k-3:4*k),... 'a', [a zA;zA a], 'b', [b zB;zB b],'u',[0;0],... 'h', [1 0 0 0;0 0 1 0], 'p', diag(p0), ... 'q', diag(q0),'r', diag(r0) ); end % Create the track data data structure %------------------------------------- mhtData = MHTInitialize('probability false alarm', 0.001,... 'probability of signal if target present', 0.999,... 'probability of signal if target absent', 0.001,... 'probability of detection', 1, ... 'measurement volume', 1.0, ... 'number of scans', 3, ... 'gate', 0.2,... 'm best', 2,... 'number of tracks', 1,... 'scan to track function',@ScanToTrackBilliards,... 'scan to track data',struct('r',diag(r0),'p',diag(p0)),... 'distance function',@MHTDistance,... 'hypothesis scan last', 0,... 'filter data',kf(1),... 'prune tracks', 1,... 'remove duplicate tracks across all trees',1,... 'average score history weight',0.01,... 'filter type','kf'); % Create the tracks %------------------ clear trk for k = 1:d.nBalls trk(k) = MHTInitializeTrk( kf(k) ); end % Size arrays %------------ b = MHTTrkToB( trk ); TOMHTTreeAnimation( 'initialize', trk ); TOMHTTreeAnimation( 'update', trk ); % Initialize MHT GUI %------------------- MHTGUI; MLog('init') MLog('name','Billiards Demo') t = 0; for k = 1:n if( printTrackUpdates ) fprintf(1,'\nScan %d\n\n',k); for j = 1:length(trk) fprintf(1,'%d: Track %d meas %d\n',j, trk(j).iD, trk(j).meas); end pause end % Get the measurements - zScan.data %---------------------------------- z = reshape( y(:,k), 2, d.nBalls ); zScan = AddScan( z(:,1) ); for j = 2:size(z,2) zScan = AddScan( z(:,j),[],[],[],zScan); end % Manage the tracks and generate hypotheses %------------------------------------------ [b, trk, sol, hyp, mhtData] = MHTTrackMgmt( b, trk, zScan, mhtData, k, t ); % Display the hypothesis %----------------------- if (printHypotheses) MHTHypothesisDisplay( hyp, trk, k, t ); end % Update MHTGUI display %---------------------- MHTGUI(trk,sol,'hide'); % Animate the tree %----------------- if( ~isempty(zScan) && makePlots ) TOMHTTreeAnimation( 'update', trk ); end t = t + dT; end % Show the GUI %------------- MHTGUI;
Plot the hypothesized trajectories against the simulation
----------------------------------------------------------
NewFig( 'Hypotheses' ); hold on kX = 1; kY = 3; s = cell(1,d.nBalls); h = []; c = 'grcmygrcmy'; kk = 0; for j = 1:length(hyp.trackIndex) kk = hyp.trackIndex(j); l(j) = plot(trk(kk).mHist(1,:),trk(kk).mHist(3,:),[c(j) '-'],... 'linewidth',2); h{j} = sprintf('Track %d',trk(kk).treeID); end for k = 1:d.nBalls % Plot the simulated data in blue plot(xP(kX,1),xP(kY,1),['o']) plot(xP(kX,:),xP(kY,:)); kX = kX + 4; kY = kY + 4; end plot(d.xLim,[1;1]*d.yLim,'k'); plot([1;1]*d.xLim,d.yLim,'k') XLabelS('x (m)'); YLabelS('y (m)'); %set(gca,'ylim',d.yLim,'xlim',d.xLim); legend(l,h) grid %-------------------------------------- % PSS internal file version information %--------------------------------------