Этот пример показывает, как моделировать многофункциональную поэтапную радиолокационную систему массивов. Многофункциональный радар может выполнить задания, которые обычно требуют нескольких традиционных радаров. Примеры традиционных радаров сканируют радары, которые ответственны за поиск целей и отслеживание радаров, которые ответственны за отслеживание целей. В этом примере многофункциональный поэтапный радар массивов выполняет и сканирующий (ищущие) и отслеживающие задачи. На основе обнаружений и дорожек, полученных из текущего эха, радар решает, что сделать рядом с, гарантируют, что цели интереса прослежены, и желаемое воздушное пространство ищется. Многофункциональный поэтапный радар массивов работает замкнутым циклом, включая функции, такие как планирование задач, выбор формы волны, генерация обнаружения и целевое отслеживание.
Этот пример требует 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.
Планирование задач
В этом примере, для простоты, многофункциональный радар выполняет только один тип задания в маленьком периоде времени, часто называемом тем, чтобы жить, но может переключиться, задачи в начале каждого живут. Поскольку каждый живет, радар смотрит на все задачи, которые подлежат выполнению, и выбирает тот, который имеет самый высокий приоритет. Следовательно, задания, которые отложены, будут теперь иметь увеличенный приоритет и, более вероятно, будут выполнены в следующем, живут.
Этот раздел примера моделирует короткий промежуток времени многофункциональной радиолокационной системы. Целая структура многофункциональной радарной симуляции представлена этой схемой.
Симуляция запускается с менеджера по радару, который обеспечивает начальное задание. На основе этого задания радар передает форму волны, моделирует эхо и применяет обработку сигналов, чтобы сгенерировать обнаружение. Обнаружение обрабатывается средством отслеживания, чтобы создать дорожки для целей. Дорожки затем возвращаются к менеджеру по радару. На основе дорожек и знания о сцене, менеджер по радару планирует задания нового трека и выбирает задание для следующего, живут.
Логику менеджера по радару операция показывают в этой блок-схеме и описывают на этих шагах.
Радар запускается с поискового задания.
Если цель будет присутствовать в обнаружении, радар планирует задание подтверждения в том же направлении, чтобы гарантировать, что присутствие этой цели не является ложным предупреждением. Задача подтверждения имеет более высокий приоритет, чем поисковая задача, но не настолько высоко как задача дорожки. Если обнаружение подтверждено, дорожка устанавливается, и задание дорожки создается, чтобы быть выполненным после того, как данный пересматривает время. Если обнаружение не подтверждено, то исходное обнаружение рассматривается как ложное предупреждение, и никакая дорожка не создается.
Если текущее задание является заданием дорожки, радар выполняет обнаружение, обновляет дорожку и создает будущее задание дорожки.
На основе приоритета и время для выполнения, радар выбирает следующее задание.
Примите, что жить составляет 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;