Пример показывает, как автоматически обнаружить отклонения и аномалии в самолете, делающем итоговые подходы к взлетно-посадочной полосе аэропорта. В этом примере вы смоделируете идеальную траекторию подхода приземления и сгенерируете варианты от него, симулируете радарные дорожки и предупреждения о проблемах, как только дорожки отклоняются от безопасных правил приземления.
Приземление является критической стадией безопасности рейса. Самолет в итоговом подходе к приземлению должен выровнять себя со взлетно-посадочной полосой, постепенно убывать к земле и уменьшать ее скорость относительно земли при хранении его безопасно выше скорости останова. Все эти шаги выполнены, чтобы гарантировать, что самолет касается земли мягко, чтобы снизить риск для пассажиров и избежать физического повреждения к самолету или взлетно-посадочной полосе. Эти правила могут быть легко заданы профессионалом авиации, или они могут быть выведены из отслеживания данных с помощью машинного обучения [1]. В этом примере вы принимаете, что правила уже заданы.
Крупнейшие аэропорты обычно имеют несколько взлетно-посадочных полос, ориентированных в различных направлениях. Приближающиеся самолеты ведутся авиадиспетчерами в башне аэропорта, чтобы приземлиться на одну из взлетно-посадочных полос, которая лучше всего выравнивается против направления ветра в то время. Во время подхода контроллеры контролируют самолет на основе систем слежения. Трафик аэропорта увеличился за прошлые десятилетия и с ним, рабочая нагрузка на авиадиспетчерах увеличилась также. В результате существует потребность к автоматически и надежно внимательные авиадиспетчеры к самолетам, которые приближаются к приземляющейся точке небезопасным способом: не выровненный хорошо со взлетно-посадочной полосой, убывая слишком быстро или слишком медленно, или приближаясь слишком быстро или слишком медленно.
Вы задаете приземляющуюся траекторию подхода в международный аэропорт Логан в Бостоне, MA с помощью geoTrajectory
объект. Траектория waypoints выравнивается со взлетно-посадочной полосой 22L, который запускается с северо-востока на юго-запад и наклона скольжения 3 градусов. Время прибытия и скороподъемность заданы, чтобы замедлить приближающийся самолет к безопасной скорости и сглаженному приземлению. Обратите внимание на то, что положительное значение скороподъемности используется для нисходящей траектории. Вы используете helperPertScenarioGlobeViewer
(см. вспомогательный файл) визуализировать траекторию на карте.
baselineApproachTrajectory = geoTrajectory([42.7069 -70.8395 1500; 42.5403 -70.9203 950; 42.3736 -71.001 0],[0;180;400],... 'ClimbRate', [6; 3.75; 3.75]); viewer = helperPertScenarioGlobeViewer; viewer.TargetHistoryLength = 0; viewer.TrackHistoryLength = 0; viewer.TrackLabelScale = 0.75; positionCamera(viewer, [42.3072 -70.8463 12455], [0 -34 335]); plotTrajectory(viewer, baselineApproachTrajectory, 'Color', [15 255 255]/255, "Width", 1);
Для траектории, прибывающей, чтобы приземлиться в аэропорту Логана на взлетно-посадочную полосу 22L, чтобы быть безопасной, траектория должна удовлетворить следующим правилам:
Траектория должна быть практически выровнена с направлением взлетно-посадочной полосы.
Наклон скольжения должен быть между 2,5 и 4 градусами в области последних 20 963 метров. На расстояниях выше 20 963 метров высота должна составить по крайней мере 3 000 футов.
Скорость должна быть между 120 узлами и 180 узлами в приземляющейся точке. Верхняя связанная скорость может увеличиться линейно с расстоянием от приземляющейся точки.
Вы задаете эти правила с помощью helperTrajectoryValidationRule
(см. вспомогательный файл), и визуализируйте правила о карте.
% Define and show trajectory rules.
trajRules = defineTrajectoryRules();
showRules(viewer, trajRules)
snap(viewer)
Вы используете perturbations
возразите функции, чтобы задать нормальное распределение вокруг базовой траектории, approachTrajectory
. Каждый waypoint в траектории встревожен с нулевым средним нормальным распределением и стандартным отклонением, которое становится меньшим сначала waypoint к последнему (приземляющаяся точка). В первом waypoint стандартное отклонение является 5e-3 степенями в области долготы и 300 метрами в высоте. Стандартное отклонение уменьшается до 1e-3 степеней в области долготы и 150 метров в высоте в средней точке и затем до 1e-4 степеней в области долготы и 0 в высоте в конечной точке на земле.
% Define perturbation to the approach trajectory perturbations(baselineApproachTrajectory, 'Waypoints', 'Normal', zeros(3,3), [0 5e-3 300; 0 1e-3 150; 0 1e-4 0]);
Создать 20 траекторий, которые встревожены от базовой траектории, первого clone
траектория и затем perturb
\it.
% Generate perturbed trajectories s = rng(2021, 'twister'); % Set random noise generator for repeatable results numTrajectories = 20; trajectories = cell(1,numTrajectories); for i = 1:numTrajectories trajectories{i} = clone(baselineApproachTrajectory); perturb(trajectories{i}); end
Чтобы видеть, который встревожил траектории, удовлетворяют правилам безопасного подхода к приземлению, вы используете функцию помощника validateTrajectory
, если в нижней части этой страницы. Функция объявляет, что траектория является аномальной, если по крайней мере 1% точек, произведенных от нее, нарушает правило траектории.
[truthAnomalyFlags, truthPercentAnomalousSteps] = validateTrajectory(trajectories, trajRules);
Постройте траектории желтого цвета для аномальных траекторий и голубой для безопасных подходов. В целом, существует 7 аномальных траекторий из 20 сгенерированных траекторий.
plotTrajectory(viewer, trajectories(truthAnomalyFlags), 'Color', [255 255 17]/255, "Width", 1); plotTrajectory(viewer, trajectories(~truthAnomalyFlags), 'Color', [15 255 255]/255, "Width", 1); positionCamera(viewer, [42.4808 -70.916 1136], [0 0 340]); snap(viewer)
Обнаружение аномалий в режиме реального времени на основе отслеживания данных является проблемой по нескольким причинам. Во-первых, поскольку данные об отслеживании несовершенны с шумом, результаты отслеживания сомнительны. В результате некоторые допуски должны быть обеспечены, чтобы не выдавать ложные предупреждения. Во-вторых, датчики сообщают о ложных обнаружениях, и система слежения должна бояться подтверждать дорожки на основе этих ложных обнаружений. Тщательное подтверждение требует, чтобы система слежения заняла больше времени, чтобы подтвердить дорожки. Чтобы избежать чрезмерных предупреждений на ложных дорожках, вы предупреждения о проблемах только после, дорожка подтверждена.
Вы задаете сосредоточенный Землей сценарий отслеживания.
% Create an Earth-centered tracking scenario scenario = trackingScenario('UpdateRate', 1, 'IsEarthCentered', true);
Приближение самолета, приземляющееся в аэропорту, как планируют, избежит аэродинамического удара от одного самолета на том после по его следу. Минимальная безопасная разница во времени между двумя самолетами является одной минутой.
Вы используете perturbations
и perturb
возразите функционирует снова, чтобы встревожить TimeOfArrival
из каждой траектории и не убедиться никакие дополнительные возмущения не применяются к Waypoints
. Затем вы присоединяете каждую траекторию к новой платформе. Чтобы встревожить целый сценарий, вы используете perturb
объектная функция.
% Schedule the trajectories and attach each to a platform. for i = 1:numTrajectories perturbations(trajectories{i}, 'TimeOfArrival', 'Uniform',(i-1)*60, (i-1)*60+10); perturbations(trajectories{i}, 'Waypoints', 'None'); platform(scenario, 'Trajectory', trajectories{i}); end perturb(scenario);
Как другие крупнейшие аэропорты в США, Логан использует оборудование Обнаружения Поверхности Аэропорта - Модель X (ASDE-X), чтобы отследить самолет во время итогового подхода и на земле [2]. ASDE-X использует радар наблюдения аэропорта, автоматический зависимый, широковещательно переданный наблюдением (ADS–B) отчеты от приближающегося самолета и другие методы, чтобы обеспечить точное отслеживание, которое обновляется каждую секунду (для получения дополнительной информации, см. [1]).
Чтобы упростить модель этой системы слежения, вы используете статистическую радарную модель, fusionRadarSensor
, присоединенный к башне аэропорта и подключению датчик к trackerGNN
объект. Вы конфигурируете средство отслеживания, чтобы быть консервативными о подтверждении дорожек путем установки ConfirmationThreshold
подтвердить, получает ли дорожка 4 5 обновлений.
asdex = fusionRadarSensor(1, ... 'ScanMode', 'No Scanning', ... 'MountingAngles', [0 0 0], ... 'FieldOfView', [360;20], ... 'UpdateRate', 1, ... 'ReferenceRange', 40000,... 'RangeLimits', [0 50000], ... 'RangeResolution', 100, ... 'HasElevation', true, ... 'HasINS', true, ... 'DetectionCoordinates', 'Scenario', ... 'FalseAlarmRate', 1e-7, ... 'ElevationResolution', 0.4, ... 'AzimuthResolution', 0.4); p = platform(scenario, 'Position', [42.3606 -71.011 0], 'Sensors', asdex); tracker = trackerGNN("AssignmentThreshold", [100 2000], "ConfirmationThreshold", [4 5]); tam = trackAssignmentMetrics('AssignmentThreshold', 100, 'DivergenceThreshold', 200);
В следующих линиях вы симулируете сценарий и отслеживаете приближающийся самолет. Вы используете validateTracks
функция помощника, чтобы сгенерировать предупреждения аномалии для дорожек. Вы видите код для функции в нижней части этой страницы.
Дорожки, которые нарушают безопасные правила подхода, отображают желтым, в то время как дорожки, которые следуют этим правилам, отображают голубым цветом. Обратите внимание на то, что предупреждение выдано сразу, когда дорожка нарушает любое правило и удалена, когда это удовлетворяет всем правилам.
% Clean the display and prepare it for the simulation. clear(viewer) positionCamera(viewer, [42.3072 -70.8463 12455], [0 -34 335]); showRules(viewer, trajRules) clear validateTracks % Main loop while advance(scenario) % Collect detections dets = detect(scenario); % Update the tracker and output tracks. if ~isempty(dets) || isLocked(tracker) tracks = tracker(dets, scenario.SimulationTime); else tracks = objectTrack.empty; end % Get platform poses and assignment between tracks and truths. poses = platformPoses(scenario,"Quaternion","CoordinateSystem","Cartesian"); tam(tracks,poses); [assignedTrackIDs, assignedTruthIDs] = currentAssignment(tam); % Validate the tracks with rules to find anomalous tracks. [tracks, trackAnomalyHistory] = validateTracks(tracks, trajRules, assignedTrackIDs, assignedTruthIDs); % Visualize updateDisplay(viewer,scenario.SimulationTime,[scenario.Platforms{:}],dets,[],tracks); end
Следующий gif был взят когда в течение минуты симуляции от этих 900 секунд до этих 960 секунд. Это показывает дорожки, идентифицированные столь же безопасный в голубом цвете, и отслеживает идентифицированный как аномальный в желтом. Эта идентификация сделана в каждом шаге симуляции как видно для дорожки 1893.
Чтобы проверить, что предупреждения аномалии были выданы для правильных дорожек, вы используете analyze
функция помощника, показанная в нижней части этой страницы.
Функция использует trackAnomalyHistory
собранный во время симуляции и сравнивает его с truthPercentAnomalousSteps
вычисленный для каждой траектории. Подобно истине дорожки являются присвоенными флагами аномалии, если они были объявлены аномальным по крайней мере 1% временных шагов. Вы видите, что аномалии выпущены правильно для семи траекторий, которые, как находили, были аномальными.
comparisonTable = analyze(trackAnomalyHistory ,truthPercentAnomalousSteps); disp(comparisonTable)
TruthID Truth Anomaly Flag Track Anomaly Flag _______ __________________ __________________ 1 false false 2 false false 3 false false 4 false false 5 false false 6 false false 7 true true 8 true true 9 false false 10 true true 11 false false 12 false false 13 true true 14 true true 15 false false 16 false false 17 false false 18 false false 19 true true 20 true true
В этом примере вы изучили, как использовать данные об отслеживании, чтобы сгенерировать предупреждения в реальном времени для аномалий как небезопасный подход приземления.
Вы использовали geoTrajectory
чтобы задать идеальное приземление приближаются к траектории в географических координатах. Вы затем использовали perturbations
и perturb
создать 20 траекторий, которые отклоняются от идеальной траектории подхода приземления и запланировать траектории один за другим в trackingScenario
. Чтобы смоделировать систему слежения аэропорта, вы упростили системную модель с помощью статистической радарной модели fusionRadarSensor
Системный объект и средство отслеживания, trackerGNN
Системный объект.
Радж Дешмах и Инсеок Хван, "Обнаружение аномалии Используя временное основанное на логике изучение для терминальных операций воздушного пространства", форум AIAA SciTech, 2019.
Федеральное управление авиации, "Фактические данные - оборудование Обнаружения Поверхности Аэропорта, Модель X (ASDE-X)". https://www.faa.gov/news/fact_sheets/news_story.cfm? newsId=17095 получил май 2020.
defineTrajectoryRules Задают правила траектории
function trajRules = defineTrajectoryRules % This function defines rules for safe approach to landing on runway 22L at % Logan International Airport in Boston, MA. % The function uses the helperTrajectoryValidationRule attached as a % supporting file to this example % The trajectory must be closely aligned with the runway direction. longitudeRule = helperTrajectoryValidationRule([42.37 42.71], [0.4587, -90.4379], [0.5128, -92.730]); % The glide slope must be between 2.5 and 4 degrees in the last 20963 % meters. At distances above 20963 meters, the altitude must be at least % 3000 ft. The rules are relative to range from the runway landing point. altitudeRule1 = helperTrajectoryValidationRule([100 20963], [sind(2.5) 0], [sind(4) 0]); altitudeRule2 = helperTrajectoryValidationRule([20963 40000], 3000 * 0.3048, [sind(4) 0]); % The speed must be between 120 knots and 180 knots at the landing point. % The upper speed bound can increase linearly with distance from the % landing point. speedRule = helperTrajectoryValidationRule([0 40000], 61.733, [1e-3 100]); % Collect all the rules. trajRules = [longitudeRule;altitudeRule1;altitudeRule2;speedRule]; end
validateTrajectory Подтверждают каждую траекторию
function [truthAnomalyFlags, percentAnomalousSteps] = validateTrajectory(trajectories, rules) numTrajectories = numel(trajectories); numAnomalousSteps = zeros(1, numTrajectories); for tr = 1:numTrajectories if iscell(trajectories) traj = trajectories{tr}; elseif numTrajectories == 1 traj = trajectories; else traj = trajectories(tr); end timesamples = (traj.TimeOfArrival(1):traj.TimeOfArrival(end)); [pos,~,vel] = lookupPose(traj, timesamples); posECEF = lookupPose(traj, timesamples, 'ECEF'); landingPoint = [1.536321 -4.462053 4.276352]*1e6; for i = 1:numel(timesamples) distance = norm(posECEF(i,:) - landingPoint); isLongitudeValid = validate(rules(1),pos(i,1),pos(i,2)); isAltitudeValid = (validate(rules(2),distance,pos(i,3)) && validate(rules(3),distance,pos(i,3))); isSpeedValid = validate(rules(4),distance,norm(vel(i,:))); isValid = isLongitudeValid && isAltitudeValid && isSpeedValid; numAnomalousSteps(tr) = numAnomalousSteps(tr) + ~isValid; end end percentAnomalousSteps = numAnomalousSteps ./ numel(timesamples) * 100; truthAnomalyFlags = (percentAnomalousSteps > 1); end
validateTrack Подтверждают дорожки по сравнению с правилами аномалии
function [tracks, history] = validateTracks(tracks, rules, assignedTrackIDs, assignedTruthIDs) persistent trackAnomalyHistory if isempty(trackAnomalyHistory) trackAnomalyHistory = repmat(struct('TrackID', 0, 'AssignedTruthID', 0, 'NumSteps', 0, 'NumAnomalousSteps', 0),30,1); end posECEF = getTrackPositions(tracks, [1 0 0 0 0 0; 0 0 1 0 0 0; 0 0 0 0 1 0]); pos = fusion.internal.frames.ecef2lla(posECEF); vel = getTrackVelocities(tracks, [0 1 0 0 0 0; 0 0 0 1 0 0; 0 0 0 0 0 1]); numTracks = numel(tracks); landingPoint = [1.536321 -4.462053 4.276352]*1e6; trackIDs = [trackAnomalyHistory.TrackID]; for tr = 1:numTracks % Only validate tracks if altitude is greater than 0 if pos(tr,3) > 15 distance = norm(posECEF(tr,:) - landingPoint); isLongitudeValid = validate(rules(1),pos(tr,1),pos(tr,2)); isAltitudeValid = (validate(rules(2),distance,pos(tr,3)) && validate(rules(3),distance,pos(tr,3))); isSpeedValid = validate(rules(4),distance,norm(vel(tr,:))); isValid = isLongitudeValid && isAltitudeValid && isSpeedValid; else isValid = true; end tracks(tr).ObjectClassID = uint8(~isValid) + uint8(isValid)*6; % To get the right color for tracks % Update anomlay history inHistory = (tracks(tr).TrackID == trackIDs); if any(inHistory) trackAnomalyHistory(inHistory).NumSteps = trackAnomalyHistory(inHistory).NumSteps + 1; trackAnomalyHistory(inHistory).NumAnomalousSteps = trackAnomalyHistory(inHistory).NumAnomalousSteps + ~isValid; else ind = find(trackIDs == 0, 1, 'first'); trackAnomalyHistory(ind).AssignedTruthID = assignedTruthIDs(tracks(tr).TrackID == assignedTrackIDs); trackAnomalyHistory(ind).TrackID = tracks(tr).TrackID; trackAnomalyHistory(ind).NumSteps = 1; trackAnomalyHistory(ind).NumAnomalousSteps = ~isValid; end end history = trackAnomalyHistory; end
анализируйте - Анализируют историю аномалии дорожки и сравнивают его с процентом аномалии истины
function comparisonTable = analyze(trackAnomalyHistory, percentTruthAnomalous) trackAnomalyHistory = trackAnomalyHistory([trackAnomalyHistory.TrackID] > 0); anomalousSteps = [trackAnomalyHistory.NumAnomalousSteps]; numSteps = [trackAnomalyHistory.NumSteps]; trackAssignedTruths = [trackAnomalyHistory.AssignedTruthID]; assignedTruths = unique(trackAssignedTruths); numTrackAnomalousSteps = zeros(numel(assignedTruths),1); numTrackSteps = zeros(numel(assignedTruths),1); for i = 1:numel(assignedTruths) inds = (assignedTruths(i) == trackAssignedTruths); numTrackAnomalousSteps(i) = sum(anomalousSteps(inds)); numTrackSteps(i) = sum(numSteps(inds)); end percentTrackAnomalous = numTrackAnomalousSteps ./ numTrackSteps * 100; trueAnomaly = (percentTruthAnomalous > 1)'; anomalyFlags = (percentTrackAnomalous > 1); comparisonTable = table((1:20)',trueAnomaly, anomalyFlags,... 'VariableNames', {'TruthID', 'Truth Anomaly Flag', 'Track Anomaly Flag'}); end