Симулируйте, обнаружьте и отследите аномалии в приземляющемся подходе

Пример показывает, как автоматически обнаружить отклонения и аномалии в самолете, делающем итоговые подходы к взлетно-посадочной полосе аэропорта. В этом примере вы смоделируете идеальную траекторию подхода приземления и сгенерируете варианты от него, симулируете радарные дорожки и предупреждения о проблемах, как только дорожки отклоняются от безопасных правил приземления.

Введение

Приземление является критической стадией безопасности рейса. Самолет в итоговом подходе к приземлению должен выровнять себя со взлетно-посадочной полосой, постепенно убывать к земле и уменьшать ее скорость относительно земли при хранении его безопасно выше скорости останова. Все эти шаги выполнены, чтобы гарантировать, что самолет касается земли мягко, чтобы снизить риск для пассажиров и избежать физического повреждения к самолету или взлетно-посадочной полосе. Эти правила могут быть легко заданы профессионалом авиации, или они могут быть выведены из отслеживания данных с помощью машинного обучения [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 Системный объект.

Ссылки

  1. Радж Дешмах и Инсеок Хван, "Обнаружение аномалии Используя временное основанное на логике изучение для терминальных операций воздушного пространства", форум AIAA SciTech, 2019.

  2. Федеральное управление авиации, "Фактические данные - оборудование Обнаружения Поверхности Аэропорта, Модель 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