主要内容

如何为跟踪器生成C代码

这个例子展示了如何为处理检测和输出轨迹的MATLAB函数生成C代码。函数包含trackerGNN,但可以使用任何跟踪器。

从MATLAB代码自动生成代码有两个关键好处:

  1. 原型可以在MATLAB环境中开发和调试。一旦MATLAB工作完成,自动生成C代码使算法可部署到各种目标。此外,还可以使用原型阶段可用的可视化和分析工具,在MATLAB环境中运行已编译的MEX文件,从而进一步测试C代码。

  2. 生成C代码后,可以生成可执行代码,在许多情况下,该代码的运行速度比MATLAB代码快。改进后的运行时间可用于开发和部署实时传感器融合和跟踪系统。它还提供了在大量数据集上批量测试跟踪系统的更好方法。

示例说明如何修改的MATLAB代码空中交通管制支持代码生成的示例。此金宝app示例需要MATLAB编码器许可证才能生成C代码。

修改并运行MATLAB代码

为了生成C代码,MATLAB Coder要求MATLAB代码以函数形式存在。此外,函数的参数不能是MATLAB类。

在本例中,空中交通管制(ATC)示例的代码已重新构造,以便trackerGNN执行传感器融合和跟踪的存储在一个单独的文件中,称为tracker_kernel.m。有关代码生成的内存分配的重要信息,请查看此文件。

为了保护国家安全trackerGNN通话间隔tracker_kernel.m,跟踪器定义为持久的变量

此函数接受目标检测对象,由fusionRadarSensor对象和时间作为输入参数。

类似地,支持代码生成的函数的输出不能是对象。金宝app的输出tracker_kernel.m是:

  1. 确认轨道-A结构体包含可变数量磁道的数组。

  2. 磁道数-一个整数标量。

  3. 关于当前更新时跟踪器处理的信息。

通过以这种方式重构代码,您可以重用在ATC示例中使用的相同显示工具。这些工具仍然可以在MATLAB中运行,并且不需要代码生成。

%如果定义了以前的跟踪器,清除它。清晰的跟踪内核%用雷达和平台创建ATC场景。[场景、塔台、雷达]=helperCreateATCScenario;%创建一个显示来显示真实的、测量的和跟踪的位置%客机。(戏剧、无花果)= helperTrackerCGExample (“创建显示”、场景);helperTrackerCGExample (“显示更新”、戏剧、场景、塔);

现在通过调用跟踪内核函数在MATLAB中实现。此初始运行提供了比较结果的基线,并使您能够在跟踪程序在MATLAB中或作为MEX文件运行时收集有关跟踪程序性能的一些度量。

模拟和跟踪航班

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

%将模拟设置为以雷达的更新速率前进。场景。UpdateRate = radar.UpdateRate;%创建一个缓冲区,以收集雷达全扫描的检测结果。scanBuffer = {};%初始化轨道数组。轨道=[];%为可重复的结果设置随机种子。rng(2020年)%在MATLAB中分配内存用于轨道数和时间测量。numSteps=12;numtrack=零(1,numSteps);运行时=零(1,numSteps);指数=0;推进(场景)& & ishghandle(图)%对雷达当前视场的目标产生探测。[引爆器,配置]=检测(场景);scanBuffer = (scanBuffer;依据);%#确定允许缓冲区增长。当360度扫描完成时,更新轨道。如果配置。IsScanDone%更新跟踪器Index = Index + 1;tic [tracks, numTracks(index), info] = tracker_kernel(scanBuffer, scenariationtime);运行时(指数)= toc;%收集MATLAB运行时数据%为下一次扫描清除扫描缓冲区。scanBuffer = {};终止%使用当前光束位置、缓冲检测和%轨道位置。helperTrackerCGExample (“显示更新”剧院、场景、塔楼、扫描缓冲区、轨道);终止

编译MATLAB函数到一个MEX文件

使用编码基因函数编译跟踪内核函数转换为一个MEX文件。您可以指定报告选项生成编译报告,其中显示在C代码生成期间创建的原始MATLAB代码和相关文件。考虑创建一个临时目录,MATLAB Coder可以在其中存储生成的文件。注意,除非你使用- o选项指定可执行文件的名称,生成的MEX文件与原始MATLAB文件具有相同的名称_mex附加。

MATLAB编码器要求您指定所有输入参数的属性。跟踪器使用输入为跟踪中使用的对象创建正确的数据类型和大小。数据帧之间的数据类型和大小不能改变。的示例在命令行中定义输入属性是一种简单的方法-args选择。有关更多信息,请参见输入规范(MATLAB编码器).

定义输入的属性。首先定义检测缓冲区为%包含objectDetection对象的可变大小的单元格数组。然后将第二个参数定义为simTime,它是一个标量双精度变量。dets = code .typeof(scanBuffer(1), [inf 1], [1 0]);compInputs = {dets scenario.SimulationTime};代码生成可能需要一些时间。h=msgbox({'生成代码。这可能需要几分钟……”;完成后此消息框将关闭。},“Codegen消息”);%生成代码。试一试编码基因跟踪内核-argscompInputs; 关闭(h)我关闭(h)把(我)终止
警告:C编译器生成了警告。有关更多详细信息,请参阅构建日志。代码生成成功(带有警告):要查看报告,请打开('codegen/mex/tracker\u kernel/html/report.mldatx')

运行生成的代码

现在代码已经生成,请使用生成的MEX文件运行完全相同的场景跟踪器\u内核\u mex. 其他一切都是一样的。

%如果定义了以前的跟踪器,清除它。清晰的跟踪器\u内核\u mex%为磁道数和时间测量分配内存numTracksMex=零(1,numSteps);runTimesMex=0(1,numSteps);%重置场景、数据计数器、绘图仪、扫描缓冲区、轨道和rng。指数=0;重新启动(场景)scanBuffer={};clearPlotterData(战区);轨道=[];rng(2020年)推进(场景)& & ishghandle(图)%对雷达当前视场的目标产生探测。[引爆器,配置]=检测(场景);scanBuffer = (scanBuffer;依据);%#确定允许缓冲区增长。当360度扫描完成时,更新轨道。如果配置。IsScanDone%更新追踪。指数=指数+1;tic[tracks,numTracksMex(index),info]=tracker\u kernel\u mex(scanBuffer,scenario.SimulationTime);runTimesMex(索引)=toc;%收集MEX运行时数据%为下一次扫描清除扫描缓冲区。scanBuffer = {};终止%使用当前光束位置、缓冲检测和%轨道位置。helperTrackerCGExample (“显示更新”剧院、场景、塔楼、扫描缓冲区、轨道);终止

比较两次运行的结果

比较生成的代码与MATLAB代码的结果和性能。以下曲线图比较了跟踪器在每个时间步保持的轨迹数。它们还显示了处理每个函数调用所花费的时间。

图(2)subplot(2,1,1) plot(2:numSteps, numTracks(2:numSteps),的:“2: numSteps numTracksMex (2: numSteps),“x”。)标题(“每一步的轨道数”);传奇(MATLAB的,墨西哥人的) grid subplot(2,1,2) plot(2:numSteps, runTimesMex(2:numSteps)*1e3);标题(“每个步骤的MEX处理时间”)网格标记(“时间步”) ylabel ('MEX处理时间[ms]')

上面的图显示了每个跟踪器所维护的轨迹数量是相同的。它用轨迹的数量来衡量跟踪问题的大小。即使在整个跟踪示例中有3条确认的轨迹,跟踪器维护的所有轨迹的总数也会根据错误检测创建的试探性轨迹的数量而变化。

下面的图显示了生成的代码函数处理每个步骤所需的时间。第一步被从图中排除了,因为在第一步中实例化所有轨道需要过多的时间。

结果显示MEX代码在计算机上执行每个更新步骤所需的毫秒数。在本例中,MEX代码运行更新步骤所需的时间以几毫秒为单位。

总结

这个例子展示了如何从MATLAB代码生成C代码,用于传感器融合和跟踪。

自动代码生成的主要好处是能够在MATLAB环境中进行原型化,并生成可以在MATLAB环境中运行的MEX文件。生成的C代码可以部署到目标。在大多数情况下,生成的代码比MATLAB代码快,可以用于算法的批量测试和生成实时跟踪系统。