[译]多功能相控阵雷达搜索与跟踪
原文链接:Search and Track Scheduling for Multifunction Phased Array Radar
翻译目的:主要是为了利用matlab的相控阵系统工具箱(Phased Array System Toolbox)来学习和差波束测角的仿真。
目录结构
雷达配置
--波形
--雷达天线
--发射器和接收器
--信号处理
--数据处理
目标场景定义
雷达资源管理
--搜索任务
--跟踪任务
--任务调度
--仿真
资源分布分析
总结
参考文献
附录
--getCurrentJob
--generateEcho
--generateDetection
--updateTrackAndJob
以下是正文
这个例子展示了如何模拟一个多功能相控阵雷达系统。多功能雷达可以执行通常需要多个传统雷达的任务。传统雷达的例子有扫描雷达(负责搜索目标)和跟踪雷达(负责跟踪目标)。在本例中,多功能相控阵雷达同时执行扫描(搜索)和跟踪任务。根据从当前回波中获得的探测和跟踪,雷达决定下一步要做什么,以确保跟踪感兴趣的目标,并搜索所需的空域。多功能相控阵雷达是一个闭环系统,包括任务调度、波形选择、检测生成、目标跟踪等功能。
示例需要相控阵系统工具箱™。
雷达配置
假设多功能雷达工作在S波段,必须探测到2公里到100公里之间的目标,最小目标雷达截面(RCS)为1平方米
fc = 2e9; % 雷达信号载频 (Hz)
c = 3e8; % 光速 (m/s)
lambda = c/fc; % 雷达波长 (m)
maxrng = 100e3; % 最大射程 (m)
minrng = 2e3; % 最小射程 (m)
波形
为了满足范围的要求,定义和使用线性调频波形与1 MHz带宽。
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
发射器和接收器
利用检测要求推导出合适的发射功率。假设接收前置放大器的噪声为7db。
pd = 0.9; % 发现概率
pfa = 1e-6; % 虚警概率
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);
信号处理
多功能雷达对接收到的信号进行一系列操作,包括匹配滤波、时变增益、单脉冲和检测,以生成被检测目标的距离和角度测量值。
% 匹配滤波器
mfcoeff = getMatchedFilter(wav);
mf = phased.MatchedFilter('Coefficients',mfcoeff,'GainOutputPort', true);
% 时变增益
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);
% 单脉冲
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平方米。
% 定义目标
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;
队列中的每个作业指定作业类型以及波束的指向方向。它还包含作业的优先级值。这个优先级值由作业类型决定。本例使用值1000作为搜索作业的优先级。
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;
因为在检测到目标之前无法初始化跟踪作业,所以所有跟踪作业都以空作业开始。一旦创建了作业,它就包含了诸如作业类型、波束方向和执行时间等信息。跟踪任务的优先级为3000,高于搜索作业的优先级1000。这个较高的优先级值意味着当时间冲突时,系统将首先执行跟踪任务。
本例中队列的大小限制设置为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
% 提供当前作业的调度程序
[current_job,jobq] = getCurrentJob(jobq,current_time);
% 模拟接收到的I/Q信号
[xsum,xdaz,xdel,mfradar] = generateEcho(mfradar,env,current_job);
% 信号处理器提取检测
[detection,mfradar] = generateDetection(xsum,xdaz,xdel,mfradar,current_job,current_time);
% 雷达管理器执行数据处理和更新跟踪队列
[jobq,allTracks,mfradar] = updateTrackAndJob(detection,jobq,mfradar,current_job,current_time,dwelltime);
% 可视化
helperMPARTaskPlot('update',sceneplot,current_job,maxrng,beamw,tgtpos,allTracks,detection.Measurement);
% 更新时间
tgtpos = env.TargetMotion(dwelltime-Npulses/mfradar.Wav.PRF);
current_time = current_time+dwelltime;
% 记录资源分配
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] Walter Weinstock, "Computer Control of a Multifunction Radar", Practical Phased Array Antenna Systems, Lex Book, 1997
附件
这些辅助功能为雷达资源管理工作流建模。
getCurrentJob
函数getCurrentJob比较搜索队列和跟踪队列中的作业,并选择要执行的优先级最高的作业。
function [currentjob,jobq] = getCurrentJob(jobq,current_time)
searchq = jobq.SearchQueue;
trackq = jobq.TrackQueue;
searchidx = jobq.SearchIndex;
num_trackq_items = jobq.NumTrackJobs;
% 更新搜索队列索引
searchqidx = mod(searchidx-1,numel(searchq))+1;
% 找一份到期且有最高优先级的跟踪工作
readyidx = find([trackq(1:num_trackq_items).Time]<=current_time);
[~,maxpidx] = max([trackq(readyidx).Priority]);
taskqidx = readyidx(maxpidx);
% 如果找到的track作业具有更高的优先级,则将其用作当前作业,
% 并增加下一个搜索作业的优先级,因为它被推迟了。
% 否则,下一个搜索作业就是当前作业。
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;