本文通过一个简单示例展示如何使用交通控制接口(简称 TraCI)。TraCI 可以在道路交通仿真运行时对其进行控制。TraCI 采用基于 TCP 的客户端/服务器架构,其中 SUMO 作为服务器,外部脚本(即“控制器”)作为客户端。在本教程中,“控制器”是一个 Python 脚本,它从服务器接收仿真状态信息,然后发送指令回去。
假设读者已通过其他教程了解了道路网络构建和路线定义,例如 Tutorials/Hello SUMO、Tutorials/quick start 或 Tutorials/Quick Start old style。
本文提到的所有文件也可以在您的安装目录 ***<SUMO_HOME>***/docs/tutorial/traci_tls 中找到。最新版本可以在代码库的 <SUMO_HOME>/tests/complex/tutorial/traci_tls/ 中找到。
示例描述#
我们的示例在一个简单的四路信号交叉口上进行。我们只在水平轴上设置交通流,而在垂直轴(从北向南)上设置重要车辆(如电车、火车、消防车等)。在北进口道上设有一个感应线圈,用于检测驶入的车辆。只要没有车辆从北边驶入,我们就一直保持水平轴绿灯;但当有车辆进入感应线圈时,我们会立即切换信号,以便该车辆可以不停顿地通过交叉口。

运行示例#
要运行此示例,您需要使用 python 执行脚本 runner.py
python runner.py
Caution
您需要在仿真 GUI 中点击“开始”才能运行此教程。
数据准备#
网络定义文件可以在 cross.nod.xml、cross.edg.xml、cross.con.xml 和 cross.det.xml 中找到。路线数据由脚本随机生成。车辆根据泊松过程离开源头,这里通过二项分布来近似。因此,脚本中的参数 p=1./30 表示平均每 30 秒生成一辆车。
代码#
控制逻辑位于 Python 脚本 runner.py 中。它生成路线,与服务器交互,并控制交通信号灯。它利用了 SUMO 捆绑的 TraCI Python API。有关 API 的描述可以在 TraCI/Interfacing_TraCI_from_Python 中找到。有关可用函数的详细列表,请参阅 pydoc 生成的文档。
仿真#
主程序在脚本 runner.py 中实现。首先,我们按上述方法生成路线。然后使用 traci.start 启动 sumo-gui 并加载配置文件 cross.sumocfg。该 start 调用还会将我们的脚本与作为服务器运行的 sumo-gui 连接起来。
然后我们开始控制仿真。我们让服务器模拟一个仿真步长,读取感应线圈数据并切换交通信号灯的相位,直到仿真结束(即道路上不再有车辆)。如果我们发现感应线圈上有车辆,则切换相位,使南北方向获得绿灯。如果检测器上没有车辆,并且我们尚未处于切换过程中(即东西方向仍为绿灯),我们尝试通过简单地再次设置该相位来保持它。最后,我们关闭连接。
TraCI#
我们希望在 SUMO 中运行此仿真(作为服务器),并根据实际仿真状态控制信号。为此,TraCI 提供了相关命令,详细描述见对应文章 TraCI。在本示例中,我们将仅使用四个命令:Simulation Step、Get Induction Loop Variable、Change Traffic Lights State 和 Close。
这些命令嵌入在 TCP 消息中,但直接的客户端-服务器通信对用户是不透明的。本教程中需要的四个命令在方法 traci.simulationStep(step)、traci.inductionloop.getLastStepVehicleNumber(IndLoopID)、traci.trafficlight.setPhase(TLID, phase) 和 traci.close() 中实现。
附录#
发送和接收消息的方法 _recvExact() 和 _sendExact() 分别隐藏在脚本 traci/__init__.py 中,无需直接调用它们。在本节中,我们将以 traci.trafficlight.setRedYellowGreenState 为例展示命令的组成。
setPhase#
此方法设置交通信号灯的相位,因此它将交通信号灯的 ID 和新相位作为参数。相位定义可以从 sumo 网络中读取,并在 Simulation/Traffic Lights#Loading a new Program 中描述。如果相位已经是当前相位,则它会从头开始重新启动。该命令在 TraCI/Change Traffic Lights State 中描述。
