VISSIM二次开发(Python)&大作业总结1

VISSIM二次开发(Python)&大作业总结1

写在前面

本次作业也是我研一的时候看到师兄们以前选过这个课,就跟风也来选了,这节课的最后要交一个大作业,需要用到交通仿真软件,而且仿真需求很大。手动输入的话,相信看到这里的朋友都和我一样觉得很难受。所以肯定会有更方便的办法~那就是二次开发。

由于本人此前没有接触过VISSIM,所以也是花了很多的心思和力气在学习VISSIM的使用以及二次开发的一些方法。本文中也记录一下在这次二次开发中遇到的一些坑和一些技巧,和大家一起共同学习~

后面还会有一个和大作业有关的总结,因为内容和这个差异比较大就分开了。

参考

由于我本人不是做交通方向的,所以事先也阅读了很多网上写的很好的例子

VISSIM&COM——Python开发教程 - 知乎 (zhihu.com)

上文似乎也是和我同一节课的师兄,他展示的代码和过程和我之后的基本一样,不过我由于暑假基本在学校能用VISSIM7.0,当然我自己也尝试了VISSIM4.3,这两者的坑都有不少,但是由于版本不同,他们对于二次开发的接口的方式都不尽相同。不过,方法都是有共通性的~

所以上文给我了非常多的借鉴意义,这里也推荐大家去看这位大神的教程,下面是他的一个简单且完整的接入案例,我将围绕这这个案例展开我们的介绍,本文会涉及一点点VISSIM界面的东西,但不会太多。

import win32com.client as com
vissim_com = com.Dispatch("Vissim.Vissim")
Sim = vissim_com.Simulation
vissim_com.LoadNet('C:\\Users\\lenovo\\Desktop\\[HW]Traffic Flow\\VISSIM SIHUO - 1\\homework.inp')
vissim_com.LoadLayout('C:\\Users\\lenovo\\Desktop\\[HW]Traffic Flow\\VISSIM SIHUO - 1\\homework.ini')
vnet = vissim_com.net
Sim = vissim_com.simulation
eval = vissim_com.Evaluation
eval.SetAttValue('DATACOLLECTION', True)  # 打开离线评价按钮
dceval = eval.DataCollectionEvaluation
dceval.SetAttValue('FILE', True)
dceval.SetAttValue('COMPILED', True)
# Sim.SetAttValue('PERIOD',100)
Sim.RandomSeed = 40
Sim.RunIndex = 0
Sim.RunContinuous()
Sim.stop()

可能很多人已经有体会了,VISSIM二次开发的代码主体就是设置一下仿真软件的一些基本参数,比如文件读写,选择仿真运行的时间种子,控制仿真的起止等等。由于软件的问题,在仿真中如果需要更改一些更加细节的设置,比如更改流量,驾驶行为参数等等,往往没那么快捷方便,下面就介绍本文的方法~

二次开发技巧

我其实更愿意说是粗暴的二次开发,vissim的文件一般都是以.inpx文件的形式存储,不同版本可能不太一致(比如4.3文件就是.inp),但都能找到类似的。

当我们用记事本打开会发现这样的形式

在这里插入图片描述

也即,我们在VISSIM构建的路网和交通相关的参数,全部存储在这个文件当中,那么是不是更改这个文件,会直接的引起文件的更改呢~ 答案是会,并且这个更改的速度很快~

先来点小菜,更改相对固定参数

如更改流量,时间段和分流比例这种量比较大,但是在一个仿真中相对比较固定的参数。找到inpx文件中以下有关的定义。

定义字节
时间段定义<timeInterval start="0.000000"/>
输入流量定义<timeIntervalVehVolume cont=“false” timeInt=“1 0” vehComp=“2” volType=“EXACT” volume=“684.000000”/>
分流区比例分配定义<timeIntervalVehVolume cont=“false” timeInt=“1 0” vehComp=“2” volType=“EXACT” volume=“684.000000”/>

接下来按照他们原本的样式填充回去即可,这里建议注意备份好文件,以免自己的误操作,导致文件损坏而无法检查的尴尬局面

#开发环境
matplotlib                         3.3.4
numpy                              1.19.5
pandas                             1.2.4

备注:部分代码前面的缩进不好把握,1,复制出来的时候直接带好格式,这样输入回去的时候格式基本不会错 2,无视,直接不缩进,VISSIM可以无视这个问题

#df的读取操作——需要先读取自己需要输入的数据

#%%分流匝道1分流比例参数更改
ratio=[]
for i in range(T):
    ratio.append(int(df1.iloc[start+i,2]/df2.iloc[start+i,2]))#这里的int很重要,决定后面的小数点舒服报错
    print('2 '+str(i*300000)+':'+str(ratio[i])+'.000000,',end='')#这里控制输出的时候在同一行,后续的都是分行输出
#%%时间段输入
for i in range(T):   
    print('    <timeInterval start="'+str(i*300)+'.000000"/>')
#%%主线流量输入
for i in range(T):
    print('				<timeIntervalVehVolume cont="false" timeInt="1 '+str(str(i*300000))+'" vehComp="1" volType="EXACT" volume="'+str(12*df6.iloc[start+i-1,2])+'"/>')
#%%匝道流量输入
for i in range(T):
    print('				<timeIntervalVehVolume cont="false" timeInt="1 '+str(str(i*300000))+'" vehComp="1" volType="EXACT" volume="'+str(12*df5.iloc[start+i-1,2])+'"/>')

我们的原则就是尽量简化调用的接口,提高速度

调用接口需要如何更改参数

这部分在前面的参考链接中也有更细致的介绍,这里简单贴一下方法,显然没有那么方便,但是对于需要动态调整的可能的确会方便一点,由于本次大作业不涉及,所以这里也不过多的涉及。

import win32com.client as com
vissim_com = com.Dispatch("Vissim.Vissim.700")#必要的引入
#%%
vissim_com.LoadNet('C:\\Users\\Administrator\\Desktop\\test\\test.inpx')#读取这两个文件
vissim_com.LoadLayout('C:\\Users\\Administrator\\Desktop\\test\\test.layx')

VI_number   = 1  #车辆输入点
flowIN=[400,3000]#这里变成需要输入的流量,第一个时刻是400,第二个是3000。
for i in range(len(flowIN)):
    
    vissim_com.Net.VehicleInputs.ItemByKey(1).SetAttValue('Volume('+str(i+1)+')', flowIN[i])
    vissim_com.Net.VehicleInputs.ItemByKey(VI_number).SetAttValue('Cont('+str(i+2)+')', False)
    
Sim = vissim_com.simulation
Sim.RunContinuous()#启动仿真
Sim.stop()

更改.inpx快捷二次开发(完整代码)

需要更改.inpx就涉及到文件的查读写了,这里不是我们的重点,这里放一个比较成熟的修改文件内容方法大家可以参考。我们选用第一种方法。

python 修改文件内容3种方法 - wc_chan - 博客园 (cnblogs.com)

import win32com.client as com
vissim_com = com.Dispatch("Vissim.Vissim.700")#必要的引入

def alter(file,old_str,new_str):
    file_data = ""
    with open(file, "r", encoding="utf-8") as f:
        for line in f:
            if old_str in line:
                line = line.replace(old_str,new_str)
                
            file_data += line
    with open(file,"w",encoding="utf-8") as f:
        f.write(file_data)
        
def SIMRUN():
    vissim_com.LoadNet('C:\\Users\\Administrator\\Desktop\\代码测试\\调试.inpx')#读取这两个文件
    vissim_com.LoadLayout('C:\\Users\\Administrator\\Desktop\\代码测试\\调试.layx')
   
    Sim = vissim_com.simulation
    vissim_com.Graphics.SetAttValue('Quickmode',True)
    Sim.SetAttValue('RandSeed',5)
    Sim.SetAttValue('UseMaxSimSpeed',True)
    Sim.RunContinuous()#启动仿真
    Sim.stop()
    print('第'+str(i+1)+'次仿真彻底结束')
    
#%%建议这里隔开,因为前面的调用VISSIM需要打开软件,效率不高
import pandas as pd
df=pd.read_csv('C:/Users/Administrator/Desktop/代码测试/8因子6水平处理后数据.csv',engine='python',sep=';',header=None)  
a=df.shape[0]
b=df.shape[1]

Line0=['w99cc0="1.500000"','w99cc1="0.900000"','w99cc2="4.000000"','w99cc4="-0.350000"','w99cc5="0.350000"','accDecelTrail="-2.000000"','safDistFactLnChg="0.600000"','coopDecel="-6.000000"','coopLnChgSpeedDiff="10.800000"']
Line1=['w99cc0="','w99cc1="','w99cc2="','w99cc4="','w99cc5="','accDecelTrail="','safDistFactLnChg="','coopDecel="','coopLnChgSpeedDiff="']

for i in range(a):
    if (i==0):
        for j in range(b):
            alter("C:\\Users\\Administrator\\Desktop\\代码测试\\调试.inpx", Line0[j], Line1[j]+'%.6f'%df.iloc[0,j]+'"')
		SIMRUN()   
    if(i>0):  
        for j in range(b):
            alter("C:\\Users\\Administrator\\Desktop\\代码测试\\调试.inpx", Line1[j]+'%.6f'%df.iloc[i-1,j]+'"', Line1[j]+'%.6f'%df.iloc[i,j]+'"')
        SIMRUN()

可以注意到需要如果更改的参数如下,那么就找到原始的文件中的这些参数(完整字节),然后将需要更改的参数以文件读写的方式直接写入.inpx。至于这个更改成什么参数,大家可以去看看正交实验的东西或者其他的启发式算法之类的东西,具体这里不展开。

Line0=['w99cc0="1.500000"','w99cc1="0.900000"','w99cc2="4.000000"','w99cc4="-0.350000"','w99cc5="0.350000"','accDecelTrail="-2.000000"','safDistFactLnChg="0.600000"','coopDecel="-6.000000"','coopLnChgSpeedDiff="10.800000"']

结果输出

由于我们设置的采集器,最关注的是速度和流量所以只设置了比较常规的线圈检测器,在线圈数据显示界面勾选按钮可以使用.att格式的文件可以自动进行存储输出,本次大作业也涉及了很多相关的数据分析以及绘图的代码,将在第二部分进行介绍。

授人以渔部分

在二次开发过程中,遇到了不知道怎么样调用某一属性的方式,有这些方法可以解决,看个人喜好,没有先后关系。当然按照本文的去找到inpx文件中的对应字节然后直接更改文件也十分方便,但是一定要做好文件的备份,并且改动完之后及时运行inpx文件查看是否更改成功~

网上查看是否有可以参考的二次开发的技术文档

多数时候我们都希望能找到和我们需求相一致的代码参考,比如我本人。

    vissim_com.Graphics.SetAttValue('Quickmode',True)
    Sim.SetAttValue('RandSeed',5)
    Sim.SetAttValue('UseMaxSimSpeed',True)
    Sim.RunContinuous()#启动仿真
    Sim.stop()
com自身提供的参考文档和参考代码

在安装了VISSIM软件的电脑上,在他的文件夹中都会有COM_example.py这类型的文件,里面会有很多可以直接使用以及直观的代码。

在软件界面上的帮助下,可以找到这样的一个文件:

帮助文档

比如我们想设置Quickmode这个参数,发现他是在Graphics这个对象里面的,所以vissim_com.Graphics.SetAttValue('Quickmode',True)我们用这种方法对其进行调用并设置为快速模式,这样软件界面的车辆运行就不会显示出来,从而就能更加快捷的运行了~

同样其它的属性需要修改的也可以按照这样的方法进行索引更改,例如前面例子中的'RandSeed'就都在simulation对象中。

本系列第二篇:VISSIM二次开发(Python)&大作业总结2~

  • 18
    点赞
  • 82
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tu_qing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值