Vissim11二次开发之C#---实现仿真时间内实施不同信号控制方案

Vissim11二次开发之C#—实现仿真时间内实施不同信号控制方案

本文起源:近些日子,由于论文仿真需求,重重重操Vissim旧业。

先说下需求情况吧:路网区域优化前后两种信号控制方案,由于论文场景要求,新的控制方案要在特定时间实施,故在vissim进行仿真时间内需要改变其信号控制方案。作为交通专业研究生,研究生期间无论是项目亦或是研究跟着给本科生讲述过一个多小时怎样使用Vissim。Vissim仿真及二次开发分为以下几个阶段。
(1)研一:Vissim软件初识。研一时候尽管本科阶段接触过Vissim软件,无奈本科土木道桥交通方向没有意识到自己认真学习Vissim,此时初期可谓透明小白,研究生一入学,刚好遇上的第一个项目就是关于Vissim建模以及二次开发的,此时主要工作:vissim仿真建模、vissim二次开发(使用语言为Vb.nebt)。当时由于要上课加上编程基础为零,vissim建模交给了本科生,本人则零敲碎打进行vissim二次开发相关工作。最后结果是:vissim仿真建模基本入门(简单的画路网),二次开发更是不甚理解(VB.net窗体调出Vissim并运行)。
(2)研二:此时由于老师安排教会本科生Vissim使用,故自己重新一步步又学了一遍Vissim,不要问为什么重新学,问就是时间太久&长时间不用。此时结果是:vissim路网建模步骤清晰化,但问题在于:本人长时间在Visssim 11、Vissim5.2、Vissim4.3不同版本之间反复横跳,亦可以说是三个版本绕着我做三体运动。由于当时经常使用编程语言为C#,而Vissim二次开发相关博文多为matlab或是python,加上本身COM文档为Vb,最后二次开发无实质进展。
(3)研三:现如今一是论文需要加上前段时间老师布置两个仿真场景的数据分析,Vissim仿真现在应该算的上熟悉了吧。而最近就是系统学习了二次开发。

  • 解决问题过程:
    好了,上面介绍了我的Vissim之路,下面介绍一下我解决这个问题的过程:
    1百度阶段
    首先,我觉得网上一定有人遇到过这个问题,一搜果然:地址为https://www.zhihu.com/question/310565097/answer/584761987
    答:Vissim仿真软件可以分不同时段采用不同信号控制方案吗?
    找到了,直接拿来用就行了,问题来了:
  • 这位博士大神的Vissim版本是4.3,我的是11,造成语法改变,参数好像也变了;
  • 其用的为python编写,我Python用的不多,笔记本没有pycharm,不能调试。
    解决思路:改参数>>改语言(matlab)>改语言(C#),最终还是没有解决。
    2发现Vissim Basic Comand文件阶段
    发现了Vissim各种语言二次开发基本之灵,选择C#照抄改成中文,绝对有点感觉了步入下一阶段
    3实践:解决本文问题。
  • 路网及信号配时如下图:

vissim路网及交通量设置
信号机控制配时
将上文知乎博士大神的Python代码改成C#版本的就行了
开始:

作者:Song
链接:https://www.zhihu.com/question/310565097/answer/584761987
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

import win32com.client as com
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
#加载接口及文件
vissim_com = com.Dispatch("Vissim.Vissim")
vissim_com.LoadNet(r'C:\Users\1.inp')
vnet = vissim_com.net
SgCtrls = vnet.SignalControllers
SgGrps1 = SgCtrls.GetSignalControllerByNumber(1).SignalGroups.GetSignalGroupByNumber(1)

# 设置仿真参数
Sim = vissim_com.simulation
Sim.RandomSeed = 60
Sim.Resolution = 10
Sim.Period = 1200
# 打开评价
eval = vissim_com.Evaluation
eval.SetAttValue('DATACOLLECTION', True)
dceval = eval.DataCollectionEvaluation
dceval.SetAttValue('FILE', True)
dceval.SetAttValue('COMPILED', True)

# 开始仿真
for SimStep in range(1, int(Sim.Period * Sim.Resolution)):
    Sim.RunSingleStep()
#设置两个信号方案
    if SimStep / Sim.Resolution < 600:#注意除以Sim.Resolution,才对应当前仿真秒
        SgGrps1.SetAttValue("REDEND", 1)
        SgGrps1.SetAttValue("GREENEND", 55)
    else:
        SgGrps1.SetAttValue("REDEND", 1)
        SgGrps1.SetAttValue("GREENEND", 5)
Sim.stop()

而我写的C#

 Vissim Vissim = new Vissim(); //如果安装多个版本的vissim,你必须设置你想要打开的vissim版本号
            string Path_of_COM_Basic_Commands_network = Directory.GetCurrentDirectory();//定义文件目录为当前文件目录
            Path_of_COM_Basic_Commands_network = "Addre\\";//最后经常使用
            string Filename = Path_of_COM_Basic_Commands_network + "vissimCOM改变控制方案.inpx"; //定义要打开的Vissim文件名称
            Vissim.LoadNet(Filename, false);//加载路网文件

            //加载设置(Layout文件)
            Filename = Path_of_COM_Basic_Commands_network + "vissimCOM改变控制方案.layx";//
            Vissim.LoadLayout(Filename);

            INet Net = Vissim.Net;//初始化net
            ISignalController SignalController = Net.SignalControllers.get_ItemByKey(1);
            ISignalGroup SgGrps1 = SignalController.SGs.get_ItemByKey(1);



            //设置仿真参数
            ISimulation Sim = Vissim.Simulation;
            //随机种子60
            int RandSeed = 60;
            Sim.set_AttValue("RandSeed",RandSeed);
            //仿真精度10
            int SimRes = 10;
            Sim.set_AttValue("SimRes", SimRes);
            //仿真时长1200s
            int SimPeriod = 1200;
            Sim.set_AttValue("SimPeriod", SimPeriod);
			int SimStep;
			for(SimStep=1;SimStep <SimRes * SimPeriod; SimStep++{
 					if (SimStep/SimRes < 600)
                    {
                    	//报错位置
                        SgGrps1.set_AttValue("ENDRED", "1");
                        SgGrps1.set_AttValue("GREENRED", "55");
                    }
                    else
                    {
                       SgGrps1.set_AttValue("ENDRED", "1");
                        SgGrps1.set_AttValue("GREENRED", "55");
                    }
			}
            

可是我运行完后报错:
运行报错
可见我属性值写的有问题,Vissim11属性值中存在或是我没有找到正确使用方法(若找到后面更新)。
查阅C#二次开发文档发现其设置新的状态代码为:

SgGrps1.set_AttValue("SigState", "GREEN");

相当于给灯组新的状态。
于是我转换思路,自己在不同时间定义灯组状态状态不就可以形成不同配时了。
前600秒内:前20s绿灯后40秒红灯

//前600秒
 if (SimTime < 60)
                    {
                        if (SimTime < 20)
                        {
                            SgGrps1.set_AttValue("SigState", "GREEN");//前20s绿灯
                        }
                        else
                        {
                            SgGrps1.set_AttValue("SigState", "RED");//后40秒红灯
                        }

                    }
//后600s
 if (SimTime < 20)
                        {
                            SgGrps1.set_AttValue("SigState", "GREEN");
                        }
                        else
                        {
                            SgGrps1.set_AttValue("SigState", "RED");
                        }

并周期性循环周期为60s
结果输出600秒前后排队长度对比结果查看代码是否正常运行:
排队长度时变图
由图可见600s后由于绿灯时间长在周期60s内为50s,红灯10s;排队长度基本为0。证明控制方案正常运行。
修改600s后灯组状态为红色结果为:
在这里插入图片描述
方案成功。

最后:对比与上面大神的方法主要存在以下不同:
(1)语言不同:python Vs C# 使用C#的可以借鉴本文
(2)版本不同:Vissim4.3 Vs Vissim 11 Vissim 6以后语句产生改变见下图
对比

后续安排:整理完成Vissim Basic Command C#语句。使用读入不同Sig文件完成本文需求 ,本文仅仅简单模拟:一方面较为代码书写在路网信号涉及较多时变得复杂,此外需要重复编写信号控制方案代码。

后附资料地址,内含路网和二次开发程序。需要自取:资源地址

评论 44
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

weixin_43604680

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

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

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

打赏作者

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

抵扣说明:

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

余额充值