主要内容

调优多对象跟踪器

这个例子展示了如何调优和运行跟踪器来跟踪场景中的多个对象。该示例解释并演示了传感器融合和跟踪工具箱中跟踪器的关键属性的重要性。

默认跟踪器配置

为了测试跟踪器跟踪多个对象的能力,您设置了一个基本场景。在这个场景中,您定义了三个物体,每个物体都沿直线匀速移动。最初,您将物体速度分别设置为48米/秒、60米/秒和72米/秒。

stopTime = 10;V = 60;scenario = trackingScenario;场景。StopTime = StopTime;场景。UpdateRate = 0;P1 =平台(场景);p1。轨迹= waypoint轨迹([20 10 0; 20 .8*v*stopTime-10 0], [0 stopTime]); p2 = platform(scenario); p2.Trajectory = waypointTrajectory([0 0 0; 0 v*stopTime 0], [0 stopTime]); p3 = platform(scenario); p3.Trajectory = waypointTrajectory([-20 -10 0; -20 1.2*v*stopTime+10 0], [0 stopTime]);

此外,您还定义了一个雷达,它盯着场景,每秒更新5次。你把它安装在移动物体一侧的平台上。

pRadar =平台(场景);pRadar。轨迹=运动学轨迹(“位置”, [-v*stopTime 0.5*v*stopTime 0]);雷达= fusionRadarSensor(1,“没有扫描”“UpdateRate”5,...“MountingAngles”, [0 0 0],“AzimuthResolution”, 1...“FieldOfView”, [100 1],“之内”,真的,“DetectionCoordinates”“场景”);pRadar。传感器=雷达;

你创造了一个戏剧情节来展示这个场景。

图;Ax =轴(fig);tp = theaterPlot(“父”ax,“XLimits”, [-11*v 100],“YLimits”, [-50 15*v],“ZLimits”, [-100 100]);rp = platformPlotter(tp,“DisplayName的”“雷达”“标记”' d ');pp = platformPlotter(tp,“DisplayName的”“平台”);dp = detectionPlotter(tp,“DisplayName的”“检测”);trp = trackPlotter(tp,“DisplayName的”“跟踪”“ConnectHistory”“上”“ColorizeHistory”“上”);covp = coveragePlotter(tp,“DisplayName的”“雷达覆盖”“α”, [0.1 0]);

最后,创建一个默认值trackerGNN对象,运行该场景,并观察结果。你使用trackGOSPAMetric评估跟踪器的性能。

tracker = trackerGNN;tgm = trackGOSPAMetric(“距离”“posabserr”);Gospa = 0 (1,51);时间步长的百分比是51I = 0;为可重复的结果定义随机数生成器种子S = rng(2019);推进(场景)%获得检测Dets =检测(场景);更新跟踪器如果isLocked(tracker) || ~isempty(dets) [tracks, ~, ~, info] = tracker(dets, scene . simulationtime);结束%评估GOSPAI = I + 1;truth = platformposed(场景);Gospa (i) = tgm(轨道,真理);更新显示updateDisplay(rp, pp, dp, trp, covp,场景,dets,轨道);结束

图中包含一个轴对象。axis对象包含9个类型为line、patch、text的对象。这些对象代表雷达、平台、探测、轨迹、(历史)、雷达覆盖范围。

Rng (s)图形图(gospa)标题(“广义OSPA vs. Timestep”

图中包含一个轴对象。标题为Generalized OSPA vs. Timestep的axes对象包含一个类型为line的对象。

您可以观察到跟踪器无法跟踪这三个对象。在某个时刻,除了三个移动物体的三条预期轨道之外,还会确认并显示其他轨道。结果,GOSPA度量的值增加了。注意,GOSPA度量值越低,跟踪器性能越好。

赋值阈值

你看信息结构,跟踪器输出,并观察CostMatrix作业不要显示你期望发生的轨道和对象对的分配。这意味着AssignmentThreshold太小了,应该增加。将分配阈值增加到50。

释放(跟踪);跟踪器。AssignmentThreshold = 50;rerunScenario(场景,跟踪器,tgm, tp);

图中包含一个轴对象。axis对象包含9个类型为line、patch、text的对象。这些对象代表雷达、平台、探测、轨迹、(历史)、雷达覆盖范围。

图中包含一个轴对象。标题为Generalized OSPA vs. Timestep的axes对象包含一个类型为line的对象。

赋值阈值属性还具有可设置的距离检测的最大距离。这是最后一个元素AssignmentThreshold价值。在处理大量检测和跟踪时,可以使用此值加快跟踪器的速度。请参阅如何有效跟踪大量对象示例获取更多详细信息。这里,您将值设置为2000而不是,这将减少用于计算分配成本的轨道和探测的组合数量。

释放(跟踪);跟踪器。AssignmentThreshold = [50 2000];rerunScenario(场景,跟踪器,tgm, tp);

图中包含一个轴对象。axis对象包含9个类型为line、patch、text的对象。这些对象代表雷达、平台、探测、轨迹、(历史)、雷达覆盖范围。

图中包含一个轴对象。标题为Generalized OSPA vs. Timestep的axes对象包含一个类型为line的对象。

Filter初始化函数

结果表明,跟踪器能够在不产生伪迹的情况下对三个运动物体保持三条轨迹。然而,如果物体以更快的速度移动,跟踪器的性能还能保持吗?为了验证这一点,修改场景并将对象速度分别提高到160、200和240米/秒。

V = 200;p1。轨迹= waypoint轨迹([20 -10 0;20 0.8*v*stopTime-10 0], [0 stopTime]);p2。轨迹= waypointTrajectory([0 0 0;0 v*stopTime 0], [0 stopTime]);p3。轨迹= waypointTrajectory([-20 10 0;-20 1.2*v*stopTime+10 0], [0 stopTime]); pRadar.Trajectory = kinematicTrajectory(“位置”, [-v*stopTime 0.5*v*stopTime 0]);tp。XLimits = [-100-v*stopTime 300];tp。YLimits = [-100 100+v*1.2*stopTime];释放(雷达);radar.RangeLimits(2) = 3000;rerunScenario(场景,跟踪器,tgm, tp);

图中包含一个轴对象。axis对象包含9个类型为line、patch、text的对象。这些对象代表雷达、平台、探测、轨迹、(历史)、雷达覆盖范围。

图中包含一个轴对象。标题为Generalized OSPA vs. Timestep的axes对象包含一个类型为line的对象。

正如你可能预料的那样,跟踪器无法建立三个物体的稳定轨迹。一个可能的解决办法是增加AssignmentThreshold甚至还允许更新音轨。但是,此选项可能会增加随机错误跟踪被分配给多次检测并得到确认的几率。因此,您选择修改筛选器的初始化方式。

你设置FilterInitializationFcn属性赋予函数。initFastCVEKF.功能与缺省值相同initcvekf除了它增加了状态中速度分量的不确定性。它允许初始状态解释更大的未知速度值,但一旦轨迹建立,不确定性再次降低。

发布追踪(追踪)。FilterInitializationFcn= @initFastCVEKF; rerunScenario(scenario, tracker, tgm, tp);

图中包含一个轴对象。axis对象包含9个类型为line、patch、text的对象。这些对象代表雷达、平台、探测、轨迹、(历史)、雷达覆盖范围。

图中包含一个轴对象。标题为Generalized OSPA vs. Timestep的axes对象包含一个类型为line的对象。

您可以观察到跟踪器再次能够保持轨道,并且三个移动对象有3个轨道,尽管它们现在移动得更快。在几个步骤之后,GOSPA值也会降低。

确认和删除阈值

您希望确保您的跟踪器对较高的误报率具有健壮性。为此,您将雷达配置为具有比以前高250倍的误报率。

您可以缩小以查看场景的更大部分,并查看是否创建了错误的轨道。

释放(雷达);雷达。FalseAlarmRate = 2.5e-4;tp。XLimits = [-2100 300];tp。YLimits = [-100 3100];tp。ZLimits = [-1000 1000];rerunScenario(场景,跟踪器,tgm, tp);

图中包含一个轴对象。axis对象包含9个类型为line、patch、text的对象。这些对象代表雷达、平台、探测、轨迹、(历史)、雷达覆盖范围。

图中包含一个轴对象。标题为Generalized OSPA vs. Timestep的axes对象包含一个类型为line的对象。

创建了一些错误的轨道(并不是所有的轨道都显示出来),它们增加了GOSPA值。

方法可以更快地删除错误音轨DeletionThreshold财产。删除阈值默认值为[5 5],即连续5次未命中才会删除已确认的音轨。您可以通过将该值减少为[3 3]或3 / 3的错误来加快删除过程。或者,由于雷达DetectionProbability是高的,你甚至可以删除一个轨道后2 / 3的失误,通过设置:

发布追踪(追踪)。DeletionThreshold= [2 3]; rerunScenario(scenario, tracker, tgm, tp);

图中包含一个轴对象。axis对象包含10个类型为line、patch、text的对象。这些对象代表雷达、平台、探测、轨迹、(历史)、雷达覆盖范围。

图中包含一个轴对象。标题为Generalized OSPA vs. Timestep的axes对象包含一个类型为line的对象。

正如预期的那样,减少删除音轨所需的步数会降低GOSPA值,因为这些假音轨是短暂的。然而,这些错误的跟踪仍然被确认,并降低了整体跟踪质量。

因此,您希望对新音轨的确认更加严格,以减少错误音轨的数量。考虑跟踪器ConfirmationThreshold财产。

disp (tracker.ConfirmationThreshold);
2 3

该值显示,如果在前三次更新中分配了两次检测,跟踪器将确认每个跟踪。您决定增加轨道确认的难度,并将值重置为4个分配中的3个。

发布追踪(追踪)。ConfirmationThreshold= [3 4]; rerunScenario(scenario, tracker, tgm, tp);

图中包含一个轴对象。axis对象包含9个类型为line、patch、text的对象。这些对象代表雷达、平台、探测、轨迹、(历史)、雷达覆盖范围。

图中包含一个轴对象。标题为Generalized OSPA vs. Timestep的axes对象包含一个类型为line的对象。

通过更加严格的航迹确认,可以消除错误航迹。结果,除了前几个步骤外,GOSPA值又降到了20左右。

最大轨道数

更严格的确认可以消除错误的轨迹。但是,跟踪器仍然为每个错误检测初始化一个跟踪,您可以通过查看跟踪器当前维护的跟踪数量来观察到这一点。

轨迹的数量在跟踪器的整个生命周期中波动。但是,您不希望它超过跟踪器可以维护的最大轨道数,由MaxNumTracks,默认为100。如果跟踪器超过这个数字,它会发出一个警告,提示不能添加新轨道,但可以继续执行。

增加跟踪的最大数量,以允许跟踪器在不发出警告的情况下跟踪更高的误报率。您还希望使轨迹确认更加严格,以减少错误轨迹的数量并减少GOSPA度量。

发布追踪(追踪)。MaxNumTracks = 200;跟踪器。ConfirmationThreshold = [5 6];释放(雷达)雷达。FalseAlarmRate = 1e-3;rerunScenario(场景,跟踪器,tgm, tp);

图中包含一个轴对象。axis对象包含9个类型为line、patch、text的对象。这些对象代表雷达、平台、探测、轨迹、(历史)、雷达覆盖范围。

图中包含一个轴对象。标题为Generalized OSPA vs. Timestep的axes对象包含一个类型为line的对象。

请注意,更严格的航迹确认需要更多的步骤来确认航迹。因此,在最初的几个步骤中,没有确定的轨道,GOSPA值仍然很高。您可以将其与本例开头的GOSPA图进行比较。

试试其他追踪器

你想尝试使用另一种跟踪器,在这种情况下,联合概率数据协会跟踪器,trackerJPDA.为前一个跟踪器定义的许多属性在JPDA跟踪器中仍然有效。你可以使用helperGNN2JPDA来构建JPDA跟踪器。

jpda = helperGNN2JPDA(跟踪器);jpda。ClutterDensity = 1e-3;rerunScenario(场景,跟踪器,tgm, tp);

图中包含一个轴对象。axis对象包含9个类型为line、patch、text的对象。这些对象代表雷达、平台、探测、轨迹、(历史)、雷达覆盖范围。

图中包含一个轴对象。标题为Generalized OSPA vs. Timestep的axes对象包含一个类型为line的对象。

总结

在这个例子中,你学习了如何设置多目标跟踪器来维护场景中真实物体的轨迹,避免错误的轨迹,保持正确的轨迹数量,以及在不同的跟踪器之间切换。

当调优多对象跟踪器时,考虑更改以下属性:

FilterInitializationFcn -定义用于初始化带有未分配检测的新轨道的筛选器。

  • 函数定义了运动和测量模型。

  • 检查状态不确定性是否正确地表示为StateCovariance过滤器的。例如,大的初始速度协方差允许跟踪快速移动的物体。

AssignmentThreshold -将探测分配到航迹时使用的最大归一化距离。

  • 减小这个值可以加快分配速度,特别是在有许多轨道的大型场景中,并避免错误轨道、冗余轨道和轨道交换。如果使用trackerJPDA,减少此值将减少被认为分配给单个轨道的检测数量。如果使用trackerTOMHT,减少分配阈值可以减少创建的轨道分支的数量。

  • 增加此值以避免在出现新探测时航迹偏离和盈亏平衡。

MaxNumTracks -跟踪器维护的最大轨道数。

  • 减小此值可最小化内存使用并加快跟踪器初始化。

  • 增加此值以避免由于达到限制而无法初始化新轨道。

ConfirmationThreshold -控制新航迹的确认。

  • 减小此值可确认更多航迹并更快地确认航迹。

  • 增加此值以减少错误轨道的数量。

DeletionThreshold -控制滑行和删除轨道。

  • 减小这个值可以更快地删除轨道(例如,当检测到的概率很高时)。

  • 增加此值以补偿较低的检测概率(例如,遮挡期间的海岸轨迹)。

你可以参考以下例子了解更多细节:如何为跟踪器生成C代码履带逻辑概论模糊状态下跟踪紧密间隔目标,利用GM-PHD跟踪器跟踪密集杂波中的点目标

效用函数

updateDisplay

这个函数在模拟的每一步更新显示。

函数updateDisplay(rp, pp, dp, trp, covp,场景,dets,轨道)绘制平台位置姿势=平台姿势(场景);姿势(1:3)。位置],3,[])';%仅限平台plotPlatform (pp、pos);radarPos =姿势(4).位置;%只有雷达radarPos plotPlatform (rp)绘制检测位置如果~isempty(dets) ds = [dets{:}];dPos =重塑([ds.]测量],3,[])';其他的dPos = 0 (0,3);结束dPos plotDetection (dp);%绘制轨道tPos = getTrackPositions(tracks, [1 0 0 0 0 0 0;0 0 1 0 0 0;0 0 0 0 0 0]);tIDs = string([tracks.TrackID]);plotTrack(trp, tPos, tIDs);绘制覆盖率covcon = coverageConfig(场景);plotCoverage (covp covcon);结束

rerunScenario

这个函数使用给定的跟踪器和跟踪GOSPA度量对象运行场景。它使用戏剧情节对象来显示结果。

函数info = rerunScenario(场景,跟踪器,tgm, tp)在上一次运行后重置对象重启(场景);重置(跟踪);重置(电报);rp = findPlotter(tp,“DisplayName的”“雷达”);pp = findPlotter(tp,“DisplayName的”“平台”);trp = findPlotter(tp,“DisplayName的”“跟踪”);dp = findPlotter(tp,“DisplayName的”“检测”);covp = findPlotter(tp,“DisplayName的”“雷达覆盖”);clearPlotterData (tp);Gospa = 0 (1,51);时间步长的百分比是51I = 0;S = rng(2019);推进(场景)%获得检测Dets =检测(场景);更新跟踪器如果isLocked(tracker) || ~isempty(dets) [tracks, ~, ~, info] = tracker(dets, scene . simulationtime);结束%评估GOSPAI = I + 1;truth = platformposed(场景);Gospa (i) = tgm(轨道,真理);更新显示updateDisplay(rp, pp, dp, trp, covp,场景,dets,轨道);结束Rng (s)图形plot(gospa(gospa>0)) title(“广义OSPA vs. Timestep”结束

initFastCVEKF

此函数修改默认值initcvekf过滤器初始化功能,允许更多的不确定性在对象速度。

函数ekf = initFastCVEKF(检测)ekf = initcvekf(检测);initialCovariance = diag(ekf.StateCovariance);initialCovariance([2,4,6]) = 300^2;增加速度协方差卡尔曼滤波器。StateCovariance = diag(initialCovariance);结束

helperGNN2JPDA

该函数提供了相当于GNN跟踪器的JPDA跟踪器作为输入。

函数jpda = helperGNN2JPDA(gnn) jpda = trackerJPDA(...“MaxNumTracks”, gnn。MaxNumTracks,...“AssignmentThreshold”, gnn。AssignmentThreshold,...“FilterInitializationFcn”, gnn。FilterInitializationFcn,...“MaxNumSensors”, gnn。MaxNumSensors,...“ConfirmationThreshold”, gnn。ConfirmationThreshold,...“DeletionThreshold”, gnn。DeletionThreshold,...“HasCostMatrixInput”, gnn。HasCostMatrixInput,...“HasDetectableTrackIDsInput”, gnn.HasDetectableTrackIDsInput);如果strcmpi (gnn。TrackLogic,“历史”jpda。TrackLogic =“历史”其他的jpda。TrackLogic =“集成”;jpda。DetectionProbability = gnn.DetectionProbability;jpda。杂波密度= gnn。FalseAlarmRate / gnn.Volume;结束结束