Обработайте измерения из последовательности в системах слежения мультидатчика

В этом примере показано, как обработать измерения из последовательности (OOSM) в системе слежения мультидатчика. Пример сравнивает результаты отслеживания, когда OOSM присутствуют с помощью различных методов обработки. Для получения дополнительной информации о OOSM обработка методов смотрите Указатель Измерения Из последовательности с Фильтром пример Retrodiction.

Введение

В системе мультидатчика, когда несколько датчиков сообщают тому же средству отслеживания, измерения могут прибыть в средство отслеживания с задержкой относительно времени, когда они сгенерированы датчиком. Задержка может быть вызвана любой из следующих причин:

  1. Датчик может потребовать, чтобы существенное количество времени обработало данные. Например, датчик видения может потребовать, чтобы десятки миллисекунд обнаружили объекты в системе координат, которую он получает.

  2. Если датчик и средство отслеживания соединяются сетью, может быть коммуникационная задержка.

  3. Средство отслеживания может обновиться на различном уровне от частоты развертки датчика. Например, если средство отслеживания обновляется непосредственно перед тем, как измерения датчика прибывают, эти измерения рассматриваются как из последовательности.

Существуют различные OOSM обработка методов. В этом примере вы исследуете два метода:

Пренебрежение: В этом методе любой OOSM просто игнорируется и не используется, чтобы обновить средство отслеживания, как показано в рисунке ниже. Этот метод является самым легким и является полезным в случаях, где OOSM, как ожидают, не будет содержать данные, которые значительно изменили бы состояние фильтра и неопределенность. Это - также самый эффективный метод, в терминах памяти и обработки.

Retrodiction: В этом методе средство отслеживания сохраняет свое состояние для последних шагов n. Когда новый набор обнаружений отправляется в средство отслеживания, средство отслеживания:

  • Использует время обнаружения, чтобы классифицировать обнаружения как: в последовательности (после того, как в прошлый раз обновления средства отслеживания) или из последовательности (прежде чем в прошлый раз обновления средства отслеживания).

  • Средство отслеживания пропускает любые обнаружения с метками времени, которые являются более старыми, чем средство отслеживания n история шагов.

  • Средство отслеживания retrodict существующие дорожки ко времени обнаружений из последовательности и вычисляют стоимость присвоения для каждой комбинации дорожки и обнаружения.

  • Средство отслеживания пытается присвоить обнаружения из последовательности дорожкам.

  • Средство отслеживания retrodicts дорожка ко времени каждого присвоенного обнаружения из последовательности и retroCorrect дорожка с OOSM, смотрите изображение ниже.

  • Средство отслеживания инициализирует новые треки от неприсвоенных обнаружений из последовательности.

  • Затем средство отслеживания возобновляет свою обычную обработку с обнаружениями в последовательности.

retrodiction метод является более дорогим в терминах памяти и время вычислений, чем метод пренебрежения. Однако важно обработать OOSM в следующих случаях:

  • Датчик, который обеспечивает OOSM, покрывает области, которые не покрыты никаким другим датчиком. В этом случае пренебрежение OOSM привело бы к полной потере покрытия в области.

  • OOSM содержат новую информацию, которую не могут предоставить другие датчики. Например, если OOSM обеспечиваются единственным датчиком, который сообщает, что предметная классификация, пропуская OOSM привела бы к дорожкам, которые не имеют никаких данных о классификации.

  • Датчики, которые сообщают средству отслеживания, действуют в низкой частоте развертки. В этом случае каждое обнаружение важно, и пропускающий OOSM привел бы к низкой точности отслеживания.

Задайте задержку сценария и датчика

Чтобы исследовать OOSM обработка методов и их удара на отслеживание, вы создаете простой сценарий. В сценарии существует две движущихся платформы, которые приближаются от левого и правого до середины сценария, куда они перемещаются друг близко к другу. Существует два радара, один слева и один справа. Радар на левых обнаружениях отчетов непосредственно к средству отслеживания без задержки. Радар на праве сообщает об обнаружениях через сеть, которая имеет задержку. Обратите внимание на то, что первоначально только радар на праве покрывает платформу справа, пока это не достигает области, покрытой левым датчиком.

Следующие строки кода создают и визуализируют сценарий.

scenario = createScenario();
[tp, platp, trajp, detp, covp, trp] = createPlotters(scenario);

Figure contains an axes object. The axes object contains 5 objects of type line, patch. These objects represent Targets, Detections, (history), Sensor Coverage, Trajectories.

В этой секции кода вы задаете задержку между радаром справа и средством отслеживания. Вы используете helperDataDelay объект добавить сетевую задержку в данные, прибывающие из правильного радарного датчика, с SensorIndex = 2, к средству отслеживания. Используйте ползунок на линии 5, чтобы выбрать задержку. Допустимые значения лежат в диапазоне от 0 (никакая задержка) к 4 секундам со значением по умолчанию 2 секунд. Если вы устанавливаете значение на ползунке, радар обновляет свою задержку.

% Set the time delay of the sensor
sensorDelay = helperDataDelay("SensorIndex", 2);
sensorDelay.ConstantTimeDelay = 2
sensorDelay = 
  helperDataDelay with properties:

          SensorIndex: 2
        DelayInterval: [0 Inf]
    ConstantTimeDelay: 2
    DelayDistribution: "None"

Задайте средство отслеживания и OOSM обработка метода

trackerGNN Системный объект позволяет вам выбирать OOSM обработка метода путем установки OOSMHandling свойство. Используйте выпадающее меню на линии 11, чтобы выбрать между 'Neglect'и 'Retrodiction'. После того, как выбранный, средство отслеживания использует значение, которое вы выбираете.

tracker = trackerGNN(...
    'FilterInitializationFcn', @initfilter, ...
    'MaxNumTracks', 10, ...
    'AssignmentThreshold', [30 Inf], ...
    'ConfirmationThreshold', [2 4]);
tracker.OOSMHandling = "Retrodiction"
tracker = 
  trackerGNN with properties:

                  TrackerIndex: 0
       FilterInitializationFcn: @initfilter
                    Assignment: 'MatchPairs'
           AssignmentThreshold: [30 Inf]
                  MaxNumTracks: 10
              MaxNumDetections: Inf
                 MaxNumSensors: 20

                  OOSMHandling: 'Retrodiction'
               MaxNumOOSMSteps: 3

                    TrackLogic: 'History'
         ConfirmationThreshold: [2 4]
             DeletionThreshold: [5 5]

            HasCostMatrixInput: false
    HasDetectableTrackIDsInput: false
               StateParameters: [1x1 struct]

                     NumTracks: 0
            NumConfirmedTracks: 0

Запустите сценарий и анализируйте метрики

В этом разделе вы запускаете сценарий с задержкой, вы устанавливаете для правильного радара и OOSM обработку метода, который вы задали для средства отслеживания.

Вы задаете метрику Обобщенной оптимальной ассоциации подшаблона (GOSPA), чтобы оценить эффективность средства отслеживания в терминах полного GOSPA, локализацию, пропустил цели и ложные дорожки. Для получения дополнительной информации о GOSPA, смотрите trackGOSPAMetric.

gospa = trackGOSPAMetric;
lgospa = zeros(1,33);
localization = zeros(1,33);
missTarget = zeros(1,33);
falseTracks = zeros(1,33);
i = 0;

Следующая секция кода инициализирует сценарий и визуализацию, сбрасывает средство отслеживания и устанавливает случайный seed для повторяемых результатов.

s = rng(2021, 'twister');
h = onCleanup(@() rng(s));
delayedDets = {};
detBuffer = {};
restart(scenario);
reset(tracker);
clearPlotterData(tp);
plotTrueTrajectories(trajp, scenario);

Затем вы запускаете основной цикл симуляции. Вы видите результаты в рисунке ниже блок кода. Поскольку средство отслеживания соединяется с левым радаром, оно обновляется, когда левый радар закончил скан, или каждые 1.7 секунды.

% Main simulation loop
while advance(scenario) && ishghandle(tp.Parent)
    % Generate sensor data
    [dets, configs, sensorConfigPIDs] = detect(scenario);

    % Apply time delay to the detections
    time = scenario.SimulationTime;
    if isLocked(sensorDelay) || ~isempty(dets)
        delayedDets = sensorDelay(dets,time);
    end

    detBuffer = vertcat(detBuffer, delayedDets); %#ok<AGROW>

    [truePosition, meas, measCov] = readData(scenario, detBuffer);

    % Tracker update
    if configs(1).IsScanDone
        if isLocked(tracker) || ~isempty(detBuffer)
            [tracks,~,~,info] = tracker(detBuffer, time);
        else
            tracks = objectTrack.empty;
        end
        detBuffer = {};

        % Update the trackPlotter
        posSelector = [1 0 0 0 0 0; 0 0 1 0 0 0; 0 0 0 0 1 0];
        trpos = getTrackPositions(tracks, posSelector);
        plotTrack(trp, trpos, string([tracks.TrackID]));

        % Update GOSPA metric
        i = i + 1;
        truths = platformPoses(scenario);
        [lgospa(i), ~, ~, localization(i), missTarget(i), falseTracks(i)] = gospa(tracks,truths(3:4));
    end

    % Update plots
    plotPlatform(platp,truePosition);
    plotDetection(detp,meas,measCov);
    plotCoverage(covp,coverageConfig(scenario));

    drawnow limitrate
end

Figure contains an axes object. The axes object contains 11 objects of type line, patch, text. These objects represent Targets, Detections, (history), Sensor Coverage, Trajectories.

Вы хотите анализировать результаты средства отслеживания для выбранной радарной задержки. Следующий блок кода показывает четыре метрики GOSPA. Помните, что более низкое метрическое значение GOSPA указывает на лучшее отслеживание.

Для выбора по умолчанию радарной задержки 2 секунд и 'Retrodiction' OOSM обработка метода, метрики GOSPA показывают, что нет никаких ложных дорожек и что обе платформы прослеживаются после 3 обновлений средства отслеживания. После третьего обновления только ошибки локализации способствуют полной метрике GOSPA.

Используйте ползунок с временной задержкой и средство отслеживания OOSM, обрабатывающий выпадающее меню в предыдущем разделе, чтобы выбрать другие комбинации и сравнить их с этими значениями. Например, если средство отслеживания обработка OOSM установлено в 'Neglect', и радарная задержка данных составляет 2 секунды, платформа справа не будет прослежена, пока это не введет зону охвата левого радара. В результате пропущенный целевой GOSPA остается высоким для первой части сценария, пока платформа не вводит зону охвата левого радарного датчика.

% Display GOSPA metrics
figure;
subplot(2,2,1),plot(lgospa);
ylim([0 30]);
grid
title('Total GOSPA')
subplot(2,2,2),plot(localization);
ylim([0 30]);
grid
title('Localization GOSPA')
subplot(2,2,3),plot(missTarget);
ylim([0 30]);
grid
title('Missed Targets GOSPA')
subplot(2,2,4),plot(falseTracks);
ylim([0 30]);
grid
title('False Tracks GOSPA');

Figure contains 4 axes objects. Axes object 1 with title Total GOSPA contains an object of type line. Axes object 2 with title Localization GOSPA contains an object of type line. Axes object 3 with title Missed Targets GOSPA contains an object of type line. Axes object 4 with title False Tracks GOSPA contains an object of type line.

Сводные данные

В этом примере вы изучили важность обработки измерений из последовательности (OOSM). Вы использовали retrodiction, обрабатывающий к обнаружениям процесса, которые прибыли поздно в средство отслеживания и сравнили результаты retrodiction к результатам пренебрежения OOSM.

Вспомогательные Функции

readData функция готовит обнаружение и данные о платформе, чтобы обновить плоттеры.

function [position, meas, measCov] = readData(scenario,dets)
allDets = [dets{:}];

if ~isempty(allDets)
    % extract column vector of measurement positions
    meas = cat(2,allDets.Measurement)';

    % extract measurement noise
    measCov = cat(3,allDets.MeasurementNoise);
else
    meas = zeros(0,3);
    measCov = zeros(3,3,0);
end

truePoses = platformPoses(scenario);
position = vertcat(truePoses(:).Position);
end

createPlotters функция создает плоттеры и настраивает начальное отображение.

function [tp, platp, trajp, detp, covp, trp] = createPlotters(scenario)
% Create plotters
tp = theaterPlot('XLim', [-1000 1000], 'YLim', [-1500 500], 'ZLim', [-1500 200]);
set(tp.Parent,'YDir','reverse', 'ZDir','reverse');

% Change to 2-D view
view(2)

platp = platformPlotter(tp,'DisplayName','Targets','MarkerFaceColor','k');
detp = detectionPlotter(tp,'DisplayName','Detections','MarkerSize',6,'MarkerFaceColor',[0.85 0.325 0.098],'MarkerEdgeColor','k','History',10000);
covp = coveragePlotter(tp,'DisplayName','Sensor Coverage');
trp = trackPlotter(tp, 'ConnectHistory', 'on', 'ColorizeHistory', 'on');

% Plot ground truth trajectories for the moving objects
poses = platformPoses(scenario);
plotPlatform(platp, vertcat(poses.Position));
trajp = trajectoryPlotter(tp,'DisplayName','Trajectories','LineWidth',1);
plotTrueTrajectories(trajp, scenario);

% Plot coverage
covcon = coverageConfig(scenario);
plotCoverage(covp,covcon);
end

createScenario функция создает сценарий, платформы и радары.

function scenario = createScenario
% Create Scenario
scenario = trackingScenario;
scenario.StopTime = Inf;
scenario.UpdateRate = 0;


% Create platforms
Tower = platform(scenario,'ClassID',3);
Tower.Dimensions = struct( ...
    'Length', 10, ...
    'Width', 10, ...
    'Height', 60, ...
    'OriginOffset', [0 0 30]);
Tower.Trajectory.Position = [-400 500 0];

Tower1 = platform(scenario,'ClassID',3);
Tower1.Dimensions = struct( ...
    'Length', 10, ...
    'Width', 10, ...
    'Height', 60, ...
    'OriginOffset', [0 0 30]);
Tower1.Trajectory.Position = [400 500 0];

Plane = platform(scenario,'ClassID',1);
Plane.Dimensions = struct( ...
    'Length', 1, ...
    'Width', 1, ...
    'Height', 1, ...
    'OriginOffset', [0 0 0]);
Plane.Signatures = {...
    rcsSignature(...
    'Pattern', [20 20;20 20], ...
    'Azimuth', [-180 180], ...
    'Elevation', [-90;90], ...
    'Frequency', [0 1e+20])};
Plane.Trajectory = waypointTrajectory( ...
    [-400 200 0;-50 100 0;-20 -600 0; 0 -1000 0], ...
    [0;22;45;60], ...
    'AutoPitch', true, ...
    'AutoBank', true);

Plane1 = platform(scenario,'ClassID',1);
Plane1.Dimensions = struct( ...
    'Length', 1, ...
    'Width', 1, ...
    'Height', 1, ...
    'OriginOffset', [0 0 0]);
Plane1.Signatures = {...
    rcsSignature(...
    'Pattern', [20 20;20 20], ...
    'Azimuth', [-180 180], ...
    'Elevation', [-90;90], ...
    'Frequency', [0 1e+20])};
Plane1.Trajectory = waypointTrajectory( ...
    [525 200 0;50 100 0;20 -600 0; 0 -1000 0], ...
    [0;22;45;60], ...
    'AutoPitch', true, ...
    'AutoBank', true);


% Create sensors
Sector = fusionRadarSensor('SensorIndex', 1, ...
    'UpdateRate', 10, ...
    'MountingLocation', [4.85 -4.98 0], ...
    'MountingAngles', [0 0 0], ...
    'FieldOfView', [5 1], ...
    'HasINS', true, ...
    'ReferenceRange', 1000, ...
    'DetectionCoordinates', 'Scenario', ...
    'MechanicalAzimuthLimits', [-150 -30]);

Sector1 = fusionRadarSensor('SensorIndex', 2, ...
    'UpdateRate', 10, ...
    'MountingLocation', [-5.01 -5.04 0], ...
    'FieldOfView', [5 1], ...
    'HasINS', true, ...
    'ReferenceRange', 1000, ...
    'DetectionCoordinates', 'Scenario', ...
    'MechanicalAzimuthLimits', [-150 -30]);


% Assign sensors to platforms
Tower.Sensors = Sector;
Tower1.Sensors = Sector1;
end

initfilter функция инициализирует почти постоянную скорость trackingEKF фильтр, сконфигурированный, чтобы позволить более высокий шум процесса.

function ekf = initfilter(detection)
ekf = initcvekf(detection);
ekf.ProcessNoise = ekf.ProcessNoise*9;
end

plotTrueTrajectories траектории основной истины графиков функций на театральном графике.

function plotTrueTrajectories(trajp, scenario)
trajpos = cell(1,2);
for i = 3:4
    trajpos{i-2} = lookupPose(scenario.Platforms{i}.Trajectory, (0:0.1:60));
end
plotTrajectory(trajp,trajpos);
end