TraCI 简介#
TraCI 是 "Traffic Control Interface"(交通控制接口)的简称。 它提供对正在运行的道路交通仿真系统的访问,允许检索仿真对象的值并在线操纵其行为。 如果性能是一个问题,您应该考虑使用 libsumo。 您也可以从 TraCI 开始,稍后切换到 libsumo,因为它们的函数签名是相同的。
使用 TraCI#
SUMO 启动#
TraCI 使用基于 TCP 的客户端/服务器架构来提供对 sumo 的访问。 在此架构中,sumo 充当服务器,通过附加的命令行选项启动:--remote-port <INT>,其中 <INT> 是 sumo 将侦听传入连接的端口。
当使用 --remote-port <INT> 选项启动时,sumo 仅准备仿真并等待所有外部应用程序连接并接管控制。 请注意,当 sumo 作为 TraCI 服务器运行时,--end <TIME> 选项会被忽略,sumo 将一直运行,直到客户端要求仿真结束。
当使用 sumo-gui 作为服务器时,必须通过使用 play 按钮 或在 TraCI 命令被处理之前设置 --start 选项来启动仿真。
多客户端#
可以连接的客户端数量可以通过附加选项 --num-clients <INT> 指定,默认值为 1。 请注意,在多客户端场景中,必须使用 SetOrder-命令 显式指定客户端的执行顺序。
每个客户端必须指定一个唯一的(但除此之外是任意的)整数值,客户端命令将按照从最低值到最高值的顺序在每个仿真步中处理。
客户端在每个仿真步之后自动同步。这意味着,在所有客户端调用 'simulationStep' 命令之前,仿真不会推进到下一步。 同样,simulationStep 命令仅在仿真推进后才将控制权返回给客户端。
Caution
只有在所有客户端都连接后,仿真才会开始。
协议规范#
请参阅 TraCI 协议规范 (包括 基本流程、消息、数据类型)。
关闭#
使用 TraCI 时,sumo 的 --end 选项会被忽略。 相反,通过发出 close 命令 来关闭仿真。 要检测是否所有路线文件都已用完且所有车辆都已离开仿真,可以检查命令 getMinExpectedNumber 是否返回 0。 一旦所有客户端都发送了 close 命令,仿真就会结束。
也可以通过使用 load-命令 重新加载具有新参数列表的仿真。
TraCI 命令#
对于以下 API,ID 等于在 sumo 输入文件中定义的 ID。在此处,您可以找到它们的 通用结构。
值检索#
- 交通对象
- 检测器和输出
- 感应线圈值检索 检索感应线圈信息
- 车道区域检测器值检索 检索车道区域检测器信息
- 多入口/出口检测器值检索 检索多入口/出口检测器信息
- 校准器值检索 检索校准器信息
- 路线探测器 检索路线探测器信息
- 网络
- 基础设施
- 其他
状态变更#
- 交通对象
- 检测器和输出
- 变更校准器状态 变更校准器状态
- 变更感应线圈状态 变更感应线圈状态
- 变更车道区域检测器状态 变更车道区域检测器状态
- 网络
- 基础设施
- 其他
订阅#
订阅是一种重复获取变量变更通知的方式。 除非另有说明,它们适用于相关领域值检索部分中提到的所有变量。 有关详细信息,请参阅关于 对象变量订阅 的单独页面。
也可以订阅另一个对象(例如特定路口周围的所有车辆)周围对象的值。 这称为 上下文订阅。
订阅可能比重复值检索更快,请参阅 性能 部分。
将 SUMO 用作库#
通常,TraCI 用于耦合多个进程:一个 SUMO 服务器进程和一个或多个 TraCI 客户端进程。 或者,Libsumo 可用于将 SUMO 作为库嵌入到客户端进程中。 这允许使用与客户端库中相同的方法签名,但避免了套接字通信的开销。 Libsumo 支持使用 SWIG 生成客户端库,因此可用于多种编程语言。 C++、Java 和 Python 绑定在下载 sumo 构建时包含在内。
示例用法#
- 有一个关于使用 TraCI 进行自适应交通信号灯的 教程(使用 Python)。
- Tutorials/CityMobil 教程使用 TraCI 为车辆分配新路线(使用 Python)。
- Tutorials/TraCIPedCrossing 教程使用 TraCI 构建一个由行人触发的交通信号灯的过街处。
资源#
按编程语言划分的接口#
- Python: python 模块 traci 允许使用 Python 与 sumo 交互(此库是 sumo 源代码和所有版本的一部分,每天进行测试并支持所有 TraCI 命令)。
它也可以在 PyPI 上获得,因此可以使用
pip install traci安装。 - C++: libtraci 是 sumo 源代码树的一部分。它与 libsumo 完全 API 兼容。
- C++: The C++ TraCIAPI 是 sumo 源代码树的一部分。(API 覆盖率很好,但此客户端不再更新。请改用 libtraci。)
- C++: The Veins project 提供了一个用于耦合 sumo 和 OMNET++ 的中间件。作为基础设施的一部分,它提供了一个用于 TraCI API 的 C++ 客户端库(API 完整性略落后于 python 客户端)。
- .NET: TraCI.NET 是一个具有良好 API 覆盖率的客户端库。
- .NET: libtracics 是一个实验性的 SWIG 生成的原始 libtraci 绑定。它具有完整的 API 覆盖率,但未经测试,需要用户从源代码生成。
- Matlab: TraCI4Matlab。该客户端作为每个 SUMO 版本的一部分包含在 *<SUMO_HOME>/tools/contributed/traci4matlab 中。并非所有 TraCI 命令都已实现。建议在 Matlab 内部 使用 python 客户端。
- Java: libtraci 是 sumo 源代码树的一部分。它与 libsumo 完全 API 兼容,SUMO 版本提供预编译的 Java 绑定(通过 SWIG)。
- Java: TraaS 提供了一个客户端库,它是 sumo 源代码树的一部分(API 覆盖率很大,但此客户端不再更新。请使用 libtraci)。
- 其他:任何 SWIG 支持的语言原则上都可以使用 libsumo 或 libtraci 提供的绑定。
V2X 仿真#
TraCI 允许将 sumo 与通信网络模拟器结合使用,以模拟 车辆通信。 有关可用解决方案的列表,请参阅 Topics/V2X。
其他资源#
- sumo 的 TraCI 服务器是标准分发版的一部分。源代码位于文件夹
src/traci-server中。
参考文献#
- Axel Wegener, Michal Piorkowski, Maxim Raya, Horst Hellbrück, Stefan Fischer and Jean-Pierre Hubaux. TraCI: An Interface for Coupling Road Traffic and Network Simulators. Proceedings of the 11th Communications and Networking Simulation Symposium, April 2008. Available at ACM Digital Library
- Axel Wegener, Horst Hellbrück, Christian Wewetzer and Andreas Lübke: VANET Simulation Environment with Feedback Loop and its Application to Traffic Light Assistance. Proceedings of the 3rd IEEE Workshop on Automotive Networking and Applications, New Orleans, LA, USA, 2008. Available at IEEEXplore
性能#
使用 TraCI 会降低仿真速度。减速的程度取决于许多因素:
- 每个仿真步的 TraCI 函数调用次数
- 被调用的 TraCI 函数类型(有些比其他的开销更大)
- TraCI 脚本内的计算
- 客户端语言
Note
如果性能很重要,请始终考虑使用 libsumo。 虽然它通常要快得多,但并非所有下面提到的优化都适用于 libsumo。 特别是,订阅甚至可能更慢。
示例#
作为一个示例用例,考虑在每个仿真步检索每辆车的 x,y 位置(使用 python 客户端):
while traci.simulation.getMinExpectedNumber() > 0:
for veh_id in traci.vehicle.getIDList():
position = traci.vehicle.getPosition(veh_id)
traci.simulationStep()
- 此脚本每秒能够处理约 25000 辆车。
- 相同的值检索也可以通过使用 订阅 加速到每秒 50000 辆车:
while traci.simulation.getMinExpectedNumber() > 0:
for veh_id in traci.simulation.getDepartedIDList():
traci.vehicle.subscribe(veh_id, [traci.constants.VAR_POSITION])
positions = traci.vehicle.getAllSubscriptionResults()
traci.simulationStep()
``
在 [Bologna 场景](Data/Scenarios.md#bologna)(9000 辆车,5000 仿真步)上使用此脚本,记录了以下运行时间:
- 无 TraCI 8s
- 普通位置检索 90s
- 使用订阅检索 42s
C++ 客户端性能更高:
- 普通位置检索 80s
- 使用订阅检索 28s
## 当前和未来的发展
历史上,TraCI 为每个域(感应线圈、车辆等)使用不同的(单字节)命令 ID,其中字节的较高有效半部分表示命令(get、set、subscribe 等),较低有效部分表示域本身。
为了允许超过由此产生的 16 个域,最高有效位(在 1.7.0 版本之前未使用,因为只有 7 个命令)现在也用于域(并且只有三个用于命令)。
这允许有 28 个域,因为四个通用命令(如 SIMSTEP)阻塞了一些可用的组合。
目前只剩下四个可能的域。
此外,在发明了 libsumo 之后,TraCI 接口的某些部分是如此通用,以至于发明一个带有 Apache Kafka 或 Google protocol buffers 的包装器可能并不困难,从长远来看,这可以取代所有字节操作和不同手工制作的客户端的需求。
## 故障排除
### 输出文件未关闭。
如果客户端尝试在仿真仍在关闭时访问输出,则会发生此问题。可以通过让客户端等待仿真关闭来解决此错误。错误报告为 #524。
### 已过时的 API
曾经有两代 [TraCI](TraCI.md) 命令。第一代主要使用 [sumo](sumo.md) 中使用的字符串类型 ID 与这些 ID 的外部表示(基于整数)之间的内部映射。映射是在 [TraCI](TraCI.md) 内部完成的。
第二代,即当前一代,使用与 [sumo](sumo.md) 读取的相同的字符串 ID。如果您必须使用第一代 API(例如,如果您想使用 TraNS),您只能使用 [sumo](sumo.md) 的 0.12.3 及以下版本。有关获取旧版本的信息,请参阅 [FAQ](FAQ.md)。
