构建一个栅格信号城市,然后采集该栅格城市各个车道的每5min的流量、速度、密度三个指标。
使用开源的交通仿真软件sumo实现,我的电脑是windows10,然后官网下载了最新版的Eclipse SUMO sumo Version 1.12.0。
sumo仿真共需要3个文件:1.供给,也就是路网文件,信号灯也包括在该文件中;2.需求,也就是个体出行routes,由于是微观仿真,所以是精细到每一辆车的路径的;3.sumo仿真配置文件,用来设置仿真的输入和输出。接下来详细介绍如何从0构建这三种文件。
构建路网的方法有很多种,比如导入shapefile文件,从osm爬取,sumo给出了很多的脚本来帮助使用者构建路网,但是由于我的需求是构建一个栅格城市,因此可以直接使用sumo给出的命令netgenerate,该命令可以一键生成需要的网络,比如栅格、spyder、随机网络,并且在生成过程中可以指定车道数,和信号灯,但是似乎信号灯设置只能进行简单的设置,不能是高度自定义的。我简单使用下述命令生成栅格网络。这里我只想要单车道,所以车道数就是默认,当然可以生成双车道的,加上车道参数即可,然后可以指定左转车道的数量,比如生成双车道,左转数量是1,就加上参数–turn-lanes=1和-L=2就行了,在路口会自动渠化成三车道,一个左转专用道,一个直行车道,一个直右车道。
netgenerate --grid --grid.x-number=8 --grid.length=200 -j=traffic_light --tls.cycle.time=60 --output-file=grid_network.net.xml
上述代码将每个路口都设置成了信号交叉口,周期都是60s,但是可能不一定是我需要的信号方案,因此还需要进行下列设置。
首先打开sumo的netedit,对某一个信号进行手动配置,配置好了之后保存到本地的xml文件,打开xml文件,将与该信号交叉口一样的交叉口进行拷贝,比如我把B0-G0交叉口都设置成相同的方案,修改好xml文件后,执行下述命令,将.net.xml中的B0-G0交叉口的信号都配置成指定的信号方案。
然后重复该操作将所有信号都设置好,当然也可以一次性配置好信号方案的xml文件,执行一下命令就可以,也可以分开配置,分多次执行命令生成需要的路网文件。
<additional xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://sumo.dlr.de/xsd/additional_file.xsd">
<tlLogic id="B0" type="static" programID="0" offset="0">
<phase duration="27" state="GGGGrrrrr"/>
<phase duration="3" state="GyyGrrrrr"/>
<phase duration="27" state="GrrGGGGGG"/>
<phase duration="3" state="GrrGyyyyy"/>
</tlLogic>
<tlLogic id="C0" type="static" programID="0" offset="0">
<phase duration="27" state="GGGGrrrrr"/>
<phase duration="3" state="GyyGrrrrr"/>
<phase duration="27" state="GrrGGGGGG"/>
<phase duration="3" state="GrrGyyyyy"/>
</tlLogic>
<tlLogic id="D0" type="static" programID="0" offset="0">
<phase duration="27" state="GGGGrrrrr"/>
<phase duration="3" state="GyyGrrrrr"/>
<phase duration="27" state="GrrGGGGGG"/>
<phase duration="3" state="GrrGyyyyy"/>
</tlLogic>
<tlLogic id="E0" type="static" programID="0" offset="0">
<phase duration="27" state="GGGGrrrrr"/>
<phase duration="3" state="GyyGrrrrr"/>
<phase duration="27" state="GrrGGGGGG"/>
<phase duration="3" state="GrrGyyyyy"/>
</tlLogic>
<tlLogic id="F0" type="static" programID="0" offset="0">
<phase duration="27" state="GGGGrrrrr"/>
<phase duration="3" state="GyyGrrrrr"/>
<phase duration="27" state="GrrGGGGGG"/>
<phase duration="3" state="GrrGyyyyy"/>
</tlLogic>
<tlLogic id="G0" type="static" programID="0" offset="0">
<phase duration="27" state="GGGGrrrrr"/>
<phase duration="3" state="GyyGrrrrr"/>
<phase duration="27" state="GrrGGGGGG"/>
<phase duration="3" state="GrrGyyyyy"/>
</tlLogic>
</additional>
根据信号灯方案配置文件为指定的交叉口配置信号方案,-s为输入的路网文件,-i为输入的信号方案文件,-o是输出的配置好指定交叉口信号方案的路网文件
netconvert -s "./network/grid_network.net.xml" -i "./network/tl_pro_down.xml" -o "./network/grid_network_d.net.xml"
需求的设置相对简单,sumo中关于需求有多种设置方法,最基础的是trip和routes,sumo最终需要的需求文件是.rou.xml文件,该文件中是每辆车的路径和出发时间,在我的需求中我可以是随机的,因此我直接使用randomTrips.py命令生成需求,首先第一步生成trip,trip文件可以认为是每个车的OD,下面代码是每s路网上随机生成5辆车的OD。
为1800s整个路网生成随机的trip,-n为路网文件,-e是结束时间,-p是每秒生成的车辆数,--binomial为每秒结束出行的车辆数的分布的最大值,-o是生成的trips.xml的保存文件名
python "E:\Program Files\sumo\tools\randomTrips.py" -n "./network/grid_network_dlurm.net.xml" -e 1800 -p 0.2 -o "./random_demand/random_trip.trips.xml"
生成OD之后,进一步按照最短路生成routes,如下命令:
将生成的trips.xml文件填补为rou.xml文件,-n是路网文件,--route-files为trips.xml文件,-o为输出的rou.xml文件
duarouter -n "./network/grid_network_dlurm.net.xml" --route-files "./random_demand/random_trip.trips.xml" -o "./random_demand/random_routes.rou.xml"
这样一来就完成了需求文件的生成。
直接写好输入输出文件就行,直接看下面代码就可以理解,不多说了。唯一需要解释的就是输出文件的设置,在下面的代码里只有输入没有输出文件的配置,这是因为输出文件设置是写在 < a d d i t i o n a l − f i l e s v a l u e = " a d d i t i o n . a d d . x m l " / >
<?xml version="1.0" encoding="iso-8859-1"?>
<configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://sumo.sf.net/xsd/sumoConfiguration.xsd">
<input>
<net-file value="E:\study_e\mfd_optimization\simulation_result\mfd_data_basedon_sumo\network\grid_network_dlurm.net.xml"/>
<additional-files value="addition.add.xml"/>
<route-files value="E:\study_e\mfd_optimization\simulation_result\mfd_data_basedon_sumo\random_demand\random_routes.rou.xml"/>
</input>
<time>
<begin value="0"/>
<end value="86400"/>
</time>
</configuration>
<additional>
<edgeData id="EDGE_MEASUREMENT" file="edge_data_output.xml" freq="300" excludeEmpty="true" />
</additional>
仿真就容易了用sumo-gui打开配置文件,点击运行就行了。那个delay是控制仿真运行速度的,0就是最快,越大就运行越慢,standard那边可以选择real world,好看一些。
仿真生成的输出文件也是xml的,可以直接处理或者用sumo命令转化为csv文件,然后csv就可以被各种软件处理了,很方便。
将最终结果的xml文件转化为csv文件
python "E:\Program Files\sumo\tools\xml\xml2csv.py" --separator="," "./sumo_simu/edge_data_output.xml"
https://tech.chaotictoejam.com/index.php/2020/07/09/how-to-create-a-network-in-sumo/