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 += linewith 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.simulationvissim_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~
總結
以上是生活随笔為你收集整理的VISSIM二次开发(Python)大作业总结1的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python3.8文档_python 3
- 下一篇: 第三篇.python编辑器和集成环境01