Поиск и планирование дорожки для многофункционального поэтапного радара массивов

Этот пример показывает, как моделировать многофункциональную поэтапную радиолокационную систему массивов. Многофункциональный радар может выполнить задания, которые обычно требуют нескольких традиционных радаров. Примеры традиционных радаров сканируют радары, которые ответственны за поиск целей и отслеживание радаров, которые ответственны за отслеживание целей. В этом примере многофункциональный поэтапный радар массивов выполняет и сканирующий (ищущие) и отслеживающие задачи. На основе обнаружений и дорожек, полученных из текущего эха, радар решает, что сделать рядом с, гарантируют, что цели интереса прослежены, и желаемое воздушное пространство ищется. Многофункциональный поэтапный радар массивов работает замкнутым циклом, включая функции, такие как планирование задач, выбор формы волны, генерация обнаружения и целевое отслеживание.

Этот пример требует Sensor Fusion and Tracking Toolbox™.

Радарная настройка

Примите, что многофункциональный радар действует в полосе S и должен обнаружить цели между 2 км и 100 км с минимальным целевым радарным сечением (RCS) 1 квадратного метра.

fc     = 2e9;                 % Radar carrier frequency (Hz)
c      = 3e8;                 % Propagation speed (m/s)
lambda = c/fc;                % Radar wavelength (m)

maxrng = 100e3;               % Maximum range (m)
minrng = 2e3;                 % Minimum range (m)

Форма волны

Чтобы удовлетворить требование области значений, задайте и используйте линейную форму волны FM с пропускной способностью на 1 МГц.

bw     = 1e6;
fs     = 1.5*bw;
prf    = 1/range2time(maxrng,c);
dcycle = 0.1;

wav = phased.LinearFMWaveform('SampleRate', fs, ...
    'DurationSpecification', 'Duty cycle', 'DutyCycle', dcycle, ...
    'PRF', prf, 'SweepBandwidth', bw);

Вычислите разрешение области значений, достижимое формой волны.

rngres = bw2range(bw,c)
rngres =

   150

Радарная антенна

Многофункциональный радар оборудован поэтапным массивом, который может электронно отсканировать радарные лучи на пробеле. Используйте 50 50 прямоугольный массив с элементами, разделенными половиной длины волны, чтобы достигнуть половины ширины луча степени приблизительно 2 градусов.

arraysz   = 50;
ant       = phased.URA('Size',arraysz,'ElementSpacing',lambda/2);
ant.Element.BackBaffled = true;

arraystv  = phased.SteeringVector('SensorArray',ant,'PropagationSpeed',c);
radiator  = phased.Radiator('OperatingFrequency',fc, ...
    'PropagationSpeed', c, 'Sensor',ant, 'WeightsInputPort', true);
collector = phased.Collector('OperatingFrequency',fc, ...
    'PropagationSpeed', c, 'Sensor',ant);

beamw = rad2deg(lambda/(arraysz*lambda/2))
beamw =

    2.2918

Передатчик и получатель

Используйте требования обнаружения, чтобы вывести соответствующую степень передачи. Примите, что шум рассчитывает на предусилитель получения, 7 дБ.

pd      = 0.9;                     % Probability of detection
pfa     = 1e-6;                    % Probability of false alarm
snr_min = albersheim(pd, pfa, 1);
ampgain = 20;
tgtrcs  = 1;
ant_snrgain = pow2db(arraysz^2);

ppower  = radareqpow(lambda,maxrng,snr_min,wav.PulseWidth,...
    'RCS',tgtrcs,'Gain',ampgain+ant_snrgain);

tx = phased.Transmitter('PeakPower',ppower,'Gain',ampgain,'InUseOutputPort',true);
rx = phased.ReceiverPreamp('Gain',ampgain,'NoiseFigure',7,'EnableInputPort',true);

Обработка сигналов

Многофункциональный радар применяет последовательность операций, включая согласованную фильтрацию, время, отличаясь усиление, моноимпульс и обнаружение, к полученному сигналу сгенерировать область значений и угловые измерения обнаруженных целей.

% matched filter
mfcoeff = getMatchedFilter(wav);
mf      = phased.MatchedFilter('Coefficients',mfcoeff,'GainOutputPort', true);

% time varying gain
tgrid   = unigrid(0,1/fs,1/prf,'[)');
rgates  = c*tgrid/2;
rngloss = 2*fspl(rgates,lambda);
refloss = 2*fspl(maxrng,lambda);
tvg     = phased.TimeVaryingGain('RangeLoss',rngloss,'ReferenceLoss',refloss);

% monopulse
monfeed = phased.MonopulseFeed('SensorArray',ant,'PropagationSpeed',c,...
    'OperatingFrequency',fc,'SquintAngle',1);
monest  = getMonopulseEstimator(monfeed);

Обработка данных

Обнаружения поданы в средство отслеживания, которое выполняет несколько операций. Средство отслеживания ведет список дорожек, то есть, оценок целевых состояний в сфере интересов. Если обнаружение не может быть присвоено никакой дорожке, уже сохраняемой средством отслеживания, средство отслеживания инициирует новый трек. В большинстве случаев, ли новый трек представляет истинную целевую или ложную цель, неясно. Сначала, дорожка создается с предварительным состоянием. Если достаточно обнаружений получено, дорожка становится подтвержденной. Точно так же, если никакие обнаружения не присвоены дорожке, дорожка курсируется (предсказанный без исправления). Если дорожка имеет несколько пропущенных обновлений, средство отслеживания удаляет дорожку.

Многофункциональный радар использует средство отслеживания, которое сопоставляет обнаружения к дорожкам с помощью алгоритма глобального самого близкого соседа (GNN).

tracker = trackerGNN('FilterInitializationFcn',@initMPARGNN,...
    'ConfirmationThreshold',[2 3], 'DeletionThreshold',5,...
    'HasDetectableTrackIDsInput',true,'AssignmentThreshold',100,...
    'MaxNumTracks',2,'MaxNumSensors',1);

Соберите в группу все радарные компоненты в структуре для более легкой ссылки в цикле симуляции.

mfradar.Tx      = tx;
mfradar.Rx      = rx;
mfradar.TxAnt   = radiator;
mfradar.RxAnt   = collector;
mfradar.Wav     = wav;
mfradar.RxFeed  = monfeed;
mfradar.MF      = mf;
mfradar.TVG     = tvg;
mfradar.DOA     = monest;
mfradar.STV     = arraystv;
mfradar.Tracker = tracker;
mfradar.IsTrackerInitialized = false;

Цель и определение сцены

Этот пример принимает, что радар является стационарным в начале координат с двумя целями в его поле зрения. Одна цель вылетает от радара и на расстоянии приблизительно 50 км. Другая цель приближается к радару и на расстоянии в 30 км. Обе цели имеют RCS 1 квадратного метра.

% Define the targets.
tgtpos = [29875 49637; 0 4225; 0 0];
tgtvel = [-100 120; 0 100; 0 0];

ntgt = size(tgtpos,2);
tgtmotion = phased.Platform('InitialPosition',tgtpos,'Velocity',tgtvel);
target = phased.RadarTarget('MeanRCS',tgtrcs*ones(1,ntgt),'OperatingFrequency',fc);

Примите, что среда распространения является свободным пространством.

channel = phased.FreeSpace('SampleRate',fs,'TwoWayPropagation',true,'OperatingFrequency',fc);

Соберите в группу цели и каналы распространения в структуре для более легкой ссылки в цикле симуляции.

env.Target       = target;
env.TargetMotion = tgtmotion;
env.Channel      = channel;

Радарное управление ресурсами

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

Поисковые задачи

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

Примите, что радар сканирует пробел от-30 до 30 азимутов степеней и от 0 до 20 повышений степеней. Вычислите угловую поисковую сетку с помощью ширины луча.

scanregion   = [-30, 30, 0, 20];
azscanspan   = diff(scanregion(1:2));
numazscan    = ceil(azscanspan/beamw);
azscanangles = linspace(scanregion(1),scanregion(2),numazscan);
elscanspan   = diff(scanregion(3:4));
numelscan    = ceil(elscanspan/beamw);
elscanangles = linspace(scanregion(3),scanregion(4),numelscan);
[elscangrid,azscangrid] = meshgrid(elscanangles,azscanangles);
scanangles   = [azscangrid(:) elscangrid(:)].';

Сетку положения луча и целевую сцену показывают ниже.

sceneplot = helperMPARTaskPlot('initialize',scanangles,azscanangles,maxrng,beamw,tgtpos);

Поисковые лучи передаются по одному последовательно, пока целая область поиска не покрыта. Если целая область поиска покрыта, радар повторяет поисковую последовательность. Поисковые запросы выполняются вдоль азимутального направления, одно повышение поворачивают время. Поисковые задачи часто содержатся в очереди заданий.

searchq = struct('JobType','Search','BeamDirection',num2cell(scanangles,1),...
    'Priority',1000,'WaveformIndex',1);
current_search_idx = 1;

Каждое задание в очереди задает тип задания, а также указывающее направление луча. Это также содержит приоритетное значение для задания. Это приоритетное значение определяется типом задания. Этот пример использует значение 1 000 как приоритет для поисковых заданий.

disp(searchq(current_search_idx))
          JobType: 'Search'
    BeamDirection: [2x1 double]
         Priority: 1000
    WaveformIndex: 1

Отследите задачи

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

trackq(10) = struct('JobType',[],'BeamDirection',[],'Priority',3000,'WaveformIndex',[],...
    'Time',[],'Range',[],'TrackID',[]);
num_trackq_items = 0;
disp(trackq(1))
          JobType: []
    BeamDirection: []
         Priority: []
    WaveformIndex: []
             Time: []
            Range: []
          TrackID: []

Соберите в группу поиск и отследите очереди в структуре для более легкой ссылки в цикле симуляции.

jobq.SearchQueue  = searchq;
jobq.SearchIndex  = current_search_idx;
jobq.TrackQueue   = trackq;
jobq.NumTrackJobs = num_trackq_items;

Поскольку задание отслеживания не может быть инициализировано, прежде чем цель обнаруживается, все задания отслеживания запускаются как пустые задания. Если задание создается, оно содержит информацию, такую как ее тип задания, направление луча, и время, чтобы выполниться. Задача отслеживания имеет приоритет 3 000, который выше, чем приоритет 1 000 для поискового задания. Это более высокое приоритетное значение означает, что, когда время находится в конфликте, система выполнит задание отслеживания сначала.

Предел размера для очереди в этом примере устанавливается к 10.

Планирование задач

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

Симуляция

Этот раздел примера моделирует короткий промежуток времени многофункциональной радиолокационной системы. Целая структура многофункциональной радарной симуляции представлена этой схемой.

Симуляция запускается с менеджера по радару, который обеспечивает начальное задание. На основе этого задания радар передает форму волны, моделирует эхо и применяет обработку сигналов, чтобы сгенерировать обнаружение. Обнаружение обрабатывается средством отслеживания, чтобы создать дорожки для целей. Дорожки затем возвращаются к менеджеру по радару. На основе дорожек и знания о сцене, менеджер по радару планирует задания нового трека и выбирает задание для следующего, живут.

Логику менеджера по радару операция показывают в этой блок-схеме и описывают на этих шагах.

  1. Радар запускается с поискового задания.

  2. Если цель будет присутствовать в обнаружении, радар планирует задание подтверждения в том же направлении, чтобы гарантировать, что присутствие этой цели не является ложным предупреждением. Задача подтверждения имеет более высокий приоритет, чем поисковая задача, но не настолько высоко как задача дорожки. Если обнаружение подтверждено, дорожка устанавливается, и задание дорожки создается, чтобы быть выполненным после того, как данный пересматривает время. Если обнаружение не подтверждено, то исходное обнаружение рассматривается как ложное предупреждение, и никакая дорожка не создается.

  3. Если текущее задание является заданием дорожки, радар выполняет обнаружение, обновляет дорожку и создает будущее задание дорожки.

  4. На основе приоритета и время для выполнения, радар выбирает следующее задание.

Примите, что жить составляет 10 мс. В начале симуляции радар сконфигурирован, чтобы искать один луч за один раз.

rng(2018);
current_time = 0;
Npulses      = 10;
numdwells    = 200;
dwelltime    = 0.01;

jobload.num_search_job = zeros(1,numdwells);
jobload.num_track_job  = zeros(1,numdwells);

Можно запустить пример в целом, чтобы видеть графики быть динамически обновленными во время выполнения. В лучших двух графиках цвет лучей указывает на типы текущего задания: красный для поиска, желтого для, подтверждают, и фиолетовый для дорожки. Нижняя часть два графика показывает истинные местоположения (треугольник), обнаружения (круг) и дорожки (квадрат) двух целей, соответственно. Системный журнал также отображается в командной строке, чтобы объяснить поведение системы в текущий момент. Затем, пример показывает больше деталей о нескольких критических моментах симуляции.

Моделируйте поведение системы, пока оно не обнаружит первую цель. Цикл симуляции следует предыдущей системной схеме.

for dwell_idx = 1:14
    % Scheduler to provide current job
    [current_job,jobq]       = getCurrentJob(jobq,current_time);

    % Simulate the received I/Q signal
    [xsum,xdaz,xdel,mfradar] = generateEcho(mfradar,env,current_job);

    % Signal processor to extract detection
    [detection,mfradar]      = generateDetection(xsum,xdaz,xdel,mfradar,current_job,current_time);

    % Radar manager to perform data processing and update track queue
    [jobq,allTracks,mfradar] = updateTrackAndJob(detection,jobq,mfradar,current_job,current_time,dwelltime);

    % Visualization
    helperMPARTaskPlot('update',sceneplot,current_job,maxrng,beamw,tgtpos,allTracks,detection.Measurement);

    % Update time
    tgtpos = env.TargetMotion(dwelltime-Npulses/mfradar.Wav.PRF);
    current_time = current_time+dwelltime;

    % Record resource allocation
    if strcmp(current_job.JobType,'Search')
        jobload.num_search_job(dwell_idx) = 1;
    else
        jobload.num_track_job(dwell_idx)  = 1;
    end

end
0.000000 sec:	Search	[-30.000000 0.000000]
0.010000 sec:	Search	[-27.692308 0.000000]
0.020000 sec:	Search	[-25.384615 0.000000]
0.030000 sec:	Search	[-23.076923 0.000000]
0.040000 sec:	Search	[-20.769231 0.000000]
0.050000 sec:	Search	[-18.461538 0.000000]
0.060000 sec:	Search	[-16.153846 0.000000]
0.070000 sec:	Search	[-13.846154 0.000000]
0.080000 sec:	Search	[-11.538462 0.000000]
0.090000 sec:	Search	[-9.230769 0.000000]
0.100000 sec:	Search	[-6.923077 0.000000]
0.110000 sec:	Search	[-4.615385 0.000000]
0.120000 sec:	Search	[-2.307692 0.000000]
0.130000 sec:	Search	[0.000000 0.000000]	Target detected at 29900.000000 m

Как ожидалось радар получает обнаружение, когда радарный луч освещает цель, как показано в фигуре. Когда это происходит, радар отправляет луч подтверждения сразу, чтобы убедиться, что это не ложное обнаружение.

Затем, покажите результаты для задания подтверждения. Остальная часть этого примера показывает упрощенный код, который комбинирует цикл симуляции в функцию системной симуляции.

[mfradar,env,jobq,jobload,current_time,tgtpos] = MPARSimRun(...
    mfradar,env,jobq,jobload,current_time,dwelltime,sceneplot,maxrng,beamw,tgtpos,15,15);
0.140000 sec:	Confirm	[-0.000586 -0.000034]	Created track 1 at 29900.000000 m

Данные теперь показывают луч подтверждения. Если обнаружение подтверждено, дорожка устанавливается для цели, и задание дорожки, как планируют, выполнится после короткого интервала.

Этот процесс повторяется для каждой обнаруженной цели до пересмотреть времени, в которую точку многофункциональный радар останавливает поисковую последовательность и выполняет задачу дорожки снова.

[mfradar,env,jobq,jobload,current_time,tgtpos] = MPARSimRun(...
    mfradar,env,jobq,jobload,current_time,dwelltime,sceneplot,maxrng,beamw,tgtpos,16,25);
0.150000 sec:	Search	[2.307692 0.000000]
0.160000 sec:	Search	[4.615385 0.000000]	Target detected at 49900.000000 m
0.170000 sec:	Confirm	[4.881676 0.000739]	Created track 2 at 49900.000000 m
0.180000 sec:	Search	[6.923077 0.000000]
0.190000 sec:	Search	[9.230769 0.000000]
0.200000 sec:	Search	[11.538462 0.000000]
0.210000 sec:	Search	[13.846154 0.000000]
0.220000 sec:	Search	[16.153846 0.000000]
0.230000 sec:	Search	[18.461538 0.000000]
0.240000 sec:	Track	[-0.000399 0.000162]	Track 1 at 29900.000000 m

Результаты показывают, что симуляция останавливается в луче дорожки. Увеличившие масштаб данные вокруг двух целей показывают, как дорожки обновляются на основе обнаружения и измерений. Задание нового трека для следующего пересматривает, также добавляется к очереди заданий во время выполнения задания дорожки.

Этот процесс повторения для каждого живет. Эта симуляция запускает радиолокационную систему в течение 2-секундного периода. Через некоторое время вторая цель обнаруживается вне 50 км. На основе этой информации менеджер по радару уменьшает, как часто система должна отследить вторую цель. Это сокращение освобождает ресурсы для другого, более насущной необходимости.

[mfradar,env,jobq,jobload,current_time,tgtpos] = MPARSimRun(...
    mfradar,env,jobq,jobload,current_time,dwelltime,sceneplot,maxrng,beamw,tgtpos,26,numdwells);
0.250000 sec:	Search	[20.769231 0.000000]
0.260000 sec:	Search	[23.076923 0.000000]
0.270000 sec:	Track	[4.882892 -0.000030]	Track 2 at 49900.000000 m
0.280000 sec:	Search	[25.384615 0.000000]
0.290000 sec:	Search	[27.692308 0.000000]
0.340000 sec:	Track	[0.001390 0.000795]	Track 1 at 29900.000000 m
0.370000 sec:	Track	[4.895153 0.000529]	Track 2 at 49900.000000 m
0.440000 sec:	Track	[0.000284 0.000446]	Track 1 at 29900.000000 m
0.470000 sec:	Track	[4.909764 -0.000394]	Track 2 at 49900.000000 m
0.540000 sec:	Track	[0.000455 -0.000130]	Track 1 at 29800.000000 m
0.570000 sec:	Track	[4.921876 -0.000210]	Track 2 at 49900.000000 m
0.640000 sec:	Track	[0.000181 -0.000020]	Track 1 at 29800.000000 m
0.670000 sec:	Track	[4.932942 -0.000988]	Track 2 at 49900.000000 m
0.740000 sec:	Track	[0.000348 0.000212]	Track 1 at 29800.000000 m
0.770000 sec:	Track	[4.944255 -0.001073]	Track 2 at 49900.000000 m
0.840000 sec:	Track	[0.000171 -0.000125]	Track 1 at 29800.000000 m
0.870000 sec:	Track	[4.954431 -0.000943]	Track 2 at 50000.000000 m
0.940000 sec:	Track	[0.000296 -0.000288]	Track 1 at 29800.000000 m
1.040000 sec:	Track	[0.000108 -0.000147]	Track 1 at 29800.000000 m
1.140000 sec:	Track	[-0.000096 -0.000179]	Track 1 at 29800.000000 m
1.240000 sec:	Track	[-0.000110 -0.000315]	Track 1 at 29800.000000 m
1.340000 sec:	Track	[-0.000291 -0.000515]	Track 1 at 29800.000000 m
1.370000 sec:	Track	[5.005679 -0.000877]	Track 2 at 50000.000000 m
1.440000 sec:	Track	[-0.000191 -0.000592]	Track 1 at 29800.000000 m
1.540000 sec:	Track	[-0.000140 -0.000787]	Track 1 at 29700.000000 m
1.640000 sec:	Track	[0.000069 -0.000600]	Track 1 at 29700.000000 m
1.740000 sec:	Track	[-0.000001 -0.000714]	Track 1 at 29700.000000 m
1.840000 sec:	Track	[0.000030 -0.000686]	Track 1 at 29700.000000 m
1.870000 sec:	Track	[5.057762 0.000107]	Track 2 at 50100.000000 m
1.940000 sec:	Track	[0.000067 -0.000511]	Track 1 at 29700.000000 m

Анализ распределения ресурса

Этот раздел примера показывает, как радарный ресурс распределяется среди различных задач. Эти данные показывают, как многофункциональная радиолокационная система в этом примере распределяет свои ресурсы между поиском и дорожкой.

L = 10;
searchpercent = sum(buffer(jobload.num_search_job,L,L-1,'nodelay'))/L;
trackpercent  = sum(buffer(jobload.num_track_job,L,L-1,'nodelay'))/L;
figure;
plot((1:numel(searchpercent))*L*dwelltime,[searchpercent(:) trackpercent(:)]);
xlabel('Time (s)');
ylabel('Job Percentage');
title('Resource Distribution between Search and Track');
legend('Search','Track','Location','best');
grid on;

Фигура предполагает, что в начале симуляции все ресурсы потрачены на поиск. Если цели обнаруживаются, радарные ресурсы разделены в 80% и 20% между поиском и дорожкой, соответственно. Однако, если вторая цель становится более далекой, больше ресурсов освобождено для поиска. Загрузка дорожки увеличивается кратко, когда время прибывает, чтобы отследить вторую цель снова.

Сводные данные

Этот пример вводит концепцию управления ресурсами и планирования задач в многофункциональной поэтапной радиолокационной системе массивов. Это показывает, что с компонентом управления ресурсами радар действует как система замкнутого цикла. Несмотря на то, что многофункциональный радар в этом примере имеет дело только с поиском и задачами дорожки, концепция может быть расширена к более реалистическим ситуациям, где другие функции, такие как самопроверка и коммуникация, также включены.

Ссылки

[1] Уолтер Вайншток, "Автоматизированный контроль многофункционального радара", практические поэтапные системы антенны массивов, книга закона, 1997

Приложения

Эти функции помощника моделируют радарный рабочий процесс управления ресурсами.

getCurrentJob

Функциональный getCurrentJob сравнивает задания в поисковой очереди и очереди дорожки и выбирает задание с самым высоким приоритетом выполниться.

function [currentjob,jobq] = getCurrentJob(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;

generateEcho

Функциональный generateEcho моделирует комплекс (I/Q) основополосное представление целевого эха, полученного в радаре.

function [xrsint,xrdazint,xrdelint,mfradar] = generateEcho(mfradar,env,current_job)

% Radar position
radarpos = [0;0;0];
radarvel = [0;0;0];

% Number of pulses and operating frequency
Npulses = 10;
fc = mfradar.TxAnt.OperatingFrequency;

for m = 1:Npulses
    % Waveform
    x = mfradar.Wav();
    
    % Update target motion
    [tgtpos,tgtvel] = env.TargetMotion(1/mfradar.Wav.PRF);
    [~,tgtang]      = rangeangle(tgtpos);
    
    % Transmit
    [xt,inuseflag]  = mfradar.Tx(x);
    w  = mfradar.STV(fc,current_job.BeamDirection);
    xt = mfradar.TxAnt(xt,tgtang,conj(w));
    
    % Propagation
    xp = env.Channel(xt,radarpos,tgtpos,radarvel,tgtvel);
    xp = env.Target(xp);
    
    % Receive and monopulse
    xr = mfradar.RxAnt(xp,tgtang);
    [xrs,xrdaz,xrdel] = mfradar.RxFeed(xr,current_job.BeamDirection);
    
    % Pulse integration
    if m == 1
        xrsint   = mfradar.Rx(xrs,~(inuseflag>0));
        xrdazint = mfradar.Rx(xrdaz,~(inuseflag>0));
        xrdelint = mfradar.Rx(xrdel,~(inuseflag>0));
    else
        xrsint   = xrsint+mfradar.Rx(xrs,~(inuseflag>0));
        xrdazint = xrdazint+mfradar.Rx(xrdaz,~(inuseflag>0));
        xrdelint = xrdelint+mfradar.Rx(xrdel,~(inuseflag>0));
    end
end

generateDetection

Функциональный generateDetection применяет методы обработки сигналов на эхо, чтобы сгенерировать целевое обнаружение.

function [detection,mfradar] = generateDetection(xrsint,xrdazint,xrdelint,mfradar,current_job,current_time)

% Compute detection threshold
nbw         = mfradar.Rx.SampleRate/(mfradar.Wav.SampleRate/mfradar.Wav.SweepBandwidth);
npower      = noisepow(nbw,mfradar.Rx.NoiseFigure,mfradar.Rx.ReferenceTemperature);
pfa         = 1e-6;
threshold   = npower * db2pow(npwgnthresh(pfa,1,'noncoherent'));
arraysz     = mfradar.TxAnt.Sensor.Size(1);
ant_snrgain = pow2db(arraysz^2);
mfcoeff     = getMatchedFilter(mfradar.Wav);
mfgain      = pow2db(norm(mfcoeff)^2);
threshold   = threshold * db2pow(mfgain+2*ant_snrgain); 
threshold   = sqrt(threshold);    

tgrid   = unigrid(0,1/mfradar.Wav.SampleRate,1/mfradar.Wav.PRF,'[)');
rgates  = mfradar.TxAnt.PropagationSpeed*tgrid/2;

% Matched filtering and time varying gain
xrsmf = mfradar.TVG(mfradar.MF(xrsint));

% Detection in range and angle estimation via monopulse
if any(abs(xrsmf)>threshold)
    [~,tgtidx] = findpeaks(abs(xrsmf),'MinPeakHeight',threshold,...
        'Sortstr','Descend','NPeaks',1);
    rng_est = rgates(tgtidx-(numel(mfcoeff)-1));
    ang_est = mfradar.DOA(xrsint(tgtidx-1),xrdazint(tgtidx-1),xrdelint(tgtidx-1),current_job.BeamDirection);
    % Form the detection object.  
    measNoise = diag([0.1, 0.1, 150].^2);           % Measurement noise matrix
    detection = objectDetection(current_time,...
        [ang_est(1);ang_est(2);rng_est], 'MeasurementNoise', measNoise,...
        'MeasurementParameters',struct('Frame','spherical', 'HasVelocity', false));  
else
    detection = objectDetection.empty;
end

if current_time < 0.3 || strcmp(current_job.JobType,'Track')
    fprintf('\n%f sec:\t%s\t[%f %f]',current_time,current_job.JobType,current_job.BeamDirection(1),...
        current_job.BeamDirection(2));
end


updateTrackAndJob

Функциональный updateTrackAndJob отслеживает обнаружение и затем передает дорожки менеджеру по радару, чтобы обновить очередь задачи дорожки.

function [jobq,allTracks,mfradar] = updateTrackAndJob(detection,jobq,mfradar,current_job,current_time,dwellinterval)

trackq           = jobq.TrackQueue;
num_trackq_items = jobq.NumTrackJobs;

% 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)
            ang_est = detection.Measurement(1:2);
            rng_est = detection.Measurement(3);
            if ~mfradar.IsTrackerInitialized
                [~,~,allTracks] = mfradar.Tracker(detection,current_time,uint32([]));
                mfradar.IsTrackerInitialized = true;
            else
                [~,~,allTracks] = mfradar.Tracker(detection,current_time,uint32([]));
            end
            num_trackq_items = num_trackq_items+1;
            trackq(num_trackq_items) = struct('JobType','Confirm','Priority',2000,...
                'BeamDirection',ang_est,'WaveformIndex',1,'Time',current_time+dwellinterval,...
                'Range',rng_est,'TrackID',allTracks(~[allTracks.IsConfirmed]).TrackID);
            if current_time < 0.3 || strcmp(current_job.JobType,'Track')
                fprintf('\tTarget detected at %f m',rng_est);
            end
        else
            allTracks = [];
        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;
            [~,~,allTracks] = mfradar.Tracker(detection,current_time,trackid);

            rng_est = detection.Measurement(3);
            if rng_est >= 50e3
                updateinterval = 0.5;
            else
                updateinterval = 0.1;
            end
            revisit_time = current_time+updateinterval;
            predictedTrack = predictTracksToTime(mfradar.Tracker,trackid,revisit_time);
            xpred = predictedTrack.State([1 3 5]);
            [phipred,thetapred,rpred] = cart2sph(xpred(1),xpred(2),xpred(3));
            num_trackq_items = num_trackq_items+1;
            trackq(num_trackq_items) = struct('JobType','Track','Priority',3000,...
                'BeamDirection',rad2deg([phipred;thetapred]),'WaveformIndex',1,'Time',revisit_time,...
                'Range',rpred,'TrackID',trackid);
            if current_time < 0.3 || strcmp(current_job.JobType,'Track')
                fprintf('\tCreated track %d at %f m',trackid,rng_est);
            end
        else
            allTracks = [];
        end

    case 'Track'
        % 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;
            [~,~,allTracks] = mfradar.Tracker(detection,current_time,trackid);

            rng_est = detection.Measurement(3);
            if rng_est >= 50e3
                updateinterval = 0.5;
            else
                updateinterval = 0.1;
            end

            revisit_time = current_time+updateinterval;
            predictedTrack = predictTracksToTime(mfradar.Tracker,trackid,revisit_time);
            xpred = predictedTrack.State([1 3 5]);
            [phipred,thetapred,rpred] = cart2sph(xpred(1),xpred(2),xpred(3));
            num_trackq_items = num_trackq_items+1;
            trackq(num_trackq_items) = struct('JobType','Track','Priority',3000,...
                'BeamDirection',rad2deg([phipred;thetapred]),'WaveformIndex',1,'Time',revisit_time,...
                'Range',rpred,'TrackID',trackid);

            if current_time < 0.3 || strcmp(current_job.JobType,'Track')
                fprintf('\tTrack %d at %f m',trackid,rng_est);
            end
        else
            trackid = current_job.TrackID;
            [~,~,allTracks] = mfradar.Tracker(detection,current_time,trackid);

            updateinterval = 0.1;  % revisit sooner
            revisit_time = current_time+updateinterval;
            predictedTrack = predictTracksToTime(mfradar.Tracker,trackid,revisit_time);
            xpred = predictedTrack.State([1 3 5]);

            [phipred,thetapred,rpred] = cart2sph(xpred(1),xpred(2),xpred(3));
            num_trackq_items = num_trackq_items+1;
            trackq(num_trackq_items) = struct('JobType','Track','Priority',3000,...
                'BeamDirection',rad2deg([phipred;thetapred]),'WaveformIndex',1,'Time',revisit_time,...
                'Range',rpred,'TrackID',trackid);

            if current_time < 0.3 || strcmp(current_job.JobType,'Track')
                fprintf('\tNo detection, track %d predicted',current_job.TrackID);
            end
        end

end
    
jobq.TrackQueue   = trackq;
jobq.NumTrackJobs = num_trackq_items;