В этом примере показано, как обработать измерения из последовательности (OOSM) в системе слежения мультидатчика. Пример сравнивает результаты отслеживания, когда OOSM присутствуют с помощью различных методов обработки. Для получения дополнительной информации о OOSM обработка методов смотрите Указатель Измерения Из последовательности с Фильтром пример Retrodiction.
В системе мультидатчика, когда несколько датчиков сообщают тому же средству отслеживания, измерения могут прибыть в средство отслеживания с задержкой относительно времени, когда они сгенерированы датчиком. Задержка может быть вызвана любой из следующих причин:
Датчик может потребовать, чтобы существенное количество времени обработало данные. Например, датчик видения может потребовать, чтобы десятки миллисекунд обнаружили объекты в системе координат, которую он получает.
Если датчик и средство отслеживания соединяются сетью, может быть коммуникационная задержка.
Средство отслеживания может обновиться на различном уровне от частоты развертки датчика. Например, если средство отслеживания обновляется непосредственно перед тем, как измерения датчика прибывают, эти измерения рассматриваются как из последовательности.
Существуют различные 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);
В этой секции кода вы задаете задержку между радаром справа и средством отслеживания. Вы используете 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"
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
Вы хотите анализировать результаты средства отслеживания для выбранной радарной задержки. Следующий блок кода показывает четыре метрики 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');
В этом примере вы изучили важность обработки измерений из последовательности (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