主要内容

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

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

简介

多功能雷达可以搜索目标,确认新的航迹,并重访航迹以更新状态。为了执行这些功能,一个多功能雷达通常由一个资源管理器来管理,该资源管理器创建用于搜索、确认和跟踪的雷达任务。这些任务根据优先级和时间安排,以便在每个时间步骤中,多功能雷达可以将波束指向所需的方向。的多功能相控阵雷达搜索与跟踪调度(雷达工具箱)实例显示了一个由资源管理器管理的多功能相控阵雷达。

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

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

  2. 目标机动的时间范围是预先未知的。如果已知目标不在机动,雷达可以不频繁地重访目标。然而,由于机动开始和结束时间是未知的,雷达必须足够频繁地重新访问每个轨道,以便能够识别机动开始和结束的时间。

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

主动跟踪以相同的方式处理所有轨迹,这使它成为一个模式基于的资源管理算法。管理雷达的一种更复杂的方法是基于每条航迹的特性。例如,使用轨道属性,如状态不确定性协方差的大小,轨道是否机动,以及它移动到雷达站点保护的资产的速度。当使用这些属性时,雷达资源管理被称为自适应跟踪[1]。

在本例中,您将比较雷达基于估计航迹机动进行适应时主动跟踪和自适应跟踪的结果。

定义场景和雷达模型

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

%创建场景updateRate = 20;scenario = trackingScenario(“UpdateRate”, updateRate);添加基准轨迹负载(“BenchmarkTrajectories.mat”“垫”);平台(场景中,“轨迹”, v1Trajectory);平台(场景中,“轨迹”, v2Trajectory);平台(场景中,“轨迹”, v3Trajectory);平台(场景中,“轨迹”, v4Trajectory);平台(场景中,“轨迹”, v5Trajectory);平台(场景中,“轨迹”, v6Trajectory);%创建可视化F =数字;Mp = uipanel(“父”f“标题”“戏剧情节”“字形大小”12...“写成BackgroundColor”“白色”“位置”,(。01 .25 .98 .73]); tax = axes(mp,“ZDir”“反向”);%可视化场景thp = theaterPlot(“父”、税收、“AxesUnits”,[“公里”“公里”“公里”),“XLimits”85000年[0],“YLimits”(-45000 70000),“ZLimits”1000年[-10000]);plp = platformPlotter(thp,“DisplayName的”“平台”);pap =轨迹绘图器(thp,“DisplayName的”“轨迹”“线宽”1);dtp = detectionPlotter(thp,“DisplayName的”“检测”);cvp = coveragePlotter(thp,“DisplayName的”“雷达覆盖”);trp = trackPlotter(thp,“DisplayName的”“跟踪”“ConnectHistory”“上”“ColorizeHistory”“上”);numPlatforms = numel(scenario.Platforms);轨迹位置= cell(1,numPlatforms);i = 1:numPlatforms trajectoryPositions{i} = lookupPose(scenario.Platforms{i}.Trajectory,(0:0.1:185));结束trajectoryPositions plotTrajectory (pap);视图(税,3)

{

定义了概率雷达模型radarDataGenerator系统对象™。设置ScanMode”属性“自定义”允许资源管理器控制雷达观察角度。这使得雷达搜索、确认和跟踪目标的调度成为可能。在该场景中,雷达安装在一个新的平台上。

雷达= radardatgenerator (1,...“ScanMode”“自定义”...“UpdateRate”updateRate,...“MountingLocation”, [0 0 -15],...“AzimuthResolution”, 1.5,...“ElevationResolution”10...“HasElevation”,真的,...“DetectionCoordinates”“球形传感器”);平台(场景中,“位置”,[0 0 0],“传感器”、雷达);

定义跟踪器

雷达探测到目标后,将探测结果反馈给跟踪器,跟踪器执行若干操作。跟踪器维护一个轨道列表,这些轨道是对感兴趣区域的目标状态的估计。如果检测不能分配给跟踪器已经维护的任何跟踪,跟踪器将启动一个新的跟踪。在大多数情况下,新轨道代表的是真实目标还是虚假目标尚不清楚。首先,创建一个带有临时状态的轨道。如果探测到足够多的信号,就可以确认航迹。类似地,如果没有将检测分配给轨道,则轨道是海岸化的(无需校正的预测)。如果轨道有一些遗漏的更新,跟踪器删除轨道。

在本例中,您使用一个跟踪器,该跟踪器使用全局最近邻(GNN)算法将检测与轨道关联起来。为了跟踪机动目标,定义一个FilterInitializationFcn初始化IMM筛选器的函数。的initMPARIMM函数使用两个运动模型:匀速模型和匀速转弯模型。的trackingIMMFilter负责估计每个模型的概率,您可以从它的ModelProbabilities财产。在本例中,当恒定转弯速率模型的概率高于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 0 1 0 0 0;0 0 0 0 0 0];

雷达资源管理

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

搜索任务

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

AzimuthLimits = [-90 60];ElevationLimits = [-9.9 0];azscanspan = diff(AzimuthLimits);numazscan = floor(azscanspan/radar.AzimuthResolution)+1;azscanangles = linspace(AzimuthLimits(1),AzimuthLimits(2),numazscan)+radar.MountingAngles(1);elscanspan = diff(ElevationLimits);numelscan = floor(elscanspan/radar.ElevationResolution)+1;elscanangles = linspace(ElevationLimits(1),ElevationLimits(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(struct(“JobType”[],“BeamDirection”[],“优先”, 3000,“WaveformIndex”[],...“时间”[],“范围”[],“TrackID”,[]), 10, 1);Num_trackq_items = 0;

将搜索和跟踪队列分组在一个结构中,以便在模拟循环中更容易引用。

jobq。SearchQueue = searchq;jobq。searchchindex = current_search_idx;jobq。TrackQueue = trackq;jobq。NumTrackJobs = num_trackq_items;jobq。PositionSelector = posSelector;保持jobq的重置状态resetJobQ = jobq;

任务调度

在本例中,为简单起见,多功能雷达在小时间周期内只执行一种类型的作业,通常称为驻留,但可以在每次驻留开始时切换任务。对于每个驻留,雷达查看所有到期执行的任务,并选择一个确认或跟踪任务(如果运行时间已经到了)。否则,雷达会选择一个搜索任务。要控制运行任务的时间,可以设置managerPreferences结构定义如下。最高的重访率,等于雷达更新率,给予确认任务,以确保确认束跟随存在的每个新的暂定轨道。类似地,您可以控制非机动目标和机动目标的重访率。在本例中,非机动目标和机动目标分别选择0.8 Hz和4 Hz的值。由于有6个目标,资源管理器将使用 6 0 8 5 如果所有目标都不机动,则每秒更新跟踪目标。假设雷达更新速率为20赫兹,雷达管理器将在每四次更新中执行大约一次目标更新。因此,雷达将花费大约75%的时间在搜索模式和25%的时间在跟踪模式。当初始化新的航迹并且跟踪器认为目标处于机动状态时,资源管理器以牺牲搜索波束为代价分配更多的跟踪波束。

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

managerPreferences = struct(...“类型”,{“搜索”“确认”“TrackNonManeuvering”“TrackManeuvering”},...“RevisitRate”, {0, updateRate, 0.8, 4},...“优先”, {1000, 3000, 1500, 2500});

运行场景

在模拟过程中,雷达波束分别用蓝色或紫色表示搜索和跟踪相关波束。您还可以通过图底部last second面板中的Resource Allocation查看模拟的最后一秒搜索和特定轨道之间的任务分布。在图的Theater Plot部分,您可以看到每个轨道的历史,并将其与轨迹进行比较。

创建雷达资源分配显示Rp = uipanel(“父”f“标题”“最后一秒的资源分配”“字形大小”12...“写成BackgroundColor”“白色”“位置”,(。01 0.01 0.98 0.23]); rax = axes(rp);%运行场景allocationType = helperAdaptiveTrackingSim(scenario, thp, rax, tracker, resetJobQ, managerPreferences);

{

分析结果

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

numSteps = numel(allocationType);allocationSummary = 0 (3,numSteps);i = 1:numStepsjobType = 1:3 allocationSummary(jobType,i) = sum(allocationType(1,max(1,i-2*updateRate+1):i)==jobType)/min(i-1,2*updateRate);结束结束图;阴谋(1:numSteps allocationSummary (: 1: numSteps))标题(“雷达分配与时间步长”);包含(“时间步”);ylabel ('每种模式中最后两秒的步数分数');传奇(“搜索”“确认”“跟踪”);网格

图中包含一个轴对象。标题为Radar Allocation vs. Time Step的axis对象包含3个类型为line的对象。这些对象表示搜索、确认、跟踪。

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

clearData (plp);clearData (dtp);clearData (trp);重置(跟踪);重启(场景);对非机动目标和机动目标修改管理员首选项为0.8 Hz重访率managerPreferences = struct(...“类型”,{“搜索”“确认”“TrackNonManeuvering”“TrackManeuvering”},...“RevisitRate”, {0, updateRate, 0.8, 0.8},...“优先”, {1000, 3000, 1500, 2500});%运行场景allocationType = helperAdaptiveTrackingSim(scenario, thp, rax, tracker, resetJobQ, managerPreferences);

ActiveTracking0808.png

显然,主动跟踪需要更高的跟踪重访率。从下面两张图可以看出,将航迹重访率提高到2hz,可以更好地跟踪机动目标。然而,代价是雷达将超过50%的时间用于跟踪任务,即使履带没有机动。如果目标数量更多,雷达就会不堪重负。

radarAllocation22.png

前人的研究结果表明,在2hz的频率下对机动目标进行重访是足够的。但是,自适应跟踪能否将非机动目标的重访率降低到0.8 Hz以上?下面的图表分别显示了0.6 Hz和4 Hz的非机动目标和机动目标的结果。通过这种设置,雷达资源分配允许80%-85%的时间处于搜索模式,使雷达具有搜索和跟踪更多目标的能力。

ActiveTracking064.png

总结

通过实例说明了如何利用跟踪与雷达资源管理相结合的方法来调整机动航迹的重访率。自适应跟踪允许您选择适合每个目标类型和机动状态的重访率。结果,雷达变得更有效,并能跟踪更多数量的机动目标。

参考文献

Charlish, Alexander, Folker Hoffmann, Christoph Degen和Isabel Schlangen。“雷达资源管理从自适应到认知的发展”IEEE航空航天和电子系统杂志35岁,没有。6(2020年6月1日):8-19。https://doi.org/10.1109/MAES.2019.2957847

支持功能

getCurrentRadarTask

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

类型(“getCurrentRadarTask.m”
function [currentjob,jobq] = getCurrentRadarTask(jobq,current_time) searchq = jobq. searchqueue;trackq = jobq.TrackQueue;searchidx = jobq. searchchindex;num_trackq_items = jobq.NumTrackJobs;%更新搜索队列索引searchqidx = mod(searchidx-1,数字(searchq))+1;查找到期且优先级最高的跟踪任务readyidx = Find ([trackq(1:num_trackq_items).Time]<=current_time);[~,maxpidx] = max([trackq(readyidx).Priority]);Taskqidx = readyidx(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”
function allocationType = helperAdaptiveTrackingSim(scenario, thp, rax, tracker, resetJobQ, managerPreferences) %初始化变量radar = scenario. platforms {end}.Sensors{1};updateRate = radar.UpdateRate;resourceAllocation = nan(1,updateRate);h =直方图(rax,resourceAllocation,'BinMethod','integers');包含(h.Parent TrackID) ylabel (h。父母,“Num梁”);numSteps = update * 185;allocationType = nan(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); ax = gca; colors = ax.ColorOrder; % 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 = colors(1, :); else detectableTracks = currentJob.TrackID; resourceAllocation(min([currentStep,updateRate])) = currentJob.TrackID; if strcmpi(currentJob.JobType,'Confirm') allocationType(currentStep) = 2; cvp.Color = colors(2, :); else allocationType(currentStep) = 3; cvp.Color = colors(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) = 1e6;cvekf.StateCovariance(4,4) = 1e6;cvekf.StateCovariance(6,6) = 1e6;Ctekf = initctekf(检测);ctekf.StateCovariance(2,2) = 1e6;ctekf.StateCovariance(4,4) = 1e6;ctekf.StateCovariance(7,7) = 1e6;ctekf.ProcessNoise(3,3) = 1e6;%未知角加速度的大噪声imm = trackingIMM('TrackingFilters', {cvekf;ctekf}, ' transitionprobability ', [0.99, 0.99]);

manageResources

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

类型(“manageResource.m”
函数jobq = manageResource(检测,jobq,tracker,tracks,current_job,current_time,managerPreferences)num_trackq_items = jobq.NumTrackJobs;如果~为空(检测)检测=检测{1};Else检测= [];执行当前作业切换current_job. end %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
Baidu
map