Этот пример показывает, как сгенерировать сценарий управления воздушным движением, моделировать радиолокационные обнаружения с радара наблюдения аэропорта (ASR) и сконфигурировать глобальный ближайший соседний трекер (GNN), чтобы отслеживать моделируемые цели с помощью радиолокационных обнаружений. Это позволяет вам оценить различные сценарии цели, требования радара и строений трекера, не нуждаясь в доступе к дорогостоящему самолету или оборудованию. Этот пример охватывает весь рабочий процесс синтетических данных.
Симулируйте башню управления воздушным движением (УВД) и движущиеся цели в сценарии как платформы. Симуляция движения платформ в сценарии управляется trackingScenario
.
Создайте trackingScenario
и добавьте башню УВД к сценарию.
% Create tracking scenario scenario = trackingScenario; % Add a stationary platform to model the ATC tower tower = platform(scenario);
Добавьте радар наблюдения аэропорта (ASR) к башне УВД. Типичная башня УВД имеет установленный в 15 метрах над землей радар. Это радиолокационные обзоры механически по азимуту с фиксированной скоростью для обеспечения покрытия 360 степеней в непосредственной близости от башни УВД. Общие спецификации для ASR перечислены:
Чувствительность: 0 дБсм при 111 км
Механический скан: Только азимут
Скорость механического скана: 12.5 RPM
Электронный скан: Нет
Поле зрения: азимут 1,4 град, повышение 10 град
Азимут Разрешение: 1.4 град
Разрешение в области значений: 135 м
Моделируйте ASR с вышеописанными спецификациями, используя monostaticRadarSensor
.
rpm = 12.5; fov = [1.4;10]; scanrate = rpm*360/60; % deg/s updaterate = scanrate/fov(1); % Hz radar = monostaticRadarSensor(1, 'Rotator', ... 'UpdateRate', updaterate, ... % Hz 'FieldOfView', fov, ... % [az;el] deg 'MaxMechanicalScanRate', scanrate, ... % deg/sec 'AzimuthResolution', fov(1), ... % deg 'ReferenceRange', 111e3, ... % m 'ReferenceRCS', 0, ... % dBsm 'RangeResolution', 135, ... % m 'HasINS', true, ... 'DetectionCoordinates', 'Scenario'); % Mount radar at the top of the tower radar.MountingLocation = [0 0 -15]; tower.Sensors = radar;
Наклоните радар так, чтобы он исследовал область, начинающуюся на 2 степени над горизонтом. Для этого включите повышение и установите пределы механического скана, чтобы охватить поле зрения повышения, начиная с 2 степеней над горизонтом. Потому что trackingScenario
использует координатную систему координат NED, отрицательные повышения соответствуют точкам над горизонтом.
% Enable elevation scanning radar.HasElevation = true; % Set mechanical elevation scan to begin at 2 degrees above the horizon elFov = fov(2); tilt = 2; % deg radar.MechanicalScanLimits(2,:) = [-fov(2) 0]-tilt; % deg
Установите значение поля зрения по повышению немного больше, чем повышение, охватываемое пределами скана. Это препятствует растровому сканированию на повышении и наклоняет радар к точке в середине пределов скана повышения.
radar.FieldOfView(2) = elFov+1e-3;
The monostaticRadarSensor
моделирует область значений и смещение повышения из-за атмосферной преломления. Эти смещения становятся более выраженными на более низких высотах и для целей на больших областях значений. Поскольку индекс преломления изменяется (уменьшается) с высотой, радиолокационные сигналы распространяются вдоль изогнутого пути. Это приводит к радиолокационному наблюдению целей на высотах, превышающих их истинную высоту, и на областях значений, выходящих за пределы их области значений видимости.
Добавьте три лайнера в секторе управления УВД. Один лайнер приближается к УВД с большой области значений, другой отправляется, а третий летит тангенциально к башне. Моделируйте движение этих лайнеров на 60-секундном интервале.
trackingScenario
использует координатную систему координат NED. При определении путевых точек для лайнеров ниже координата z соответствует понижению, поэтому высоты над землей устанавливаются на отрицательные значения.
% Duration of scenario sceneDuration = 60; % s % Inbound airliner ht = 3e3; spd = 900*1e3/3600; % m/s wp = [-5e3 -40e3 -ht;-5e3 -40e3+spd*sceneDuration -ht]; traj = waypointTrajectory('Waypoints',wp,'TimeOfArrival',[0 sceneDuration]); platform(scenario,'Trajectory', traj); % Outbound airliner ht = 4e3; spd = 700*1e3/3600; % m/s wp = [20e3 10e3 -ht;20e3+spd*sceneDuration 10e3 -ht]; traj = waypointTrajectory('Waypoints',wp,'TimeOfArrival',[0 sceneDuration]); platform(scenario,'Trajectory', traj); % Tangential airliner ht = 4e3; spd = 300*1e3/3600; % m/s wp = [-20e3 -spd*sceneDuration/2 -ht;-20e3 spd*sceneDuration/2 -ht]; traj = waypointTrajectory('Waypoints',wp,'TimeOfArrival',[0 sceneDuration]); platform(scenario,'Trajectory', traj);
Создайте trackerGNN
для формирования дорожек от радиолокационных обнаружений, сгенерированных тремя лайнерами. Обновите трекер с обнаружениями, сгенерированными после завершения полного 360 степеней скана по азимуту.
Трекер использует initFilter
поддерживающая функция для инициализации расширенного фильтра Калмана с постоянной скоростью для каждой новой дорожки. initFilter
изменяет фильтр, возвращенный initcvekf
для соответствия целевым скоростям и интервалу обновления трекера.
tracker = trackerGNN( ... 'Assignment', 'Auction', ... 'AssignmentThreshold',50, ... 'FilterInitializationFcn',@initFilter);
Вы используете helperATCMap
для визуализации результатов на верхнюю часть отображения карты. Вы позиционируете источник локальной системы координат North-East-Down (NED), используемой радаром и трекером башни, на позиции аэропорта Логан в Бостоне. Источник расположен на 42.36306 широты и -71.00639 долготы и 50 метрах над уровнем моря. Помощник предоставляет необходимые утилиты для преобразования координат из NED в ориентированную на Землю координатную систему координат, используемую картой.
origin = [42.366978, -71.022362, 50];
mapViewer = helperATCMap('ReferenceLocation',origin);
setCamera(mapViewer, origin + [0 0 1e5]);
showScenario(mapViewer,scenario);
snap(mapViewer);
Следующий цикл совершенствует положения платформы до тех пор, пока не будет достигнут конец сценария. Для каждого шага вперед в сценарии радар генерирует обнаружения от целей в своем поле зрения. Трекер обновляется этими обнаружениями после того, как радар выполнил степень 360 сканов по азимуту.
% Set simulation to advance at the update rate of the radar scenario.UpdateRate = radar.UpdateRate; % Create a buffer to collect the detections from a full scan of the radar scanBuffer = {}; % Initialize the track array tracks = []; % Save visualization snapshots for each scan allsnaps = {}; scanCount = 0; % Set random seed for repeatable results s = rng; rng(2020) while advance(scenario) % Update airliner positions plotTarget(mapViewer, scenario.Platforms([2 3 4])); % Generate detections on targets in the radar's current field of view [dets,config] = detect(scenario); scanBuffer = [scanBuffer;dets]; %#ok<AGROW> % Plot beam and detections plotCoverage(mapViewer,coverageConfig(scenario)) plotDetection(mapViewer,scanBuffer); % Update tracks when a 360 degree scan is complete simTime = scenario.SimulationTime; isScanDone = config.IsScanDone; if isScanDone scanCount = scanCount+1; % Update tracker [tracks,~,~,info] = tracker(scanBuffer,simTime); % Clear scan buffer for next scan scanBuffer = {}; elseif isLocked(tracker) % Predict tracks to the current simulation time tracks = predictTracksToTime(tracker,'confirmed',simTime); end % Update map and take snapshots allsnaps = snapPlotTrack(mapViewer,tracks,isScanDone, scanCount, allsnaps); end allsnaps = [allsnaps, {snap(mapViewer)}];
Отображение первого снимка, сделанного по завершении второго скана радара.
figure imshow(allsnaps{1});
Предыдущий рисунок показывает сценарий в конце второго 360 степеней скана радара. Радиолокационные обнаружения, показанные как светло-синие точки, присутствуют для каждого из моделируемых лайнеров. На данной точке трекер уже обновлен одним полным сканом радара. Внутренне трекер инициализировал дорожки для каждого из лайнеров. Эти треки будут показаны после обновления после этого скана, когда треки будут повышены до подтвержденных, удовлетворяя требованию трекера о подтверждении 2 хитов из 3 обновлений.
Следующие два снимка показывают отслеживание исходящего авиалайнера.
figure imshow(allsnaps{2});
figure imshow(allsnaps{3});
Предыдущие рисунки показывают изображение дорожки до и сразу после обновления трекера после второго скана радара. Обнаружение на рисунке перед обновлением трекера используется для обновления и подтверждения инициализированной дорожки от обнаружения предыдущего скана для этого лайнера. Следующий рисунок показывает положение и скорость подтвержденного трека. Неопределенность оценки положения дорожки показана как серый эллипс. После всего двух обнаружений трекер установил точную оценку положения и скорости исходящего авиалайнера. Истинная высота лайнера составляет 4 км, и он движется на восток со скоростью 700 км/ч.
figure imshow(allsnaps{4});
figure imshow(allsnaps{5});
Состояние пути исходящего авиалайнера покрывается до конца третьего скана и показано на рисунке выше вместе с последним обнаружением для авиалайнера. Заметьте, как неопределенность трека выросла с момента ее обновления на предыдущем рисунке. Дорожка после обновления с обнаружением показана на следующем рисунке. Вы замечаете, что неопределенность положения дорожки уменьшается после обновления. Неопределенность трека растет между обновлениями и уменьшается каждый раз, когда она обновляется новым измерением. Вы также замечаете, что после третьего обновления трасса лежит на верхнюю часть истинного положения авиалайнера.
figure imshow(allsnaps{6});
Окончательный рисунок показывает состояние всех трех трасс авиалайнеров в конце сценария. На каждый из трех лайнеров приходится ровно по одному пути. Одинаковые номера треков присваиваются каждому из лайнеров на протяжении всей длительности, что указывает на то, что ни один из этих треков не был сброшен во время сценария. Оценочные дорожки тесно совпадают с истинным положением и скоростью авиалайнеров.
truthTrackTable = tabulateData(scenario, tracks) %#ok<NOPTS>
truthTrackTable=3×4 table
TrackID Altitude Heading Speed
True Estimated True Estimated True Estimated
_______ _________________ _________________ _________________
"T1" 4000 3874 90 89 700 710
"T2" 4000 3977 0 358 300 293
"T3" 3000 3077 0 0 900 899
Визуализируйте дорожки в 3D, чтобы получить лучшее представление о предполагаемых высотах.
% Reposition and orient the camera to show the 3-D nature of the map camPosition = origin + [0.367, 0.495, 1.5e4]; camOrientation = [0, -17, 235]; %Looking south west, 17 degrees below the horizon setCamera(mapViewer, camPosition, camOrientation);
Рисунок ниже показывает 3-D карту сценария. Можно увидеть моделируемые струи в белых треугольниках с их траекториями, изображенными в виде белых линий. Радиолокационный луч показан в виде синего конуса с голубыми точками, представляющими радиолокационные обнаружения. Дорожки показаны желтым, оранжевым и синим цветом, а их информация указана в их соответствующем цвете. Из-за особенностей 3-D отображения некоторые маркеры могут быть скрыты позади других.
Для получения различных видов сцены можно использовать следующие элементы управления на карте:
Чтобы панорамировать карту, вы левее кликните мышью и перетащите карту.
Чтобы повернуть карту, удерживая кнопку ctrl, вы левее кликните мышью и перетащите карту.
Чтобы масштабировать карту и уменьшить ее, вы используете колесо прокрутки мыши.
snap(mapViewer);
Этот пример показывает, как сгенерировать сценарий управления воздушным движением, моделировать радиолокационные обнаружения с радара наблюдения аэропорта (ASR) и сконфигурировать глобальный ближайший соседний трекер (GNN), чтобы отслеживать моделируемые цели с помощью радиолокационных обнаружений. В этом примере вы узнали, как логика, основанная на истории трекера, продвигает треки. Вы также узнали, как неопределенность дорожки растет, когда дорожка покрыта и уменьшается, когда дорожка обновляется новым обнаружением.
initFilter
Эта функция изменяет функцию initcvekf
для обработки целей более высокой скорости, таких как лайнеры в сценарии УВД.
function filter = initFilter(detection) filter = initcvekf(detection); classToUse = class(filter.StateCovariance); % Airliners can move at speeds around 900 km/h. The velocity is % initialized to 0, but will need to be able to quickly adapt to % aircraft moving at these speeds. Use 900 km/h as 1 standard deviation % for the initialized track's velocity noise. spd = 900*1e3/3600; % m/s velCov = cast(spd^2,classToUse); cov = filter.StateCovariance; cov(2,2) = velCov; cov(4,4) = velCov; filter.StateCovariance = cov; % Set filter's process noise to match filter's update rate scaleAccelHorz = cast(1,classToUse); scaleAccelVert = cast(1,classToUse); Q = blkdiag(scaleAccelHorz^2, scaleAccelHorz^2, scaleAccelVert^2); filter.ProcessNoise = Q; end
tabulateData
Эта функция возвращает таблицу, сравнивающую основную истину и треки
function truthTrackTable = tabulateData(scenario, tracks) % Process truth data platforms = scenario.Platforms(2:end); % Platform 1 is the radar numPlats = numel(platforms); trueAlt = zeros(numPlats,1); trueSpd = zeros(numPlats,1); trueHea = zeros(numPlats,1); for i = 1:numPlats traj = platforms{i}.Trajectory; waypoints = traj.Waypoints; times = traj.TimeOfArrival; trueAlt(i) = -waypoints(end,3); trueVel = (waypoints(end,:) - waypoints(end-1,:)) / (times(end)-times(end-1)); trueSpd(i) = norm(trueVel) * 3600 / 1000; % Convert to km/h trueHea(i) = atan2d(trueVel(1),trueVel(2)); end trueHea = mod(trueHea,360); % Associate tracks with targets atts = [tracks.ObjectAttributes]; tgtInds = [atts.TargetIndex]; % Process tracks assuming a constant velocity model numTrks = numel(tracks); estAlt = zeros(numTrks,1); estSpd = zeros(numTrks,1); estHea = zeros(numTrks,1); truthTrack = zeros(numTrks,7); for i = 1:numTrks estAlt(i) = -round(tracks(i).State(5)); estSpd(i) = round(norm(tracks(i).State(2:2:6)) * 3600 / 1000); % Convert to km/h; estHea(i) = round(atan2d(tracks(i).State(2),tracks(i).State(4))); estHea(i) = mod(estHea(i),360); platID = tgtInds(i); platInd = platID - 1; truthTrack(i,:) = [tracks(i).TrackID, trueAlt(platInd), estAlt(i), trueHea(platInd), estHea(i), ... trueSpd(platInd), estSpd(i)]; end % Organize the data in a table names = {'TrackID','TrueAlt','EstimatedAlt','TrueHea','EstimatedHea','TrueSpd','EstimatedSpd'}; truthTrackTable = array2table(truthTrack,'VariableNames',names); truthTrackTable = mergevars(truthTrackTable, (6:7), 'NewVariableName', 'Speed', 'MergeAsTable', true); truthTrackTable.(6).Properties.VariableNames = {'True','Estimated'}; truthTrackTable = mergevars(truthTrackTable, (4:5), 'NewVariableName', 'Heading', 'MergeAsTable', true); truthTrackTable.(4).Properties.VariableNames = {'True','Estimated'}; truthTrackTable = mergevars(truthTrackTable, (2:3), 'NewVariableName', 'Altitude', 'MergeAsTable', true); truthTrackTable.(2).Properties.VariableNames = {'True','Estimated'}; truthTrackTable.TrackID = "T" + string(truthTrackTable.TrackID); end
snapPlotTrack
Эта функция обрабатывает перемещение mapViewer
фотоаппарат, создание соответствующих снимков и обновление треков визуализации.
function allsnaps = snapPlotTrack(mapViewer,tracks,isScanDone, scanCount,allsnaps) % Save snapshots during first 4 scans if isScanDone && any(scanCount == [2 3]) allsnaps = [allsnaps, {snap(mapViewer)}]; %move camera if scanCount == 2 % Show the outbound airliner setCamera(mapViewer, [42.5650 -70.8990 7e3]); allsnaps = [allsnaps, {snap(mapViewer)}]; end end % Update display with current track positions plotTrack(mapViewer,tracks); if isScanDone && any(scanCount == [2 3]) % Take a snapshot of confirmed track allsnaps = [allsnaps, {snap(mapViewer)}]; % Reset Camera view to full scene if scanCount == 3 origin = [42.366978, -71.022362, 50]; setCamera(mapViewer, origin + [0 0 1e5]); end end end