主要内容

空中交通管制

这个示例演示了如何生成一个空中交通管制场景,模拟机场监视雷达(ASR)的雷达探测,并配置一个全局最近邻(GNN)跟踪器来使用雷达探测跟踪模拟目标。这使您能够评估不同的目标场景、雷达需求和跟踪器配置,而不需要访问昂贵的飞机或设备。这个示例涵盖了整个合成数据工作流。

空中交通管制方案

在场景中模拟空中交通管制(ATC)塔台和移动目标为平台.该方案中平台的运动仿真由trackingScenario

创建一个trackingScenario并将空中交通管制塔添加到场景中。

%创建跟踪场景场景= trackingScenario;添加一个固定平台来模拟空中交通管制塔塔=平台(场景);

机场监控雷达

在空中交通管制塔台增加机场监视雷达(ASR)。一个典型的空中交通管制塔有一个雷达安装在离地面15米的地方。该雷达以固定速率机械地扫描方位,为空中交通管制塔附近提供360度的覆盖。ASR的常用规格如下:

  • 灵敏度:0 dBsm @ 111公里

  • 机械扫描:方位扫描

  • 机械扫描速度:12.5 RPM

  • 电子扫描:没有

  • 视野:1.4°方位角,10°仰角

  • 方位分辨率:1.4 deg

  • 距离分辨率:135米

根据上述规格,使用fusionRadarSensor

rpm = 12.5;fov = (1.4; 10);scanrate = rpm * 360/60;%度/秒updaterate = scanrate / fov(1);%Hz.雷达= Fusionradarsensor(1,“旋转”......“UpdateRate”updaterate,......%Hz.“FieldOfView”fov,......% (az; el)度“MaxAzimuthScanRate”scanrate,......%度/秒“AzimuthResolution”fov (1),......%度“ReferenceRange”111年e3,......%M.'referencercs',0,......%dbsm.'rangeresolution',135,......%M.“之内”,真的,......“DetectionCoordinates”“场景”);塔顶的%安装雷达雷达。安装位置= [0 0 -15];塔。传感器=雷达;

倾斜雷达,使其在地平线以上2度处开始探测区域。要做到这一点,启用仰角,并设置机械扫描限制,以跨越雷达的仰角视野,从地平线以上2度开始。因为trackingScenario使用向东(NED)坐标框架,负面高度对应于地平线上方的点。

%启用仰角扫描雷达。HasElevation = true;%设置机械仰角扫描从地平线以上2度开始elFov = fov (2);倾斜= 2;%度雷达。MechanicalElevationLimits = [-fov(2) 0]-tilt;%度

将仰角视场设置为略大于扫描限制所跨越的仰角。这防止了光栅在仰角扫描和倾斜雷达指向中间的仰角扫描限制。

radar.FieldOfView (2) = elFov + 1 e - 3;

fusionRadarSensor由于大气折射,模型范围和高度偏置。这些偏差在较低的海拔地区和长范围内的目标变得更加明显。因为折射率变化(减小)的高度,所以雷达信号沿着曲线传播。这导致雷达观察到高度的目标,高于其真正的高度和超出其视线范围的范围。

在空中交通管制区域增加三架客机。一架飞机从远程接近空中交通管制中心,另一架离开,第三架飞机沿切线飞向塔台。模拟这些飞机在60秒间隔内的运动。

trackingScenario使用向东(NED)坐标框架。当定义下面的客机的航路点时,Z坐标对应于下降,因此地面上方的高度被设置为负值。

%场景持续时间sceneDuration = 60;%S.%的入站客机ht = 3 e3;社民党= 900 * 1 e3/3600;% 多发性硬化症wp = [-5e3 -40e3 -ht;-5e3 -40e3+spd*sceneDuration -ht];traj = waypointTrajectory (“锚点”wp,“TimeOfArrival”[0 sceneDuration]);平台(场景中,“轨迹”,traj);%出站客机ht = 4 e3;社民党= 700 * 1 e3/3600;% 多发性硬化症wp = [20e3 10e3 -ht;20e3+spd*sceneDuration 10e3 -ht];traj = waypointTrajectory (“锚点”wp,“TimeOfArrival”[0 sceneDuration]);平台(场景中,“轨迹”,traj);%切线客机ht = 4 e3;社民党= 300 * 1 e3/3600;% 多发性硬化症WP = [-20e3 -spd * sceneduration / 2-ht; -20e3 spd * sceneduration / 2-ht];traj = waypointTrajectory (“锚点”wp,“TimeOfArrival”[0 sceneDuration]);平台(场景中,“轨迹”,traj);

GNN跟踪器

创建一个trackerGNN以形成三架客机的雷达探测轨迹。在完成360度全方位方位扫描后,用生成的检测结果更新跟踪器。

跟踪器使用initFilter金宝app为每条新轨道初始化一个恒定速度扩展卡尔曼滤波器。initFilter修改返回的过滤器initcvekf以匹配目标速度和跟踪器更新间隔。

跟踪器= trackergnn(......“作业”“拍卖”......“AssignmentThreshold”, 50岁,......“FilterInitializationFcn”, @initFilter);

在地图上形象化

你使用trackingGlobeViewer在地图显示顶部可视化结果。你在波士顿洛根机场定位塔台雷达和跟踪器使用的本地东北-下(NED)坐标系统的原点。原点位于纬度42.36306,经度-71.00639,海拔50米。

Origin = [42.366978, - 71.022362,50];mapview = trackingGlobeViewer (“ReferenceLocation”,起源,......'底画'“streets-dark”);campos(mapViewer, origin + [0 0 1e5]);drawnow;plotScenario (mapview场景);快照(mapview);

模拟和跟踪航班

下面的循环推进平台位置,直到场景结束。对于场景中的每向前一步,雷达从其视场中的目标生成探测。在雷达完成360度方位扫描后,跟踪器将更新这些探测结果。

%设置仿真以在雷达的更新速率下提前场景。UpdateRate = radar.UpdateRate;%创建一个缓冲区,从雷达的全扫描收集检测scanbuffer = {};%初始化轨道阵列跟踪= objectTrack.empty;%保存每次扫描的可视化快照allsnaps = {};scanCount = 0;%设置随机种子以获得可重复的结果s =提高;rng (2020)推进(场景)%更新客机位置plotplatform(MapViewer,方案.platforms([2 3 4]),“TrajectoryMode”“全部”);%对雷达当前视场的目标产生探测[引爆器,配置]=检测(场景);scanBuffer = (scanBuffer;依据);% #好< AGROW >绘制波束和检测plotCoverage (mapview coverageConfig(场景)plotDetection (mapview scanBuffer);当360度扫描完成时,更新轨道SIMTIME =场景.simulationtime;iscandone = config.isscandone;如果isScanDone scanCount = scanCount+1;%更新追踪[痕迹,~,~,信息]=追踪(scanBuffer simTime);%清除扫描缓冲区,用于下次扫描scanbuffer = {};elsef.isLocked(跟踪)%预测电流模拟时间的曲目tracks = predicttrackstototime(跟踪器,“确认”, simTime);结束%更新映射并拍摄快照Allsnaps = Snapplottrack(MapViewer,Tracks,Isscandone,Scancount,Allsnaps);结束allsnaps = [allsnaps, {snapshot(mapViewer)}];

显示在雷达完成第二次扫描时拍摄的第一张快照。

图imshow (allsnaps {1});

上图显示了雷达第二次360度扫描结束时的场景。每架模拟客机的雷达探测都显示为淡蓝色的小点。此时,跟踪器已经通过一次完整的雷达扫描进行了更新。在内部,跟踪器已经初始化了每个航班的轨迹。这些轨迹将在扫描后的更新后显示,当轨迹被提升到确认时,满足跟踪者3次更新中2次点击的确认要求。

接下来的两张快照显示了出站航班的跟踪情况。

图imshow (allsnaps {2});

图imshow (allsnaps {3});

上图显示的是雷达第二次扫描后跟踪器更新前后的轨迹图。图中跟踪器更新前的检测用于更新和确认该航班先前扫描检测的初始轨道。下图显示了确认的航迹位置和速度。轨道位置估计的不确定性用黄色椭圆表示。仅在两次探测后,跟踪器就能准确估计出飞机的位置和速度。这架客机的真正高度是4公里,它以每小时700公里的速度向北飞行。

图imshow (allsnaps {4});

图imshow (allsnaps {5});

出站航班的轨道状态被滑行到第三次扫描的末尾,并显示在上图中,与最近对航班的检测一起显示。注意轨道的不确定性是如何增长的,因为它更新在前面的数字。经过检测更新后的轨迹如下图所示。你会注意到轨迹位置的不确定性在更新后降低了。轨迹不确定度在更新之间增加,并且在使用新测量进行更新时降低。你还可以观察到,在第三次更新后,轨道位于客机的真实位置之上。

数字imshow(Allsnaps {6});

最终图显示了场景结束时所有三个客机曲目的状态。三个客机中的每一个都有一条轨道。在场景的整个持续时间内分配相同的轨道编号,指示在场景期间没有丢弃这些曲目中的任何一个轨道。估计的轨道与客机的真实位置和速度紧密匹配。

truthTrackTable = tabulateData(场景,轨迹)% #好< NOPTS >
truthTrackTable =3×4表TrackID高度航向速度真估计真估计真估计_______ _________________ _________________ _________________ "T1" 4000 4051 90 90 700 710 "T2" 4000 4070 0 359 300 300 "T3" 3000 3057 0 359 900 908

可视化3D的曲目以获得更好的估计高度感。

重新定位和定位相机,以显示3-D性质的地图camPosition = origin + [0.367, 0.495, 1.5e4];camOrientation = [235, - 17,0];向西南看,地平线下17度坎波斯(mapview camPosition);camorient (mapview camOrientation);drawnow

下图显示了场景的三维图。您可以在白色三角形中看到模拟喷射,其轨迹描绘为白线。雷达光束显示为具有表示雷达检测的蓝色点的蓝色锥体。曲目以黄色,橙色和蓝色显示,其信息列于各自的颜色。由于三维显示器的性质,一些标记可能隐藏在其他标记之后。

你可以在地图上使用以下控件来获得场景的不同视图:

  • 要平移地图,您左键单击鼠标并拖动地图。

  • 要旋转地图,请在按住Ctrl按钮时,您左键单击鼠标并拖动地图。

  • 要放大或缩小地图,可以使用鼠标滚轮。

快照(mapview);

总结

这个示例演示了如何生成一个空中交通管制场景,模拟机场监视雷达(ASR)的雷达探测,并配置一个全局最近邻(GNN)跟踪器来使用雷达探测跟踪模拟目标。在此示例中,您了解了Tracker的历史历史逻辑如何促销曲目。您还了解了在轨道上滑行时的轨道不确定性如何生长,并且当通过新检测更新轨道时减少。

金宝app支持功能

initFilter

这个函数修改函数initcvekf处理诸如ATC方案中的轿车等速度目标。

函数filter = initcvekf(检测);classToUse =类(filter.StateCovariance);客机可以以900公里/小时左右的速度移动。速度是%初始化为0,但需要能够快速适应以这种速度飞行的飞机。以900 km/h为1个标准差初始化轨道速度噪声的百分比。社民党= 900 * 1 e3/3600;% 多发性硬化症velCov =投(社民党^ 2,classToUse);x = filter.StateCovariance;浸(2,2)= velCov;浸(4,4)= velCov;过滤器。StateCovariance =浸;%设置过滤器的进程噪声匹配过滤器的更新速率scaleaccelhorz =演员(1,Classe);scaleaccelvert =演员(1,Classtouse);q = blkdiag(scaleaccelhorz ^ 2,scaleaccelhorz ^ 2,scaleaccelvert ^ 2);filter.processnoise = q;结束

表格

此函数返回比较地面真理和曲目的表格

函数truthTrackTable = tabulateData(场景,轨迹)%处理真实数据平台=场景.platforms(2:结束);平台1是雷达numPlats =元素个数(平台);trueAlt = 0 (numPlats, 1);trueSpd = 0 (numPlats, 1);trueHea = 0 (numPlats, 1);i = 1:numPlats traj =平台{i}.轨迹;路点= traj.Waypoints;* = traj.TimeOfArrival;trueAlt (i) =锚点(结束,3);true = (waypoints(end,:) - waypoints(end-1,:)) / (times(end)-times(end-1));true espd (i) = norm(true level) * 3600 / 1000;%转换为km/htrueHea (i) = atan2d (trueVel (1) trueVel (2));结束trueHea =国防部(trueHea, 360);将跟踪与目标关联丙氨酸= [tracks.ObjectAttributes];tgtInds = [atts.TargetIndex];假设恒定速度模型的过程轨迹numtrks = numel(曲目);estalt =零(numtrks,1);estspd = zeros(numtrks,1);Esthea = Zeros(Numtrks,1);真相=零(numtrks,7);i = 1:numTrks estAlt(i) = -round(tracks(i).State(5));estSpd(i) = round(norm(tracks(i).State(2:2:6)) * 3600 / 1000);%转换为km/h;estHea (i) =圆(atan2d(跟踪(i) .State(2),追踪(i) .State (4)));estHea (i) =国防部(estHea(我),360);platID = tgtInds(我);platID = 1;truthTrack(我:)= ((i)。TrackID, trueAlt(platInd), estAlt(i), trueHea(platInd), estHea(i),......trueSpd (platInd) estSpd (i)];结束%组织表中的数据名称= {“TrackID”“TrueAlt”“EstimatedAlt”“TrueHea”“EstimatedHea”“TrueSpd”“EstimatedSpd”};truthTrackTable = array2table (truthTrack,'variablenames'、名称);truthTrackTable = mergevars(truthTrackTable, (6:7),“NewVariableName”“速度”'mergeastable',真正的);truthTrackTable。(6). properties。VariableNames = {'真的'“估计”};truthTrackTable = mergevars(truthTrackTable, (4:5),“NewVariableName”“标题”'mergeastable',真正的);truthTrackTable。(4). properties。VariableNames = {'真的'“估计”};truthTrackTable = mergevars(truthTrackTable, (2:3),“NewVariableName”“高度”'mergeastable',真正的);truthTrackTable。(2). properties。VariableNames = {'真的'“估计”};truthTrackTable。TrackID =“T”+字符串(truthTrackTable.TrackID);结束

snapPlotTrack

此功能处理移动相机,以相关的快照和更新轨道视觉。

函数allsnaps = snapPlotTrack(mapViewer,tracks,isScanDone, scanCount,allsnaps)%在前四次扫描时保存快照如果Isscandone &&任何(scancount == [2 3])newsnap =快照(MapViewer);Allsnaps = [Allsnaps, {newsnap}];%移动相机如果scanCount = = 2显示出的航班campos(mapViewer, [42.5650 -70.8990 7e3]);drawnow newsnap = snapshot(mapViewer);Allsnaps = [Allsnaps, {newsnap}];结束结束%更新显示使用当前曲目位置Plottrack(MapViewer,Tracks,“LabelStyle”ATC的);如果isScanDone && any(scanCount ==[2 3]) / /删除所有的scanCount对已确认的轨道进行快照drawnow newsnap = snapshot(mapViewer);Allsnaps = [Allsnaps, {newsnap}];重置摄像机视图到全场景如果scanCount == 3 origin = [42.366978, - 71.022362,50];campos(mapViewer, origin + [0 0 1e5]);drawnow结束结束结束