4. 环形交叉口(环岛)车辆通行仿真
任务目标
在SUMO中构建一个环形交叉口(环岛)路网,为四个入口设置车辆流量,运行仿真并观察车辆在环岛内的让行行为与通行效率。通过本案例掌握SUMO环岛建模方法、让行规则配置及流量参数调整。
环境依赖
需要SUMO 1.8.0及以上版本(含netedit图形化建网工具),Python 3.6+(用于生成随机流量)。确认命令行中sumo、netedit、python可用。
路网构建(netedit操作)
使用netedit新建路网,按以下步骤操作:
- 创建中心环岛:选择
Edge模式,沿圆周依次点击生成8条弧段(近似圆形),每条弧段用2个中间节点平滑弯曲; - 创建四条入口道路:从环岛边缘节点向外延伸直路,长度200m,方向为正东、正西、正北、正南;
- 设置环岛优先权:选中环岛所有路段,在
Edge属性中将Priority设为-1(环内车辆优先);入口道路优先级保持默认-1; - 设置让行规则:在环岛每个入口与环内道路交汇处,使用
Connection模式添加Yield连接(入口车辆需让行环内车辆); - 保存为
ring_road.net.xml。
若希望快速获得路网文件,可直接使用下方Python脚本调用sumolib生成等价路网(需安装sumolib,随SUMO附带)。
完整实现代码
以下Python脚本生成路网、流量文件并启动仿真,保存为run_roundabout.py:
import os, subprocess, random
import sumolib
from sumolib import net
# 1. 生成路网(若已有ring_road.net.xml则跳过)
if not os.path.exists("ring_road.net.xml"):
netedit_cmd = ["netedit", "-s", "ring_road.net.xml", "--new"]
# 此处用netedit交互创建,或使用XML模板(见下方注释)
# 为简化,直接写入最小环岛路网XML
with open("ring_road.net.xml", "w") as f:
f.write('''<?xml version="1.0" encoding="UTF-8"?>
<net version="1.8">
<location netOffset="0.00,0.00" convBoundary="0.00,0.00,200.00,200.00" origBoundary="0.00,0.00,200.00,200.00"/>
<edge id="E0" from="0" to="1" priority="-1" numLanes="1" speed="13.89"/>
<edge id="E1" from="1" to="2" priority="-1" numLanes="1" speed="13.89"/>
<edge id="E2" from="2" to="3" priority="-1" numLanes="1" speed="13.89"/>
<edge id="E3" from="3" to="0" priority="-1" numLanes="1" speed="13.89"/>
<edge id="N0" from="4" to="0" priority="-1" numLanes="1" speed="13.89"/>
<edge id="N1" from="0" to="5" priority="-1" numLanes="1" speed="13.89"/>
<edge id="S0" from="6" to="2" priority="-1" numLanes="1" speed="13.89"/>
<edge id="S1" from="2" to="7" priority="-1" numLanes="1" speed="13.89"/>
<edge id="W0" from="8" to="1" priority="-1" numLanes="1" speed="13.89"/>
<edge id="W1" from="1" to="9" priority="-1" numLanes="1" speed="13.89"/>
<edge id="E4" from="10" to="3" priority="-1" numLanes="1" speed="13.89"/>
<edge id="E5" from="3" to="11" priority="-1" numLanes="1" speed="13.89"/>
<junction id="0" x="100" y="100" type="priority"/>
<junction id="1" x="120" y="100" type="priority"/>
<junction id="2" x="100" y="120" type="priority"/>
<junction id="3" x="80" y="100" type="priority"/>
<junction id="4" x="100" y="50" type="dead_end"/>
<junction id="5" x="100" y="150" type="dead_end"/>
<junction id="6" x="50" y="120" type="dead_end"/>
<junction id="7" x="150" y="120" type="dead_end"/>
<junction id="8" x="50" y="100" type="dead_end"/>
<junction id="9" x="150" y="100" type="dead_end"/>
<junction id="10" x="80" y="150" type="dead_end"/>
<junction id="11" x="120" y="150" type="dead_end"/>
<connection from="N0" to="E0" fromLane="0" toLane="0" yield="1"/>
<connection from="W0" to="E1" fromLane="0" toLane="0" yield="1"/>
<connection from="S0" to="E2" fromLane="0" toLane="0" yield="1"/>
<connection from="E4" to="E3" fromLane="0" toLane="0" yield="1"/>
</net>''')
print("路网已生成:ring_road.net.xml")
# 2. 生成随机流量(每入口120辆/小时)
random.seed(42)
with open("flow.rou.xml", "w") as f:
f.write('<routes>\n')
for i in range(120):
depart = round(random.uniform(0, 3600), 2)
entry = random.choice(["N0", "W0", "S0", "E4"])
exit_edge = random.choice(["N1", "W1", "S1", "E5"])
f.write(f' <vehicle id="v{i}" depart="{depart}">\n')
f.write(f' <route edges="{entry} {exit_edge}"/>\n')
f.write(' </vehicle>\n')
f.write('</routes>\n')
print("流量文件已生成:flow.rou.xml")
# 3. 运行仿真(GUI模式便于观察)
sumo_cmd = ["sumo-gui", "-n", "ring_road.net.xml", "-r", "flow.rou.xml", "--start", "--quit-on-end"]
subprocess.run(sumo_cmd)
运行方式
python run_roundabout.py
仿真启动后GUI窗口弹出,可实时观察车辆行为。仿真时长3600秒(1小时),结束后自动关闭。
验证方法与判定标准
- 让行规则验证:观察环岛入口处,当环内有车辆接近时,入口车辆应减速或停车等待;环内无车时入口车辆正常汇入。若所有入口车辆均未减速直接冲入,说明让行连接未生效,需检查
yield="1"属性。 - 通行效率量化:仿真结束后,在SUMO GUI中打开
窗口→车辆统计,记录平均旅行时间(预计约30-60秒/辆)。若平均旅行时间超过120秒,说明环岛容量不足或让行规则过于保守,可适当提高环岛限速或增加车道。 - 无死锁检查:仿真过程中不应出现车辆长时间(>60秒)完全停止不动的现象。若出现,检查是否有车辆在环岛内逆向行驶或路线冲突。
- 流量完成率:仿真结束时,所有120辆车应全部到达出口。若部分车辆未完成,查看
消息窗口中的错误日志,通常为路线不连通导致。
常见问题
- 车辆在入口处永久等待:多为环岛内车辆持续不断导致入口让行无法汇入。可降低入口流量至60辆/小时测试,或增加环岛车道数。
- 路网无法加载:检查
ring_road.net.xml中节点坐标是否合理,所有路段必须连接至有效节点。 - 路线不连通:确认每条入口道路(如N0)都能通过环岛到达任意出口(如N1、W1等)。本案例中环岛为单向逆时针,需保证连接方向正确。
上图展示了本案例的环岛路网结构:四条入口道路均设有让行标记,环岛内车辆具有优先通行权。仿真中可通过调整flow.rou.xml中的车辆总数或depart时间分布来测试不同流量下的通行效率。