文章目录
前言
1. COM接口功能与定位
2. COM框架搭建
2.1 导入COM模块
2.2 程序头部格式
2.3 实现功能
总结
VISSIM软件是一种微观的、基于时间间隔和驾驶行为的仿真建模工具,用以城市交通和公共交通运行的交通建模,比如复现道路微观交通组织运行状态、控制交通系统信号灯、管理停车、管理与运营公共交通等功能。
COM接口是VISSIM的附加功能,可以获取VISSIM的对象、方法和特征属性,并支持VB、Java、C#、C++、Python等软件进行二次开发、实现自定义场景下的自定义功能。本文旨在介绍采用Python对VISSIM软件进行二次开发时的一些基本教程。
VISSIM软件虽然复现了某些场景下的交通运行状态,但是难以直接调用自定义的控制模型。比如以下几种功能,难以直接在VISSIM软件中实现,而采用COM接口对VISSIM文件进行二次开发可以实现此类自定义的控制功能。
以基于单点定时控制路口场景的多时段信号控制功能为例,在不同时间区间执行不同的配时方案。本文采取早上06:00-10:00这一区间,在VISSIM路网的信号控制机中预设三种信号配时方案:在06:00-07:00执行平峰方案1、在07:00-09:00执行高峰方案1、在09:00-10:00执行平峰方案2,具体方案如下表,其中黄灯、全红分别是3s、2s,在VISSIM路网文件中分别按照时间顺序将平峰方案1 、高峰方案1 和平峰方案2分别记录为1、2和3。
方案 | 相位1(主路直行) |
相位2(主路左转) |
相位3(次路放行) |
周期 |
平峰方案1 |
20 |
15 |
15 |
65 |
高峰方案1 |
35 |
30 |
30 |
110 |
平峰方案2 |
25 |
20 |
20 |
80 |
在python环境下安装COM接口相关的安装包,本文以集成开发环境Pycharm为例。首先在当前项目场景中安装pywin32包并导入。
import win32com.client as com
基于VISSIM和Python二次开发的信号控制程序,其头部格式主要包含四个部分:路网、信号控制机、仿真相关参数、评价相关参数。下面依次进行介绍。
1)读取路网接口
首先,通过COM接口引入VISSIM软件;其次,分别加载inpx和layx两个路网文件,然后记录路网接口。
Vissim_com = com.Dispatch('Vissim.Vissim-32.700')
Vissim_road_path = '仿真文件'
Vissim_com.LoadNet(vissim_road_path + '\\主支.inpx')
Vissim_com.LoadNet(vissim_road_path + '\\主支.layx')
S_net = Vissim_com.net
2)读取信号控制机接口
根据inpx文件中控制路口处的信号控制机编号,读取并记录该路口信号控制机接口。当存在多个路口时,建议使用列表等数据形式记录。
SC_number = 1 # 单个路口
SC = S_net.SignalControllers.ItemByKey(SC_number)
# SC_number = {'路口1': 1, '路口2': 2} # 多个路口
# SC = [S_net.SignalControllers.ItemByKey(SC_number[sc_i]) for sc_i in SC_number.keys()]
3)标定仿真相关参数
设置仿真开始与结束时间、随机种子、仿真精度、仿真速度、快速仿真模式等参数。
Sim = Vissim_com.Simulation
Sim.SetAttValue('SimPeriod', 1000) # 仿真时长
Sim.SetAttValue("RandSeed", 42) # 随机种子
Sim.SetAttValue("SimRes", 1) # 设置仿真精度
Sim.SetAttValue("SimSpeed", 5) # 设置仿真速度
Vissim_com.Graphics.CurrentNetworkWindow.SetAttValue('QuickMode', True) # 开启快速模式
4)开启评价按钮接口
在程序控制过程中如果需要使用实时交通评价数据,则需要开启评价接口;如果只采用事后评价衡量控制效果,则可以忽略此接口,直接在仿真运行结束后输出数据评价结果即可。
Eval = vissim_com.Evaluation
Eval.SetAttValue('DATACOLLECTION', True) # 打开离线评价按钮
DC_eval = Eval.DataCollectionEvaluation # 打开具体的数据采集接口
仿真路网的运行可分为连续仿真和单步仿真两种,可使用单步仿真控制方式在不同时段实施调用不同的信号控制方案,并在到达仿真时长时停止仿真。
SC.SetAttValue("ProgNo", 1) # 选取编号为1的信号方案
for i_step in range(Sim_sta, Sim_end):
Sim.RunSingleStep()
Sim.Stop()
最终,完整的控制程序如下:
import win32com.client as com
def Simulator(path, sc_number, sim_end, sim_res):
# 加载本地的vissim,请注意版本
Vissim_com = com.Dispatch('Vissim.Vissim-32.700')
# 读取路网接口
Vissim_com.LoadNet(path[0])
Vissim_com.LoadNet(path[1])
S_net = Vissim_com.net
# 读取信号控制机接口
SC = S_net.SignalControllers.ItemByKey(sc_number)
# 标定仿真相关参数
Sim = Vissim_com.Simulation
Sim.SetAttValue('SimPeriod', sim_end)
Sim.SetAttValue('RandSeed', 42)
Sim.SetAttValue('SimRes', sim_res)
Sim.SetAttValue('SimSpeed', 5)
Vissim_com.Graphics.CurrentNetworkWindow.SetAttValue('QuickMode', True)
# 开启评价按钮接口
Eval = Vissim_com.Evaluation
Eval.SetAttValue('DATACOLLECTION', True)
return Vissim_com, S_net, SC, Sim
Path = ['主支.inpx', '主支.layx']
SC_number = 1
Sim_sta, Sim_res = 1, 1
Scheme_time = [[Sim_sta, Sim_sta + 1 * 3600], # 平峰方案1的开启与关闭时间
[Sim_sta + 1 * 3600, Sim_sta + 3 * 3600], # 高峰方案1
[Sim_sta + 3 * 3600, Sim_sta + 4 * 3600]] # 平峰方案2
Sim_end = Scheme_time[-1][-1]
Vissim_com, S_net, SC, Sim = Simulator(Path, SC_number,Sim_end, Sim_res)
for i_step in range(Sim_sta * Sim_re, Sim_end * Sim_res + 1):
if i_step == Sim_end * Sim_res:
break
if i_step == Scheme_time[0][0] * Sim_res:
SC.SetAttValue("ProgNo", 1)
elif i_step == Scheme_time[1][0] * Sim_res:
SC.SetAttValue("ProgNo", 2)
elif i_step == Scheme_time[2][0] * Sim_res:
SC.SetAttValue("ProgNo", 3)
Sim.RunSingleStep()
Sim.Stop()
本文主要介绍VISSIM和Python软件的二次开发环境搭建、以及COM接口的调用,并以多时段信号控制功能为例编辑了具体的Python程序。
# 如有需要,可加qq: [email protected]