В этом примере показано, как имитировать обнаружение и отслеживание с помощью сканирующего моностатического радара. Мы рассмотрим, как настроить статистическую модель радара с механическими и электронными возможностями сканирования, как настроить инструмент управления сценариями для обработки динамики и синхронизации платформы, а также как проверить генерируемые обнаружения и дорожки.
Статистические радиолокационные модели, такие как radarDataGenerator обеспечение ценных данных для разработки радиолокационных систем на ранних этапах. Система моделируется с точки зрения её рабочих характеристик, а минимальный набор параметров используется вместе с устоявшейся теорией для определения того, как эта система будет взаимодействовать со своей средой. Это включает в себя спецификацию основных системных параметров, таких как рабочая частота, полоса пропускания и частота повторения импульсов (PRF), а также важные метрики, такие как угол и разрешение диапазона, частота ложных аварийных сигналов и вероятность обнаружения. Модель РЛС имеет выделенные режимы для моностатической, бистатической и пассивной работы. Основным результатом этой модели являются необработанные данные обнаружения или последовательность обновлений дорожки. Хотя сигналы во временной области не генерируются, эмиттер может указать числовой идентификатор для формы сигнала, который он использует, чтобы можно было рассмотреть соответствующий коэффициент усиления и отклонения сигнала. Обнаружения могут выводиться в кадре радара или в кадре сценария, если принимающий радар знает местоположение и ориентацию передатчика. Дорожки генерируются с использованием одного из множества алгоритмов отслеживания и управления дорожками. Скорость передачи данных обрабатывается спецификацией скорости обновления системы, так что обнаружения генерируются с соответствующей скоростью.
Модель работает в паре с radarScenario генерировать данные обнаружения или отслеживания во времени в динамической среде. Этот объект сценария не только управляет временем моделирования, но и может обрабатывать передачу структур данных между объектами в сцене, когда запрашивается кадр обнаружения или обновления дорожки. Радиолокационный объект установлен на платформе, которая управляет динамикой, такой как положение, скорость и ориентация в кадре сценария. Эти сценарные платформы также могут содержать информацию о сигнатуре, которая описывает, как платформа выглядит для различных типов датчиков. Для наших целей, rcsSignature класс будет использоваться для наделения целевых платформ радиолокационным сечением.
Функциональность сканирования задается самим радаром, и может быть выполнена в механическом или электронном стиле. При механическом сканировании направление указания не может изменяться мгновенно, но ограничено максимальной скоростью вращения по азимуту и отметке. При электронном сканировании такого ограничения нет, и направление сканирования сбрасывается в начале каждого цикла. Радар также может одновременно выполнять механическое и электронное сканирование. На рисунке ниже показана разница в схеме сканирования между этими двумя режимами. Обратите внимание, что в электронном режиме угол сканирования всегда увеличивается, а в механическом - положение сканирования всегда меняется на соседнее положение. Сначала сканирование выполняется по азимуту, потому что это основное направление сканирования, которое является направлением с наибольшим пределом сканирования.

Для этого сценария мы рассмотрим сканирующую радиолокационную систему с антенной, установленной на башне, которая может использоваться для слежения за самолетами. Мы просканируем относительно небольшую область, рассмотрим пару входящих платформ с различными профилями RCS и проверим обнаружение и отслеживание данных. Мы увидим влияние SNR и диапазона на нашу способность делать обнаружения.
Используйте центральную частоту 1 ГГц и полосу пропускания 1,5 МГц, чтобы получить разрешение диапазона около 100 метров. Для моделирования одиночного импульса на позицию сканирования установите частоту обновления равной требуемому PRF. Задайте размер неоднозначности диапазона, чтобы отразить наш выбор PRF, и установите наш верхний предел диапазона в два раза больше размера неоднозначности диапазона, чтобы разрешить обнаружение объектов в первой неоднозначности диапазона.
% Set the seed for repeatability rng(2021); % System parameters c = physconst('lightspeed'); fc = 1e9; % Hz bandwidth = 1.5e6; % Hz prf = 4e3; % Hz updateRate = prf; rangeRes = c/(2*bandwidth); % m rangeAmb = c/(2*prf); % m rangeLims = [0 2*rangeAmb];
Помимо выбора между механическим и электронным режимами сканирования, поведение сканирования контролируется спецификацией пределов обзора и поля зрения (FoV) по азимуту и отметке. FoV состоит из азимута и степени возвышения наблюдаемой области в каждой позиции сканирования, аналогично двухсторонней спецификации ширины луча половинной мощности. Точки сканирования выбирают так, чтобы общая угловая протяженность, определяемая пределом сканирования, покрывалась неперекрывающимися сегментами размером, равным FoV. Пределы обзора задаются в кадре РЛС, который может вращаться от кадра его платформы через MountingAngles собственность.
Мы просканируем +/-20 градусов по азимуту и +/-10 градусов по отметке. Установите FoV на 4 градуса по азимуту и 8 градусов по отметке. Наконец, укажите общее количество выполненных сканирований для моделирования, которое будет определять общее время моделирования.
% Scanning parameters azLimits = [-20 20]; elLimits = [-10 10]; fov = [4;8]; % deg numFullScans = 20; % number of full scans to simulate
Общее количество точек сканирования можно найти следующим образом. Пределы сканирования обозначают минимальный и максимальный углы сканирования, относящиеся к вектору визирования антенны, так что общая площадь, сканированная в одном направлении, больше, чем протяженность пределов сканирования, до половины FoV в этом направлении. Узор всегда представляет собой прямоугольную сетку над az/el.
numScanPointsAz = floor(diff(azLimits)/fov(1)) + 1; numScanPointsEl = floor(diff(elLimits)/fov(2)) + 1; numScanPoints = numScanPointsAz*numScanPointsEl;
Будет использована спецификация углового разрешения отдельно от FoV, которая позволяет моделировать что-то вроде оценки моноимпульсного угла. Это угловое разрешение предназначено для определения нашей способности различать цели. и используется для получения фактической точности угла из нижней границы Крамера-Рао (CRLB) для оценки моноимпульсного угла с таким разрешением. Аналогично, разрешение диапазона определяет минимальный интервал в диапазоне, необходимый для различения двух целей, но фактическая точность измерения диапазона исходит из CRLB для оценки диапазона. Точные измеримые значения могут быть использованы путем отключения шума измерения с помощью HasNoise собственность. Как правило, погрешность измерения не достигает 0 при увеличении SNR без привязки. Это может быть зафиксировано свойствами «смещения», из которых есть по одному для каждого типа измеримых. Для наших целей мы оставим их по умолчанию.
Пусть наше угловое разрешение будет 1/4 FoV в каждом направлении, что позволит нам различать до 16 точечных целей в FoV в одном и том же диапазоне.
angRes = fov/4;
Вместо того, чтобы непосредственно задавать мощность передачи, мощность шума и специфику используемого алгоритма обнаружения, эта радиолокационная модель использует концепцию усиления радиолокационного контура для преобразования целевой RCS и дальности в SNR, которая преобразуется непосредственно в вероятность обнаружения. Коэффициент усиления радиолокационного контура является важным свойством любой радиолокационной системы и вычисляется с опорной целью, которая состоит из опорного диапазона и RCS, и рабочей характеристики приемника (ROC) для заданных вероятностей обнаружения и ложной сигнализации.
Мы используем вероятность обнаружения по умолчанию 90% для эталонной цели на расстоянии 20 км и 0 дБсм. Мы будем использовать частоту ложных аварийных сигналов по умолчанию 1e-6 ложных аварийных сигналов на ячейку разрешения на обновление.
refTgtRange = 20e3; refTgtRCS = 0; detProb = 0.9; faRate = 1e-6;
Давайте построим наш радар, используя параметры, указанные выше. С помощью нижнего предела обзора по высоте установите угол установки тангажа РЛС с ее платформы. Это указывает на наш прицел так, что нижний край области сканирования параллелен земле (то есть ни одна из наших точек сканирования не будет указывать на радар в сторону земли).
pitch = elLimits(1); % mount the antenna rotated upwardsВключить измерения угла возвышения, формирование ложных аварийных сигналов и неоднозначность диапазона с соответствующими Has... собственность. Для моделирования радара, измеряющего только дальность и угол, установите HasRangeRate в значение false. Чтобы получить обнаружения в координатах сценария, наш радар должен знать ориентацию передатчика. Поскольку мы используем моностатический радар, это может быть достигнуто путем включения функции инерциальной навигационной системы (INS) с HasINS собственность.
% Create radar object sensorIndex = 1; % a unique identifier is required radar = radarDataGenerator(sensorIndex,'UpdateRate',updateRate,... 'DetectionMode','Monostatic','ScanMode','Electronic','TargetReportFormat','Detections','DetectionCoordinates','scenario',... 'HasElevation',true,'HasINS',true,'HasRangeRate',false,'HasRangeAmbiguities',true,'HasFalseAlarms',true,... 'CenterFrequency',fc,'Bandwidth',bandwidth,... 'RangeResolution',rangeRes,'AzimuthResolution',angRes(1),'ElevationResolution',angRes(2),... 'ReferenceRange',refTgtRange,'ReferenceRCS',refTgtRCS,'DetectionProbability',detProb,'FalseAlarmRate',faRate,... 'RangeLimits',rangeLims,'MaxUnambiguousRange',rangeAmb,'ElectronicAzimuthLimits',azLimits,'ElectronicElevationLimits',elLimits,... 'FieldOfView',fov,'MountingAngles',[0 pitch 0]);
Предоставленный класс помощника можно использовать для визуализации нашего шаблона сканирования. Этот плоттер также будет использоваться для анимации образца сканирования в цикле моделирования.
scanplt = helperScanPatternDisplay(radar); scanplt.makeOverviewPlot;

Обратите внимание, что наши точки сканирования по азимуту точно соответствуют указанным пределам сканирования по азимуту, в то время как точки сканирования по высотам немного притягиваются, чтобы избежать наложения или избыточности точек сканирования.
Рассчитайте общее количество ячеек разрешения угла дальности для нашей системы и общее количество кадров, которые будут использоваться для обнаружения. Затем мы можем вычислить ожидаемое количество ложных аварийных сигналов, умножив частоту ложных аварийных сигналов на общее количество ячеек разрешения, опрошенных в ходе моделирования.
numResolutionCells = diff(rangeLims)*prod(fov)/(rangeRes*prod(angRes)); numFrames = numFullScans*numScanPoints; % total number of frames for detection expNumFAs = faRate*numFrames*numResolutionCells % expected number of FAs
expNumFAs = 7.9200
Мы будем использовать radarScenario для управления потоком моделирования верхнего уровня. Этот объект предоставляет функциональные возможности для добавления новых платформ и быстрого создания обнаружений из всех объектов датчиков в сценарии. Он также управляет потоком времени в моделировании. Используйте общее количество кадров, вычисленное выше, чтобы найти требуемые StopTimeи для адаптивного обновления времени моделирования на основе скорости обновления объектов в сцене установите скорость обновления сценария равной 0.
% Create scenario stopTime = numFullScans*numScanPoints/prf; scene = radarScenario('StopTime',stopTime,'UpdateRate',0);
Используйте platform создание новых объектов платформы, их добавление в сцену и возврат дескриптора для доступа к свойствам платформы. Каждая платформа имеет уникальный идентификатор, который присваивается сценарием при построении. Для статической платформы необходимо задать только свойство Position. Для моделирования стандартной кинематической траектории с постоянной скоростью используйте kinematicTrajectory и указать положение и скорость.
Давайте создадим две целевые платформы на разных диапазонах, как входящие на разных скоростях, так и под разными углами.
% Create platforms rdrPlat = platform(scene,'Position',[0 0 12]); % place 12 m above the origin tgtPlat(1) = platform(scene,'Trajectory',kinematicTrajectory('Position',[38e3 6e3 10e3],'Velocity',[-380 -50 0])); tgtPlat(2) = platform(scene,'Trajectory',kinematicTrajectory('Position',[25e3 -3e3 1e3],'Velocity',[-280 10 -10]));
Для обеспечения удобных методов обнаружения и автоматического увеличения времени моделирования сценарий должен быть осведомлен о построенном ранее радиолокационном объекте. Для этого установите радар на платформу, заполнив свойство Sensors платформы. Для установки более одного датчика на платформе свойство Sensors может представлять собой массив ячеек объектов датчика.
% Mount radar to platform
rdrPlat.Sensors = radar; rcsSignature может использоваться для задания RCS платформы как функции ракурса. Для простой RCS-подписи просто установите Pattern для скалярного значения. Пусть одна платформа будет 20 дБсм, а другая 4 дБсм, чтобы продемонстрировать разницу в обнаруживаемости.
% Set target platform RCS profiles tgtRCS = [20, 4]; % dBsm tgtPlat(1).Signatures = rcsSignature('Pattern',tgtRCS(1)); tgtPlat(2).Signatures = rcsSignature('Pattern',tgtRCS(2));
Давайте рассмотрим теоретическое SNR, которое можно ожидать для исходящих целей. Поскольку мы используем простую кинематическую траекторию, мы можем вычислить истинное положение и диапазон как таковые:
time = (0:numFrames-1).'/updateRate; tgtPosTruth(:,:,1) = tgtPlat(1).Position + time*tgtPlat(1).Trajectory.Velocity; tgtPosTruth(:,:,2) = tgtPlat(2).Position + time*tgtPlat(2).Trajectory.Velocity; tgtRangeTruth(:,1) = sqrt(sum((tgtPosTruth(:,:,1)-rdrPlat.Position).^2,2)); tgtRangeTruth(:,2) = sqrt(sum((tgtPosTruth(:,:,2)-rdrPlat.Position).^2,2));
Затем мы можем использовать известную целевую RCS и коэффициент усиления радиолокационного контура, вычисленный радиолокационной моделью, чтобы получить истинное SNR для каждой цели:
tgtSnr = tgtRCS - 40*log10(tgtRangeTruth) + radar.RadarLoopGain;
Минимальное значение SNR, требуемое для обнаружения с помощью схемы обнаружения только по величине, такой как CFAR, учитывая нашу вероятность обнаружения и частоту ложных аварийных сигналов, равно
minSnr = 20*log10(erfcinv(2*radar.FalseAlarmRate) - erfcinv(2*radar.DetectionProbability)); % dBНемного дальше, мы можем вычислить наш минимальный диапазон для обнаружения:
Rd = 10.^((tgtRCS - minSnr + radar.RadarLoopGain)/40); % metersДавайте сравним средний диапазон и SNR наших целей с минимальным диапазоном и пороговыми значениями SNR. Общая дистанция пути наших целей достаточно мала, чтобы SNR на основе дальности существенно не менялся.
snrMargin = mean(tgtSnr,1) - minSnr
snrMargin = 1×2
8.0827 0.0019
rangeMargin = (Rd - mean(tgtRangeTruth,1))/1e3 % kmrangeMargin = 1×2
23.5299 0.0028
Первая цель примерно на 8 дБ ярче, чем необходимо для обнаружения с заданными параметрами CFAR, в то время как вторая цель считается едва обнаруживаемой.
Цикл первичного моделирования начинается с вызова advance на объекте сценария. Этот метод переводит сценарий в следующий раз, когда определено, что объект в сцене требует обновления, и возвращает значение false при достижении указанного времени остановки, выходя из цикла. Обратите внимание, что первый вызов advance не делает шаг во времени моделирования, так что первый кадр сбора данных может произойти в 0 с. В качестве альтернативы использованию advance, scene.SimulationStatus может быть проверено, чтобы определить, была ли sim запущена до завершения.
Внутри контура методы обнаружения и формирования дорожки могут вызываться для любого объекта датчика по отдельности (см. датчик). step метод), но удобные методы существуют для генерации обнаружений и дорожек для всех датчиков и от всех целей в сцене с одним вызовом функции. Потому что у нас только один датчик, detect(scene) является хорошим решением для получения списка обнаружений для всех целей в сцене. Инициируя генерацию обнаружений на верхнем уровне, как это, сцена сама будет обрабатывать передачу необходимых временных данных, INS и других конфигурационных данных датчику. Класс визуализации, использованный ранее, будет также использоваться здесь для анимации шаблона сканирования.
allDets = []; % initialize list of all detections generated lookAngs = zeros(2,numFrames); simTime = zeros(1,numFrames); frame = 0; % current frame while advance(scene) % advance until StopTime is reached % Increment frame index and record simulation time frame = frame + 1; simTime(frame) = scene.SimulationTime; % Generate new detections dets = detect(scene); % Record look angle for inspection lookAngs(:,frame) = radar.LookAngle; % Update coverage plot scanplt.updatePlot(radar.LookAngle); % Compile any new detections allDets = [allDets;dets]; end

Постройте график записанных углов обзора для первых двух полных сканирований для проверки шаблона. Радар сначала сканирует по азимуту и поднимается на высоту в конце каждого сканирования по азимуту, мгновенно сбрасывая угол обзора в начале каждого нового сканирования.
figure; plot(simTime(1:2*numScanPoints)*1e3,lookAngs(:,1:2*numScanPoints)); xlabel('Time (ms)'); ylabel('Look Angle (deg)'); legend('Azimuth','Elevation'); title('Look Angles');

Давайте проверим содержимое objectDetection на выходе нашего радара.
allDets{1} % look at the first detectionans =
objectDetection with properties:
Time: 7.5000e-04
Measurement: [3x1 double]
MeasurementNoise: [3x3 double]
SensorIndex: 1
ObjectClassID: 0
MeasurementParameters: [1x1 struct]
ObjectAttributes: {[1x1 struct]}
Time - время моделирования, в которое было сгенерировано обнаружение. SensorIndex сообщает нам, каким датчиком было сгенерировано это обнаружение (что важно, когда у нас есть несколько датчиков и мы используем метод обнаружения уровня сцены). Measurement - измеряемое значение, связанное с обнаружением. Формат зависит от выбора нашего режима обнаружения и координат вывода. MeasurementNoise дает дисперсию или ковариацию измерения и используется моделями трекера. Поскольку мы выводим детекции в координатах сценария, поле измерения является просто оценочным вектором положения цели, и шум измерения дает ковариацию этой оценки положения.
ObjectAttributes содержит некоторые полезные метаданные:
allDets{1}.ObjectAttributes{1}ans = struct with fields:
TargetIndex: 3
SNR: 12.5894
Это говорит нам, что обнаружение произошло от платформы с индексом 2, который является уникальным идентификатором, присвоенным сценарием нашей первой целевой платформе (второй платформе, добавляемой к сцене). Мы также видим SNR этого обнаружения о том, что мы ожидали для нашей первой цели. Если обнаружен ложный аварийный сигнал, TargetIndex будет равен -1, что является недопустимым идентификатором платформы. Скомпилировать целевой индекс, SNR и время каждого обнаружения.
detTgtIdx = cellfun(@(t) t.ObjectAttributes{1}.TargetIndex, allDets);
detTgtSnr = cellfun(@(t) t.ObjectAttributes{1}.SNR, allDets);
detTime = cellfun(@(t) t.Time, allDets);
firstTgtDet = find(detTgtIdx == tgtPlat(1).PlatformID);
secondTgtDet = find(detTgtIdx == tgtPlat(2).PlatformID);Общее количество обнаружений ОС можно найти с помощью:
numFAs = numel(find(detTgtIdx==-1))
numFAs = 8
которое близко к ожидаемому количеству ТВС, вычисленному ранее.
Сбор данных измерений по обнаружениям и построение графика вместе с позициями истинности для двух целевых платформ.
tgtPosObs = cell2mat(cellfun(@(t) t.Measurement,allDets,'UniformOutput',0).'); subplot(1,2,1); helperPlotPositionError( tgtPosTruth(:,:,1),time,tgtPosObs(:,firstTgtDet),detTime(firstTgtDet),scene.SimulationTime ); title('Target 1 Position Error'); subplot(1,2,2); helperPlotPositionError( tgtPosTruth(:,:,2),time,tgtPosObs(:,secondTgtDet),detTime(secondTgtDet),scene.SimulationTime ); title('Target 2 Position Error'); set(gcf,'Position',get(gcf,'Position')+[0 0 600 0]);

Большинство наших обнаружений происходит от первой цели, что неудивительно, учитывая анализ обнаруживаемости ранее. Однако он не был обнаружен на каждом кадре, и вторая цель генерировала множество обнаружений, несмотря на низкое SNR. Хотя первая цель легко обнаруживается, ошибка измерения велика, потому что цель находится во втором диапазоне неоднозначности, и не было выполнено никакого определения, в то время как вторая цель, когда она обнаружена, показывает ошибку положения, которая согласуется с разрешением диапазона 100 метров и относительно плохим разрешением угла.
Давайте также посмотрим на общую дисперсию обнаружений против SNR. Общая дисперсия - это сумма предельных дисперсий в каждом декартовом направлении (X, Y и Z). Эта дисперсия включает в себя эффекты оценки в диапазоне-угольном пространстве наряду с преобразованием этих статистических данных в координаты сценария.
detTotVar = cellfun(@(t) trace(t.MeasurementNoise),allDets); figure; subplot(1,2,1); helperPlotPositionTotVar( detTgtSnr(firstTgtDet),detTotVar(firstTgtDet) ); title('First Target'); subplot(1,2,2); helperPlotPositionTotVar( detTgtSnr(secondTgtDet),detTotVar(secondTgtDet) ); title('Second Target'); set(gcf,'Position',get(gcf,'Position')+[0 0 600 0]);

Следует отметить, что хотя абсолютная ошибка положения для первой цели была больше из-за неоднозначности диапазона, более низкая дисперсия измерения отражает как большее SNR первой цели, так и ее, по-видимому, короткий диапазон.
radarDataGenerator также способен выполнять отслеживание с разомкнутым контуром. Вместо вывода объектов обнаружения он может выводить обновления отслеживания.
Давайте снова запустим симуляцию, но на этот раз мы позволим нашей радарной модели непосредственно отслеживать вывод. Во-первых, переустановить некоторые свойства радиолокационной модели для генерации дорожек в кадре сценария.
release(radar); % unlock for re-simulation radar.TargetReportFormat = 'Tracks'; radar.TrackCoordinates = 'Scenario';
Отслеживание может выполняться с помощью ряда различных алгоритмов. Существуют простые альфа-бета-фильтры и фильтры Калмана линейного, расширенного и незаметного разнообразия, а также модели движения с постоянной скоростью, с постоянным ускорением и с постоянным поворотом. Используемый алгоритм указывается с помощью FilterInitializationFcn собственность. Это дескриптор функции или имя функции в символьном векторе, т.е. @initcvekf или 'initcvekf', который принимает начальное обнаружение в качестве входных данных и возвращает инициализированный объект трекера. Можно использовать любую определяемую пользователем функцию с той же самой сигнатурой. Мы будем использовать поставляемый фильтр Калмана с постоянной скоростью.
radar.FilterInitializationFcn = @initcvekf;
Общая структура sim-петли та же, однако мы должны называть радар step функция вручную. Требуемые входные данные представляют собой структуру целевой позы, получаемую вызовом targetPoses на нашей радиолокационной платформе, структура INS, приобретенная вызовом pose на радиолокационной платформе и текущее время моделирования.
restart(scene); % restart scenario allTracks = []; % initialize list of all track data while advance(scene) % Generate new track data tgtPoses = targetPoses(rdrPlat); ins = pose(rdrPlat); tracks = radar(tgtPoses,ins,scene.SimulationTime); % Compile any new track data allTracks = [allTracks;tracks]; end
Проверка объекта дорожки:
allTracks(1) % look at first track updateans =
objectTrack with properties:
TrackID: 1
BranchID: 0
SourceIndex: 1
UpdateTime: 0.0093
Age: 34
State: [6x1 double]
StateCovariance: [6x6 double]
StateParameters: [1x1 struct]
ObjectClassID: 0
TrackLogic: 'History'
TrackLogicState: [1 1 0 0 0]
IsConfirmed: 1
IsCoasted: 0
IsSelfReported: 1
ObjectAttributes: [1x1 struct]
TrackID является уникальным идентификатором файла дорожки, и SourceIndex идентификатор объекта трекера, сообщающего о дорожке, который полезен при наличии нескольких трекеров в сцене. При использовании трекера с несколькими гипотезами BranchID дает индекс используемой гипотезы. State содержит информацию о состоянии этого обновления. Потому что мы используем модель постоянной скорости и координаты дорожки кадра сценария, State состоит из векторов положения и скорости. UpdateTime указывает время, в которое было создано это обновление дорожки. Другое важное свойство, IsCoasted, сообщает вам, если это обновление дорожки использовало новое обнаружение цели для обновления фильтра, или если оно просто распространяется вперед во времени от последнего обнаружения цели (дорожка «покрыта»).
Структура ObjectAttributes дает идентификатор платформы, подпись которой обнаруживается, и SNR этой подписи во время обновления.
allTracks(1).ObjectAttributes
ans = struct with fields:
TargetIndex: 3
SNR: 18.5910
Соберите целевой индекс и время обновления. Также проверьте, сколько обнаружений было использовано для обновления наших треков.
trackTgtIdx = arrayfun(@(t) t.TargetIndex,[allTracks.ObjectAttributes]);
updateTime = [allTracks.UpdateTime];
firstTgtTrack = find(trackTgtIdx == tgtPlat(1).PlatformID);
secondTgtTrack = find(trackTgtIdx == tgtPlat(2).PlatformID);
numUpdates = numel(find(~[allTracks.IsCoasted])) % total number of track updates with new detection datanumUpdates = 31
Это примерно количество обнаружений без учета основных средств, сгенерированных в первой части.
Давайте рассмотрим сообщаемые положения в плоскости XY и их ковариации, а также истинные данные положения. Поскольку первая цель находится в первом диапазоне неоднозначности и не выполняется никакого определения, давайте сначала найдем «истинную» неоднозначную позицию для первой цели как таковой:
los = tgtPosTruth(:,:,1) - rdrPlat.Position; R = sqrt(sum(los.^2,2)); los = los./R; Ramb = mod(R,rangeAmb); tgtPosTruthAmb = rdrPlat.Position + los.*Ramb;
Теперь используйте предоставленную вспомогательную функцию для построения графика визуализации траектории положения.
figure; subplot(1,2,1); helperPlotPositionTrack( tgtPosTruthAmb,allTracks(firstTgtTrack) ); title('First Target Track'); subplot(1,2,2); helperPlotPositionTrack( tgtPosTruth(:,:,2),allTracks(secondTgtTrack) ); title('Second Target Track'); set(gcf,'Position',get(gcf,'Position')+[0 0 600 0]);

В обоих случаях оценки положения начинаются с схождения на истинной (или неоднозначной по диапазону) траектории. Для первой цели у нас есть больше обновлений отслеживания, и конечное состояние появляется ближе к стационарной сходимости. Глядя на контуры ковариации, мы видим ожидаемое начальное уменьшение размера по мере прогрева фильтра слежения.
Чтобы поближе взглянуть на нашу производительность отслеживания, постройте график величины ошибки оценки положения для обеих целей и укажите, какие выборки были обновлены с помощью целевых обнаружений.
figure; subplot(1,2,1); helperPlotPositionTrackError( tgtPosTruthAmb,time,allTracks(firstTgtTrack),updateTime(firstTgtTrack) ); title('First Target Ambiguous Position Error'); subplot(1,2,2); helperPlotPositionTrackError( tgtPosTruth(:,:,2),time,allTracks(secondTgtTrack),updateTime(secondTgtTrack) ); title('Second Target Position Error'); set(gcf,'Position',get(gcf,'Position')+[0 0 600 0]);

Для первой цели ошибка положения уменьшается на образцах, которые имели новое обнаружение для обновления файла дорожки (обозначается красным кругом). Поскольку вторая цель имела гораздо более низкое SNR, ошибка в некоторых индивидуальных обнаружениях была достаточно большой, чтобы увеличить ошибку положения дорожки. Несмотря на это, ошибка положения второй целевой дорожки имеет небольшой нисходящий тренд, указывающий на то, что оценочное состояние, вероятно, сойдется. Однако мы видим проблему с нашей способностью отслеживать первую цель. Поскольку она находится в первом диапазоне неоднозначности и имеет компонент движения, перпендикулярный линии визирования, видимая скорость фактически изменяется, и фильтр Калмана с постоянной скоростью не может сходиться.
В этом примере мы сконфигурировали статистическую радиолокационную систему для использования в моделировании и анализе обнаруживаемости и отслеживаемости цели. Мы посмотрели, как использовать ограничения сканирования и свойства поля зрения для определения шаблона сканирования, как запустить модель радара с помощью инструмента управления сценарием, а также как проверить сгенерированные обнаружения и дорожки.
function helperPlotPositionError( tgtPosTruth,time,tgtPosObs,detTime,T ) tgtPosTruthX = interp1(time,tgtPosTruth(:,1),detTime).'; tgtPosTruthY = interp1(time,tgtPosTruth(:,2),detTime).'; tgtPosTruthZ = interp1(time,tgtPosTruth(:,3),detTime).'; err = sqrt((tgtPosTruthX - tgtPosObs(1,:)).^2+(tgtPosTruthY - tgtPosObs(2,:)).^2+(tgtPosTruthZ - tgtPosObs(3,:)).^2); plot(detTime*1e3,err/1e3,'--o'); grid on; xlim([0 T*1e3]); ylabel('RMS Error (km)'); xlabel('Time (ms)'); end function helperPlotPositionTotVar( detTgtSnr,detTotVar ) plot(detTgtSnr,detTotVar,'--o'); grid on; xlabel('SNR (dB)'); ylabel('Total Var (m^2)'); end function helperPlotPositionTrack( tgtPosTruth,tracks ) plot(tgtPosTruth(:,1)/1e3,tgtPosTruth(:,2)/1e3); hold on; updateIdx = find(~[tracks.IsCoasted]); theta = 0:0.01:2*pi; for ind = 1:2:numel(updateIdx) % plot update T = tracks(updateIdx(ind)); plot(T.State(1)/1e3,T.State(3)/1e3,'*black'); sigma = T.StateCovariance([1 3],[1 3]); [evec,eval] = eigs(sigma); mag = sqrt(diag(eval)).'; u = evec(:,1)*mag(1); v = evec(:,2)*mag(2); x = cos(theta)*u(1) + sin(theta)*v(1); y = cos(theta)*u(2) + sin(theta)*v(2); plot(x/1e3 + T.State(1)/1e3,y/1e3 + T.State(3)/1e3,'magenta'); end hold off; grid on; xlabel('X (km)'); ylabel('Y (km)'); legend('Truth Position','Position Estimates','Covariance','Location','northwest'); end function helperPlotPositionTrackError( tgtPosTruth,time,tracks,updateTime ) state = [tracks.State]; sx = state(1,:); sy = state(3,:); sz = state(5,:); x = interp1(time,tgtPosTruth(:,1),updateTime); y = interp1(time,tgtPosTruth(:,2),updateTime); z = interp1(time,tgtPosTruth(:,3),updateTime); err = sqrt((x-sx).^2+(y-sy).^2+(z-sz).^2); isUpdate = ~[tracks.IsCoasted]; plot(updateTime*1e3,err); hold on; plot(updateTime(isUpdate)*1e3,err(isUpdate),'or'); hold off; grid on; xlabel('Update Time (ms)'); ylabel('Error (m)') legend('Coasted','Update','Location','northwest'); end