基于sumo和车牌识别数据的城市仿真

2023-05-16

前言

最近希望能仿真出一个城市的交通状态,也就是知道在不同的需求加载下城市宏观交通状态的变化情况,同时,因为我手头有车牌识别数据,因此需求将来自于车牌识别数据。
但是仿真过后发现,并不能很好的模拟真实世界,我个人认为是因为openstreetmap下载下来的路网和真实世界出入太大,导致经常出现局部交叉口堵死的情况。
接下来我就将基于sumo和车牌识别数据的城市仿真过程公开进行介绍。
如果有大佬知道如何解决基于osm数据进行sumo仿真时,和真实世界情况不符,在我的案例中是出现堵死的情况,请留言或私信我,当然对这块感兴趣的有解决想法的,我们也可以探讨一下。


根据后续研究发现osm爬取下来的路网车道数基本都偏少,因此需要增加车道数,此外需要关注time-to-teleport这个参数,这个参数是帮助解决路网死锁问题的,仿真时特别容易出现死锁情况的,因此time-to-teleport对仿真结果的影响非常大。

目标

希望用sumo对杭州市萧山区进行仿真,通过给定trips,来仿真出萧山区的交通状况。

路网

使用openstreetmap的地图作为底图,下载下来并整理成sumo需要的格式。sumo中存在一些脚本使得用户可以方便的从osm下载地图并进行格式转换。
sumo关于下载osm的介绍:https://sumo.dlr.de/ docs/Networks/Import/OpenStreetMapDownload.html
这边我选择的osm爬取方法是“Downloading a Larger Rectangular Area Using the OpenStreetMap API“,因为我希望下载有电警卡口区域的osm路网,如果对范围不要求精确的话可以使用osmWebWizard,这是一个可视化拖拽方法,可以手工拖拽指定范围。

基于osm的路网构建步骤

  1. 获得所需要区域的西南角和东北角点位的经纬度;比如我所需要区域的西南角和东北角点位经纬度分别是:(120.22565726848745,30.139564620975033),(120.28777679230367,30.248882870725584)。
  2. 构建URI,http://api.openstreetmap.org/api/0.6/map?bbox=<SW-longitude,SW-latitude,NE-longitude,NE-latitude>,因此本例中URI应该是http://api.openstreetmap.org/api/0.6/map?bbox=120.22565726848745,30.139564620975033,120.28777679230367,30.248882870725584 ;
  3. 官方说可以通过命令 wget.exe “http://api.openstreetmap.org/api/0.6/map?bbox=120.22565726848745,30.139564620975033,120.28777679230367,30.248882870725584” -O xiaoshan.osm.xml或者直接浏览器直接拷贝这个链接即可,我使用了浏览器拷贝链接的方式获取指定方形区域的路网;
  4. 下载下来的文件是xml格式,文件名自己改一下就行了,比如这边我修改成xiaoshan.osm,但是该文件也不能被sumo直接应用,需要进行格式转换;
  5. 格式转换使用的命令是netconvert,我这边都使用默认值,包括投影,默认会将wgs84坐标系转换为utm,这方便后续距离等的计算。使用该命令进行转换:netconvert --osm-files xiaoshan.osm -o xiaoshan.net.xml ;转换后的文件就可以用netedit打开了;

下下来基本没啥问题,但是奇怪的是不知道为啥有两条路这么长。我猜测可能是因为osm爬取的时候会把边界内的道路完整的下下来,有两条路特别长,所以出现该情况。
在这里插入图片描述

需求

由于我期望使用电警卡口来给予真实需求,在sumo中有多种方式可以模拟电警卡口给予需求,在此列举我考虑过的三种形式:

  1. 第一种是通过OD矩阵的形式,但是如果希望使用OD矩阵,一个前提条件必然就是需要设置好交通小区,交通小区通常有两种方式设置,一种是人为设定交通小区,一种就是栅格化,对于没有太多要求的话,栅格化往往是比较好的一种方式。
  2. 第二种方式是Using detector data (observation points),通过在观测点设置需求来模拟真实条件。
  3. 得到每辆车的trip作为需求;

可以想到第一种方式是需要对电警卡口原数据做较多处理的,第一需要划分好交通小区,第二需要基于车牌识别数据得到OD矩阵;而第二种方式相对而言需要的处理比较少;第三种方式也是处理比较少的。

Demand using detector data

首先就来探索下第二种方式,因为第二种方式相对比较简单。该种方式生成的需求要求要与检测器采集得到的交通情况相匹配,在sumo中提供了一系列的工具帮助用户完成需求生成的工作,主要是下面四种:

  1. dfrouter uses edge based counts
  2. flowrouter uses edge based counts
  3. jtcrouter uses turn-counts
  4. routeSampler uses turn-counts and edge counts (and also origin-destination counts)

每种工具都有适应的场景,具体可以参加sumo的文档:https://sumo.dlr.de/docs/Demand/Routes_from_Observation_Points.html。在我们的需求中第四种方式即routeSampler应该是最合适的,routeSampler可以设置边的流量,也可以设置好OD借助duarouter工具生成route作为输入。但是可以发现无论哪种方式,缺失肯定都是很大的,因为电警卡口数据对于某些路口只拍摄部分车道,因此流量对于edge来说肯定是偏小很多的,而对于设置OD的话也是缺失严重,因为根据之前的分析经验,绝大部分车辆只被拍摄到了一两次,根本无法生成比较可信的OD pair。

基于OD矩阵的需求

这也就是上述所说的第一种方式,在sumo中给了OD矩阵之后,必然也是需要转化为车辆的route的,因为sumo是微观仿真,是需要告诉sumo车辆轨迹的,因此如何从OD矩阵转化为车辆的轨迹就是这种方式必经的一步。
在sumo中OD也被称作为trip,route就是具体的车辆轨迹。 在我们给定trip的情况下,就需要进一步去得到route,一种最简单的得到route的方式就是使用最短路算法,也就是假设车辆都是按照最短路去走的,但是这种简单粗暴的问题会带来很多bug,因为这是静态的分配,会导致有些edge流量过大。而解决该问题的一个常见手段就是动态用户分配算法,比如Dynamic User Equilibrium,用户均衡算法不断迭代,使得每一个用户都是当前条件下的最优路线,这也就是假设每一个用户都是“自私”的,这个相对比较符合实际情况。
上述说的是OD转化为具体的route,而可以想到OD矩阵到OD中间还是需要经过一定的处理的,在sumo中该步骤是由od2trips这个命令实现的,具体逻辑sumo官方文档没有写,暂时不知道。
但是这种OD矩阵的方式同样也会造成严重的缺失,因为OD矩阵同样需要知道OD,而很多车辆只被检测一次,无法知道OD。

使用trip作为需求

根据LPR数据生成trip之后,需要进一步生成route,因为sumo是微观仿真,需要每一辆车的route才可以,通过trip生成route有很多种方式,比如最短路,用户均衡,Automatic Routing等等。
如何通过车牌识别数据得到trip是一个有意思的研究方向,而在此我将使用较为简单的方式进行,即直接用相邻被检测时间的阈值作为出行链打断标准,打断后直接得到OD,可以想到这样误差是较大的,一方面这种出行链打断方式不一定正确,第二这样得到的OD不是真正的OD,而是一次trip的首末次被检测位置。

基于车牌识别数据得到车辆trip

首先要了解下sumo中的trip文件的格式是怎么样的,我用randomTrips.py生成的一个trip文件random_trip.trips.xml的具体格式是这样的:

<?xml version="1.0" encoding="UTF-8"?>
<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://sumo.dlr.de/xsd/routes_file.xsd">
    <trip id="0" depart="0.00" from="F0F1" to="A2A1"/>
    <trip id="1" depart="0.25" from="C2C3" to="B7A7"/>
    ......
</routes>

所以根据车牌识别数据生成trip文件的算法如下:

  1. 将电警卡口设备与edge id相匹配;
  2. 进行出行链打断,得到所有的车辆OD(edge id)、离开时间以及travel time;
  3. 生成.trip.xml文件;

但是可以想到上述方法生成的trip文件缺失是很严重的,因为有大量车辆一天只被检测到一次,无法生成OD信息,还有大量车辆漏检等等,因此通过上述方法生成的trip文件肯定是少于真实路网情况的,这是后续需要validate的一个地方。

将电警卡口设备与edge id相匹配

要想实现这一步,需要首先将sumo的network进行转换,因为现在该文件是.net.xml格式的,借助sumo中的net2geojson.py脚本将.net.xml文件转化为geojson文件。切换到sumo的tools文件夹后,执行命令:

python ./net/net2geojson.py -n E:\study_e\traffic_simu_xiaoshan\network\xiaoshan.net.xml -o E:\study_e\traffic_simu_xiaoshan\network\xiaoshan.geojson

便会生成一个geojson文件,该命令还会将坐标系转换回WGS84坐标系。
接着就可以对两个文件进行操作处理了,需要对每个电警卡口设备分析距离其最近的edge以进行匹配,可能这样匹配会有一些bug,但是这个bug对后续影响不大,因为虽然可能有一些误差,但是后续得到trip时,这些误差仅仅是使得OD可能偏离了一两条路而已。保存结果为:
在这里插入图片描述

OD生成

首先通过车牌和被检测时间作为第一二索引进行排序,然后将下一行的车牌和被检测时间上移一行并拼接。然后看这一行和下一行被检测车辆是否是同一辆车,以及旅行时间是多少。按照旅行时间和是否是同一辆车为依据进行出行链打断。只保留不是同一辆车和相邻两次被检测时间大于阈值的rows,也就是只保留需要打断出行链的rows,此时保留的每一行分别是(last trip destination, this trip origin),只需要将last trip destination的信息上移一行即可,就可以得到每一次trip的OD了,将结果保存至…/data/trip_basedon_lpr.csv,数据结构为:
在这里插入图片描述

生成.trip.xml文件

遍历一遍OD生成中的trip文件,为每一行生成一行。结果保存至demand文件夹下,命名为xiaoshan_lpr_trip.trip.xml即可。
但是有一点需要优化,通过车牌识别数据是可以得到车辆的type的,萧山的数据中共包括三种车辆的type:Truck、Car、Bus。不同车辆的跟驰模型都是有区别的,因此需要指定每一次trip的车辆类型。每种车辆类型的参数可以人为指定,也可以直接使用sumo系统中的值,在本案例中,我们直接使用sumo中的默认值,各类型车辆的参数详见链接:https://sumo.dlr.de/docs/Vehicle_Type_Parameter_Defaults.html,vehicle type设置方法详见:https://sumo.dlr.de/docs/Definition_of_Vehicles%2C_Vehicle_Types%2C_and_Routes.html#abstract_vehicle_class。

基于trip.xml文件的需求生成

在之前已经基于车牌识别数据生成了trip.xml文件,而要想进一步生成需求也有若干方法,比如可以直接用trip作为需求,也可以基于trip进一步生成route文件。在本案例中,我们主要考虑两种方式:

  1. 直接使用trip.xml文件作为需求;
  2. 用户均衡方法进行分配,将trip.xml进一步处理为route文件;

根据官网的说明,一般第一种方式适用于下列三种情况:

  • there is not enough time / computing power to wait for the dynamic user equilibrium
  • changes to the net occur while the simulation is running
  • vehicles need to adapt their route while running

在本案例中这三种情况似乎并不存在,唯一可能制约的是第一点,即计算量太大,但是这点也可以通过减少用户均衡分配的迭代次数来缓解,因此本案例中我们主要使用用户均衡方法进行分配,将trip.xml文件进一步处理为route文件。
sumo中有现成的脚本可以使用,Dynamic User Assignment说明链接:https://sumo.dlr.de/docs/Demand/Dynamic_User_Assignment.html。
首先,切换到输出文件的文件夹。

cd /d C:\traffic_simu_xiaoshan\demand\route

然后执行下列命令:

python "C:\Program Files (x86)\Eclipse\Sumo\tools\assign\duaIterate.py" -n "C:\traffic_simu_xiaoshan\network\xiaoshan.net.xml" -t "C:\traffic_simu_xiaoshan\demand\xiaoshan_lpr_trip.trips.xml" -l 100

出现错误为:Execution of [‘C:\Program Files (x86)\Eclipse\Sumo\bin\duarouter’, ‘-c’, ‘000/iteration_000_xiaoshan_lpr_trip.duarcfg’] failed. Look into dua.log for details.
也就是在调用duarouter命令时报错了,因此需要解决duarouter命令报错的问题。
执行下列命令进行尝试:

duarouter -n "C:\traffic_simu_xiaoshan\network\xiaoshan.net.xml"  --route-files "C:\traffic_simu_xiaoshan\demand\xiaoshan_lpr_trip.trips.xml" -o "C:\traffic_simu_xiaoshan\demand\example_route\example_routes.rou.xml"

确实出现一模一样的bug,为了解决该bug,在上述命令的后面增加–ignore-errors “true”,在此执行,确实运行成功了,但是新出现了很多warning,包括下列这些:

  1. The vehicle ‘浙AF06170_78642_543446’ has no valid route.
  2. Vehicle ‘浙AF63516_78642_543447’ is not allowed to arrive on edge ‘320835563#8’.
  3. The route of the vehicle ‘赣BQA790_78788_544017’ is not known.
  4. No connection between edge ‘578296331#2’ and edge ‘486375249’ found.
  5. Mandatory edge ‘154107486’ not reachable by vehicle ‘浙AE8W78_79325_546115’.

不过warnning不影响命令的成功执行,只是会导致很多trip的缺失。
但是即使duarouter成功了依然不能解决duaIterate.py失败的问题,因为duaIterate.py命令并无法传入–ignore-errors "true"这个参数,为了解决该问题,使用下述方法:
基于duaIterate.py进行用户均衡分配
为了解决本案例duaIterate.py脚本的bug,本案例使用下列的命令解决该问题;
1.首先执行该命令;

duarouter -n "C:\traffic_simu_xiaoshan\network\xiaoshan.net.xml"  --route-files "C:\traffic_simu_xiaoshan\demand\xiaoshan_lpr_trip.trips.xml" -o "C:\traffic_simu_xiaoshan\demand\route\first_shortestroutes.rou.xml" --ignore-errors "true"

2.第一步的命令执行后会生成first_shortestroutes.rou.xml文件,该文件其实就是第一次对短路分配的结果,这个文件里应该是没有bug的,所以后续就用这个文件作为需求的输入进一步去进行用户均衡分配,命令如下:

cd /d C:\traffic_simu_xiaoshan\demand\route;

python "C:\Program Files (x86)\Eclipse\Sumo\tools\assign\duaIterate.py" -n "C:\traffic_simu_xiaoshan\network\xiaoshan.net.xml" -t "C:\traffic_simu_xiaoshan\demand\route\first_shortestroutes.rou.xml" -l 10

上述方法确实可以解决该问题,最终也生成了用户均衡的结果,但是该算法非常耗时,一次循环共包括两个步骤,第一个步骤使进行最短路分配,第二个步骤是进行仿真计算旅行时间等等。进行最短路分配共耗时6分35秒,其实还是挺快的,但是从0点仿真到12点06分共花了1个半小时,可以想到如果要循环10次,是一个不可以接受的时间,因此需要想办法进行优化。

基于车牌识别数据的需求生成优化

在之前,基于车牌识别数据的需求生成的整套流程已经实现了,但是运行时间过长,因此需要进行优化处理,在此考虑的优化方法主要是只对早晚高峰进行仿真优化,而且早晚高峰分开仿真,如此一来需要仿真的时长大大缩短了,而一般交通管理政策也仅仅针对早晚高峰实施,因此这样的一种优化思路也是有依据的。
在本案例中,早高峰设定为06:30 AM – 10:00 AM,晚高峰设定为05:00 PM – 07:30 PM(参考之前发表的part c),但是如果仅仅选取这个时间段的数据作为需求的话是会出问题的,因为之前一些遗留的车等于是完全没有考虑,为了解决该问题,我在上述时间段的基础上进一步扩展半个小时,也就是早高峰选取06:00 AM – 10:30 AM,晚高峰选取04:30 PM – 08:00 PM,但是在后续分析时,依然只取原来的晚高峰时间进行分析,也就是说把扩展时间段去掉。
首先以早高峰为例进行分析:
1.基于“OD生成”一节生成的OD文件进行分析,在生成.trips.xml文件时增加了一个时间过滤,将OD文件中早高峰/晚高峰的数据过滤出,然后保存为.trips.xml文件;python脚本主函数运行下列代码:

obj.generate_trip_file(trip_basedon_lpr_file='../data/trip_basedon_lpr.csv',
        time_interval="06:00:00,10:30:00",output_file="C:\\traffic_simu_xiaoshan\\demand\\xiaoshan_lpr_trip_morning_peak.trips.xml")

2.执行命令生成进行需求的用户均衡分配,命令如下:

duarouter -n "C:\traffic_simu_xiaoshan\network\xiaoshan.net.xml"  --route-files "C:\traffic_simu_xiaoshan\demand\xiaoshan_lpr_trip_morning_peak.trips.xml" -o "C:\traffic_simu_xiaoshan\demand\route\first_shortestroutes.rou.xml" --ignore-errors "true"

cd /d C:\traffic_simu_xiaoshan\demand\route

python "C:\Program Files (x86)\Eclipse\Sumo\tools\assign\duaIterate.py" -n "C:\traffic_simu_xiaoshan\network\xiaoshan.net.xml" -r "C:\traffic_simu_xiaoshan\demand\route\first_shortestroutes.rou.xml" -l 10

需要说明的是仿真开始和结束的时间并没有进行调整,因为早高峰前并没有需求,因此仿真速度是飞快的,实际上不修改也没关系,所以并未调整,而且不进行调整还有一个好处是仿真时间和一天的时间是相同的,这对后续的分析是有利的。
但是在仿真过程中也出现了一些bug,bug详见bug一节所示,在这里不再阐述了。为了使得用户均衡分配可以继续下去,我使用的方法是人为设定好仿真开始和结束的时间,到了结束时间也许还有车,但是也强制停止仿真,此时需要使用下列命令:

duarouter -n "C:\traffic_simu_xiaoshan\network\xiaoshan.net.xml"  --route-files "C:\traffic_simu_xiaoshan\demand\xiaoshan_lpr_trip_morning_peak.trips.xml" -o "C:\traffic_simu_xiaoshan\demand\route\first_shortestroutes.rou.xml" --ignore-errors "true"

cd /d C:\traffic_simu_xiaoshan\demand\route

python "C:\Program Files (x86)\Eclipse\Sumo\tools\assign\duaIterate.py" -n "C:\traffic_simu_xiaoshan\network\xiaoshan.net.xml" -r "C:\traffic_simu_xiaoshan\demand\route\first_shortestroutes.rou.xml" -l 3 -b 21600 -e 39600

使用上述命令后便可以成功跑完循环,一次循环中进行最短路算法分配需要2分钟,仿真需要一个小时。我设置了循环3次,因此大概需要3个小时来得到用户均衡分配的route结果。duaIterate.py脚本完整运行一次的结果如下图所示,本例中一共运行了3个半小时。根据下图可以知道,总共分配了3次route,也仿真了3次,其中最后一次仿真是基于first_shortestroutes_002.rou.xml跑的,也就是最后ICI分配的route,因此其实不需要在对最新的route进行一次仿真了,可以直接取最后一次仿真的结果进行后续分析,当然如果最后一次仿真没有输出想要的信息,那么就需要在仿真一次。

<input>
	<net-file value="C:\traffic_simu_xiaoshan\network\xiaoshan.net.xml"/>
	<route-files value="first_shortestroutes_002.rou.xml"/>
	<additional-files value="../edgedata.add.xml"/>
</input>

在这里插入图片描述

bug

  1. 命令行都没有bug,但是有一点奇怪的是生成最短路结束后,cmd会卡主,不再继续往下运行,也就是说仿真不会继续,但是可以看一下dua.log文件,如果已经运行完了,可以按一下crtl+C,此时便会继续往下运行。包括第一次循环执行完了也会卡主,但是按一下crtl+C就可以继续执行;最后一次没有出现该bug,直接就运行成功了,好像不去不断的看log文件就不会暂停掉。
  2. 第二个问题是我这边的需求设置是早上6点到早上10点半,可是在按照最短路分配好,开始仿真时,一直仿真到22:00还是没有仿真结束,也就是说虽说早上10点半之后就没有新的车辆出现了,但是已经出现在路上的车一直到晚上都没有到达目的地,这可能是多个因素造成的结果,比如车辆一直拥堵无法前进,车辆无法到达目的地等,但是具体是什么原因导致的我也不知道。

仿真分析

仿真

如**“基于车牌识别数据的需求生成优化”**一节中所说的,在进行用户均衡分配时,最后一次仿真的结果其实就可以直接作为仿真分析结果来使用,若没有全部的信息,则可以自己配置好仿真配置文件,在进行一次仿真,如果信息完备的话则不需要再进行进一步的仿真了。
用户均衡分配时,在仿真完之后有两个结果文件:

  1. summary_002.xml
  2. tripinfo_002.xml

首先看第一个summary.xml的内容是什么,看名字这个文件就是一个结果的汇总文件,其官方链接是https://sumo.dlr.de/docs/Simulation/Output/Summary.html,summary文件是每个step输出一次结果,默认就是每一秒输出一次结果,这个结果中包含着很多统计指标,具体可以看链接中所说明的,包含每一个指标的解释说明,取了一个step的summary结果在下面展示:

<step time="21600.00" loaded="1" inserted="0" running="0" waiting="0" ended="0" arrived="0" collisions="0" teleports="0" halting="0" stopped="0" meanWaitingTime="-1.00" meanTravelTime="-1.00" meanSpeed="-1.00" meanSpeedRelative="-1.00" duration="797437483"/>
  • loaded:截止目前为止,从输入文件中载入的车辆数,但是这个值并不是加入到网络中的车辆,有些depart time在未来的车也会被计数进来;
  • inserted:截止目前已经插入的车辆数,这个值应该就是截止目前已经插入到路网中的车辆,包括正在运行和已经结束运行的总车辆数;
  • running:在当前的这个时间步,正在运行的车辆数;
  • waiting:等待要插入,但是无法插入的车辆数,可能因为拥堵等原因无法插入;
  • ended:已经到达目的地或被移除的车辆数总数,这个值应该是包括结束旅行和出bug的车辆数之和;
  • arrived:已经到达终点的车辆数;
  • collisions:发生碰撞的车辆数;
  • teleports:被远距离传送的车辆数(由于拥堵或碰撞),这个指标不大清楚是什么意思;
  • halting:网络中速度低于0.1m/s的车辆数,这些车不是停在那,而是由于拥堵造成的速度慢;
  • stopped:停着不动的车辆;
  • meanWaitingTime:截止目前为止,所有等待被插入的车辆的等待时间的平均值;
  • meanTravelTime:截止当前时间步为止,所有结束仿真的车辆的平均行程时间;
  • meanSpeed:当前网络中除了等待车辆外的所有车辆的平均速度;
  • meanSpeedRelative:网络中除了等待车辆外所有车辆相对于限速的平均相对速度;
  • duration:截止到当前的仿真耗时;

接着看第二个文件tripinfo_002.xml的内容情况,该文件的官方说明链接是:https://sumo.dlr.de/docs/Simulation/Output/TripInfo.html,借助该文件可以知道每一次trip的开始时间(depart),trip的到达时间(arrival),trip的长度(routeLength),duration(花费时间),vaporized(是否车辆被移除仿真在车辆到达终点之前)。

结果分析

summary文件的处理

对summary文件进行处理,这个文件的基本数据格式为:

<?xml version="1.0" encoding="UTF-8"?>
<summary xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://sumo.dlr.de/xsd/summary_file.xsd">
  	<step time="21600.00" loaded="1" inserted="0" running="0" waiting="0" ended="0" arrived="0" collisions="0" teleports="0" halting="0" stopped="0" meanWaitingTime="-1.00" meanTravelTime="-1.00" meanSpeed="-1.00" meanSpeedRelative="-1.00" duration="797437483"/>
    <step time="21601.00 ..."/>
</summary>

处理时有几种思路,可以直接读取xml文件使用python进行处理,转化为dataframe格式,也可以用sumo的脚本xml2csv.py先把xml文件转化成csv,然后直接读取csv来进行分析。在此为了方便,我先将xml文件转化为csv,然后在进行后续的处理分析。执行下列命令即可,该脚本命令的详细信息可参加官方文档:https://sumo.dlr.de/docs/Tools/Xml.html

python "C:\Program Files (x86)\Eclipse\Sumo\tools\xml\xml2csv.py" "C:\traffic_simu_xiaoshan\demand\route\002\summary_002.xml" --output "C:\traffic_simu_xiaoshan\demand\route\002\summary_002.csv" 

在cmd执行上述命令后就会出现一个summary_002.csv文件,这个csv文件就包含上述说明的summary的所有字段,直接对该文件进行处理即可。
描述性统计结果见下表:

step_arrivedstep_collisionsstep_durationstep_endedstep_haltingstep_insertedstep_loadedstep_meanSpeedstep_meanSpeedRelativestep_meanTravelTimestep_meanWaitingTimestep_runningstep_stoppedstep_teleportsstep_timestep_waiting
count18000180001800018000180001800018000180001800018000180001800018000180001800018000
mean18706.941.0047.99E+0818706.9415610.1836500.5371117.852.9717240.1150291199.512486.899817793.59013284.1830599.533888.1
std10021.091.88375134154910021.099738.47820404.5245693.24.5650790.17212751.7394469.345110415.69012158.795196.29725644.36
min007.97E+080001-1-1-1-1000216000
25%10472.507.98E+0810472.55526.517792.5249750.390.02512.09573.587573200174026099.755991.25
50%20451.507.99E+0820451.518243.540999773300.660.031091.585290.5052054801026030599.535905.5
75%2726618E+082726624333.2554446.51146193.060.121812.3851.602527180.5023245.535099.2559056.25
max3331278.02E+0833312279326375913096719.980.752684.071553.36304570390863959970022

基于summary文件的仿真效果评价

要想做validation,首先肯定是需要对仿真的效果进行评价,在本案例中,由于真实数据我只得到了每次trip的行程时间,所以这个效果评价肯定是围绕行程时间了。
行程时间均值比较
粗略判断仿真效果的话只需要计算下车牌识别数据得到的所有trip的行程时间的均值和仿真得到的所有trip的行程时间均值进行比较。
仿真数据集上得到的结果为:
萧山区仿真实验中早上06:00 - 10:00 AM所有完成trip的车辆数为28581辆,所有完成trip的车辆的平均行程时间为33.07分钟,所有被插入到网络中的车辆数为56688辆。
真实数据集上得到的结果为:
萧山区车牌识别数据得到早上06:00 - 10:00 AM所有完成trip的车辆数为144768辆,所有完成trip的车辆的平均行程时间为14.85分钟,所有被插入到网络中的车辆数为153139辆。
问题推断:
可以发现仿真结果和实际结果的差距非常之大,于是,使用gui重新仿真了下进行观察,可以看到很多路口都堵死了,车辆根本动不了,这就是为什么仿真需求比实际需求小这么多,可是行程时间却大很多,且进入路网但是无法完成行程的车辆数很多的原因,早上6点到10点一半车都是进入了路网但是无法完成行程,这些车都是在路上被堵死了。接着分析车辆在路上被堵死的原因:

  1. 从osm爬取的路网拓扑不正确;
  2. 从osm爬取的路网绝大多数路口都缺失信号灯;
  3. 仿真车辆在经过无信号交叉口时,并不像真实世界一样会让对方,而是尽力往前冲,因此容易堵死;

我从sumo-gui截取了下列三张图来说明这种现象,当然造成仿真不准确还有其他很多原因,比如电警和路段匹配时,由于匹配错误,导致损失了很多需求,这也是为什么,仿真需求比实际需求少这么多的原因,但是这个需求问题之后在解决,现在当务之急是需要解决无信号交叉口无序出行导致碰撞的问题。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

解决思路:
为了解决该问题,主要是对交叉口设置进行改进,交叉口的官方文档为:https://sumo.dlr.de/docs/Simulation/Intersections.html,在本案例中采取的解决方案是忽略交叉口内的车辆行为,即车辆一到达交叉口将直接到交叉口出口处,交叉口内的行为将被忽略,这也就不会发生碰撞了,但是对于信号交叉口等红绿灯的时间依然是会被考虑在内的,但是由于我们的拓扑缺失了很多信号灯,因此这种处理手段将会导致车辆的行程时间大幅缩短。
对路网拓扑进行–no-internal-links设置后在重新进行仿真。

  1. 路网拓扑设置更新,使用的命令如下:
netconvert -s "C:\traffic_simu_xiaoshan\network\xiaoshan.net.xml" -o "C:\traffic_simu_xiaoshan\network\xiaoshan_new.net.xml" --no-internal-links True

命令结束后就会生成xiaoshan_new.net.xml文件。

  1. 根据新的路网拓扑数据xiaoshan_new.net.xml生成geojson格式的路网数据,为设备和edge的匹配做铺垫,命令如下:
python "C:\Program Files (x86)\Eclipse\Sumo\tools\net\net2geojson.py" -n "C:\traffic_simu_xiaoshan\network\xiaoshan_new.net.xml" -o "C:\traffic_simu_xiaoshan\network\xiaoshan_new.geojson"
  1. 执行generate_network.py脚本的match_dev_edge函数,进行设备和edge的匹配;
  2. 基于车牌识别数据的OD生成可以直接调用generate_network.py脚本的get_veh_od_tratime函数,由于设备和edge重新匹配了,因此OD也需要重新生成一下;
  3. trips.xml文件的生成可以直接调用generate_network.py脚本的generate_trip_file函数,早高峰直接使用06:30 AM – 10:00 AM,而不再拓展半个小时(这样做,主要是为了简化,因为summary中的统计指标都是截止目前为止的统计指标,因此不往前拓展,忽略这种误差会方便后续的处理);
  4. 对trips进行用户均衡分配,命令如下(都是和之前一样的),现在修改优化后,仿真一次速度提升至17分钟,3次用户均衡迭代也仅仅需要1个小时而已了。
duarouter -n "C:\traffic_simu_xiaoshan\network\xiaoshan_new.net.xml"  --route-files "C:\traffic_simu_xiaoshan\demand\xiaoshan_lpr_trip_morning_peak.trips.xml" -o "C:\traffic_simu_xiaoshan\demand\route\first_shortestroutes.rou.xml" --ignore-errors "true"

cd /d C:\traffic_simu_xiaoshan\demand\route

python "C:\Program Files (x86)\Eclipse\Sumo\tools\assign\duaIterate.py" -n "C:\traffic_simu_xiaoshan\network\xiaoshan_new.net.xml" -r "C:\traffic_simu_xiaoshan\demand\route\first_shortestroutes.rou.xml" -l 3 -b 23400 -e 36000
  1. 结束了之后,就得到最新的summary文件,需要将summary.xml文件转化为csv文件,调用sumo的转换脚本转换一下就行了:
python "C:\Program Files (x86)\Eclipse\Sumo\tools\xml\xml2csv.py" "C:\traffic_simu_xiaoshan\demand\route\002\summary_002.xml" --output "C:\traffic_simu_xiaoshan\demand\route\002\summary_002.csv" 
  1. summary文件转换好之后,再次进行基于summary文件的仿真效果评价,直接调用simu_result_ana.py文件就行了,main脚本如下:
obj=simu_summary_file_ana()
simu_df = obj.read_summary_file(summary_file="C:\\traffic_simu_xiaoshan\\demand\\route\\002\\summary_002.csv")
obj.comp_simu_real(simu_df=simu_df, real_df_file="C:\\traffic_simu_xiaoshan\\data\\trip_basedon_lpr.csv")

通过该方式重新评估仿真结果和车牌识别数据结果的差异,结果如下:
仿真结果:
萧山区仿真实验中早上06:30 - 10:00 AM所有完成trip的车辆数为46021辆,所有完成trip的车辆的平均行程时间为18.53分钟,所有被插入到网络中的车辆数为69291辆。
车牌识别数据结果:
萧山区车牌识别数据得到早上06:30 - 10:00 AM所有完成trip的车辆数为140825辆,所有完成trip的车辆的平均行程时间为14.96分钟,所有被插入到网络中的车辆数为147033辆。
问题推断:
可以看到,结果相对于之前有明显的改进,但是依然没有彻底解决问题,通过观察gui可以发现运行到后来基本上加起来有1/4的区域完全被堵死了。造成这个现象的原因应该还是由于从osm爬取的路网拓扑不正确导致的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于sumo和车牌识别数据的城市仿真 的相关文章

  • SUMO文档:有关需求建模(Demand Modelling)

    Demand Introduction to demand modelling in SUMO 在生成了路网后 xff0c 我们可以在sumo gui上查看 xff0c 但是路网上并没有车辆运行 我们还需要一些有关车辆的描述 我们称之为 交
  • sumo仿真软件拒绝访问_Prescan和sumo的联合仿真操作说明

    本篇内容主要是介绍Prescan和Sumo的联合仿真方式 xff0c 以期让客户可以掌握sumo和prescan联合的方式 01 Sumo简介 Sumo是比较目前比较常见也是开源的交通流仿真软件 他是一个微观的 xff0c 空间上连续 xf
  • sumo之模拟行人

    在前面的文章中介绍了模拟车辆以及交通工具 公共汽车 xff0c 在道路上除了车辆外还有行人参与 在本文中介绍添加行人 详细的方法和参数可以前往官网查看 本部分的模拟路网全部沿用上次公共汽车模拟的环境 xff0c 只需要对部分代码进行修改 首
  • SUMO 使用netconvert报错解决办法

    SUMO 使用netconvert报错 问题描述正确解决方法不适用的解决方法 问题描述 刚开始学习使用sumo xff0c 版本是sumo1 8 0 第一次使用netconvert转换地图时出现报错 xff0c 提示没有PROJ Libra
  • SUMO入门(四) - 需求建模 车辆和路线的定义

    SUMO入门 四 需求建模 车辆和路线的定义 Demand Introduction to demand modelling in SUMO 在生成网络之后 xff0c 可以使用SUMO GUI来查看它 xff0c 但是没有汽车可以行驶 人
  • SUMO跟车模型之IDM模型

    IDM 智能交通模型Intelligent Driver Model 优点 xff1a IDM模型的参数数量少 意义明确 xff0c 并且能用统一的模型描述从自由流到完全拥堵流的不同状态 缺点 xff1a 缺乏随机项 xff0c 也就是输入
  • SUMO模拟网络时报错:Warning: Environment variable SUMO_HOME is not set, XML validation will fail or use...

    Windows系统 xff0c 在使用SUMO模拟建立模拟网络时 xff0c 输入以下代码 xff0c 用以生成route文件 duarouter n sumotest net xml route files sumotest trips
  • sumo教程 Hello World

    sumo教程 Hello World 注意事项 确保安装的sumo版本至少为1 4 0 以便能够使用本教程中显示的所有功能 要求 sumo gui和netedit的版本大于等于1 4 0 介绍 这个教程服务于第一次使用sumo的人员 我们准
  • sumo教程——Manhattan

    介绍 本教程介绍了如何在 SUMO 中构建曼哈顿移动模型 在这个模型中 xff0c 固定数量的车辆在曼哈顿电网网络上随机行驶 所有文件也可以在 lt SUMO HOME gt docs tutorial manhattan 目录中找到 创建
  • SUMO输出文件设置

    1 fcd浮动车数据输出 轨迹数据输出 sumo c demo sumocfg fcd output fcd1 xml 2 设置E3检测器 E3检测器简介 Multi Entry Exit Detectors xff08 E3 xff09
  • 基于openstreetmap数据的SUMO路网生成路线

    一 一步到位 xff1a 基于SUMO自带工具smWebWizard py 使用SUMO自带的osmWebWizard py脚本 xff08 sumo tools xff09 进行下载 xff0c 脚本执行后会打开一个操作网页 xff0c
  • 基于sumo和车牌识别数据的城市仿真

    前言 最近希望能仿真出一个城市的交通状态 xff0c 也就是知道在不同的需求加载下城市宏观交通状态的变化情况 xff0c 同时 xff0c 因为我手头有车牌识别数据 xff0c 因此需求将来自于车牌识别数据 但是仿真过后发现 xff0c 并
  • sumo中随机产生车流

    在sumo中绘制地图 xff0c 然后利用sumo中的randomTrips py工具产生随机的车流量 一 首先绘制路网 xff0c 本文绘制了一个九宫格路网 xff08 myroad net xml xff09 xff0c 如下图 xff
  • sumo入门-保姆级教程

    SUMO学习 入门篇 1 安装SUMO 在sumo官网 xff08 https sumo dlr de docs Downloads php xff09 安装即可 xff0c 为省略不必要的困扰 xff0c 推荐安装在C盘 xff0c xf
  • SUMO 换道设置,靠右行驶

    vType中设置换道参数 xff0c 解决仿真中车辆一直靠右行驶和无脑逮着一个进口道走等情况 lt vType id 61 34 type1 34 accel 61 34 0 8 34 decel 61 34 4 5 34 sigma 61
  • SUMO 设置速度后正常行驶

    先附上traci vehicle setSpeed vehID speed 的使用说明 xff1a setSpeed self vehID speed 在最后一步中为命名车辆设置速度 xff08 以 m s 为单位 xff09 以 spee
  • sumo osmWebWizard.py不生成OSM.sumocfg

    osmWebWizard在确定地图范围和车辆数 xff0c 点击Generate Scenario选项后 生成文件只含有osm netccfg和osm polycfg xff0c 如图 xff1a 主要原因是 当前版本默认仅勾选Add Po
  • 静脉如何在简单路径损耗模型中计算 RSSI?

    我们正在开发一个基于 Veins 框架的应用程序 它需要接收信号的 RSSI 值以及发送器和接收器之间的距离 我们参考了 VeReMi 项目 它也计算 RSSI 值并将其发送到上层 我们将模拟结果 RSSI 与距离 与 VeReMi 数据集
  • 有没有办法将多个 TraCI 模块连接到 OMNet++/veins 模拟?

    要启动任何静脉模拟 需要使用 Veins launchd 守护进程 它基本上采用 sumo 配置文件 找到未使用的端口 启动 sumo 并桥接 sumo 和 OMNet 之间的连接 现在 由于这是基于套接字的通信 我想连接一个单独的 Tra
  • 关于 VEINS 中的车辆编号

    我使用 duarouter 修改了 erlagen rou xml 来获取车辆的随机路线 它看起来像这样

随机推荐

  • centos卸载软件三种方式

    1 我们来卸载用yum安装的软件 xff1a yum remove 软件名字 xff1b 2 如果是用rpm包安装的软件呢 xff0c 则使用如图命令进行卸载 xff1b rpm e 软件名 xff1b 3 如果是用tar包安装的软件呢 x
  • Pycharm设置http代理

    1 Pycharm设置 2 urllib下载数据配置 span class token keyword from span urllib span class token punctuation span error span class
  • Docker 配置网络代理

    有时因为网络原因 xff0c 比如公司 NAT xff0c 或其它啥的 xff0c 需要使用代理 Docker 的代理配置 xff0c 略显复杂 xff0c 因为有三种场景 但基本原理都是一致的 xff0c 都是利用 Linux 的 htt
  • 安装 OpenVPN 客户端

    安装 OpenVPN 客户端 yum y span class token function install span epel release yum y span class token function install span op
  • 字符串-字符串匹配

    Leetcode 28题 1 题目描述 Given two strings needle and haystack return the index of the first occurrence of needle in haystack
  • pip无法安装包到新创建的虚拟环境下面,安装包冲突

    第1步 xff1a 查看安装包的路径 span class token punctuation span label studio span class token punctuation span user 64 master pytho
  • 数组-二分查找

    1 Search a 2D Matrix 1 1 题目描述 span class token comment You are given an m x n integer matrix matrix with the following t
  • 渗透测试工具学习笔记(1)——netcat(nc)

    v 显示详细输出内容 n 跟IP地址 xff0c 不进行DNS解析 l 打开一个listen端口 p 端口号 q n 当标准输出完成后延迟n秒断开 z 扫描模式 xff0c 不做I O操作 1 telnet banner nc vn ip地
  • 渗透测试工具学习笔记(2)——netcat(ncat)

    nc的缺点 xff1a nc缺乏加密和身份验证的能力 ncat包含于nmap工具包中 allow 允许连接的IP地址 A ncat c bash allow 192 168 20 14 vnl 333 ssl 用ssl加密 B ncat n
  • 渗透测试工具学习笔记(3)——wireshark

    manjaro安装GUI版本 xff1a yaourt S wireshark qt 需用sudo wireshark图形化版本以顺利使用全部功能 抓包嗅探协议分析 安全专家必备的技能 抓包引擎 Libpcap9 Linux Winpcap
  • PostgreSQL操作

    一 进入PostgreSQL数据库 Linux下切换到postgres用户 xff0c 执行psql即可进入 span class token function su span postgres bash 4 4 psql 此时就进入pos
  • 渗透测试工具学习笔记(4)——tcpdump

    no GUI的抓包分析工具 Linux Unix系统默认安装 说是这么说但是manjaro下没有 xff0c pacman一下即可 抓包 xff1a 默认只抓68个字节 i interface s snaplen 大小 w file tcp
  • 渗透测试工具学习笔记(5)——dradis、keepnote、truecrypt

    过程文档记录工具 1 dradis 导入导出扫描器日志 webapp 默认在http 0 0 0 0 3000 2 keepnote 层级化 3 truecrypt 加密工具 已停止更新 官方原因是安全性不够 xff0c 但实际使用却依然较
  • 渗透测试工具学习笔记(6)——nplookup(被动信息收集)

    被动信息收集 34 开源智能 34 open source OSINT 都是公开渠道可获得的信息 与目标系统不产生直接交互 尽量避免留下一切痕迹 Passive reconnaissance no direct interaction gt
  • PCL学习笔记——合并点云

    合并点云分为两种类型 xff1a 第一种是两个点云数据集的字段类型和维度相同 xff0c 合并之后点云只是点的数量增加了 xff1b 第二种是两个点云数据集的字段类型或维度不同 xff0c 但是点的数量相同 xff0c 合并之后相当于扩展了
  • 云服务器的图形界面的安装和远程连接xfce4 + VNC

    对于阿里和腾讯的云服务器学生价真的很优惠 xff0c 但是对于凑热闹买的我还是个小白 xff0c 我想装一个图形界面 xff08 特别是最近在用腾讯的CVM做HIT操作系统的实验 xff0c 其中有个软件必须要显示图形界面 xff09 较为
  • 【ROS学习】-tf学习(tf_monitor、tf_echo、static_transform_publisher、view_frames)

    写在前面 本文的内容主要来自 ros wiki 上的教程 xff1a http wiki ros org tf 简短总结 xff1a tf monitor 将当前的坐标系转换关系打印到终端控制台 tf echo lt source fram
  • Ubuntu使用WPS打开文档出现缺失字体情况解决方法

    一 问题描述 Ubuntu 通过官网下载deb安装 WPS 之后 xff0c 打开文档出现字体缺失的问题 xff1a 二 解决方法 下载缺失的字体 xff0c 百度网盘下载链接 xff08 TODO xff09 xff0c 然后解压 xff
  • PendSV中断服务函数

    之前在系统滴答定时器中断服务函数中调用API函数xPortSysTickHandler xff09 xff0c xPortSysTickHandler xff09 函数中通过向中断和状态寄存器的bit28写入1来启动PendSV中断 xff
  • 基于sumo和车牌识别数据的城市仿真

    前言 最近希望能仿真出一个城市的交通状态 xff0c 也就是知道在不同的需求加载下城市宏观交通状态的变化情况 xff0c 同时 xff0c 因为我手头有车牌识别数据 xff0c 因此需求将来自于车牌识别数据 但是仿真过后发现 xff0c 并