主要内容

管理雷达的机动目标的自适应跟踪

该实例说明了如何利用雷达资源管理有效地跟踪多个机动目标。跟踪机动目标比跟踪非机动目标需要雷达更频繁地重访目标。采用交互多模型(IMM)滤波器对目标进行机动时的估计。这种估计有助于管理雷达重访时间,从而增强跟踪。本示例使用雷达工具箱™用于雷达模型,传感器融合和跟踪工具箱™用于跟踪。

介绍

多功能雷达可以搜索目标,确认新的轨道,并重新访问轨道以更新状态。为了执行这些功能,多功能雷达通常由资源管理器管理,该资源管理器创建用于搜索、确认和跟踪的雷达任务。这些任务按照优先级和时间进行调度,以便在每个时间步骤中,多功能雷达都能将波束指向期望的方向。的用于多功能相控阵雷达的搜索和跟踪调度(雷达工具箱)示例显示了使用资源管理器管理的多功能相控阵列雷达。

在这个例子中,我们扩展了用于多功能相控阵雷达的搜索和跟踪调度(雷达工具箱)以多个机动目标为例。用于跟踪机动目标的雷达有两个相互冲突的要求:

  1. 目标的数量和它们的初始位置通常是事先不知道的。因此,雷达必须不断搜索感兴趣的区域以找到目标。此外,当雷达进入雷达覆盖区域时,雷达需要探测并建立对每个目标的跟踪。

  2. 目标机动的时间周期是事先未知的。如果已知目标没有机动,雷达可以不频繁地重新访问目标。然而,由于机动的开始和结束时间是未知的,雷达必须频繁地重新访问每个航迹,以能够识别机动的开始和结束时间。

雷达必须在提供足够的波束以跟踪目标为中心和留出足够的时间搜索新目标之间取得平衡。一种方法是简单地定义每个跟踪目标的重访率,而不考虑其机动状态,并将剩余的时间留给新目标搜索。这种雷达管理方案有时被称为积极跟踪[1].随着越来越多的目标被跟踪,雷达要么可以执行更少的搜索任务,要么可以更少地跟踪每个目标。显然,如果目标数量很大,雷达就会被淹没。

主动跟踪以相同的方式处理所有的轨迹,这使它成为一个模式基于资源管理算法。一种更复杂的管理雷达方式是基于每个轨道的属性。例如,使用轨道属性,例如状态不确定性协方差的大小,是轨道是否正在操纵,以及它朝向资产的速度快速地移动雷达站点。当使用此类属性时,雷达资源管理被称为自适应跟踪[1].

在此示例中,当基于估计的轨道操纵时,比较雷达时激活的主动跟踪和自适应跟踪的结果。

定义方案和雷达模型

您定义了一个场景和一个更新速率为20hz的雷达,这意味着该雷达每秒有20个波束用于搜索、确认或跟踪。加载的基准轨迹多目标跟踪的基准轨迹的例子。有六个基准轨迹你为每一个定义一个轨迹。图中六个平台由非机动支腿和机动支腿穿插而成。你可以在图中看到轨迹。

%创建场景updateRate = 20;场景= trackingScenario (“UpdateRate”, updateRate);%添加基准轨迹负载('BenchmarkTrajects.mat''-垫');平台(场景中,“轨迹”, v1Trajectory);平台(场景中,“轨迹”, v2Trajectory);平台(场景中,“轨迹”, v3Trajectory);平台(场景中,“轨迹”, v4Trajectory);平台(场景中,“轨迹”, v5Trajectory);平台(场景中,“轨迹”, v6Trajectory);%创建可视化f =图;议员= uipanel ('父母',F,“标题”“戏剧情节”“字形大小”12...“写成BackgroundColor”“白色”“位置”,[。01 .25 .98 .73]);税=轴(MP,“ZDir”“反向”);%可视化方案thp = theaterPlot ('父母'、税收、'axesunits',[“公里”“公里”“公里”],'xlimits'85000年[0],'ylimits'(-45000 70000),“ZLimits”,[ -  10000 1000]);PLP = platformplotter(THP,“DisplayName的”“平台”);人民行动党= trajectoryPlotter (thp,“DisplayName的”“轨迹”“线宽”1);dtp = detectionPlotter (thp,“DisplayName的”'检测');本量利= coveragePlotter (thp,“DisplayName的”“雷达覆盖”);trp = trackplotter(THP,“DisplayName的”“跟踪”“ConnectHistory”'在''colorizehistory''在');numPlatforms =元素个数(scenario.Platforms);trajectoryPositions =细胞(1、numPlatforms);为了i = 1: numplatestrajectorypositions {i} = lookupPose(scenario. plates{i}.Trajectory,(0:0.1:185));结尾plottrajectory(pap,轨迹属性);查看(税,3)

使用概率雷达模型使用radardatageneratorSystem Object™。设置'ScanMode”属性'风俗'允许资源管理器控制雷达角度。这使得雷达能够进行搜索、确认和跟踪目标的调度。在场景中,雷达安装在一个新的平台上。

雷达= radarDataGenerator (1,...“ScanMode”'风俗'...“UpdateRate”updateRate,...“MountingLocation”, [0 0 -15],...“FieldOfView”(3; 10),...“AzimuthResolution”, 1.5,...“HasElevation”,真的,...'检测''传感器球形');平台(场景中,“位置”(0 0 0),'传感器',雷达);

定义跟踪器

雷达探测到目标后,将探测结果反馈给跟踪器,跟踪器执行几项操作。跟踪器维护一个跟踪列表,这些跟踪是对感兴趣区域的目标状态的估计。如果一个检测不能被分配到任何已经由跟踪器维护的轨道,跟踪器会启动一个新的轨道。在大多数情况下,新轨迹代表的是真目标还是假目标尚不清楚。首先,创建一个带有试探性状态的轨道。如果获得足够的检测,轨迹就得到确认。类似地,如果没有对轨道进行检测,轨道就被滑行(预测没有校正)。如果曲目有一些遗漏的更新,跟踪器就会删除曲目。

在本例中,您使用了一个跟踪器,该跟踪器使用全局最近邻(GNN)算法将检测与轨迹关联起来。为了跟踪机动目标,你定义filterinitializationfcn.函数,用于初始化IMM过滤器。的initMPARIMM函数使用两个运动模型:一个恒定速度模型和一个恒定旋转速率模型。的trackingIMM过滤器负责估计每个模型的概率,您可以从其访问型号扶手财产。在本例中,当常数转弯率模型的概率大于0.6时,将目标分类为机动目标。

追踪= trackerGNN (“FilterInitializationFcn”,@ initmparimm,...“ConfirmationThreshold”3 [2],“DeletionThreshold”, 5 [5],...“HasDetectableTrackIDsInput”,真的,'AssignmentThreshold', 150,...“MaxNumTracks”10“MaxNumSensors”1);posSelector = [1 0 0 0 0 0;0 0 1 0 0 0;0 0 0 1 0];

雷达资源管理

本节只简要介绍雷达资源管理。有关详细信息,请参见管理雷达的机动目标的自适应跟踪(雷达工具箱)的例子。

搜索任务

在本例中,您确定地分配搜索任务。光栅扫描用于覆盖所需的空域。方位扫描限制被设置为[-90 60]度,仰角限制被设置为[-9.9 0]度。如果没有其他任务存在,雷达每次只扫描一个角单元。角单元的大小由雷达的大小决定FieldOfView财产。负仰角意味着雷达将波束从地平线指向上方。

AzimuthLimits = [-90 60];ElevationLimits = [-9.9 0];azscanspan = diff (AzimuthLimits);numazscan =地板(azscanspan / radar.FieldOfView (1) + 1;AzimuthLimits azscanangles = linspace (AzimuthLimits (1), (2), numazscan) + radar.MountingAngles (1);elscanspan = diff (ElevationLimits);numelscan =地板(elscanspan / radar.FieldOfView (2) + 1;ElevationLimits elscanangles = linspace (ElevationLimits (1), (2), numelscan) + radar.MountingAngles (2);[elscangrid, azscangrid] = meshgrid (elscanangles azscanangles);Scanangles = [azscangrid(:) elscangrid(:)].'; searchq = struct(“JobType”“搜索”'beamdirection'num2cell (scanangles 1),...“优先”, 1000,'waveformindex'1);current_search_idx = 1;

跟踪任务

与搜索任务不同,跟踪任务不能提前计划。相反,资源管理器会根据变化的场景创建确认和跟踪任务。这个例子和管理雷达的机动目标的自适应跟踪(雷达工具箱)例如JobType对于每个跟踪任务可以是“tracknonmaneuvering”“trackmaneuvering”.这两种跟踪任务之间的区别使您能够以不同的重访率为每种类型的跟踪安排任务,使其成为一种自适应跟踪算法。与搜索任务类似,跟踪任务也在作业队列中进行管理。

trackq = repmat(结构体(“JobType”,[],'beamdirection',[],“优先”, 3000,'waveformindex',[],...“时间”,[],'范围',[],“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;保持jobq的重置状态resetJobQ = jobq;

任务调度

在本例中,为简单起见,多功能雷达在一小段时间内只执行一种类型的任务,通常称为驻留,但可以在每个驻留开始时切换任务。对于每个驻留,雷达查看所有即将执行的任务,并选择一个确认任务或跟踪任务(如果运行时间到了)。否则,雷达会选择搜索任务。要控制运行任务的时间,可以设置经理服务结构如下所定义。给出了相当于雷达更新率的最高重新访问率确认任务,以确保确认波束遵循每个存在的新试探性轨道。类似地,您可以控制非机动和机动目标的重访率。在这种情况下,对于非机动目标和机动目标,分别选择0.8 Hz和4hz的值。由于有6个目标,资源管理器将使用 6 0 8 5 如果所有这些都没有操纵,则每秒更新每秒跟踪目标。鉴于雷达更新速率为20 Hz,雷达管理器将在每四个更新中执行大约一个目标更新。因此,雷达将在搜索模式中花费约75%的时间和跟踪模式中的25%的时间。当初始化新曲目并且当跟踪器认为目标正在操纵时,资源管理器以牺牲搜索波束为代价分配更多的跟踪波束。

“分析结果”部分显示了其他选项的结果。

managerPreferences =结构(...“类型”,{“搜索”“确认”“tracknonmaneuvering”“trackmaneuvering”},...'revisitrate',{0,updaterate,0.8,4},...“优先”, {1000, 3000, 1500, 2500});

运行场景

在仿真过程中,雷达波束分别用蓝色和紫色表示搜索波束和轨道波束。您还可以使用图底部的“最后一秒”面板中的“资源分配”,查看模拟的最后一秒在搜索和特定轨道之间的任务分配。在图的剧场图部分,你可以看到每个轨迹的历史,并将其与轨迹进行比较。

%创建雷达资源分配显示rp = uipanel ('父母',F,“标题”“最后一秒的资源配置”“字形大小”12...“写成BackgroundColor”“白色”“位置”,(。01 0.01 0.98 0.23]); rax = axes(rp);%运行该场景AllocationType = HelperAdiveTrackingsim(方案,THP,rax,跟踪器,resetjobq,ManagerPreferences);

分析结果

分析雷达任务负荷及其搜索、确认和跟踪任务的划分。从图中可以看出,大多数情况下,雷达分配约75%的搜索任务和25%的跟踪任务,这与目标不机动时的预期情况一致。当目标被操纵时,资源管理器进行调整以分配更多的跟踪作业。当更多的轨道同时机动时,跟踪任务就会更多,如图所示,在第700个时间步附近。确认任务占用的雷达时间很少,因为跟踪器被配置为在三次尝试中两次检测关联后确认跟踪。因此,确认或拒绝试探性轨道是迅速的。

numSteps =元素个数(allocationType);numSteps allocationSummary = 0(3日);为了我= 1:numSteps为了jobType = 1:3 allocationSummary(jobType,i) = sum(allocationType(1,max(1,i-2*updateRate+1):i)==jobType)/min(i-1,2*updateRate);结尾结尾数字;plot(1:numsteps,Allocationsummary(:,1:numsteps))标题(“雷达分配与时间步长”);包含(“时间步”);ylabel (“每个模式最后两秒的步数”);传奇(“搜索”“确认”'追踪');网格

将此结果与0.8 Hz航迹重访率下主动跟踪的结果进行比较。下图显示了主动跟踪案例的跟踪结果和雷达分配图。跟踪结果表明,有部分航迹丢失或损坏,但雷达资源分配图与自适应跟踪情况下的75%搜索和25%跟踪任务划分相似。您可以通过执行下面的代码示例来获得这些结果。

cleardata(plp);cleardata(DTP);cleardata(TRP);重置(跟踪);重启(方案);%对非机动和机动目标修改管理器首选项为1hz重访率managerPreferences =结构(...“类型”,{“搜索”“确认”“tracknonmaneuvering”“trackmaneuvering”},...'revisitrate', {0, updateRate, 0.8, 0.8},...“优先”, {1000, 3000, 1500, 2500});%运行该场景AllocationType = HelperAdiveTrackingsim(方案,THP,rax,跟踪器,resetjobq,ManagerPreferences);

显然,主动跟踪需要更高的跟踪重访率。从下图可以看出,将跟踪重访率提高到2hz可以改善机动目标的跟踪。然而,雷达的成本是,即使在轨迹不机动的情况下,也要将超过50%的时间用于跟踪任务。如果目标数量更多,雷达就会不堪重负。

以往的研究结果表明,以2hz的频率重新访问机动目标就足够了。然而,自适应跟踪是否可以降低0.8 Hz以上非机动目标的重访率?下图分别给出了无机动和机动目标在0.6 Hz和4hz下的结果。有了这个设置,雷达资源分配允许80%-85%的时间在搜索模式,使雷达有能力搜索和跟踪更多的目标。

总结

该实例说明了如何将跟踪和雷达资源管理相结合来适应机动航迹的重访率。自适应跟踪允许您选择适合每个目标类型和机动状态的重访率。结果,雷达变得更加高效,可以跟踪更多机动目标。

参考文献

[1]浅效,亚历山大,民谣霍夫曼,Christoph Degen和Isabel Schlangen。“从自适应到认知雷达资源管理的发展。”航空和电子系统杂志35岁,没有。6(2020年6月1日):8-19。https://doi.org/10.1109/maes.2019.2957847

金宝app支持功能

getCurrentRadarTask

返回用于指向雷达波束的雷达任务。

类型(“getCurrentRadarTask.m”
函数[currentjob,jobq] = getCurrentradArtask(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 = RequestIdX(maxpidx);%如果找到的曲目作业具有更高的优先级,则使用它作为当前的作业%并增加下一个搜索作业优先级,因为它被推迟。否则%,下一个搜索作业到期是当前作业。 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

运行仿真

类型(“helperAdaptiveTrackingSim.m”
函数allocationType = helperAdaptiveTrackingSim(scenario, thp, rax, tracker, resetJobQ, managerPreferences) %初始化变量radar = scenario. platform {end}.Sensors{1};updateRate = radar.UpdateRate;resourceAllocation =南(1、updateRate);h =直方图(resourceAllocation伸出,“BinMethod”,“整数”);包含(h.Parent TrackID) ylabel (h。父母,“Num梁”);numSteps = updateRate * 185;allocationType =南(1、numSteps);currentStep = 1;重启(场景);重置(跟踪); % 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 tracks = {}; 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); radar.LookAngle = 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) [confirmedTracks,tentativeTracks,~,analysisInformation] = tracker(detections, time, detectableTracks); pos = getTrackPositions(confirmedTracks,jobq.PositionSelector); plotTrack(trp,pos,string([confirmedTracks.TrackID])); tracks.confirmedTracks = confirmedTracks; tracks.tentativeTracks = tentativeTracks; tracks.analysisInformation = analysisInformation; tracks.PositionSelector = jobq.PositionSelector; end % Manage resources for next jobs jobq = manageResource(detections,jobq,tracker,tracks,currentJob,time,managerPreferences); end

initMPARIMM

初始化跟踪器使用的IMM过滤器。

类型(“initMPARIMM.m”
函数imm = initMPARIMM(检测)cvekf = initcvekf(检测);cvekf.StateCovariance (2, 2) = 1 e6;cvekf.StateCovariance (4, 4) = 1 e6;cvekf.StateCovariance (6,6) = 1 e6;ctekf = initctekf(检测);ctekf.StateCovariance (2, 2) = 1 e6;ctekf.StateCovariance (4, 4) = 1 e6;ctekf.StateCovariance (7) = 1 e6;ctekf.ProcessNoise (3) = 1 e6;%大噪声未知角加速度imm = trackingIMM('TrackingFilters', {cvekf;ctekf}, ' transitionprobability ', [0.99, 0.99]);

manageResources

管理作业队列并根据跟踪结果创建新任务。

类型(“manageResource.m”
函数jobq = manageResource(detectionjobq,tracker,tracks,current_job,current_time,managerPreferences) trackq = jobq. trackqueue;num_trackq_items = jobq.NumTrackJobs;如果~为空(检测)检测=检测{1};Else检测= [];end %执行当前任务开关current_job。JobTypecase 'Search' % For search job, if there is a detection, establish tentative % track and schedule a confirmation job if ~isempty(detection) % 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. Create % confirm jobs for tentative tracks created at this update. numTentative = numel(tracks.tentativeTracks); for i = 1:numTentative if tracks.tentativeTracks(i).Age == 1 && tracks.tentativeTracks(i).IsCoasted == 0 trackid = tracks.tentativeTracks(i).TrackID; job = revisitTrackJob(tracker, trackid, current_time, managerPreferences, 'Confirm', tracks.PositionSelector); num_trackq_items = num_trackq_items+1; trackq(num_trackq_items) = job; end end end case 'Confirm' % For a confirm job, if the track ID is within the tentative % tracks, it means that we need to run another confirmation job % regardless of having a detection. If the track ID is within the % confirmed tracks, it means that we must have gotten a detection, % and the track passed the confirmation logic test. In this case we % need to schedule a track revisit job. trackid = current_job.TrackID; tentativeTrackIDs = [tracks.tentativeTracks.TrackID]; confirmedTrackIDs = [tracks.confirmedTracks.TrackID]; if any(trackid == tentativeTrackIDs) job = revisitTrackJob(tracker, trackid, current_time, managerPreferences, 'Confirm', tracks.PositionSelector); num_trackq_items = num_trackq_items+1; trackq(num_trackq_items) = job; elseif any(trackid == confirmedTrackIDs) job = revisitTrackJob(tracker, trackid, current_time, managerPreferences, 'TrackNonManeuvering', tracks.PositionSelector); num_trackq_items = num_trackq_items+1; trackq(num_trackq_items) = job; end otherwise % Covers both types of track jobs % For track job, if the track hasn't been dropped, update the track % and schedule a track job corresponding to the revisit time % regardless of having a detection. In the case when there is no % detection, we could also predict and schedule a track job sooner % so the target is not lost. This would require defining another % job type to control the revisit rate for this case. trackid = current_job.TrackID; confirmedTrackIDs = [tracks.confirmedTracks.TrackID]; if any(trackid == confirmedTrackIDs) jobType = 'TrackNonManeuvering'; mdlProbs = getTrackFilterProperties(tracker, trackid, 'ModelProbabilities'); if mdlProbs{1}(2) > 0.6 jobType = 'TrackManeuvering'; end job = revisitTrackJob(tracker, trackid, current_time, managerPreferences, jobType, tracks.PositionSelector); num_trackq_items = num_trackq_items+1; trackq(num_trackq_items) = job; end end jobq.TrackQueue = trackq; jobq.NumTrackJobs = num_trackq_items; end function job = revisitTrackJob(tracker, trackID, currentTime, managerPreferences, jobType, positionSelector) types = [managerPreferences.Type]; inTypes = strcmpi(jobType,types); revisitTime = 1/managerPreferences(inTypes).RevisitRate + currentTime; predictedTrack = predictTracksToTime(tracker,trackID,revisitTime); xpred = getTrackPositions(predictedTrack,positionSelector); [phipred,thetapred,rpred] = cart2sph(xpred(1),xpred(2),xpred(3)); job = struct('JobType',jobType,'Priority',managerPreferences(inTypes).Priority,... 'BeamDirection',rad2deg([phipred thetapred]),'WaveformIndex',1,'Time',revisitTime,... 'Range',rpred,'TrackID',trackID); end