引言
(本文内容总结自 SUMO 官网 和 Youtube 视频教程 published by Rodrigue Tchamna.)
SUMO ( Simulation of Urban Mobility) 是免费、开源的交通系统仿真软件,可以实现交通流的微观控制,即具体到道路上每一辆车的运行路线都可以单独规划。
SUMO 最早发布于 2001年,主要由 German Aerospace Center 下属的 Institute of Transportation Systems 的研究人员开发。
如果使用 SUMO 仿真,官方希望引用的参考文献为:
Pablo Alvarez Lopez, Michael Behrisch, Laura Bieker-Walz, Jakob Erdmann, Yun-Pang Flötteröd, Robert Hilbrich, Leonhard Lücken, Johannes Rummel, Peter Wagner, and Evamarie Wießner. Microscopic Traffic Simulation using SUMO. IEEE Intelligent Transportation Systems Conference (ITSC), 2018.
安装 SUMO
SUMO 已经在 Ubuntu 的官方 repo 中了,可以用如下命令直接安装:
sudo apt-get install sumo sumo-tools sumo-doc
如果要安装最新版本,也可以手动添加 SUMO 的 repo 再安装
sudo add-apt-repository ppa:sumo/stable
sudo apt-get update
sudo apt-get install sumo sumo-tools sumo-doc
SUMO 并不是单个程序,而是包含了多个 package/ application,提供了丰富的交通系统建模仿真的功能。主要包括如下应用程序:
Demo 1:手动创建路网并仿真
对于小型网络,或者一些需要特别构造的道路网络,可以采用手动方式创建,主要包含 5 个文件:
- 节点文件 node file (.nod.xml)
- 连边文件 edge file (.edg.xml)
- 类型文件 edge type file (.type.xml)
- 基于上述三个文件创建路网文件 net file (.net.xml)
- 路由文件 route file (.rou.xml)
上述文件本质上都是 xml 文件,不过为了方便区分其作用,额外增加了一个后缀名。
假设我们要创建如下图所示的小型道路网络
图中黑色节点对应交通路口,连边对应道路。每个路口所在位置坐标已给出。
node file
创建如下 node file,名为 my_nod.nod.xml:
<nodes>
<node id="n1" x="-500" y="0" type="priority"/>
<node id="n2" x="-250" y="0" type="traffic_light"/>
<node id="n3" x="-150" y="200" type="traffic_light"/>
<node id="n4" x="0" y="0"/>
<node id="n5" x="150" y="200"/>
</nodes>
edge file
创建对应上述路网的 edge file,名为 my_edge.edg.xml,内容如下:
<edges>
<edge from="n1" to="n2" id="1to2" type="3L45"/>
<edge from="n2" to="n3" id="2to3" type="2L15"/>
<edge from="n3" to="n4" id="3to4" type="3L30"/>
<edge from="n4" to="n5" id="out" type="3L30"/>
</edges>
其中 id 和 type 可以随便命名,这里为了方便记忆,用 3L45,表示有 3 条 lane,速度上限是 45 m/s,随后会在 type file 中对相应的 type 进行定义。
type file
对前述 edge 文件中的 type 进行定义,文件名为 my_type.type.xml:
<types>
<type id="3L45" priority="3" numLanes="3" speed="45"/>
<type id="2L15" priority="3" numLanes="2" speed="15"/>
<type id="3L30" priority="2" numLanes="3" speed="30"/>
</types>
convert to network file
基于以上三个文件,可以通过命令 netconvert 创建 net 文件,命令如下:
netconvert --node-files my_nodes.nod.xml --edge-files my_edge.edg.xml -t my_type.type.xml -o my_net.net.xml
命令中各个参数的含义非常直观。
上述命令生成 my_net.net.xml 文件。以后如果改动了 node, edge, type files,都要重新生成一次 net file.
route file
定义 route file,名为 my_route.rou.xml:
<routes>
<route id="route0" edges="1to2 2to3"/> # edges 中的基本格式为"edge1 edge2 edge3 ..."
<route id="route1" edges="2to3 3to4"/>
<route id="route2" edges="3to4 out"/>
<vType accel="1.0" decel="5.0" id="Car" length="2.0" maxSpeed="100.0" sigma="0.0"/>
<vType accel="1.0" decel="5.0" id="Bus" length="12.0" maxSpeed="1.0" sigma="0.0"/> # sigma 随机程度,0 为无随机
<vehicle id="veh0" depart="10" route="route0" type="Bus"/>
<vehicle id="veh1" depart="10" route="route1" type="Car"/>
<vehicle id="veh2" depart="30" route="route2" type="Car"/>
</routes>
关于 Vehicle 和 route 的详细介绍,可以参考官网。
测试
运行程序时需要送入一些参数,可以通过命令行形式送入,如果参数太多、太长,为了方便起见,可以将参数统一放到 xml config 文件中,在运行时,可以调用这个 config 文件。
定义 my_config_file.sumocfg:
<configuration>
<input>
<net-file value="my_net.net.xml"/>
<route-files value="my_route.rou.xml"/>
</input>
<time>
<begin value="0"/>
<end value="2000"/>
</time>
</configuration>
如果一个参数既出现在了 config 文件中,又在 command line 中,则采用 command line 的设置。
一切准备就绪,下边运行程序
sumo-gui my_config_file.sumocfg
出现如下界面:
可以检查一下生成的路网是否与期望的相同,以及每条路上的 lane 数目。
然后将工具栏中的 Delay 设置为 100 ms,否则仿真开始之后瞬间结束。
点击绿色三角符号,运行仿真。在时间走到 10 时,bus 和 car 出现在相应的到路上。时间到达 1999 时仿真结束。
在工具栏中还可以设置 standard, fast standard, real world。可以切换一下,看看显示效果。
至此,一个简单的 SUMO 仿真 demo 就完成了。
在手动构造路网 net.xml 文件时,我们也可以用 SUMO 自带的 NETEDIT 程序,通过 NETEDIT GUI 编辑路网,可能效率更高一些。感兴趣的读者可以参考 SUMO 官网的教程。
上述手动设置路网的方式只适用于比较简单的情况,如果要构造与现实世界比较接近的大型路网,我们可以用下边的从外部导入 OSM 路网的方法。
Demo 2:从外部导入 OSM 地图并仿真
下载 open street map
进入 https://www.openstreetmap.org, 通过搜索城市、街道找到目标道路网,然后 export 即可。
这里我选用了上海市东川路附近的路网,如下图
转化成 SUMO 路网文件
netconvert --osm-files map.osm -o sjtu.net.xml
以上就得到了 .net.xml 文件,这里不是通过基于 node, edge, type 文件的整合,而是直接从 osm 地图转化过来。下边就是如何得到 route 文件。
route file
对于这种大型的路网,手动创建 route 文件也很麻烦,这里我们用 SUMO 自带的 randomTrips.py 程序创建随机的 route 文件
python <path_to_randomTrips.py> -n sjtu.net.xml -r sjtu.rou.xml -e 50 -l # -e 表示 end time
其中 randomTrips.py 文件放在了 SUMO_HOME 目录下,即 /usr/share/sumo 目录下。
config file
config 文件名为 sjtu.sumocfg,内容如下:
<configuration>
<input>
<net-file value="sjtu.net.xml"/>
<route-files value="sjtu.rou.xml"/>
</input>
<time>
<begin value="0"/>
<end value="2000"/>
</time>
</configuration>
运行仿真
到目前为止,已经设置好了所有必须的文件,可以通过以下命令启动仿真:
sumo-gui sjtu.sumocfg
启动仿真,截图如下:
局部放大:
用 osmWebWizard.py 实现 “一站式” 仿真
上边导入 osm 地图的方法还是比较麻烦,它主要包括 4 步:
- 从 osm 网站获取 osm 地图
- 用 netconvert 将 osm 地图转化成 SUMO 的 .net.xml 格式地图
- 用 randomTrip.py 生成随机 route 文件
- 开启仿真
实际上,SUMO 自带了一个 osmWebWizard.py 程序,整合了上述较为独立的步骤,在同一个操作界面,“一站式” 完成上述步骤。
用 osmWebWizard.py 运行仿真也是 SUMO tutorial 中的第一个项目。
注意:必须以 python 2 运行,python 3 会在 generate scenario 的时候报错。
python osmWebWizard.py
如果提示找不到该文件,就直接去 SUMO_HOME 的目录下面 /usr/share/sumo/tools
运行该文件。
没有问题的话,应该会在浏览器中打开如下页面。这里初始地图位置是 Berlin。
右侧有四个 tab,由上到下以此为:
位置:这里可以选择其他城市或者其他经纬度坐标,数字中,纬度在前,经度在后。
车辆类型:里面几乎涵盖了常见的交通工具,以及行人。可以设置交通流的密集程度。
其他选项:例如行驶在路的左侧还是右侧
copyright 信息
首先是选定要仿真的地图环境。可以缩放、移动视图,通过右侧的 Select Area 可以选定一个区域。最好不要选择太大范围,否则仿真很占资源,甚至导致死机。
然后选择交通流中的车辆类型和密集程度,through traffic factor 对应了车辆穿过率,count 的单位是 per hour-lane-kilometer。基于这里的参数设置,randomTrip 程序会产生相应的 random route。
以上就设定好了地图和 route,点击右上方的 Generate Scenario, 就可以进入仿真界面了。