В этом примере показано, как использовать управление радиолокационными ресурсами для эффективного отслеживания нескольких маневрирующих целей. Сопровождение маневрирующих целей требует от РЛС более частого повторного захода на цели, чем сопровождение маневрирующих целей. Фильтр взаимодействия с несколькими моделями (IMM) оценивает, когда цель маневрирует. Эта оценка помогает управлять временем повторного посещения радара и, следовательно, улучшает отслеживание. В этом примере используется Toolbox™ радара для модели радара и Toolbox™ слияния и отслеживания датчиков для отслеживания.
Многофункциональные РЛС могут искать цели, подтверждать новые дорожки и повторно посещать дорожки для обновления состояния. Для выполнения этих функций многофункциональный радар часто управляется менеджером ресурсов, который создает радиолокационные задачи для поиска, подтверждения и слежения. Эти задачи планируются в соответствии с приоритетом и временем, так что на каждом шаге времени многофункциональный радар может указывать свой луч в нужном направлении. Пример планирования поиска и отслеживания для многофункционального радиолокатора с фазированной решеткой показывает многофункциональный радиолокатор с фазированной решеткой, управляемый менеджером ресурсов.
В этом примере мы распространяем пример адаптивного слежения за маневрирующими целями с управляемым радаром на случай множественных маневрирующих целей. Существует два противоречивых требования к радару, используемому для слежения за маневрирующими целями:
Количество целей и их начальное местоположение, как правило, не известны заранее. Поэтому радар должен постоянно искать интересующую область, чтобы найти цели. Кроме того, радар должен обнаруживать и устанавливать путь на каждой цели, как только она попадает в зону действия радара.
Временной период маневрирования цели заранее неизвестен. Если известно, что цели не маневрируют, радар может возвращаться к целям нечасто. Однако, поскольку время начала и окончания маневра неизвестно, радар должен достаточно часто посещать каждую трассу, чтобы быть в состоянии распознать, когда маневр начинается и заканчивается.
Радар должен балансировать между обеспечением достаточного количества лучей, центрированных на отслеживаемых целях, и оставлением достаточного времени для поиска новых целей. Один из подходов заключается в том, чтобы просто определить скорость повторного посещения каждой отслеживаемой цели независимо от ее статуса маневрирования и оставить оставшееся время для поиска новой цели. Эту схему управления РЛС иногда называют активным отслеживанием [1]. По мере отслеживания большего числа целей радар может либо выполнять меньшее количество поисковых задач, либо отслеживать каждую цель реже. Очевидно, что если количество целей велико, радар может быть переполнен.
Активное отслеживание обрабатывает все дорожки одинаково, что делает его алгоритмом управления ресурсами на основе режима. Более сложный способ управления РЛС основан на свойствах каждого пути. Например, используйте свойства дорожки, такие как размер ковариации неопределенности состояния, маневрирует ли трасса и насколько быстро она движется к активу, защищаемому радиолокационным узлом. При использовании таких свойств управление радиолокационными ресурсами называется адаптивным отслеживанием [1].
В этом примере сравниваются результаты активного и адаптивного слежения, когда радар адаптируется на основе расчетного маневра пути.
Вы определяете сценарий и радар с частотой обновления 20 Гц, что означает, что радар имеет 20 лучей в секунду, выделенных для поиска, подтверждения или отслеживания. Загружаются траектории эталонного теста, используемые в примере «Траектории эталонного теста для многообъектного отслеживания» (Sensor Fusion and Tracking Toolbox). Существует шесть эталонных траекторий, и вы определяете траекторию для каждой из них. На рисунке ниже шесть платформ следуют за неманевренными ногами вперемежку с маневрирующими ногами. Траектории можно просмотреть на рисунке ниже.
% Create scenario updateRate = 20; scenario = trackingScenario('UpdateRate',updateRate); % Add the benchmark trajectories load('BenchmarkTrajectories.mat','-mat'); platform(scenario,'Trajectory',v1Trajectory); platform(scenario,'Trajectory',v2Trajectory); platform(scenario,'Trajectory',v3Trajectory); platform(scenario,'Trajectory',v4Trajectory); platform(scenario,'Trajectory',v5Trajectory); platform(scenario,'Trajectory',v6Trajectory); % Create visualization f = figure; mp = uipanel('Parent',f,'Title','Theater Plot','FontSize',12,... 'BackgroundColor','white','Position',[.01 .25 .98 .73]); tax = axes(mp,'ZDir','reverse'); % Visualize scenario thp = theaterPlot('Parent',tax,'AxesUnits',["km","km","km"],'XLimits',[0 85000],'YLimits',[-45000 70000],'ZLimits',[-10000 1000]); plp = platformPlotter(thp, 'DisplayName', 'Platforms'); pap = trajectoryPlotter(thp, 'DisplayName', 'Trajectories', 'LineWidth', 1); dtp = detectionPlotter(thp, 'DisplayName', 'Detections'); cvp = coveragePlotter(thp, 'DisplayName', 'Radar Coverage'); trp = trackPlotter(thp, 'DisplayName', 'Tracks', 'ConnectHistory', 'on', 'ColorizeHistory', 'on'); numPlatforms = numel(scenario.Platforms); trajectoryPositions = cell(1,numPlatforms); for i = 1:numPlatforms trajectoryPositions{i} = lookupPose(scenario.Platforms{i}.Trajectory,(0:0.1:185)); end plotTrajectory(pap, trajectoryPositions); view(tax,3)

Радар определяется с помощью helperManagedRadarDataGenerator , который является объектом, наследуемым от radarDataGenerator Системный объект. helperManagedRadarDataGenerator обеспечивает вероятностную модель РЛС и позволяет наводить РЛС на определённое направление. Эта настройка позволяет диспетчеру радиолокационных ресурсов планировать радар для поиска, подтверждения и слежения за целями. Радар моделирует электронные лучи, имеющие азимутальные пределы обзора [-90 60] градусов и высотные пределы [-9,9 0] градусов. Отрицательные углы возвышения означают, что РЛС указывает луч от горизонта вверх. Установите радар на новую платформу в сценарии.
radar = helperManagedRadarDataGenerator(1, ... 'ScanMode', 'Electronic', ... 'UpdateRate', updateRate, ... 'MountingLocation', [0 0 -15], ... 'FieldOfView', [3;10], ... 'AzimuthResolution', 1.5, ... 'ElectronicAzimuthLimits', [-90 60], ... 'ElectronicElevationLimits', [-9.9 0], ... 'HasElevation', true, ... 'DetectionCoordinates', 'Sensor spherical'); platform(scenario,'Position',[0 0 0],'Sensors',radar);
После того, как радар обнаруживает объекты, он подает обнаруженные объекты на трекер, который выполняет несколько операций. Трекер поддерживает список дорожек, которые являются оценками целевых состояний в интересующей области. Если обнаружение не может быть назначено какой-либо дорожке, уже поддерживаемой трекером, трекер инициирует новую дорожку. В большинстве случаев неясно, представляет ли новая дорожка истинную цель или ложную цель. Сначала создается трек с предварительным статусом. Если получено достаточно обнаружений, дорожка становится подтвержденной. Аналогично, если дорожке не назначено никаких обнаружений, дорожка покрывается (прогнозируется без коррекции). Если дорожка имеет несколько пропущенных обновлений, трекер удаляет дорожку.
В этом примере используется трекер, который связывает обнаружения с дорожками с помощью глобального алгоритма ближайшего соседа (GNN). Для отслеживания маневрирующих целей необходимо определить FilterInitializationFcn инициализирует фильтр Interacting Multiple Model (IMM). initMPARIMM функция использует две модели движения: модель постоянной скорости и модель скорости постоянного поворота. trackingIMM (Sensor Fusion and Tracking Toolbox) фильтр отвечает за оценку вероятности каждой модели, доступ к которой можно получить из ее ModelProbabilities собственность. В этом примере цель классифицируется как маневрирующая, когда вероятность модели скорости с постоянным поворотом выше 0,6.
tracker = trackerGNN('FilterInitializationFcn',@initMPARIMM,... 'ConfirmationThreshold',[2 3], 'DeletionThreshold',[5 5],... 'HasDetectableTrackIDsInput',true,'AssignmentThreshold',150,... 'MaxNumTracks',10,'MaxNumSensors',1); posSelector = [1 0 0 0 0 0; 0 0 1 0 0 0; 0 0 0 0 1 0];
В этом разделе кратко описывается управление радиолокационными ресурсами. Дополнительные сведения см. в примере Адаптивное отслеживание маневрирующих целей с управляемым радиолокатором.
Задачи поиска
В этом примере задания поиска присваиваются детерминированно. Растровое сканирование используется для покрытия требуемого воздушного пространства. Если других задач не существует, радар сканирует пространство по одной угловой ячейке за раз. Размер угловой ячейки определяется радаром FieldOfView свойство и ограничено радиолокатором ElectronicAzimuthLimits и ElectronicElevatonLimits свойства.
azscanspan = diff(radar.ElectronicAzimuthLimits); numazscan = floor(azscanspan/radar.FieldOfView(1))+1; azscanangles = linspace(radar.ElectronicAzimuthLimits(1),radar.ElectronicAzimuthLimits(2),numazscan)+radar.MountingAngles(1); elscanspan = diff(radar.ElectronicElevationLimits); numelscan = floor(elscanspan/radar.FieldOfView(2))+1; elscanangles = linspace(radar.ElectronicElevationLimits(1),radar.ElectronicElevationLimits(2),numelscan)+radar.MountingAngles(2); [elscangrid,azscangrid] = meshgrid(elscanangles,azscanangles); scanangles = [azscangrid(:) elscangrid(:)].'; searchq = struct('JobType','Search','BeamDirection',num2cell(scanangles,1),... 'Priority',1000,'WaveformIndex',1); current_search_idx = 1;
Отслеживать задачи
В отличие от задач поиска, задачи отслеживания нельзя планировать заранее. Вместо этого менеджер ресурсов создает задачи подтверждения и отслеживания на основе изменяющегося сценария. Основное отличие этого примера от примера адаптивного слежения за маневрирующими целями с управляемым радаром состоит в том, что JobType для каждой задачи дорожки может быть либо "TrackNonManeuvering" или "TrackManeuvering". Различие между двумя типами задач отслеживания позволяет планировать задачи для каждого типа трека с различной скоростью повторного посещения, что делает его адаптивным алгоритмом отслеживания. Аналогично задачам поиска, задачи отслеживания также управляются в очереди заданий.
trackq = repmat(struct('JobType',[],'BeamDirection',[],'Priority',3000,'WaveformIndex',[],... 'Time',[],'Range',[],'TrackID',[]), 10, 1); num_trackq_items = 0;
Группирование очередей поиска и отслеживания в структуре для упрощения ссылок в цикле моделирования.
jobq.SearchQueue = searchq;
jobq.SearchIndex = current_search_idx;
jobq.TrackQueue = trackq;
jobq.NumTrackJobs = num_trackq_items;
jobq.PositionSelector = posSelector;
% Keep a reset state of jobq
resetJobQ = jobq;Планирование задач
В этом примере для простоты многофункциональный радар выполняет только один тип задания в течение небольшого периода времени, часто называемого задержкой, но может переключать задачи в начале каждой остановки. Для каждого пребывания радар просматривает все задачи, которые должны быть выполнены, и выбирает задачу подтверждения или отслеживания, если их время выполнения пришло. В противном случае радар выбирает задачу поиска. Для управления временем выполнения задач необходимо установить managerPreferences структура определена ниже. Самая высокая скорость повторного посещения, которая равна скорости обновления радара, задается для confirm задача гарантировать, что луч подтверждения следует за каждой новой предварительной дорожкой, которая существует. Точно так же можно управлять скоростью повторного посещения неманевренных и маневрирующих целей. При этом выбираются значения 1Hz и 4 Гц для неманевренных и маневрирующих целей соответственно. Поскольку существует шесть целей, в то время как скорость обновления РЛС составляет 20, если цели не маневрируют, то РЛС должна проводить около 70% времени в режиме поиска и 30% времени в режиме сопровождения. Когда новые дорожки инициализируются и когда трекер считает, что цели маневрируют, менеджер ресурсов выделяет больше отслеживающих лучей за счет поисковых лучей.
В разделе Анализ результатов (Analyze Results) показаны результаты других опций.
managerPreferences = struct(... 'Type', {"Search","Confirm","TrackNonManeuvering","TrackManeuvering"}, ... 'RevisitRate', {0, updateRate, 1, 4}, ... 'Priority', {1000, 3000, 1500, 2500});
Во время моделирования радиолокационный луч изображается синими или фиолетовыми цветами, представляющими соответственно поисковые и связанные с дорожкой лучи. Распределение задач между поиском и определенными дорожками для последней секунды моделирования можно также просмотреть с помощью функции «Распределение ресурсов» на панели «Последняя секунда» в нижней части рисунка. На верхней фигуре можно увидеть историю каждого трека и сравнить её с траекторией.
% Create a radar resource allocation display rp = uipanel('Parent',f,'Title','Resource Allocation in the Last Second','FontSize',12,... 'BackgroundColor','white','Position',[.01 0.01 0.98 0.23]); rax = axes(rp); % Run the scenario allocationType = helperAdaptiveTrackingSim(scenario, thp, rax, tracker, resetJobQ, managerPreferences);

Проанализируйте нагрузку на радар и ее разделение между заданиями поиска, подтверждения и отслеживания. График ниже показывает, что в течение большей части времени радар выделяет около 70% поисковых заданий и 30% заданий слежения, что соответствует ожиданиям, когда цели не маневрируют. Когда цели маневрируют, менеджер ресурсов адаптируется к выделению большего количества заданий отслеживания. Когда одновременно маневрирует больше трасс, появляется больше заданий слежения, как видно, например, около 700-го шага времени. Задания подтверждения занимают очень мало времени радара, потому что трекер сконфигурирован для подтверждения дорожек после двух ассоциаций обнаружения в трех попытках. Поэтому подтверждение или отклонение предварительных дорожек происходит быстро.
numSteps = numel(allocationType); allocationSummary = zeros(3,numSteps); for i = 1:numSteps for jobType = 1:3 allocationSummary(jobType,i) = sum(allocationType(1,max(1,i-2*updateRate+1):i)==jobType)/min(i-1,2*updateRate); end end figure; plot(1:numSteps,allocationSummary(:,1:numSteps)) title('Radar Allocation vs. Time Step'); xlabel('Time Step'); ylabel('Fraction of step in the last two seconds in each mode'); legend('Search','Confirmation','Tracking'); grid on

Теперь вы хотите сравнить результат, приведенный выше, с результатом активного отслеживания 1Hz скорости повторного посещения трека. На следующих рисунках показаны результаты отслеживания и график распределения радаров для случая активного отслеживания. Результаты отслеживания показывают, что некоторые следы были потеряны и сломаны, но график распределения радиолокационных ресурсов показывает такой же 70% поиск и 30% разделение задач отслеживания, как в случае адаптивного отслеживания. Эти результаты можно получить, выполнив приведенный ниже пример кода.
% Modify manager preferences to 1Hz revisit rate for both non-maneuvering and maneuvering targets managerPreferences = struct(... 'Type', {"Search","Confirm","TrackNonManeuvering","TrackManeuvering"}, ... 'RevisitRate', {0, updateRate, 1, 1}, ... 'Priority', {1000, 3000, 1500, 2500}); % Run the scenario allocationType = helperAdaptiveTrackingSim(scenario, thp, rax, tracker, resetJobQ, managerPreferences);


Очевидно, что для активного отслеживания требуется более высокая частота повторных посещений. Два графика ниже показывают, что увеличение скорости повторного захода на трассу до 2Hz улучшает сопровождение маневрирующих целей. Однако стоимость заключается в том, что радар посвящает более 50% своего времени отслеживанию задач даже тогда, когда трассы не маневрируют. Если бы количество целей было больше, радар стал бы переполнен.


Предыдущие результаты показывают, что достаточно вернуться к маневрирующим целям со скоростью 2Hz. Однако можно ли использовать Adaptive Tracking для снижения скорости повторного посещения неманевренных целей до 0.5Hz? Приведенные ниже графики показывают, что отслеживание по-прежнему хорошо. При такой настройке распределение РЛС позволяет 80% -90% времени в режиме поиска, оставляя РЛС с возможностью поиска и отслеживания ещё большего количества целей.


В этом примере показано, как использовать сочетание отслеживания и управления радиолокационными ресурсами для адаптации скорости повторного посещения для маневрирующих трасс. Адаптивное отслеживание позволяет выбрать скорость повторного посещения, подходящую для каждого типа цели и статуса маневрирования. В результате радар становится более эффективным и может отслеживать большее количество маневрирующих целей.
Ссылки
[1] Александр Шарлиш, Фолкер Гофман, Кристоф Деген и Изабель Шланген, «Развитие от адаптивного к управлению когнитивными радиолокационными ресурсами», в журнале IEEE Aerospace and Electronic Systems Magazine, том 35, № 6, стр. 8-19, 1 июня 2020 г., дои: 10.1109/MAES.2019.2957847.
getCurrentRadarTask
Возвращает задачу радара, которая используется для наведения луча радара.
type('getCurrentRadarTask.m')function [currentjob,jobq] = getCurrentRadarTask(jobq,current_time)
searchq = jobq.SearchQueue;
trackq = jobq.TrackQueue;
searchidx = jobq.SearchIndex;
num_trackq_items = jobq.NumTrackJobs;
% Update search queue index
searchqidx = mod(searchidx-1,numel(searchq))+1;
% Find the track job that is due and has the highest priority
readyidx = find([trackq(1:num_trackq_items).Time]<=current_time);
[~,maxpidx] = max([trackq(readyidx).Priority]);
taskqidx = readyidx(maxpidx);
% If the track job found has a higher priority, use that as the current job
% and increase the next search job priority since it gets postponed.
% Otherwise, the next search job due is the current job.
if ~isempty(taskqidx) % && trackq(taskqidx).Priority >= searchq(searchqidx).Priority
currentjob = trackq(taskqidx);
for m = taskqidx+1:num_trackq_items
trackq(m-1) = trackq(m);
end
num_trackq_items = num_trackq_items-1;
searchq(searchqidx).Priority = searchq(searchqidx).Priority+100;
else
currentjob = searchq(searchqidx);
searchidx = searchqidx+1;
end
jobq.SearchQueue = searchq;
jobq.SearchIndex = searchidx;
jobq.TrackQueue = trackq;
jobq.NumTrackJobs = num_trackq_items;
helperAdaptiveRadarSim
Выполнение моделирования
type('helperAdaptiveTrackingSim.m')function allocationType = helperAdaptiveTrackingSim(scenario, thp, rax, tracker, resetJobQ, managerPreferences)
% Initialize variables
radar = scenario.Platforms{end}.Sensors{1};
updateRate = radar.UpdateRate;
resourceAllocation = nan(1,updateRate);
h = histogram(rax,resourceAllocation,'BinMethod','integers');
xlabel(h.Parent,'TrackID')
ylabel(h.Parent,'Num beams');
numSteps = updateRate * 185;
allocationType = nan(1,numSteps);
currentStep = 1;
restart(scenario);
reset(tracker);
% Return to a reset state of jobq
jobq = resetJobQ;
% Plotters and axes
plp = thp.Plotters(1);
dtp = thp.Plotters(3);
cvp = thp.Plotters(4);
trp = thp.Plotters(5);
% For repeatable results, set the random seed and revert it when done
s = rng(2020);
oc = onCleanup(@() rng(s));
% Main loop
while advance(scenario)
time = scenario.SimulationTime;
% Update ground truth display
poses = platformPoses(scenario);
plotPlatform(plp, reshape([poses.Position],3,[])');
% Point the radar based on the scheduler current job
[currentJob,jobq] = getCurrentRadarTask(jobq,time);
currentStep = currentStep + 1;
if currentStep > updateRate
resourceAllocation(1:end-1) = resourceAllocation(2:updateRate);
end
if strcmpi(currentJob.JobType,'Search')
detectableTracks = zeros(0,1,'uint32');
resourceAllocation(min([currentStep,updateRate])) = 0;
allocationType(currentStep) = 1;
cvp.Color = [0 0 1];
else
detectableTracks = currentJob.TrackID;
resourceAllocation(min([currentStep,updateRate])) = currentJob.TrackID;
cvp.Color = [1 0 1];
if strcmpi(currentJob.JobType,'Confirm')
allocationType(currentStep) = 2;
else
allocationType(currentStep) = 3;
end
end
ra = resourceAllocation(~isnan(resourceAllocation));
h.Data = ra;
h.Parent.YLim = [0 updateRate];
h.Parent.XTick = 0:max(ra);
point(radar, currentJob.BeamDirection);
plotCoverage(cvp, coverageConfig(scenario));
% Collect detections and plot them
detections = detect(scenario);
if isempty(detections)
meas = zeros(0,3);
else
dets = [detections{:}];
meassph = reshape([dets.Measurement],3,[])';
[x,y,z] = sph2cart(deg2rad(meassph(1)),deg2rad(meassph(2)),meassph(3));
meas = (detections{1}.MeasurementParameters.Orientation*[x;y;z]+detections{1}.MeasurementParameters.OriginPosition)';
end
plotDetection(dtp, meas);
% Track and plot tracks
if isLocked(tracker) || ~isempty(detections)
tracks = tracker(detections, time, detectableTracks);
pos = getTrackPositions(tracks,jobq.PositionSelector);
plotTrack(trp,pos,string([tracks.TrackID]));
end
% Manage resources for next jobs
jobq = manageResource(detections,jobq,tracker,currentJob,time,managerPreferences);
end
initMPARIMM
Инициализирует взаимодействующий фильтр нескольких моделей, используемый трекером.
type('initMPARIMM.m')function imm = initMPARIMM(detection)
cvekf = initcvekf(detection);
cvekf.StateCovariance(2,2) = 1e6;
cvekf.StateCovariance(4,4) = 1e6;
cvekf.StateCovariance(6,6) = 1e6;
ctekf = initctekf(detection);
ctekf.StateCovariance(2,2) = 1e6;
ctekf.StateCovariance(4,4) = 1e6;
ctekf.StateCovariance(7,7) = 1e6;
ctekf.ProcessNoise(3,3) = 1e6; % Large noise for unknown angular acceleration
imm = trackingIMM('TrackingFilters', {cvekf;ctekf}, 'TransitionProbabilities', [0.99, 0.99]);
manageResources
Управляет очередью заданий и создает новые задачи на основе результатов отслеживания.
type('manageResource.m')function jobq = manageResource(detections,jobq,tracker,current_job,current_time,managerPreferences)
trackq = jobq.TrackQueue;
num_trackq_items = jobq.NumTrackJobs;
if ~isempty(detections)
detection = detections{1};
else
detection = [];
end
% Execute current job
switch current_job.JobType
case 'Search'
% For search job, if there is a detection, establish tentative
% track and schedule a confirmation job
if ~isempty(detection)
rng_est = detection.Measurement(3);
revisit_time = current_time+1;
allTracks = predictTracksToTime(tracker, 'all', revisit_time);
% A search task can still find a track we already have. Define
% a confirmation task only if it's a tentative track. There
% could be more than one if there are false alarms.
toConfirm = find(~[allTracks.IsConfirmed]);
numToConfirm = numel(toConfirm);
for i = 1:numToConfirm
trackid = allTracks(toConfirm(i)).TrackID;
job = revisitTrackJob(tracker, trackid, current_time, managerPreferences, 'Confirm');
num_trackq_items = num_trackq_items+1;
trackq(num_trackq_items) = job;
end
end
case 'Confirm'
% For confirm job, if the detection is confirmed, establish a track
% and create a track job corresponding to the revisit time
if ~isempty(detection)
trackid = current_job.TrackID;
job = revisitTrackJob(tracker, trackid, current_time, managerPreferences, 'TrackNonManeuvering');
if ~isempty(job)
num_trackq_items = num_trackq_items+1;
trackq(num_trackq_items) = job;
end
end
otherwise % Covers both types of track jobs
% For track job, if there is a detection, update the track and
% schedule a track job corresponding to the revisit time. If there
% is no detection, predict and schedule a track job sooner so the
% target is not lost.
if ~isempty(detection)
trackid = current_job.TrackID;
job = revisitTrackJob(tracker, trackid, current_time, managerPreferences, 'TrackNonManeuvering');
if ~isempty(job)
num_trackq_items = num_trackq_items+1;
trackq(num_trackq_items) = job;
end
else
trackid = current_job.TrackID;
job = revisitTrackJob(tracker, trackid, current_time, managerPreferences, 'TrackNonManeuvering');
if ~isempty(job)
num_trackq_items = num_trackq_items+1;
trackq(num_trackq_items) = job;
end
end
end
jobq.TrackQueue = trackq;
jobq.NumTrackJobs = num_trackq_items;
end
function job = revisitTrackJob(tracker, trackID, currentTime, managerPreferences, jobType)
types = [managerPreferences.Type];
inTypes = strcmpi(jobType,types);
revisitTime = 1/managerPreferences(inTypes).RevisitRate + currentTime;
predictedTracks = predictTracksToTime(tracker,'All',revisitTime);
% If the track is not dropped, try to revisit it
allTrackIDs = [predictedTracks.TrackID];
if any(trackID == allTrackIDs)
mdlProbs = getTrackFilterProperties(tracker, trackID, 'ModelProbabilities');
if mdlProbs{1}(2) > 0.6
jobType = 'TrackManeuvering';
inTypes = strcmpi(jobType,types);
revisitTime = 1/managerPreferences(inTypes).RevisitRate+currentTime;
predictedTracks = predictTracksToTime(tracker,trackID,revisitTime);
xpred = predictedTracks.State([1 3 5]);
else
xpred = predictedTracks(trackID == allTrackIDs).State([1 3 5]);
end
[phipred,thetapred,rpred] = cart2sph(xpred(1),xpred(2),xpred(3));
job = struct('JobType',jobType,'Priority',3000,...
'BeamDirection',rad2deg([phipred thetapred]),'WaveformIndex',1,'Time',revisitTime,...
'Range',rpred,'TrackID',trackID);
else
job = [];
end
end