3、交通需求生成:用flowrouter和duarouter搞定交通流
大家好,我是老张。今天咱们聊聊交通需求生成这块。说实话,很多新手在SUMO里卡住的地方,就是不知道怎么把路网和车流串起来。你路网画得再漂亮,没有车跑,那就是个空城计。
我个人习惯把交通需求生成分成两派:静态路线和动态OD流。前者适合小场景测试,后者才是仿真实战的标配。咱们一个一个说。
3.1 先搞懂.rou.xml文件长啥样
路线文件,后缀是.rou.xml。说白了,它就是告诉SUMO:什么车、从哪出发、走哪条路、什么时候出发。
一个最简单的例子:
<routes>
<vType id="car" accel="2.6" decel="4.5" sigma="0.5" length="4.5" maxSpeed="50"/>
<vehicle id="v0" type="car" depart="0">
<route edges="edge1 edge2 edge3"/>
</vehicle>
</routes>
嗯,这里要注意:depart是出发时间,单位秒。edges里写的是路网中的edge ID,顺序不能乱。我在项目中遇到过有人把edge写反了,结果车直接逆行——SUMO虽然不会报警,但仿真结果全废了。
3.2 定义车辆类型(vType)——别小看这一步
很多教程把vType一笔带过,但我得说,vType是仿真精度的基石。你想想看,一辆卡车和一辆小轿车的加速度能一样吗?
| 参数 | 含义 | 典型值(小车) | 典型值(卡车) |
|---|---|---|---|
| accel | 最大加速度 (m/s²) | 2.6 | 1.2 |
| decel | 最大减速度 (m/s²) | 4.5 | 2.5 |
| sigma | 驾驶不完美度 (0~1) | 0.5 | 0.3 |
| length | 车辆长度 (m) | 4.5 | 10.0 |
| maxSpeed | 最高速度 (m/s) | 50.0 | 30.0 |
3.3 用duarouter生成静态路线
duarouter是SUMO自带的路线计算工具。你给它一个OD对(起点-终点),它帮你算最短路径。适合场景固定的仿真。
用法很简单:
duarouter --net-file mynet.net.xml \
--route-files trips.xml \
--output-file routes.rou.xml
这里的trips.xml长这样:
<trips>
<trip id="t0" depart="0" from="edge1" to="edge5"/>
<trip id="t1" depart="10" from="edge2" to="edge8"/>
</trips>
3.4 用flowrouter处理动态OD流
flowrouter就高级多了。它适合做宏观交通流生成。你给它一个OD矩阵,它自动生成车流,还能考虑路网容量。
基本用法:
flowrouter.py --net-file mynet.net.xml \
--flows-file flows.xml \
--output-file routes.rou.xml \
--flow-output flows.xml
flows.xml示例:
<flows>
<flow id="f1" from="edge1" to="edge5" begin="0" end="3600" number="500"/>
<flow id="f2" from="edge2" to="edge8" begin="0" end="3600" number="300"/>
</flows>
这里number="500"表示1小时内发500辆车。flowrouter会自动分配每辆车的出发时间,避免扎堆。
3.5 随机交通流生成——实战中最常用的
说实话,我90%的项目都用随机流。因为真实交通就是随机的。SUMO里生成随机流有两种方式:
- 用flow标签配合random参数:适合简单场景
- 用Python脚本生成:适合复杂需求
先看第一种:
<flow id="random_flow" type="car" from="edge1" to="edge5"
begin="0" end="3600" probability="0.1"/>
probability="0.1"表示每秒有10%的概率发一辆车。这个参数我特别喜欢,因为它能模拟出车流忽密忽疏的效果。
第二种,用Python脚本生成随机路线:
import random
import xml.etree.ElementTree as ET
routes = ET.Element("routes")
vType = ET.SubElement(routes, "vType", id="car", accel="2.6", decel="4.5", sigma="0.5")
for i in range(100):
depart = random.uniform(0, 3600)
veh = ET.SubElement(routes, "vehicle", id=f"v{i}", type="car", depart=str(depart))
route = ET.SubElement(veh, "route", edges="edge1 edge2 edge3")
tree = ET.ElementTree(routes)
tree.write("random_routes.rou.xml")
3.6 本章知识体系总览
下面这张图,是我自己总结的交通需求生成流程。建议你保存下来,写脚本时对照着看:
好了,这一章的内容就到这。交通需求生成是仿真的灵魂,你花多少功夫都不为过。下一章咱们聊聊怎么让这些车跑起来,以及如何采集仿真数据。
可可精品资料库