主要内容

生成代码的跟踪与定影异构源曲目

这个示例展示了如何在轨迹来自具有不同状态定义的异构源的场景中为轨迹级融合算法生成代码。这个例子是基于雷达和激光雷达数据的轨迹级融合例如,由激光雷达和雷达源生成的轨迹的状态空间不同。

定义用于代码生成的跟踪Fuser

您可以为跟踪定影器使用MATLAB®编码器™。为此,您必须修改代码以符合以下限制:

代码生成入口函数

按照有关如何使用的说明进行操作MATLAB代码生成中的系统对象(MATLAB编码器).对于代码生成,您必须首先定义一个入门级函数,在该函数中定义对象。此外,该函数不能使用对象数组作为输入或输出。在本例中,将入门级函数定义为heterogeneousInputsFuser作用为函数生成代码时,该函数必须位于路径上。因此,它不能成为此live脚本的一部分,并附加在此示例中。该函数接受本地轨迹和当前时间作为输入,并输出中心轨迹。

为了在调用函数之间保持fuser的状态,可以将fuser定义为持续的第一次调用时,必须定义fuser变量,因为它是空的跟踪定影器并返回融合轨迹。

作用跟踪= heterogeneousInputsFuser (localTracks、时间)%#编码基因持续的熔化炉如果isempty(熔化炉)%定义雷达源配置radarConfig = fuserSourceConfiguration(“源索引”1,......“IsInitializingCentralTracks”符合事实的......“CentralToLocalTransformFcn”,@central2local,......“LocalToCentralTransformFcn”, @local2central);%定义激光雷达源配置lidarConfig = fuserSourceConfiguration(“源索引”2,......“IsInitializingCentralTracks”符合事实的......“CentralToLocalTransformFcn”,@central2local,......“LocalToCentralTransformFcn”, @local2central);%创建trackFuser对象熔化炉= trackFuser (......'MaxNumSources'2,......“源配置”{radarConfig; lidarConfig},......“StateTransitionFcn”,@helpercuboid,......“StateTransitionJacobianFcn”@helperctcuboidjac,......“ProcessNoise”诊断接头([1 3]),......“HasAdditiveProcessNoise”错误的......“AssignmentThreshold”[250 INF]......“ConfirmationThreshold”[3 - 5],......“DeletionThreshold”[5 5],......“StateFusion”“习俗”......“CustomStateFusionFcn”,@ helperRadarLidarFusionFcn);结束轨迹=定影器(本地轨迹,时间);结束

均匀源配置

在本例中,定义的雷达和激光雷达源配置与原始配置中的不同雷达和激光雷达数据的轨迹级融合在原始示例中CentralToLocalTransformFcn本地到中心传输MFCN因为它们使用不同的函数处理两个源配置的特性是不同的。这使得源配置异构单元阵列。在MATLAB中执行时,这种定义是正确的和有效的。然而,在代码生成,所有源配置必须使用相同的函数处理。为了避免不同功能的手柄,您可以定义一个函数来从中央(定影器)定义的变换轨迹本地(源)的定义,一个功能转换,从地方到中央。在原始示例的各个源中定义的变换函数之间的每个的这些功能进行切换。这两个功能是部分heterogeneousInputsFuser函数。

这是代码本地2中心函数,它使用SourceIndex属性来确定要使用的正确函数。由于两种类型的局部轨迹转换为相同的中心轨迹定义,因此无需预定义中心轨迹。

作用centralTrack = local2central(localTrack)转换localTrack.SourceIndex案件1%的雷达centralTrack = radar2central (localTrack);否则激光雷达%centralTrack=lidar2central(本地轨道);结束结束

功能central2local将中心轨迹转换为雷达轨迹SourceIndex为1或为激光雷达轨道如果SourceIndex是2。因为这两个轨迹对状态状态协方差TrackLogicState,必须首先预定义输出。以下是该函数的代码段:

作用localTrack = central2local(centralTrack)状态= 0;stateCov = 1;coder.varsize(“国家”, [10, 1], [1 0]); 变码器(“stateCov”, [10 10], [1 1]); localTrack=objectTrack(“状态”, 状态,“状态协方差”,stateCov);转换centralTrack.SourceIndex案件1 localTrack = central2radar(centralTrack);案件2 localTrack = central2lidar(centralTrack);否则%此分支永远无法到达,但对强制代码是必要的%生成使用预定义localTrack。结束结束

的函数radar2centralcentral2radar是一样的,在最初的例子,但是从现场脚本移到heterogeneousInputsFuser函数。你还需要添加利达中心central2lidar功能heterogeneousInputsFuser这两个函数从定影器使用的轨迹定义转换为激光雷达轨迹定义。

在MATLAB中运行该示例

生成代码之前,请确保毕竟更改到定影所作的例子仍然运行。文件lidarRadarData.mat包含与原始示例相同的场景。它还包含一组在该示例的每个步骤中记录的雷达和激光雷达轨迹。您还可以使用类似的显示来可视化示例并进行相同的定义trackGOSPAMetric对象来评估跟踪性能。

%加载场景和录制的本地轨道装载(“LidaradarData.mat”“场景”'localTracksCollection')显示=HelperTrackFusionDegendDisplay(“FollowActorID”3);showLegend(显示、场景);%雷达GOSPAgospaRadar = trackGOSPAMetric (“距离”'风俗'......'DistanceFcn'@ helperRadarDistance,......“CutoffDistance”25);%激光雷达GOSPAgospaLidar = trackGOSPAMetric(“距离”'风俗'......'DistanceFcn'@helperLidarDistance,......“CutoffDistance”25);中央/融合GOSPA %gospaCentral = trackGOSPAMetric (“距离”'风俗'......'DistanceFcn'@helperLidarDistance,......%状态空间与激光雷达相同“CutoffDistance”25);gospa = 0 (0);missedTargets = 0 (0);falseTracks = 0 (0);%度量的基本事实。此变量在每个时间步都会更新%,因为它是角色的句柄。groundTruth = scenario.Actors(2:结束);fuserStepped = false;fusedTracks = objectTrack.empty;idx = 1;清晰的heterogeneousInputsFuser虽然提前(场景)时间= scenario.SimulationTime;localTracks = localTracksCollection {IDX};如果~isempty(localTracks) || fusersteps fusedTracks = heterogeneousInputsFuser(localTracks,时间);fuserStepped = true;结束radarTracks=localTracks([localTracks.SourceIndex]==1);lidarTracks=localTracks([localTracks.SourceIndex]==2);%捕获所有跟踪器的GOSPA及其组件[gospa(1,idx),~,~, missedTargets(1,idx),falseTracks(1,idx)] = gospaRadar(radarTracks, groundTruth);[gospa(2,idx),~,~, missedTargets(2,idx),falseTracks(2,idx)] = gospaLidar(lidarTracks, groundTruth);[gospa(3,idx),~,~, missedTargets(3,idx),falseTracks(3,idx)] = gospaCentral(fusedTracks, groundTruth);%更新显示显示器(方案中,[],[],radarTracks,......[]、[]、[]、[]、lidarTracks、fusedTracks);idx=idx+1;结束

图中包含uipanel类型的对象。

生成代码的轨道定影

要生成代码,您必须定义输入类型的雷达和激光雷达跟踪和时间戳两个。在这两种原始脚本和上一节中,雷达和激光雷达轨道被定义为阵列对象跟踪对象。在代码生成中,入门级函数不能使用对象数组。相反,您需要定义一个结构数组。

你使用结构体oneLocalTrack定义来自雷达和激光雷达轨道的输入。在代码生成中,结构中每个字段的特定数据类型必须定义为与记录轨道中相应属性定义的类型完全相同。此外,必须正确定义每个字段的大小。您使用编码员(MATLAB编码器)功能来指定具有可变大小字段:状态状态协方差TrackLogicState.你定义本地轨道使用oneLocalTrack结构和编码员函数,因为在每个步骤中输入轨道的数量从0到8个不等。你用这个函数codegen(MATLAB编码器)生成代码。

笔记:

  1. 如果输入的轨迹使用不同类型的状态状态协方差属性,必须决定使用哪种类型,双人或单人。在这个例子中,所有曲目使用双精度和没有必要的这一步。

  2. 如果输入轨道使用不同的定义状态参数,您必须首先创建所有的超集状态参数使用超集状态参数字段。必须对ObjectAttributes字段。在本例中,所有轨道使用相同的定义状态参数ObjectAttributes

%定义FuserHeterogeneOutsInputs的输入以生成代码oneLocalTrack=struct(......“TrackID”,UINT32(0),......'BranchID',UINT32(0),......“源索引”,UINT32(0),......“更新时间”,双(0),......“年龄”,UINT32(0),......“状态”,coder.typeof(1[10 1],[10]),......“状态协方差”编码器。Typeof (1, [10 10], [1 1]),......“StateParameters”、结构、......“ObjectClassID”,双(0),......“TrackLogic”“历史”......“TrackLogicState”,coder.typeof(假的,[1 10],[0 1]),......“IsConfirmed”, 错误的,......“IsCoasted”, 错误的,......'IsSelfReported', 错误的,......“ObjectAttributes”、结构);localTracks =编码器。typeof(oneLocalTrack, [8 1], [1 0]);fuserinputararguments = {localTracks, time};codegenheterogeneousInputsFuserarg游戏模糊推理
代码生成成功。

使用生成的代码运行示例

您可以像运行MATLAB代码一样运行生成的代码,但首先必须重新初始化场景、GOSPA对象和显示。

您可以使用toStruct目标函数的输入轨迹转换成结构的阵列。

笔记:

  1. 如果输入磁道使用不同的数据类型状态状态协方差属性,请确保强制转换状态状态协方差所有的轨道的数据类型你选择,当你定义的oneLocalTrack上面的结构。

  2. 如果输入跟踪需要字段的超集结构状态参数ObjectAttributes,请确保在调用墨西哥文件。

您可以使用戈斯帕克变量保存此运行的GOSPA指标,以便您可以将它们与MATLAB运行中的GOSPA值进行比较。

%使用生成的代码重新运行该场景fuserStepped = false;fusedTracks = objectTrack.empty;gospaCG = 0 (0);missedTargetsCG = 0 (0);falseTracksCG = 0 (0);idx = 1;清晰的非均匀输入用户重置(显示);重置(gospaRadar);重置(gospaLidar);重置(gospaCentral);重新启动(场景);虽然提前(场景)时间= scenario.SimulationTime;localTracks = localTracksCollection {IDX};如果~isempty(localTracks) || fusersteps fusedTracks = heterogeneousInputsFuser_mex(toStruct(localTracks),time);fuserStepped = true;结束radarTracks=localTracks([localTracks.SourceIndex]==1);lidarTracks=localTracks([localTracks.SourceIndex]==2);%捕获所有跟踪器的GOSPA及其组件[gospaCG(1,idx),~,~, missedTargetsCG(1,idx),falseTracksCG(1,idx)] = gospaRadar(radarTracks, groundTruth);[gospaCG(2,idx),~,~, missedTargetsCG(2,idx),falseTracksCG(2,idx)] = gospaLidar(lidarTracks, groundTruth);[gospaCG(3,idx),~,~, missedTargetsCG(3,idx),falseTracksCG(3,idx)] = gospaCentral(fusedTracks, groundTruth);%更新显示显示器(方案中,[],[],radarTracks,......[]、[]、[]、[]、lidarTracks、fusedTracks);idx=idx+1;结束

图中包含uipanel类型的对象。

在运行结束时,要验证所生成的代码提供了相同的结果MATLAB代码。使用您在两个试验中收集的GOSPA指标,则可以在高水平的比较结果。由于数值roundoffs,有可能是在生成相对于MATLAB代码的代码的结果的微小差异。为了比较的结果,您使用GOSPA值之间的绝对差值,并检查它们是否比1E-10的所有小。结果表明,该差异非常小。

比较MATLAB运行的GOSPA值和生成的代码areGOSPAValuesEqual =所有(ABS(gospa-gospaCG)<1E-10,“所有”);disp(“GOSPA值是否等于第十个小数(真/假)?”+字符串(areGOSPAValuesEqual))
是GOSPA值等于到10十进制(真/假)?真的

总结

在本例中,您学习了如何在输入轨迹异构时为轨迹级融合算法生成代码跟踪定影器及其SourceConfigurations属性来支持异构数据源。金宝app您还学会了如何在编译时间,以及如何将它传递给在运行时MEX文件中定义的输入。

金宝app辅助功能

GOSPA度量使用了以下函数。

助手身份

函数来计算轨道的雷达状态空间估计和所分配的基础事实之间的标准化距离。

作用DIST = helperLidarDistance(轨道,真理)%计算跟踪器估计的状态的实际值%中心比原产地不同的,跟踪评估中心rOriginToCenter=-truth.OriginOffset(:)+[0;0;truth.Height/2];rot=四元数([truth.Yaw truth.Pitch truth.Roll],“eulerd”“ZYX股票”“帧”)actPos=真值位置(:)+旋转点(旋转,旋转中心“);实际速度和z率actVel=[标准(真理.速度(1:2));真理.速度(3)];%实际偏航actYaw = truth.Yaw;%实际尺寸。actDim=[真值.长度;真值.宽度;真值.高度];实际偏航率actYawRate = truth.AngularVelocity (3);%计算误差由的“要求”加权的每个估计%系统。在各个方面使用马氏距离指定的距离%的估计,其中协方差是由“需求”定义的。这当轨道过低/过低报告时,有助于避免偏离距离%由于状态/测量模型的不精确性而产生的不确定性。%位置误差。estPos=轨道状态([1 2 6]);reqPosCov=0.1*眼(3);e=estPos-actPos;d1=sqrt(e'/reqPosCov*e);%速度误差estVel =。状态(7 [3]);reqVelCov = 5 *眼(2);e = estVel - actVel;d2 =√e”/ reqVelCov * e);%偏航误差estYaw = track.State (4);reqYawCov = 5;e = estYaw - actYaw;d3 =√e”/ reqYawCov * e);%偏航率误差estYawRate = track.State (5);reqYawRateCov = 1;e = estYawRate - actYawRate;d4 =√e”/ reqYawRateCov * e);%尺寸误差estDim=轨道状态([8 9 10]);reqDimCov=眼睛(3);e=estDim-actDim;d5=sqrt(e'/reqDimCov*e);%总距离DIST = D1 + D2 + D3 + D4 + D5;结束

helperRadarDistance

函数来计算轨道的雷达状态空间估计和所分配的基础事实之间的标准化距离。

作用距离=帮助距离(轨迹、真相)%计算跟踪器估计的状态的实际值%中心比原产地不同的,跟踪评估中心rOriginToCenter=-truth.OriginOffset(:)+[0;0;truth.Height/2];rot=四元数([truth.Yaw truth.Pitch truth.Roll],“eulerd”“ZYX股票”“帧”)actPos=真值位置(:)+旋转点(旋转,旋转中心“);actPos = actPos (1:2);%只2- d%实际速度actVel=标准(真理速度(1:2));%实际偏航actYaw = truth.Yaw;%实际尺寸。只有2-d雷达actDim = [truth.Length; truth.Width];实际偏航率actYawRate = truth.AngularVelocity (3);%计算误差由的“要求”加权的每个估计%系统。在各个方面使用马氏距离指定的距离%的估计,其中协方差是由“需求”定义的。这当轨道过低/过低报告时,有助于避免偏离距离%由于状态/测量模型的不精确性而产生的不确定性。%位置误差estPos = track.State([1 2]);reqPosCov = 0.1 *眼(2);E = estPos  -  actPos;D1 = SQRT(E'/ reqPosCov * E);%的速度误差estVel = track.State(3);reqVelCov = 5;e = estVel - actVel;d2 =√e”/ reqVelCov * e);%偏航误差estYaw = track.State (4);reqYawCov = 5;e = estYaw - actYaw;d3 =√e”/ reqYawCov * e);%偏航率误差estYawRate = track.State (5);reqYawRateCov = 1;e = estYawRate - actYawRate;d4 =√e”/ reqYawRateCov * e);%尺寸误差estDim =。状态(7 [6]);reqDimCov =眼(2);e = estDim - actDim;d5 =√e”/ reqDimCov * e);%总距离DIST = D1 + D2 + D3 + D4 + D5;%A恒定惩罚不测量3-d状态Dist = Dist + 3;结束