主要内容

如何为跟踪器生成C代码

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

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

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

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

实例说明了如何修改MATLAB中的代码空中交通管制支持代码生成的示例。金宝app这个例子需要一个MATLAB Coder许可证来生成C代码。

修改并运行MATLAB代码

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

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

以保存状态trackerGNN在调用到tracker_kernel.m时,跟踪器定义为持续的变量。

的单元格数组objectDetection对象生成的fusionRadarSensor对象,并将时间作为输入参数。

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

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

  2. 轨道数-整数标量。

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

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

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

方法运行示例tracker_kernel函数的MATLAB。这个初始运行提供了一个基线来比较结果,并使您能够收集有关跟踪器在MATLAB中运行或作为MEX文件运行时的性能的一些指标。

模拟和跟踪客机

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

设置模拟以雷达的更新速度前进。场景。UpdateRate = radar.UpdateRate;创建一个缓冲区来收集雷达全面扫描的检测。。scanBuffer = {};初始化轨道数组。Tracks = [];为可重复的结果设置随机种子。rng (2020)在MATLAB中为轨道数和时间测量分配内存。numSteps = 12;numTracks =零(1,numSteps);runTimes = 0 (1, numSteps);指数= 0;Advance(场景)&& ishhandle(图)在雷达当前视场内对目标产生探测。%[dets,config] =检测(场景);scanBuffer = [scanBuffer;dets];允许缓冲区增长。* 360度扫描完成时更新跟踪。如果配置。IsScanDone%更新跟踪器指数=指数+ 1;tic [tracks, numTracks(index), info] = tracker_kernel(scanBuffer,scenario.SimulationTime);runTimes(index) = toc;收集MATLAB运行时数据为下次扫描清除扫描缓冲区。scanBuffer = {};结束更新显示当前波束位置,缓冲检测,和%跟踪位置。helperTrackerCGExample (“显示更新”、戏剧、场景、塔、scanBuffer跟踪);结束

将MATLAB函数编译成MEX文件

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

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

定义输入的属性。首先将检测缓冲区定义为包含objectDetection对象的可变大小单元格数组。然后将第二个参数定义为simTime,这是一个标量双精度。dets = code .typeof(scanBuffer(1), [inf 1], [1 0]);compInputs = {dets scenario.SimulationTime};代码生成可能需要一些时间。H = msgbox({“生成代码。这可能要花几分钟……”完成后此消息框将关闭},“Codegen消息”);生成代码。试一试codegentracker_kernelarg游戏compInputs;关闭(h)ME close(h) throw(ME)结束
警告:C编译器产生警告。有关更多详细信息,请参阅构建日志。要查看报告,打开('codegen/mex/tracker_kernel/html/report.mldatx')

运行生成的代码

现在代码已经生成,使用生成的MEX文件运行完全相同的场景tracker_kernel_mex.其他一切都保持不变。

%如果定义了以前的跟踪器,清除它。清晰的tracker_kernel_mex为轨道数和时间测量分配内存numTracksMex = 0 (1, numSteps);runTimesMex = 0 (1, numSteps);重置场景、数据计数器、绘图仪、扫描缓冲区、轨道和rng。指数= 0;restart(scenario) scanBuffer = {};clearPlotterData(戏剧);Tracks = [];rng (2020)Advance(场景)&& ishhandle(图)在雷达当前视场内对目标产生探测。%[dets,config] =检测(场景);scanBuffer = [scanBuffer;dets];允许缓冲区增长。* 360度扫描完成时更新跟踪。如果配置。IsScanDone%更新跟踪器。指数=指数+ 1;tic [tracks, numTracksMex(index), info] = tracker_kernel_mex(scanBuffer,scenario.SimulationTime);runTimesMex(index) = toc;收集MEX运行时数据为下次扫描清除扫描缓冲区。scanBuffer = {};结束更新显示当前波束位置,缓冲检测,和%跟踪位置。helperTrackerCGExample (“显示更新”、戏剧、场景、塔、scanBuffer跟踪);结束

比较两次运行的结果

比较生成的代码与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每一步处理时间”grid xlabel(“时间步”) ylabel (“MEX处理时间[毫秒]”

上面的图显示了每个跟踪器维护的轨道数量是相同的。它根据跟踪的数量来衡量跟踪问题的大小。尽管在整个跟踪示例中有3个确认的轨道,但跟踪器维护的所有轨道的总数根据由错误检测创建的暂定轨道的数量而变化。

下面的图表显示了生成的代码函数处理每个步骤所需的时间。第一步被排除在图之外,因为在第一步中实例化所有轨迹所花费的时间要长得不成比例。

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

总结

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

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