主要内容

生成代码的跟踪熔化炉与异类源的踪迹

这个例子展示了如何生成代码track-level融合算法在跟踪一个场景,来自异构数据源的不同状态的定义。这个例子是基于Track-Level雷达和激光雷达数据的融合例子,状态空间生成的跟踪激光雷达和雷达来源是不同的。

定义一个跟踪代码生成的熔化炉

您可以生成代码trackFuser使用MATLAB®编码器™。要做到这一点,您必须修改代码遵守以下限制:

代码生成入口函数

按照说明如何使用系统在MATLAB代码生成对象(MATLAB编码器)。对于代码生成,您必须首先定义一个入门级函数,对象的定义。同时,函数不能用对象数组作为输入或输出。在本例中,您定义的入门级函数heterogeneousInputsFuser函数。函数必须生成代码时的道路上。因此,它不能被这生活脚本的一部分,是连接在这个例子。函数接受当地的追踪和当前时间作为输入和输出中心跟踪。

保持熔化炉的状态之间的调用函数,定义fuser作为持续的变量。在第一次调用时,您必须定义fuser变量,因为它是空的。下面的代码步骤trackFuser并返回融合跟踪。

函数跟踪= heterogeneousInputsFuser (localTracks、时间)% # codegen持续的熔化炉如果isempty(熔化炉)%定义雷达源配置radarConfig = fuserSourceConfiguration (“SourceIndex”,1“IsInitializingCentralTracks”,真的,“CentralToLocalTransformFcn”@central2local,“LocalToCentralTransformFcn”,@local2central);%定义激光源的配置lidarConfig = fuserSourceConfiguration (“SourceIndex”2,“IsInitializingCentralTracks”,真的,“CentralToLocalTransformFcn”@central2local,“LocalToCentralTransformFcn”,@local2central);%创建一个trackFuser对象熔化炉= trackFuser (“MaxNumSources”2,“SourceConfigurations”{radarConfig; lidarConfig},“StateTransitionFcn”@helperctcuboid,“StateTransitionJacobianFcn”@helperctcuboidjac,“ProcessNoise”诊断接头([1 3]),“HasAdditiveProcessNoise”假的,“AssignmentThreshold”,250年正无穷,“ConfirmationThreshold”[3 - 5],“DeletionThreshold”,5 [5],“StateFusion”,“自定义”,“CustomStateFusionFcn”,@helperRadarLidarFusionFcn);结束跟踪=熔化炉(localTracks、时间);结束

均质源配置

在本例中,您定义雷达和激光雷达比原始源配置不同Track-Level雷达和激光雷达数据的融合的例子。在原始的例子中,CentralToLocalTransformFcnLocalToCentralTransformFcn两个源的属性配置是不同的,因为他们使用不同的处理函数。这使得源配置一个异构单元阵列。这样的定义是正确的和有效的执行在MATLAB。然而,在代码生成,所有源配置必须使用相同的函数处理。为了避免不同的处理函数,定义一个函数将跟踪从中央(熔化炉)定义地方(源)的定义和一个函数将从地方到中央。每一个功能开关之间的转换函数定义为个人来源在原始的例子。这两个功能的一部分heterogeneousInputsFuser函数。

这里的代码local2central函数实现的,它使用这个SourceIndex使用属性来确定正确的函数。因为这两种类型的地方跟踪变换到同一个轨道中心的定义,不需要预先确定中央跟踪。

函数centralTrack = local2central (localTrack)开关localTrack.SourceIndex情况下1%的雷达centralTrack = radar2central (localTrack);否则%激光雷达centralTrack = lidar2central (localTrack);结束结束

这个函数central2local将中央跟踪转换成一个雷达跟踪SourceIndex是1或激光雷达跟踪如果SourceIndex是2。两轨道有不同的定义状态,StateCovariance,TrackLogicState,首先你必须预先确定输出。这是函数的代码片段:

函数localTrack = central2local (centralTrack)状态= 0;stateCov = 1;coder.varsize (“状态”1,[1]、[0]);coder.varsize (“stateCov”,10 [10],[1]);localTrack = objectTrack (“状态”、州、“StateCovariance”,stateCov);开关centralTrack.SourceIndex情况下1 localTrack = central2radar (centralTrack);情况下2 localTrack = central2lidar (centralTrack);否则%这个分支是从来没有达到但迫使代码是必要的使用预定义的localTrack %的一代。结束结束

的函数radar2centralcentral2radar在最初的例子是一样的但是从现场脚本heterogeneousInputsFuser函数。你也加入lidar2centralcentral2lidar功能heterogeneousInputsFuser函数。这两个函数转换从跟踪定义fuser使用激光雷达跟踪的定义。

在MATLAB运行示例

在生成代码之前,确保所有更改后仍然运行示例熔化炉。该文件lidarRadarData.mat包含原始示例中的场景一样。它还包含一组雷达和激光雷达跟踪记录每一步的例子。你也使用类似的显示可视化例子和定义相同的trackGOSPAMetric对象评估跟踪性能。

%加载场景和记录当地的踪迹负载(“lidarRadarData.mat”,“场景”,“localTracksCollection”)显示= helperTrackFusionCodegenDisplay (“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) | | fuserStepped fusedTracks = heterogeneousInputsFuser (localTracks、时间);fuserStepped = true;结束radarTracks = localTracks ([localTracks.SourceIndex] = = 1);lidarTracks = localTracks ([localTracks.SourceIndex] = = 2);%所有追踪器捕获GOSPA及其组件[gospa idx), ~, ~, ~, missedTargets (1, idx) falseTracks (idx)] = gospaRadar (radarTracks groundTruth);[gospa (2, idx), ~, ~, ~, missedTargets (2, idx) falseTracks (idx)] = gospaLidar (lidarTracks groundTruth);[gospa (3, idx), ~, ~, ~, missedTargets (3 idx) falseTracks (idx)] = gospaCentral (fusedTracks groundTruth);%更新显示显示器(radarTracks场景、[][],[],[]、[][],lidarTracks, fusedTracks);idx = idx + 1;结束

图包含uipanel类型的对象。”width=

生成的代码跟踪熔化炉

生成的代码,您必须定义的输入类型雷达和激光雷达跟踪和时间戳。在最初的脚本和在前面的小节中,雷达和激光雷达跟踪被定义为数组objectTrack对象。在代码生成,入门级功能不能使用一个对象数组。相反,你定义一个结构数组。

使用结构体oneLocalTrack定义输入来自雷达和激光雷达跟踪。在代码生成,具体每个字段的数据类型必须定义结构体一模一样的类型定义了相应的属性记录跟踪。此外,每个字段必须定义正确的大小。您使用coder.typeof(MATLAB编码器)函数指定字段的变量大小:状态,StateCovariance,TrackLogicState。你定义localTracks输入用oneLocalTrack结构体和coder.typeof函数,因为输入跟踪变化的数量从0到8在每一步。你使用的函数codegen(MATLAB编码器)生成的代码。

注:

  1. 如果输入跟踪使用不同类型状态StateCovariance属性,你必须决定使用哪一个类型,或单一的两倍。在这个例子中,所有跟踪使用双精度和不需要这一步。

  2. 如果输入跟踪使用不同的定义StateParameters,您必须首先创建一个超集StateParameters和使用的超集StateParameters字段。类似的过程必须的完成ObjectAttributes字段。在这个例子中,所有使用相同的定义StateParametersObjectAttributes

%定义输入fuserHeterogeneousInputs代码生成oneLocalTrack =结构(“TrackID”uint32 (0)“BranchID”uint32 (0)“SourceIndex”uint32 (0)“UpdateTime”、双(0)“年龄”uint32 (0)“状态”编码器。typeof (1 [10 1] 1 [0]),“StateCovariance”编码器。typeof (10 [10], [1]),“StateParameters”、结构、“ObjectClassID”、双(0)“ObjectClassProbabilities”双(1),“TrackLogic”,“历史”,“TrackLogicState”编码器。typeof (false, 10 [1], [0 1]),“IsConfirmed”假的,“IsCoasted”假的,“IsSelfReported”假的,“ObjectAttributes”、结构);localTracks =编码器。typeof (oneLocalTrack 8 [1], [1 0]);fuserInputArguments = {localTracks,时间};codegenheterogeneousInputsFuserarg游戏fuserInputArguments;
代码生成成功。

运行示例生成的代码

运行生成的代码像你跑MATLAB代码,但是首先你必须重新启动的情况下,GOSPA对象和显示。

您使用toStruct目标函数将输入跟踪数组的结构。

注:

  1. 如果输入跟踪使用不同的数据类型状态StateCovariance属性,一定要把状态StateCovariance所有的跟踪定义的数据类型时,您选择的oneLocalTrack上面的结构。

  2. 如果输入跟踪所需的一个超集结构的字段StateParametersObjectAttributes,确保正确地填充这些结构在调用之前墨西哥人文件。

您使用gospaCG变量保持GOSPA指标的运行,这样你就可以比较他们从MATLAB GOSPA值运行。

%重新运行场景生成的代码fuserStepped = false;fusedTracks = objectTrack.empty;gospaCG = 0 (0);missedTargetsCG = 0 (0);falseTracksCG = 0 (0);idx = 1;清晰的heterogeneousInputsFuser_mex重置(显示);重置(gospaRadar);重置(gospaLidar);重置(gospaCentral);重启(场景);推进(场景)时间= scenario.SimulationTime;localTracks = localTracksCollection {idx};如果~ isempty (localTracks) | | fuserStepped fusedTracks = heterogeneousInputsFuser_mex (toStruct (localTracks)、时间);fuserStepped = true;结束radarTracks = localTracks ([localTracks.SourceIndex] = = 1);lidarTracks = localTracks ([localTracks.SourceIndex] = = 2);%所有追踪器捕获GOSPA及其组件[gospaCG idx), ~, ~, ~, missedTargetsCG (1, idx) falseTracksCG (idx)] = gospaRadar (radarTracks groundTruth);[gospaCG (2, idx), ~, ~, ~, missedTargetsCG (2, idx) falseTracksCG (idx)] = gospaLidar (lidarTracks groundTruth);[gospaCG (3, idx), ~, ~, ~, missedTargetsCG (3 idx) falseTracksCG (idx)] = gospaCentral (fusedTracks groundTruth);%更新显示显示器(radarTracks场景、[][],[],[]、[][],lidarTracks, fusedTracks);idx = idx + 1;结束

图包含uipanel类型的对象。”width=

在运行结束时,你想验证生成的代码提供了MATLAB代码相同的结果。使用GOSPA度量您收集在运行时,您可以比较高水平的结果。由于数值舍入,可能会有小的差异的结果相对于MATLAB代码生成的代码。比较的结果,您可以使用GOSPA值之间的绝对差异和检查,如果他们都小于1平台以及。结果表明,差异非常小。

%比较GOSPA值从MATLAB运行和生成的代码areGOSPAValuesEqual =所有(abs (gospa-gospaCG) < 1平台以及“所有”);disp (“GOSPA值等于10小数(真/假)?”+字符串(areGOSPAValuesEqual))
GOSPA值相等的10日小数(真/假)?真正的

总结

在这个例子中,您学习了如何生成代码track-level当输入跟踪异构融合算法。您学习了如何定义trackFuser和它的SourceConfigurations支持异构数据源的属性。万博1manbetx您还了解了如何定义输入编译时间以及如何在运行时将它传递给墨西哥人文件。

万博1manbetx支持功能

以下功能GOSPA所使用的指标。

helperLidarDistance

函数计算归一化距离估计的跟踪雷达状态和分配的地面实况。

函数dist = helperLidarDistance(跟踪、真理)%计算实际值的状态估计的跟踪器%中心是不同的起源和追踪评估中心rOriginToCenter = -truth.OriginOffset (:) + (0, 0, truth.Height / 2);腐烂=四元数([真理。偏航真理。距truth.Roll),“eulerd”,“ZYX股票”,“帧”);actPos = truth.Position (:) + rotatepoint(腐烂,rOriginToCenter ') ';实际速度和z-rate %actVel =[规范(truth.Velocity (1:2)); truth.Velocity (3)];%实际偏航actYaw = truth.Yaw;%的实际尺寸。actDim = [truth.Length; truth.Width truth.Height];%实际偏航率actYawRate = truth.AngularVelocity (3);%计算每个估计误差加权的“需求”%的系统。使用指定的距离距离在各个方面%的估计,协方差的定义是“需求”。这%有助于避免倾斜距离当跟踪下/ /报告%的不确定性,因为在状态/计量模型不准确。%位置错误。estPos =。状态([1 2 6]); reqPosCov = 0.1*eye(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 = eye(3); e = estDim - actDim; d5 = sqrt(e'/reqDimCov*e);%总距离dist = d1 + d2 + d3 + d4 + d5;结束

helperRadarDistance

函数计算归一化距离估计的跟踪雷达状态和分配的地面实况。

函数dist = helperRadarDistance(跟踪、真理)%计算实际值的状态估计的跟踪器%中心是不同的起源和追踪评估中心rOriginToCenter = -truth.OriginOffset (:) + (0, 0, truth.Height / 2);腐烂=四元数([真理。偏航真理。距truth.Roll),“eulerd”,“ZYX股票”,“帧”);actPos = truth.Position (:) + rotatepoint(腐烂,rOriginToCenter ') ';actPos = actPos (1:2);%只有二维%的实际速度actVel =规范(truth.Velocity (1:2));%实际偏航actYaw = truth.Yaw;%的实际尺寸。只有二维雷达actDim = [truth.Length; truth.Width];%实际偏航率actYawRate = truth.AngularVelocity (3);%计算每个估计误差加权的“需求”%的系统。使用指定的距离距离在各个方面%的估计,协方差的定义是“需求”。这%有助于避免倾斜距离当跟踪下/ /报告%的不确定性,因为在状态/计量模型不准确。%位置错误estPos =。状态([1 - 2]);reqPosCov = 0.1 *眼(2);e = estPos - actPos;d1 =√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;%一个恒定的点球没有测量三维状态dist = dist + 3;结束