Этот пример иллюстрирует отслеживание объектов, используя измерения с пространственно распределенных и синхронных пассивных датчиков. В Пассивном Диапазоне Используя Один Датчик Маневрирования, вы узнали, что пассивные измерения обеспечивают неполную наблюдаемость состояния цели и как один датчик может маневрировать, чтобы получить информацию о области значений. Альтернативно, несколько стационарных датчиков могут также использоваться для усиления наблюдаемости. В этом примере вы научитесь отслеживать несколько объектов путем слияния нескольких обнаружений с пассивных синхронных датчиков.
В синхронизированной задаче отслеживания мультисенсора-мультитаргета обнаружение с нескольких пассивных датчиков собирается синхронно и используется для оценки следующего:
Количество целей в сценарии
Положение и скорость этих целей
Этот пример демонстрирует использование архитектуры Static Fusion Before Tracking [1] для отслеживания с помощью пассивных измерений. Часть архитектуры Static Fusion нацелена на триангуляцию наиболее вероятного набора обнаружений и вывод сплавленных обнаружений, содержащих предполагаемые положения целей. Поскольку измерения должны быть объединены вместе статическим слиянием, датчики должны сообщать о измерениях синхронно.
При измерениях, содержащих только информацию о линии видимости (LOS), для поиска положения необходимо не менее 2 датчиков. Однако с 2 датчиками проблема призрака (пересечения в точках без целей) возникает, когда несколько целей лежат в одной плоскости. С 2 целями и 2 датчиками невозможно идентифицировать правильную пару из одной системы измерений, как показано на рисунке ниже:
Поэтому необходимо использовать 3 или более датчиков, чтобы уменьшить проблему призрака. Из-за наличия измерительного шума и ложных измерений трудно полностью устранить проблему призрака. Триангуляции призраков, возвращенные статической ассоциацией, вероятно, будут отброшены блоками динамической ассоциации, когда геометрия целей и датчиков изменяется во время сценария.
Относительное размещение датчиков и целей в используемом здесь сценарии взято из примера в [1]. Сценарий состоит из пяти равномерно расположенных целей, наблюдаемых тремя-пятью пассивными датчиками. Пассивные обнаружения моделируются с помощью radarEmitter
и radarSensor
с DetectionMode
установлено на ESM
. The HasNoise
свойство датчиков установлено в false
для генерации обнаружений без шума вместе с ложными предупреждениями. Шум к измерениям добавляется в этом примере через управляемую пользователем переменную. Это для моделирования эффекта шума датчика на статическое слияние. Каждый датчик имеет поле зрения 180 степеней по азимуту и FalseAlarmRate
1e-3 на камеру азимутального разрешения. Это приводит к 2-3 ложным предупреждениям на скан. Определение сценария переносится внутрь вспомогательной функции helperGenerateFusionScenarioData
.
[detectionBuffer,truthLog,theaterDisplay] = helperGenerateStaticFusionScenarioData; showScenario(theaterDisplay);
showGrabs(theaterDisplay,[]);
В этом разделе рассматриваются только измерения от внутренних трех датчиков и ковариация шума измерения для каждого датчика устанавливается на 0,01 степени в квадрате.
Обнаружения от каждого датчика передаются в staticDetectionFuser
. The MeasurementFusionFcn
для пассивной триангуляции задается как triangulateLOS
. The MeasurementFusionFcn
позволяет задать функцию для сплавления заданной комбинации обнаружений (самое большее одно обнаружение от каждого датчика) и возврата сросшегося положения и его ковариационной ошибки. Параметры FalseAlarmRate
, Volume
и DetectionProbability
заданы для отражения параметров датчиков, моделируемых в этом сценарии. Эти параметры используются, чтобы вычислить вероятность допустимых ассоциаций. The UseParallel
свойство, если установлено в true
, позволяет fuser оценить допустимые ассоциации с помощью параллельных процессоров.
Отслеживание выполняется ассоциацией данных GNN при помощи trackerGNN
.
Отслеживающая эффективность оценивается с помощью trackAssignmentMetrics
и trackErrorMetrics
.
Setup
% Number of sensors numSensors = 3; % Create a detection fuser using triangulateLOS function as the % MeasurementFusionFcn and specify parameters of sensors. fuser = staticDetectionFuser('MeasurementFusionFcn',@triangulateLOS,... 'MaxNumSensors',numSensors,... 'UseParallel',true,... 'FalseAlarmRate',1e-3,... 'Volume',0.0716,... 'DetectionProbability',0.99); % Tracking using a GNN tracker tracker = trackerGNN('AssignmentThreshold',50,... 'ConfirmationThreshold',[3 5],'DeletionThreshold',[4 5]); % Use assignment and error metrics to compute accuracy. trackingMetrics = trackAssignmentMetrics('DistanceFunctionFormat','custom',... 'AssignmentDistanceFcn',@trueAssignment,'DivergenceDistanceFcn',@trueAssignment); errorMetrics = trackErrorMetrics;
Запустите симуляцию с тремя датчиками
% Measurement noise measNoise = 0.01; time = 0; dT = 1; % 1 Hz update rate of scenario. % Loop through detections and track targets for iter = 1:numel(detectionBuffer) % Truth information sensorPlatPoses = truthLog{iter}(1:numSensors); targetPlatPoses = truthLog{iter}(6:end); groundTruth = [sensorPlatPoses;targetPlatPoses]; % Generate noisy detections using recorded detections thisBuffer = detectionBuffer{iter}; availableDetections = vertcat(thisBuffer{1:numSensors}); noiseDetections = addNoise(availableDetections,measNoise); % Fuse noisy detections using fuser fusedDetections = fuser(noiseDetections); % Run a tracker on fused detections confTracks = tracker(fusedDetections,time); % Update track and assignment metrics trackingMetrics(confTracks,targetPlatPoses); [trackIDs,truthIDs] = currentAssignment(trackingMetrics); errorMetrics(confTracks,trackIDs,targetPlatPoses,truthIDs); % Update theater display detsToPlot = [noiseDetections(:);fusedDetections(:)]; theaterDisplay(confTracks,detsToPlot,groundTruth); % Update time time = time + dT; end axes(theaterDisplay.TheaterPlot.Parent);
ylim([0 1.5]);
Результаты отслеживания с использованием трех датчиков с 0,01 градусами в квадрате шумовой ковариации могут быть суммированы с помощью метрик присвоения. Обратите внимание, что все треки были присвоены правильным истинам и никакие ложные треки не были подтверждены трекером. Эти результаты указывают на хорошую точность статической связи.
assignmentTable = trackMetricsTable(trackingMetrics); assignmentTable(:,{'TrackID','AssignedTruthID','TotalLength','FalseTrackStatus'})
ans = 5×4 table TrackID AssignedTruthID TotalLength FalseTrackStatus _______ _______________ ___________ ________________ 1 10 59 false 2 9 59 false 3 8 59 false 4 7 59 false 5 6 59 false
Ошибка в оцененном положении и скорости целевых объектов может быть суммирована с помощью метрики ошибки. Ошибки в положении и скорости находятся в пределах 7 метров и 2 метра/с соответственно для всех целей, а нормализованные ошибки близки к 1. Метрики ошибки указывают на хорошую динамическую ассоциацию и эффективность отслеживания.
disp(cumulativeTrackMetrics(errorMetrics));
TrackID posRMS velRMS posANEES velANEES _______ ______ ______ ________ ________ 1 5.8143 1.5379 1.7273 0.61788 2 4.0385 1.2251 1.7547 0.66935 3 4.1647 1.2866 1.7555 0.64513 4 3.6861 1.3207 1.3389 0.44256 5 5.364 1.2745 1.6521 0.52297
Эффект точности измерений
Слияние пассивных обнаружений для устранения призрака сильно зависит от точности пассивных измерений. Когда шум измерения увеличивается, различие между ассоциациями призраков и истинными ассоциациями становится менее заметным, что приводит к значительному снижению точности статической ассоциации. При близко расположенных мишенях может также происходить неправильная связь сплавленных обнаружений с треками. В следующем разделе функция helper helperRunStaticFusionSimulation
используются для повторного запуска сценария с ковариацией шума измерения 2 степени в квадрате.
Запустите сценарий снова с высоким шумом измерения
numSensors = 3;
measNoise = 2; %standard deviation of sqrt(2) degrees
[trackingMetrics,errorMetrics] = helperRunStaticFusionSimulation(detectionBuffer,truthLog,numSensors,measNoise,theaterDisplay,false);
axes(theaterDisplay.TheaterPlot.Parent);
ylim([0 1.5]);
Обратите внимание, что большое количество треков было подтверждено, а затем сброшено в этой симуляции. Плохая точность статической ассоциации приводит к триангуляциям призрачных целей чаще, что приводит к удалению трекером этих треков из-за нескольких промахов.
assignmentTable = trackMetricsTable(trackingMetrics); assignmentTable(:,{'TrackID','AssignedTruthID','TotalLength','FalseTrackStatus'})
ans = 11×4 table TrackID AssignedTruthID TotalLength FalseTrackStatus _______ _______________ ___________ ________________ 1 9 58 false 4 NaN 6 true 5 7 59 false 6 6 58 false 7 10 58 false 8 NaN 13 true 9 NaN 12 false 15 8 52 false 16 NaN 4 true 20 NaN 4 true 28 NaN 3 true
Предполагаемая ошибка для каждой истинности выше. Заметьте, что дорожка скачет в кинотеатре, показанном выше.
disp(cumulativeTruthMetrics(errorMetrics));
TruthID posRMS velRMS posANEES velANEES _______ ______ ______ ________ ________ 6 517.05 4.5871 109.74 1.0434 7 51.5 3.8501 3.281 0.83398 8 59.893 3.0373 3.1765 0.63048 9 105.88 17.459 6.821 9.9861 10 68.313 4.7792 2.42 0.90618
Точность ассоциации может быть улучшена путем увеличения количества датчиков. Однако вычислительные требования увеличиваются экспоненциально с сложением каждого датчика. Статический алгоритм слияния проводит большую часть времени, вычисляя допустимость каждой триангуляции. Эта часть алгоритма параллельна, когда UseParallel
свойство staticDetectionFuser
установлено в true
, что обеспечивает линейную скорость, пропорциональную количеству процессоров. Для дальнейшего ускорения выполнения можно также сгенерировать код C/C + +, который также будет выполняться параллельно на нескольких процессорах. Основам генерации кода можно научиться с помощью Coder™ MATLAB ® в Запуск with MATLAB Coder (MATLAB Coder).
Чтобы ускорить КОД MATLAB для симуляции, алгоритм должен быть реструктурирован как функция MATLAB, которая может быть скомпилирована в файл MEX или общую библиотеку. Для этой цели статический алгоритм слияния перестраивается в функцию. Чтобы сохранить состояние фузера между несколькими вызовами, это определяется как persistent
переменная.
type('mexFuser');
function [superDets,info] = mexFuser(detections) %#codegen persistent fuser if isempty(fuser) fuser = staticDetectionFuser('MeasurementFusionFcn',@triangulateLOS,... 'MaxNumSensors',5,... 'UseParallel',true,... 'FalseAlarmRate',1e-3,... 'Volume',0.0716,... 'DetectionProbability',0.99); end [superDets,info] = fuser(detections);
MATLAB ® Coder™ требует определения свойств всех входных параметров. Легкий способ сделать это - определить входные свойства по примеру в командной строке с помощью -args
опция. Для получения дополнительной информации смотрите Задать входные свойства по примеру в командной строке (MATLAB Coder). Чтобы разрешить переменное количество обнаружений, вы будете использовать coder.typeof
функция для распределения типов данных и размеров для входов.
% Get a sample detection from the stored buffer sampleDetection = detectionBuffer{1}{1}{1}; % Use the coder.typeof function to allow variable-size inputs for % detections. maxNumDets = 500; inputDets = coder.typeof({sampleDetection},[maxNumDets,1],[1 0]); h = msgbox({'Generating code for function. This may take a few minutes...';... 'This message box will close when done.'},'Codegen Message'); % Use the codegen command to generate code by specifying input arguments % via example by using the |-args| option. codegen mexFuser -args {inputDets}; close(h);
Code generation successful.
Можно проверить скорость, достигнутую генерацией кода, сравнив время, затрачиваемое ими на плавление одной системы координат обнаружений
testDetections = addNoise(vertcat(detectionBuffer{1}{1:5}),1); tic;mexFuser(testDetections);t_ML = toc; tic;mexFuser_mex(testDetections);t_Mex = toc; disp(['MATLAB Code Execution time = ',num2str(t_ML)]); disp(['MEX Code Execution time = ',num2str(t_Mex)]);
MATLAB Code Execution time = 27.0929 MEX Code Execution time = 0.3682
В этом разделе для отслеживания используются обнаружения от всех пяти датчиков и используется шум измерения 2 степени в квадрате.
measNoise = 2; % Same noise as 3 sensors
numSensors = 5;
[trackingMetrics,errorMetrics] = helperRunStaticFusionSimulation(detectionBuffer,truthLog,numSensors,measNoise,theaterDisplay,true);
axes(theaterDisplay.TheaterPlot.Parent);
ylim([0 1.5]);
Результаты присвоения от отслеживания с помощью пяти датчиков показывают, что всем истинам был назначен трек в течение всей симуляции. Также не было падений дорожки в симуляции по сравнению с 6 падениями дорожки в низкоточной симуляции трех датчиков.
assignmentTable = trackMetricsTable(trackingMetrics); assignmentTable(:,{'TrackID','AssignedTruthID','TotalLength','FalseTrackStatus'})
ans = 5×4 table TrackID AssignedTruthID TotalLength FalseTrackStatus _______ _______________ ___________ ________________ 1 10 59 false 2 9 59 false 3 8 59 false 4 7 59 false 5 6 59 false
Предполагаемые ошибки для позиций намного ниже для каждой истинной цели по сравнению с симуляцией трех датчиков. Заметьте, что результаты оценки положения и скорости действительно ухудшаются по сравнению с тремя датчиками с высокоточными измерениями.
disp(cumulativeTruthMetrics(errorMetrics))
TruthID posRMS velRMS posANEES velANEES _______ ______ ______ ________ ________ 6 22.362 3.2363 1.5848 0.58334 7 15.024 2.6634 1.613 0.60255 8 22.632 2.7984 2.5508 0.82252 9 24.555 3.4442 2.6984 0.98232 10 24.388 2.7997 1.7192 0.57244
Этот пример показал, как отслеживать объекты с помощью сети распределенных пассивных датчиков. Вы научились использовать staticDetectionFuser
статически ассоциировать и взрывать обнаружения от нескольких датчиков. Пример, продемонстрированный как эта архитектура зависит от параметров, таких как количество датчиков в сети и точность измерений датчика. Пример также показал, как ускорить эффективность с помощью параллельных вычислений и автоматической генерации кода С из кода MATLAB.
trueAssignment
Используйте ObjectAttributes of track, чтобы назначить его правильной истине.
function distance = trueAssignment(track,truth) tIDs = [track.ObjectAttributes.TargetIndex]; tIDs = tIDs(tIDs > 0); if numel(tIDs) > 1 && all(tIDs == truth.PlatformID) distance = 0; else distance = inf; end end
addNoise
Добавьте шум к обнаружениям
function dets = addNoise(dets,measNoise) for i = 1:numel(dets) dets{i}.Measurement(1) = dets{i}.Measurement(1) + sqrt(measNoise)*randn; dets{i}.MeasurementNoise(1) = measNoise; end end
[1] Бар-Шалом, Яаков, Питер К. Виллетт и Синь Тянь. «Отслеживание и слияние данных: справочник алгоритмов». (2011).