0%

Vissim COM接口教程--VISSIM数据提取(二)

前言

距离上一篇的教程已经过去了好久了,为了写毕业论文,似乎没有思路和激情来写这部分教程了。
闲话少说了,上一批的引用环境是VISSIM7.0+VS2013,由于VISSIM7.0的COM接口无法提取出检测器(DataCollection)中占有率的数据,因此我在后续的研究中重新采用VISSIM5.4+VS2013的环境,主要采用C#。
本篇的主要内容为如何从VISSIM中提取所需要的数据。

VISSIM的数据提取

任何VISSIM元素都有其ID(NAME为非必须参数),所以我们在通过程序提取VISSIM中数据时,首先要知道的就是你需要完成下列任务:

  • 确认自己的研究需要提取那些数据,如路段几何参数,车辆行驶数据,流量,速度,占有率,行程时间,延误等等等;
  • 明确这些数据可以通过VISSIM中的哪些元素获取到,如流量、速度、占有率这几个可以从DataCollection(数据采集器)中得到,行程时间和延误从行程时间检测器得到等等;
  • 在VISSIM中定义好对应的元素ID(主要是为了方便在程序中找到对应的对象);
  • 利用程序接口,找到对应ID的所需数据。

在此过程中你需要仔细的查看VISSIM手册,了解各参数的属性,是否可读,如何获取。上一篇的最后手册已经上传。
后面我将用几个例子展示如何获取各类型的数据。
本篇采用的路网如下图:
VISSIM路网
路网上存在的VISSIM元素包括;detector,datacollection,routes,traveltime,signalcontrol等,后面对这些元素的提取数据进行示例。

离线的数据返回测试

所谓离线的数据是指无需仿真运行及存在的数据,主要是路网的元素ID和NAME的返回。

1.两种检测器元素返回

VISSIM 中存在两种不同的检测器,与实际的线圈数据类似的是datacollection,而detector主要用于做感应控制。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//测试两种检测器对象
//dataconllection
string res = "Allcollections:" + vissim.Net.DataCollections.Count.ToString();
listView1.Items.Add(res);
foreach (DataCollection dc in vissim.Net.DataCollections)
{
string res1 = "DataCollection name:" + dc.Name + "," + "id:" + dc.ID;
listView1.Items .Add(res1);
}
//detector
//detector检测器主要的作用是做感应控制,会返回脉冲式的检测数据
foreach (SignalController sc in vissim.Net.SignalControllers )
{
string res2 = "SignalControllerID:"+sc.ID;
listView1.Items.Add(res2);
foreach (Detector de in sc.Detectors)
{
string res3 = "detectorid:" + de.ID;
listView1.Items.Add(res3);
}
}

测试的结果如图,datacollection返回的是设置的断面检测器
dataconllection

2.路径测试

Routesdecisions包含了所有的路径选择对象,然后每个Routesdecision下,有Route的对象来操作具体的参数。
通过这样来获取相对比例,后面的1代表第一个时间间隔

1
route.get_AttValue1("RELATIVEFLOW",1)
1
2
3
4
5
6
7
8
9
10
11
string res1 = "RoutingDecisions.Count" + vissim.Net.RoutingDecisions.Count.ToString();
listView1.Items.Add(res1);
for(int i=1;i<=9;i++)
{
listView1.Items.Add("第"+ i +"次");
foreach (Route route in vissim.Net.RoutingDecisions.GetRoutingDecisionByNumber(i).Routes)
{
string res2 = "route ID:" + route.ID + ",route flow" + route.get_AttValue1("RELATIVEFLOW:",1);
listView1.Items.Add(res2);
}
}

测试结果:
routes

在线数据返回测试

所谓在线数据,是指只有在仿真的过程当中才存在的数据,如检测器检测的参数,行程时间,延误,车辆位置信息等等。
在做研究的过程当中,在线的数据往往是我们更需要的。

1.datacollection数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//实例化一个检测器对象,将检测器ID为1112的数据取出
DataCollection dc = vissim.Net.DataCollections.GetDataCollectionByNumber(1112);
for (int i= 1;i<=30000;i++)
{
Application.DoEvents();//使仿真运行时界面可动
vissim.Simulation.RunSingleStep();
if (i>=600 && i%200==0)
{
ListViewItem temp = new ListViewItem();
temp.Text = dc.ID.ToString();
temp.SubItems.Add((i / 10).ToString() + "s");
temp.SubItems.Add(dc.GetResult("SPEED", "MEAN", 0).ToString());//获取速度
temp.SubItems.Add(dc.GetResult("NVEHICLES", "sum", 0).ToString());//获取流量
temp.SubItems.Add(dc.GetResult("OCCUPANCYRATE", "sum", 0).ToString());//获取占有率
listView1.Items.Add(temp);
}
}

需要注意的是,datacollection在采集数据的时候是有时间间隔的,这里设置了20S采集一次数据,那么在用COM接口取出数据的时候,20S内的数据都不会更新。
测试结果:
data

2.route参数修改

在VISSIM中,由于路径是在车辆生成时候就已经确定,且在仿真过程中是无法更改的,所以需要实现VMS的功能,需要通过修改路径的相对转向比来实现。
通过如下命令可修改:

1
route.get_AttValue1("RELATIVEFLOW",1)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
listView1.Columns.Add("routedecide", 80);
listView1.Columns.Add("routesid", 80);
listView1.Columns.Add("相对流量",80);
listView1.Columns.Add("是否修改", 80);
for (int i=1;i<=30000;i++)
{
Application.DoEvents();
vissim.Simulation.RunSingleStep();
if (i == 1)
{
for (int j = 1; j <= 9; j++)
{
foreach (Route route in vissim.Net.RoutingDecisions.GetRoutingDecisionByNumber(j).Routes)
{
ListViewItem temp = new ListViewItem();
temp.Text = i.ToString();
temp.SubItems.Add(route.ID.ToString());
temp.SubItems.Add(route.get_AttValue1("RELATIVEFLOW", 1).ToString());
temp.SubItems.Add("F");
listView1.Items.Add(temp);
}
}
}
if (i%1000==0)
{
for (int j = 1; j <= 9; j++)
{
foreach (Route route in vissim.Net.RoutingDecisions.GetRoutingDecisionByNumber(j).Routes)
{
route.set_AttValue1("RELATIVEFLOW", 1, j);
ListViewItem temp = new ListViewItem();
temp.Text = i.ToString();
temp.SubItems.Add(route.ID.ToString());
temp.SubItems.Add(route.get_AttValue1("RELATIVEFLOW", 1).ToString());
temp.SubItems.Add("T");
listView1.Items.Add(temp);
}
}
}
}

测试结果:
routechange

traveltime测试

traveltime与datacollection一样,都是有采集间隔的,在没有到下一个采集间隔时,数据不会更新。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
listView1.Columns.Add("TTid");
listView1.Columns.Add("TT");
listView1.Columns.Add("NV");
for(int i=1;i<=42000;i++)
{
Application.DoEvents();
vissim.Simulation.RunSingleStep();
if(i>6000 && i%600==0)
{
foreach(TravelTime TT in vissim.Net.TravelTimes)
{
//TravelTime TT = vissim.Net.TravelTimes.GetTravelTimeByNumber(1);
ListViewItem temp = new ListViewItem();
temp.Text = TT.ID.ToString();
temp.SubItems.Add(TT.GetResult((double)i / 10, "TRAVELTIME", "", 0).ToString());
temp.SubItems.Add(TT.GetResult((double)i / 10, "NVEHICLES", "", 0).ToString());
listView1.Items.Add(temp);
listView1.Items[listView1.Items.Count - 1].EnsureVisible();
}
}
}

测试结果:
traveltime

小结:
VISSIM对象中的数据读取都大同小异,首先需要对VISSIM熟悉,才能更好的使用COM接口,在需要使用特点的函数时,对应手册进行查询。