В этом примере показано, как отследить маневрирующие цели с помощью различных фильтров отслеживания. Пример показывает различие между фильтрами, которые используют одну модель движения и несколько моделей движения.
В этом примере вы задаете единую цель, которая первоначально перемещается при постоянной скорости 200 м/с в течение 33 секунд, затем входит в постоянный поворот 10 градусов/с. Поворот длится в течение 33 секунд, затем цель ускоряется в прямой линии на уровне 3 м/с^2.
[trueState, time, fig1] = helperGenerateTruthData; dt = diff(time(1:2)); numSteps = numel(time); figure(fig1)
Задайте измерения, чтобы быть положением и добавить нормальный случайный шум со стандартным отклонением 1 к измерениям.
% Set the RNG seed for repeatable results s = rng; rng(2018); positionSelector = [1 0 0 0 0 0;0 0 1 0 0 0;0 0 0 0 1 0]; % Position from state truePos = positionSelector * trueState; measNoise = randn(size(truePos)); measPos = truePos + measNoise;
Вы задаете trackingEKF
с моделью движения постоянной скорости. Вы используете первое измерение, чтобы задать начальное состояние и ковариацию состояния, и установить шум процесса быть недополнением, задавать шум процесса в терминах неизвестного ускорения в x, y, и z компоненты. Это определение похоже на как функциональный initcvekf
работает.
initialState = positionSelector' * measPos(:,1); initialCovariance = diag([1,1e4,1,1e4,1,1e4]); % Velocity is not measured cvekf = trackingEKF(@constvel, @cvmeas, initialState, ... 'StateTransitionJacobianFcn', @constveljac, ... 'MeasurementJacobianFcn', @cvmeasjac, ... 'StateCovariance', initialCovariance, ... 'HasAdditiveProcessNoise', false, ... 'ProcessNoise', eye(3));
Для каждого измерения вы предсказываете фильтр, вычисляете расстояние предсказанного состояния от истинного положения и корректируете фильтр с помощью измерения, чтобы получить отфильтрованную оценку положения.
dist = zeros(1,numSteps); estPos = zeros(3,numSteps); for i = 2:size(measPos,2) predict(cvekf, dt); dist(i) = distance(cvekf,truePos(:,i)); % Distance from true position estPos(:,i) = positionSelector * correct(cvekf, measPos(:,i)); end figure(fig1); plot(estPos(1,:),estPos(2,:),'.g','DisplayName','CV Low PN') title('True and Estimated Positions') axis([5000 8000 -500 2500])
Как изображено в фигуре, фильтр может отследить постоянную скоростную часть движения очень хорошо, но когда цель выполняет поворот, фильтр оценил, что положение отличается от истинного положения. Вы видите расстояние оценки от истины в следующем графике. Во время поворота, в 33-66 секунд, нормированное расстояние переходит к очень высоким значениям, что означает, что фильтр не может отследить маневрирующую цель.
fig2 = figure; hold on plot((1:numSteps)*dt,dist,'g','DisplayName', 'CV Low PN') title('Normalized Distance From Estimated Position to True Position') xlabel('Time (s)') ylabel('Normalized Distance') legend
Одно возможное решение состоит в том, чтобы увеличить шум процесса. Шум процесса представляет несмоделированные условия в модели движения. Для постоянной скоростной модели это неизвестные ускоряющие условия. Путем увеличения шума процесса вы допускаете большую неопределенность в модели движения, которая заставляет фильтр использовать измерения больше, чем на модели. Следующие линии создают постоянный скоростной фильтр с высокими значениями шума процесса, которые соответствуют о повороте 5-G.
cvekf2 = trackingEKF(@constvel, @cvmeas, initialState, ... 'StateTransitionJacobianFcn', @constveljac, ... 'MeasurementJacobianFcn', @cvmeasjac, ... 'StateCovariance', initialCovariance, ... 'HasAdditiveProcessNoise', false, ... 'ProcessNoise', diag([50,50,1])); % Large uncertainty in the horizontal acceleration dist = zeros(1,numSteps); estPos = zeros(3,numSteps); for i = 2:size(measPos,2) predict(cvekf2, dt); dist(i) = distance(cvekf2,truePos(:,i)); % Distance from true position estPos(:,i) = positionSelector * correct(cvekf2, measPos(:,i)); end figure(fig1) plot(estPos(1,:),estPos(2,:),'.c','DisplayName','CV High PN') axis([5000 8000 -500 2500])
Увеличение шума процесса значительно улучшает способность фильтра отследить цель во время поворота. Однако существует стоимость: фильтр менее способен к сглаживанию шума измерения в постоянный скоростной период движения. Даже при том, что нормированное расстояние во время поворота было значительно уменьшено, нормированное расстояние, увеличенное за первые 33 секунды, в постоянный скоростной период движения.
figure(fig2) plot((1:numSteps)*dt,dist,'c','DisplayName', 'CV High PN') axis([0 100 0 50])
Другое решение состоит в том, чтобы использовать фильтр, который может считать все модели движения одновременно, названными фильтром взаимодействующей многоуровневой модели (IMM). Фильтр IMM может обеспечить столько моделей движения, сколько вы хотите, но обычно используется с 2-5 моделями движения. В данном примере три модели достаточны: постоянная скоростная модель, постоянная модель поворота и постоянная ускоряющая модель.
imm = trackingIMM('TransitionProbabilities', 0.99); % The default IMM has all three models % Initialize the state and state covariance in terms of the first model initialize(imm, initialState, initialCovariance);
Вы используете фильтр IMM таким же образом, что EKF использовался.
dist = zeros(1,numSteps); estPos = zeros(3,numSteps); modelProbs = zeros(3,numSteps); modelProbs(:,1) = imm.ModelProbabilities; for i = 2:size(measPos,2) predict(imm, dt); dist(i) = distance(imm,truePos(:,i)); % Distance from true position estPos(:,i) = positionSelector * correct(imm, measPos(:,i)); modelProbs(:,i) = imm.ModelProbabilities; end figure(fig1) plot(estPos(1,:),estPos(2,:),'.m','DisplayName','IMM')
trackingIMM
фильтр может отследить маневрирующую цель во всех трех частях движения.
Исследуя расстояние между предсказанным состоянием фильтра и истинным положением, вы видите, что фильтр IMM может уменьшить расстояние для всех фрагментов движения. На самом деле фильтр IMM лучше в отслеживании движения, чем обе других постоянных скоростных модели, используемые ранее.
figure(fig2) hold on plot((1:numSteps)*dt,dist,'m','DisplayName', 'IMM') axis([0 100 0 50])
Чтобы лучше изучить, как фильтр IMM работает, постройте вероятности модели как функцию времени. Рисунок показывает, что фильтр инициализируется с этими тремя моделями, имеющими ту же вероятность. Когда фильтр обновляется, он быстро сходится к очень высокой вероятности, что модель является постоянной скоростной моделью. После 33 секунд движения постоянная скоростная модель более не верна, и вероятность постоянной модели поворота становится очень высокой на время поворота. В последнем разделе движения, во время постоянного ускоряющего маневра, фильтр IMM определяет высокую вероятность, что движение является постоянным ускорением, но фильтр менее уверен в правильной модели движения, и существует приблизительно 0,3 вероятности постоянного скоростного движения.
figure plot((1:numSteps)*dt, modelProbs) title('Model Probabilities vs. Time') xlabel('Time (s)') ylabel('Model Probabilities') legend('IMM-CV','IMM-CA','IMM-CT') % Return the RNG to its previous state rng(s)
Этот пример показал вам, как отследить цель, маневрирующую с постоянным поворотом и постоянным ускоряющим движением. Пример показал, как можно увеличить шум процесса, чтобы получить неизвестный маневр с постоянной скоростной моделью. Вы также видели, как улучшить отслеживание маневрирующей цели при помощи фильтра IMM.
helperGenerateTruthData
Эта функция генерирует траекторию основной истины.
function [Xgt, tt, figs] = helperGenerateTruthData % Generate ground truth vx = 200; % m/s omega = 10; % deg/s acc = 3; % m/s/s dt = 0.1; tt = (0:dt:floor(1000*dt)); figs = []; Xgt = NaN(9,numel(tt)); Xgt(:,1) = 0; % Constant velocity seg1 = floor(numel(tt)/3); Xgt(2,1) = vx; slct = eye(9); slct(3:3:end,:) = []; for m = 2:seg1 X0 = slct*Xgt(:,m-1); X1 = constvel(X0, dt); X1 = slct'*X1; Xgt(:,m) = X1; end % Constant turn seg2 = floor(2*numel(tt)/3); slct = eye(9); slct(3:3:end,:) = []; for m = seg1+1:seg2 X0 = slct*Xgt(:,m-1); X0 = [X0(1:4);omega]; X1 = constturn(X0, dt); X1 = X1(1:4); X1 = [X1(1:2);0;X1(3:4);0;zeros(3,1)]; Xgt(:,m) = X1; end % Constant acceleration first = true; for m = seg2+1:numel(tt) X0 = Xgt(:,m-1); if first vel = X0(2:3:end); ua = vel/norm(vel); va = acc*ua; X0(3:3:end) = va; first = false; end X1 = constacc(X0, dt); Xgt(:,m) = X1; end % Drop acceleration dimension slct = eye(9); slct(3:3:end,:) = []; Xgt = slct*Xgt; figs = [figs figure]; plot(Xgt(1,1:seg1),Xgt(3,1:seg1),'.-'); hold on; plot(Xgt(1,seg1+1:seg2),Xgt(3,seg1+1:seg2),'.-'); plot(Xgt(1,seg2+1:end),Xgt(3,seg2+1:end),'.-'); grid on; xlabel('X Position (m)'); ylabel('Y Position (m)'); title('True Position') axis equal; legend('Constant Velocity', 'Constant Turn', 'Constant Acceleration') end