Page tree
Skip to end of metadata
Go to start of metadata

概述

本文档是关于VtdWorker,以及可选的VtdSideCarWorker和VtdResultProcessor。这些是VtdScale的组成部分,负责运行VTD仿真、可选的VTD有关的定制开发,以及处理仿真结果。

VTD是什么?

VTD是一个完整的工具链,用于驾驶仿真应用。VTD是我们的工具包,用于创建、配置、展示和评估基于公路和铁路的仿真范围内的虚拟环境。它可用于ADAS和自动驾驶系统的开发,也是训练仿真器的核心。它涵盖了从3D内容的生成到复杂交通场景的仿真,最后到简化的或真实的驾驶传感器仿真的全部范围。它可用于SiL、DiL、ViL和HiL的应用,也可进行联合仿真(包括第三方或定制化软件包)。通过其开放式和模块化的设计,可以轻松地进行对接和集成。

VtdScale是什么?

VtdScale是一个平台,通过使用定制化设置的VTD,以及使用VTD相关的定制化开发,便可以执行大规模的并行仿真。仿真结果可以被处理和分析,然后反馈给用户。

VtdScale分为两部分,分别是Scale框架和Scale工作节点。本文档是关于VTD环境中的Scale工作节点。Scale框架提供和运行工作节点,它为每个工作节点分配输入,并且关注于输出。

VTD工作节点

Scale的VTD工作节点,如VtdWorker、VtdSideCarWorkers和VtdResultProcessor,都是以Docker镜像的形式提供的。还有其他的由Scale框架启动的工作者,如下载器(Downloader)、填充器(Applicator)。在下文中,它们统称为Scale工作节点,或工作节点。

一般来说,有三种类型的工作节点在VTD环境中运行:

  • VtdWorker:运行VTD自身
  • VtdSideCarWorker:运行定制化的应用程序,或者定制化的ModuleManager插件,它们连接至VTD。
  • VtdResultProcessor:处理仿真输出,并且提供其中的关键信息。

Scale工作节点作为独立的Docker容器执行,但是它们在Kubernetes(k8s)工作舱(Pod)环境中运行。因此,容器的应用程序之间的网络和IPC通信表现为在同一主机上运行,而不是在多个主机上。

持有VTD的VtdWorker通过仿真输入获得配置和动态仿真数据,但是可执行文件是不可修改的。另一方面,VtdSideCarWorker和VtdResultProcessor甚至连逻辑都要通过仿真输入来提供。这就使得VtdScale用户能够在VTD内启动仿真,使用给定的场景、道路布局、视觉数据库和ModuleManager配置,但是也可以将定制化功能添加至仿真环境中,并且根据其特殊需要处理结果。

结构图

图-1中的“总体结构”显示了在VtdScale工作舱(Pod)运行期间执行的一些工作节点。有些工作节点是逐个运行的,有些工作节点是并列运行的,这些工作节点之间可能会互相通信。图-1显示了多个VtdSideCarWorker,它们是可选的工作节点,可以根据使用情况连接至VtdWorker,即作为SiL设置中的SUT(动力学、传感器或驾驶员模型)和/或作为消费VTD的ImageGenerator输出的感知管道。


图-1:注重于VtdWorker的Scale框架的总体结构


图-2中的“详细结构”还显示了在VtdWorker和VtdSideCarWorker中运行的组件。在REST服务接管Scale框架和独立工作节点之间的通信时,它还会运行一个控制器,这个控制器通过定制化插件或提供给VtdSideCarWorker的定制化应用程序来运行实际的应用程序,如VTD或VTD ModuleManager。控制器的任务是处理依赖于VTD状态的信息,并且将其转发给底层应用。


图-2还显示了VtdWorker/VtdSideCarWorker设置中的通信路径。虽然VTD在运行期间总是提供SCP和RDB连接,但只有当ImageGenerator是VTD设置的一部分,并且SHM通信被激活时,共享内存(SHM)通信才有可能。虽然SCP/RDB连接是与VTD通信的必要条件,但是SHM连接也可根据使用情况使用。如果有必要,VtdSideCarWorker也可以相互通信。


图-2:VtdWorker和VtdSideCarWorker的详细结构

VtdWorker

VtdWorker是持有实际VTD实例的工作节点,它还持有VtdController,可以使VTD自动化,触发仿真,并且写入来自于仿真的数据。s

VtdController

VtdController是实现VTD自身自动化、触发仿真和写入仿真数据的软件组件。如图-2所示,REST服务在仿真输入时调用VtdController。仿真输入必须有一个config.xml文件,VtdController将这个文件作为VTD自动化及其仿真的基础。VtdController还准备了所使用的项目,因此它可以访问动态数据,如ModuleManager配置、场景、道路布局,以及(如果需要的话)视觉数据库。


在“仿真输入”和“使用示例”章节中,可以找到更多关于仿真输入内容的信息。

VtdScale环境中的VTD

Scale环境中的VTD与桌面版本相比有其局限性。特别是ImageGenerator会受到影响,因为生成的图像不能像在工作站那样直接显示给用户。如果正在VtdScale中使用ImageGenerator,那么它是在EGL环境中运行的,并且按照VTD设置中的配置,将图像写入共享内存(SHM)段。EGL环境使ImageGenerator仍然能够生成图像,即使它所运行的系统没有图形输出,但是它仍然需要访问NVIDIA GPU。要访问ImageGenerator生成的图像,就必须消费这些SHM段。


对于VtdScale,VTD已经被拆解开来,以便于尽可能快地运行。它拥有几个车辆模型,但是没有动态数据,如场景、道路布局或视觉数据库。甚至VTD设置和VTD项目也从VTD安装中被移除。


在“局限性”章节中,可以找到更多关于VtdScale内VTD局限性的信息。

VtdSideCarWorker

VtdSideCarWorker也是工作节点,可以运行定制化应用程序或带有定制化插件的ModuleManager实例。对于定制化应用程序,与VtdWorker的连接是通过localhost网络通信实现的,而对于启用ImageGenerator/GPU的应用程序,则通过SHM通信实现。可以像使用本地ModuleManager实例那样使用ModuleManager插件。

VtdSideCarController

与VtdWorker的VtdController一样,VtdSideCarController也是一个软件组件,用于自动化执行实际的边车应用程序。REST服务在仿真输入时调用VtdSideCarController,并且根据给定的边车配置来启动和停止边车应用程序。


在“仿真输入”和“使用示例”章节中,可以找到更多关于仿真输入内容的信息。

定制化ModuleManager插件

若要在VtdSideCarWorker中使用ModuleManager插件,则必须通过仿真输入的特定边车子目录来提供插件本身和ModuleManager配置。可以从示例中获取启动和停止脚本,以及sidecar-config.xml文件。


VtdSideCarWorker会自动注册为VTD组件,并且需要作为SyncSource执行,这样才能保证仿真的确定性行为。在ModuleManager应用程序将自身注册为VTD组件之后,执行链中最新的定制化ModuleManager插件必须在处理完每一帧后发送RDB同步消息。在VTD文档或“使用示例”章节中,可以找到更多有关信息。

定制化VtdSideCar应用程序

若要在VtdSideCarWorker中使用定制化应用程序,则必须通过仿真输入的特定边车子目录来提供待运行的应用程序,以及运行所需的所有东西。此外,启动脚本和停止脚本(如果有必要的话),以及sidecar-config.xml文件,都必须设置正确。在示例中可以找到更多信息。


VtdSideCarWorkers会自动注册为VTD组件,并且需要作为SyncSource执行,这样才能保证仿真的确定性行为。这就意味着定制化VtdSideCar应用程序在初始化完成时,必须发送一条“initDone”消息,并且必须在处理完每一帧后,也要发送RDB同步消息。在VTD文档或“使用示例”章节中,可以找到更多有关信息。

网络通信

VtdSideCarWorker应用程序可以通过RDB和SCP本地主机网络通信的标准VTD端口与VTD进行通信。

共享内存访问

如果正在使用启用ImageGenerator/GPU的设置,VtdSideCar应用程序便可以消费ImageGenerator写入的共享内存。


Deterministic.headless设置使用SHM键“0x08130”,还有releaseFlag=2选项,用于ImageGenerator向内存写入数据。请查看“边车-图像输出”示例,以便于获得更多信息。

VtdResultProcessor

在仿真执行之后,VtdResultProcessor使用仿真输出,并且计算出有价值的仿真指标。VtdResultProcessor逻辑正在通过仿真输入动态加载。VtdResultProcessor的输出是包含处理结果的Python字典的形式。Scale框架通过Jupyter笔记本以Spark数据帧的形式提供这些结果。


动态处理逻辑的入口是通过processor/worker/目录中的vtdprocessorfunction_helper.py文件来建立的,processor/worker/目录是仿真输入目录的子目录。任何进一步的依赖关系也必须在这个processor目录中提供。


在“使用示例”章节中,可以找到更多有关信息。

仿真输入

仿真输入是一个由多个条目组成的目录,其中有些条目是可选的,但是将它们提供给VtdWorker时,所有的条目都必须是具体的:

  • config.xml
  • scenario.xml
  • moduleManager.xml
  • [道路布局文件]
  • [视觉数据库]
  • 处理器(可能有多个处理器条目)
  • 边车(可选 — 可能有多个边车条目)

下面的章节将更详细地描述具体的条目。

配置文件(config.xml)

config.xml是VtdController的配置文件,一个典型的config.xml文件看起来像这样:

<?xml version="1.0" encoding="UTF-8"?>
<VTDtest verbose="true"
         vtdRoot="/opt/VTD/"
         testTime="60.0"
         packageIds="1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50"
         recordSimulation="true">
        <Setup name="Deterministic.noIG"/>
        <Project name="ScaleDemo-Project"/>
</VTDtest>
  • verbose — 更多日志
  • vtdRoot — VTD的根目录
  • testTime 在仿真停止之前,仿真正在执行的最大时间。总有一种可能性,即仿真自己停止或被其他组件停止。
  • packageIds 正在从RDB流中写入RDB_Data.h5输出文件的RDB数据包的ID
  • recordSimulation 仿真录像,以便于能够通过本地安装的VTD重放仿真
  • Setup 要使用的VTD设置的名称(“Deterministic.noIG”或“Deterministic.headless”)
  • Project 要使用的VTD项目的名称(“ScaleDemo-Project”或“SampleProject”)

ModuleManager配置(moduleManager.xml)

这个配置文件是标准的moduleManager.xml配置文件,与本地VTD安装使用的配置文件相同。VtdController负责本地VTD能够访问这个文件。请查看VTD文档或示例。

场景文件(scenario.xml)

场景文件保存特定仿真的动态内容,如车辆、行人和自行车,以及它们的行为。scenario.xml文件与本地VTD安装使用的文件相同。场景文件还定义了道路布局文件以及视觉数据库文件的路径和名称。有关场景的更多信息,请参考VTD文档。

道路布局文件(*.xodr)

道路布局文件或OpenDrive文件包含场景发生的道路布局。它甚至可能包含更多关于建筑物、交通标志、交通灯等静态物体的信息。一般来说,VtdScale仿真输入中的道路布局文件可以有任何名称,但必须在scenario.xml文件中进行适当的链接。有关道路布局的更多信息,请参考VTD文档。

视觉数据库文件(*.opt.osgb)

视觉数据库包含VTD的ImageGenerator所需的模型,用来生成图像输出。类似于场景文件和道路布局文件,这个文件与VTD的桌面安装使用的文件相同。由于视觉数据库只被ImageGenerator使用,因此在不使用ImageGenerator的仿真运行中不需要它。视觉数据库的名称是从场景中获得的。有关视觉数据库的更多信息,请参考VTD文档。

边车配置(sidecar目录)

sidecar目录保存配置数据,以及用来运行VtdSideCarWorker的动态数据。VtdSideCarWorker是可选的,但是每个仿真可以使用多个VtdSideCarWorker。VtdSideCarWorker配置目录总是以“sidecar”作为前缀。一般来说,VtdSideCarWorker正在执行的操作由用户决定,但是有3个条目必须始终存在:

sidecar-config.xml

一般来说,sidecar-config.xml决定了VtdSideCarWorker是在“ModuleManager”配置还是“CustomApplication”配置下执行。

sidecar-launch.sh

这个脚本由VtdSideCarController在作业传输时启动,用来启动实际的VtdSideCarWorker应用程序,或者至少通知应用程序(如果已经启动)新的仿真输入的有关信息。

sidecar-stop.sh

这个脚本由VtdSideCarController在向应用程序发送停止命令时启动,用来停止实际的VtdSideCarWorker应用程序,或者至少通知应用程序仿真停止的有关信息。

可选的VtdSideCarWorker文件

除了上述3个文件之外,还必须提供运行定制化开发所需的一切,对于定制化ModuleManager插件,这包括moduleManger.xml文件,以及预编译的插件本身。对于定制化应用程序,这包括可执行文件,以及运行这个可执行文件所需的任何配置和文件。

处理器配置(processor目录)

processor目录保存VtdResultProcessor的逻辑。VtdResultProcessor的输入是仿真的输出,它会对这些输出执行动态提供的逻辑。

仿真输出/处理器输入

图像输出(images目录)

在VtdWorker或VtdSideCarWorker的SHM2PNG示例中,如果激活图像输出,那么这个目录将充满来自于仿真的逐帧图像。

处理器配置(processor目录)

仿真输入的processor目录被带进仿真输出,因为这是VtdResultProcessor实际执行的地方。

仿真数据输出(RDB_Data.h5)

RDB_Data.h5文件是逐帧的仿真数据,存储为HDF5格式。关于RDB数据的更多信息,请查看你的VTD安装的RDB文档。

报告(report.html)

report.html应该让人们初步了解正在执行的任务和已经成功的任务。

使用本地VTD安装进行调试

为了能够预览或回顾仿真运行,可以使用本地VTD安装来调试具体的仿真输入。有必要向本地VTD安装手动提供所有需要的数据。


VtdScale设置所使用的VTD设置不能在标准的VTD工作站环境中使用,因为它们需要一个外部应用程序来触发仿真。因此,必须使用不同的设置,例如“标准”设置,以便于能够运行仿真。由于这一限制,以及VTD不受VtdController控制的事实,因此运行本地VTD仿真不可能像运行VtdScale仿真那样具有完全的确定性。


使用本地VTD安装进行仿真可以检查所有的输入数据是否设置正确、是否正常工作。它们还能让我们更好地了解仿真中实际发生的情况。另一方面,使用本地VTD安装进行仿真没有一种标准化的方法来生成VtdScale仿真所具有的仿真输出。


在运行本地VTD仿真时,应该如何处理不同的VtdScale仿真输入条目,如下表所示:

  • config.xml
    这个配置文件不能用于本地VTD安装。
  • moduleManager.xml
    必须放在所使用的VTD项目的Config/ModuleManager目录中。
  • scenario.xml
    必须放在所使用的VTD项目的scenarios目录,甚至在scenarios的子目录中。
  • 道路布局文件(*.xodr)
    必须直接放在所使用的VTD项目的Databases目录中。
  • 视觉数据库(*.opt.osgb)
    必须直接放在所使用的VTD项目的Databases目录中。
  • 定制化ModuleManager插件
    必须通过所使用的VTD项目的Plugins/ModuleManager目录来提供。如果有必要,VtdSideCar的moduleManager.xml配置和VtdWorker的moduleManager.xml配置必须进行合并,并且必须在所使用的VTD项目的Config/ModuleManager目录中提供。
  • 定制化VtdSideCar应用程序
    无法为本地VTD仿真运行自动集成定制化VtdSideCar应用程序。定制化VtdSideCar应用程序可以与VTD仿真同时手动启动,或者甚至可以通过使用VTD设置中的simServer.xml文件,将其作为VTD组件集成进来。可以在VTD文档中找到更多信息。
    如果定制化VtdSideCar应用程序需要访问写入至共享内存的ImageGenerator数据,则必须通过VTD设置进行配置。
  • VtdResultProcessor
    到目前为止,VtdScale中的仿真输出还没有写入至本地VTD安装,因此不能将VtdResultProcessor自动添加至本地仿真的执行链中。无论如何,你都可以在本地机器上手动运行VtdResultProcessor的逻辑,以便于处理VtdScale的仿真输出。

回放仿真录像

如果将VtdScale仿真配置为记录仿真运行,则仿真输出会保存一个“recording.dat”文件。然后,可以在本地VTD安装中,使用这个文件来重放仿真。VtdScale的仿真记录保存了整个仿真过程中的RDB和SCP数据流。因此,没有必要使用任何ModuleManager插件或定制化VtdSideCar应用程序,因为它们对仿真的影响已经被记录下来了。


至于“使用本地VTD安装进行调试”,本地VTD安装必须使用VtdScale仿真输入的一些动态数据进行准备。必须准备道路布局和视觉数据库,除此之外,还要将“recording.dat”文件复制到所使用的VTD项目的Recordings目录中。如果这些文件已经准备好了,则可以启动重放录像的标准程序了。将VTD设置为重放模式,应用配置,然后启动“recording.dat”文件。

确定性的定义

仿真的确定性行为是通过检查仿真输出与参考数据来进行测试的,而参考数据是在装有NVIDIA GeForce GT 1030显卡(驱动版本为450.66)的系统构建机器上产生的。


在下列情况中,输出被认为是确定性的:

  • 生成RDB_Data.h5文件,其数据和参照的RDB_Data文件相似,精度为10^-3。这适用于文件中的所有数据集,除了数据集“/RDB_PKG_ID_SYNC/tableName.c_str()”,因为它包含的时间戳在不同的仿真中有所不同。
  • 对于使用GPU的docker容器,生成的图像与参考图像相似,最多有10个像素的差异,允许有2%的模糊颜色。这是针对图像分辨率为960x540的情况。

VtdResultProcessor示例

VtdResultProcessor读取仿真的RDB打包数据输出(.hdf5文件),以便于计算有价值的仿真指标进行分析。RDB打包数据描述了仿真的结果,例如,所有玩家的位置、速度、包围盒。


VtdResultProcessor的标准实现语言是Python(3.7及以上版本)。


为了将VtdResultProcessor与一个给定的仿真结合起来,必须遵循以下步骤(注意:为了便于解释,下面将使用/share/Basic):


1)配置仿真(将RDB数据包写入hdf5文件)

VtdResultProcessor需要的所有RDB数据包都应该由仿真写入至.hdf5文件。哪些RDB数据包应该由仿真写入,必须在仿真的config.xml中使用packageIds标签来指定。config.xml文件位于/share/Basic-Run目录中。


示例:

<?xml version="1.0" standalone="no" ?>
<VTDtest verbose="true"
         vtdRoot="/opt/VTD/"
         testTime="60.0"
         packageIds="1,9,26"
         recordSimulation="true">
        <Setup name="Deterministic.noIG"/>
        <Project name="SampleProject"/>
</VTDtest>


在上述的config.xml示例中,指定RDB数据包的ID为1926,仿真会将这些数据写入至.hdf5输出文件,这个文件位于/share/Basic-Run-Output目录。


VTD的RDB数据包ID的数据格式和数据字段在下列文件中规定:https://secure.vires.com/workgroups/vtd/Common/Doc/rdb/index.html

2)将仿真的输出数据映射至VtdResultProcessor的数据结构

仿真将RDB数据包的输出写入至.hdf5文件。.hdf5文件的数据格式是hdf5,需要将其映射至VtdResultProcessor的数据结构。

RDB的hdf5文件的命名和结构约定

  • RDB数据包分组只有子分组,但是没有数据集。
  • 子分组的命名取决于条目ID(玩家ID、交通灯ID,等等):例如,玩家-1的子分组名为“Player_ID_1”。
  • RDB数据包分组的子分组只能直接包含数据集,或者包含“基础”和“扩展”(如果RDB数据包有可能提供扩展信息)的子分组。
  • 每个子分组中至少要有一个名为“data”的数据集,其中包含数据。进一步的数据集是根据RDB结构来命名的。
  • 分组名称必须以大写字母开头。
  • 数据集名称都是小写的字符。
  • 数据集成员的名称与它们的RDB数据包的名称相匹配。
  • 所有RDB数据包的数据都能在一个单一的“data”数据集中找到。
  • 为了便于使用,可适用这个规则的例外情况:RDB_PKG_ID_WHEEL将包含玩家子分组内的每个车轮的子分组:“RDB_PKG_ID_WHEEL->Player_ID_1->Wheel_ID_0->Base->data”。

RDB_Data.hf5文件格式示例

RDB_PKG_ID_DRIVER_CTRL
  Player_ID_1 (group)
    data (data set)
RDB_PKG_ID_OBJECT_STATE
  Player_ID_1 (group)
    Base (group)
      data (data set with geo and pos data)
    Ext (group)
      data (dataset with accel and speed data)


对于每个RDB数据包的ID来说,需要在VtdResultProcessor的settings.json映射模式文件中定义一个查询映射,这个文件位于/share/Basic-Run/processor/vtd目录。


数据查询代码必须在vtd模块的Result类中实现。Result类存放在/share/Basic-Run/processor/vtd目录中的result.py文件中:

{
    "h5": {
        "result": {
            "players": "/RDB_PKG_ID_OBJECT_STATE/",
            "position": "/RDB_PKG_ID_OBJECT_STATE/%s/base",
            "road_position": "/RDB_PKG_ID_ROAD_POS/%s/data",
            "velocity": "/RDB_PKG_ID_OBJECT_STATE/%s/ext",
            "acceleration": "/RDB_PKG_ID_OBJECT_STATE/%s/ext",
            "objectDetection": "/RDB_PKG_ID_OBJECT_STATE/%s/base/geo/geo/WRONG",
            "playerBoundingBox": "/RDB_PKG_ID_OBJECT_STATE/%s/base"
        },
        "Acceleration": "Acceleration"
    }
}

3)编写结果数据查询代码

将hdf5数据映射至Python数据结构的数据查询代码必须在vtd模块的Result类中实现。Result类在result.py文件中实现,位于/share/Basic-Run/processor/vtd目录中。

4)使用Python编写仿真数据处理逻辑

在步骤-3中提供给VtdResultProcessor的仿真输出数据可以用来计算仿真指标,以便于对齐进行分析。分析代码在vtd模块的ResultProcessor类和ResultComfortFactor类中实现。ResultProcessor和ResultComfortFactor的实现分别存放在result_processor.py和result_comfort_factor.py文件中。

5)返回VtdResultProcessor的仿真处理结果

在VtdResultProcessor完成计算之后,它将分析指标结果作为数据字典返回给调用者(VtdScale)。vtdprocessorfunction_helper.py返回key_results字典。vtdprocessorfunction_helper.py文件位于/share/Basic-Run/processor/worker目录中。

6)可选:从VtdResultProcessor提供额外或不同的结果

如果修改了VtdResultProcessor样本,并且结果数据字典的键/值不同,那么就必须实现一个定制化的make_processor_schema方法,并且作为一个函数输入传递给simulate()调用。下面的段落显示了可以对已交付的VtdResultProcessor样本进行的修改:

6.1)向VtdResultProcessor添加额外的输出参数

修改vtdprocessorfunction_helper.py文件,添加或修改VtdResultProcessor应该计算和返回的结果值。必须在vtdprocessor_schema_gen.py文件中的make_processor_schema方法和get_dict_for_schema方法中指定仿真中的额外输出变量的数量和类型,以及玩家(车辆)的数量。必须在仿真输入平台的processor/vtd目录中提供vtdprocessor_schema_gen.py文件。

6.2)实现定制化的make_processor_schema方法

下面是get_dict_for_schema方法和make_processor_schema方法的一个实现示例。在get_dict_for_schema方法中,THIS_SIMULATION_PLAYERS变量用于指定参加仿真的玩家(车辆)数量,将其设置为6。在make_processor_schema方法中,已经指定了玩家-1(主车)的3个仿真级别变量(“safety_factor”、“comfort_factor”、“is_collision”)、每个仿真帧的6个变量(“x”、“y”、“z”、“vx”、“vy”、“vz”)和每个仿真帧额外的3个变量(“ax”、“ay”、“az”)。每次仿真结束后,Scale框架都会调用get_dict_for_schema方法来格式化处理器的结果,以便于在Jupyter笔记本的Panda数据帧中显示这些结果。


def get_dict_for_schema() -> dict:
    """Returns a JSON Schema of the data structure being return by this processor.
    To verify correntness, the processor return values can be validated using
    https://python-jsonschema.readthedocs.io/en/stable/    Returns:
        dict: JSON Schema
    """
    THIS_SIMULATION_PLAYERS = 6
    return make_processor_schema(num_players=THIS_SIMULATION_PLAYERS)


def make_processor_schema(
        simulation_level_floats=['safety_factor', 'comfort_factor', 'is_collision'],
        num_players=3,
        frame_level_player_floats=['x', 'y', 'z', 'vx', 'vy', 'vz'],
        frame_level_player1_floats=['ax', 'ay', 'az']):

    props = {attr: {'type': 'number'} for attr in  simulation_level_floats}
    for player in range(num_players):
        p = "p" + str(player+1) + "_"
        for attr in frame_level_player_floats:
            props[p+attr] = {
                'type': 'array',
                'items': {
                    'type': 'number'
                }
            }

        if player == 0:
            for attr in frame_level_player1_floats:
                props[p+attr] = {
                    'type': 'array',
                    'items': {
                        'type': 'number'
                    }
                }

    return {
        'type': 'object',
        'properties': props,
        'required': list(props.keys()),
        'additionalProperties': False
    }


使用示例

出于演示目的,有几个具体仿真的输入样本,使用VtdWorker功能的不同组合。

概述


VtdWorkerVtdWorkerVtdSideCarVtdSideCar

模块管理器插件GPU定制化模块管理器插件定制化应用程序
Basic-Run



Basic-Run-GPU
x

ScaleDriverx


ScaleDriver-GPUxx

ScaleDriver-LaneChangex


SideCar-Driver

x
SideCar-ImageOutputxx
x
Basic-Run-Multi-IG
x

详细配置

名称描述VTD设置CPU/GPU

共享内存
数量

VtdWorker
模块管理器插件

玩家
数量

行人自行车

路网
(尺寸)

边车类型

结果处理器
(安全因数,舒适因数)

Basic-Run自车在十字路口左转Deterministic.noIGCPU-TrafficDyn6--Crossing8Course (12 MB)-0.0205, 1.172
Basic-Run-GPU自车在十字路口左转Deterministic.headlessGPU1TrafficDyn6--Crossing8Course (12 MB)-0.0205, 1.172
ScaleDriver前车制动时,自车也制动Deterministic.noIGCPU-AccDriver、 TargetListRadar、 TrafficDyn2--Germany_2018 (13MB)-0.0196, 0.206
ScaleDriver-Advanced-SafetyFactor前车制动时,自车也制动Deterministic.noIGCPU-AccDriver、 TargetListRadar、 TrafficDyn2--Germany_2018 (13MB)-0.0196, 0.206
ScaleDriverDesignSpace前车制动时,自车也制动Deterministic.noIGCPU-AccDriver、 TargetListRadar、 TrafficDyn2--Germany_2018 (13MB)--
ScaleDriver-GPU前车制动时,自车也制动Deterministic.headlessGPU1AccDriver、 TargetListRadar、 TrafficDyn2--Germany_2018 (240 MB)-0.0196, 0.206
ScaleDriver_LaneChange当前车变道,另一辆较慢的车变为前车时,自车制动Deterministic.noIGCPU-AccDriver、 TargetListRadar、 TrafficDyn3--Germany_2018 (240 MB)-0.0137, -1.247
ScaleDriver_LaneChangeDesignSpace当前车变道,另一辆较慢的车变为前车时,自车制动Deterministic.noIGCPU-AccDriver、 TargetListRadar、 TrafficDyn3--Germany_2018 (240 MB)--
SideCar-Driver前车制动时,自车也制动Deterministic.noIGCPU-TrafficDyn2--Germany_2018 (13MB)模块管理器 (AccDriver, TargetListRadar)0.0196, 0.206
SideCar-ImageOutput前车制动时,自车也制动Deterministic.headlessGPU1AccDriver、 TargetListRadar、 TrafficDyn2--Germany_2018 (13MB)定制化应用程序 (Image Output)0.0196, 0.206
Basic-Run-Multi-IG自车在十字路口左转Deterministic.headless.multiIGGPU3TrafficDyn6--Crossing8Course (12 MB)-0.0205, 1.172

VtdWorker的模块管理器插件

对于本地VTD安装,ModuleManager插件是通过VTD在VtdWorker中执行的,VTD是通过仿真输入目录中的moduleManager.xml文件来配置的。只有一部分VTD插件可以作为VtdWorker的ModuleManager插件。

VtdWorker GPU

如果在VtdWorker内使用“Deterministic.headless”的VTD设置,ImageGenerator将作为仿真的一部分被执行。正如“定制化VtdSideCar应用程序”的章节所述,ImageGenerator将数据写入一个共享内存段,然后VtdController和定制化VtdSideCar应用程序可以再次消费这些数据。

VtdSideCar的定制化模块管理器插件

VtdSideCarWorker执行客户提供的插件,这些插件由ModuleManager负责管理。在本例中,传感器插件radar(ScaleRadar)向动力学插件(ScaleDriver)提供距离测量数据。


插件和它们的参数化是在仿真输入目录的sidecar子目录的moduleManager.xml(在VTD文档中查找更多信息)文件中配置的。

Vtdworker的VtdSideCar定制化应用程序

在本例中,VtdSideCarWorker执行一个仿真输入提供的程序,它会与VtdWorker内运行的仿真进行互动。VtdSideCarController执行定制化应用程序,它会将这个应用程序注册为在VtdWorker内执行的仿真的VTD组件。然后,将定制化应用程序注册为同步源,能够通过共享内存访问每一帧数据,在VtdWorker内运行的ImageGenerator会生成这些数据。

开发定制化的VtdSideCar应用程序

要构建一个定制化的VtdSideCar,需要一台运行Linux OS 18.04(或更高版本)和Docker 19(或更高版本)的工作站,还需要一个网络连接。


要构建ExampleSharedMemory2Png示例,需要遵循以下步骤:

  1. 从Vires私有云下载ExampleSharedMemory2Png.tar.gz示例:https://owncloud.vires.com/s/Q5QmDICAPeL03QO(密码:VtdScale)
    将ExampleSharedMemory2Png.tar.gz解压缩至工作站的任意位置。
  2. 进入ExampleSharedMemory2Png目录。
  3. 对main.cpp中提供的示例代码进行修改。VtdApiHelper.cpp程序提供了有用的辅助方法,可用于定制化边车实现,这样便能与在VtdWorker内运行的仿真建立连接。在定制化边车使用VtdApiHelper的init方法初始化连接,并且将自身注册为VTD组件之后,它便可以访问在VtdWorker容器内执行的仿真的共享内存。
  4. 启动buildSample.sh来编译示例。
  5. 将位于ExampleSharedMemory2Png/lib中的所有文件复制到你要运行的边车输入平台的仿真输入目录中。

注意:如果你的边车标识符是sidecar_0,那么必须将ExampleSharedMemory2Png/lib目录中的所有文件复制到你的仿真输入平台的sidecar_0目录中。

局限性

  • 只有特定的设置和项目是分布式的
  • 目前不支持FMU集成
  • ImageGenerator只能在EGL环境中运行,这是由于无头的云环境造成的
  • 目前不支持HDR渲染
  • 目前不支持Optix
  • Multi-IG支持只支持单个GPU

已知问题

  • 脱离VtdScale的本地VTD安装不能提供完全的确定性
Write a comment...