4. SUMO文件体系:四类核心文件详解
做SUMO仿真,说白了就是跟四种文件打交道。我刚开始接触SUMO时,也被这堆.xml文件搞得头晕。后来做多了才发现,这四类文件各司其职,理解透了,整个仿真流程就清晰了。
今天我就把这四类文件掰开揉碎了讲清楚。你想想看,就像盖房子需要图纸、材料清单、施工方案一样,SUMO仿真也需要这四样东西。
4.1 .net.xml路网文件——仿真的"骨架"
路网文件是整个仿真的基础。没有它,车都没地方跑。
它长什么样?
<?xml version="1.0" encoding="UTF-8"?>
<net version="1.16" junctionCornerDetail="5" limitTurnSpeed="5.50">
<location netOffset="0.00,0.00" convBoundary="0.00,0.00,1000.00,500.00"
projParameter="!"/>
<edge id="gneE0" from="J0" to="J1" priority="3" length="500.00">
<lane id="gneE0_0" index="0" speed="13.89" length="500.00"
shape="0.00,-1.60 500.00,-1.60"/>
<lane id="gneE0_1" index="1" speed="13.89" length="500.00"
shape="0.00,1.60 500.00,1.60"/>
</edge>
<junction id="J0" type="dead_end" x="0.00" y="0.00" incLanes="" intLanes="">
<request index="0" foes="0" cont="0"/>
</junction>
</net>
这里有几个关键元素:
- edge:就是道路段。每个edge有from和to属性,指向两个junction(交叉口)。
- lane:车道。一个edge可以包含多条lane。每条lane有自己的速度限制、长度和形状。
- junction:交叉口或节点。它连接不同的edge。
核心要点:.net.xml定义了车辆可以行驶的物理空间。包括道路走向、车道数、限速、交叉口规则等。
我在项目中遇到过一个问题:从OpenStreetMap导入的路网,交叉口类型经常标错。明明是个环岛,它标成了普通交叉口。嗯,这时候就得手动改junction的type属性。
4.2 .rou.xml路线文件——仿真的"血液"
路网搭好了,车呢?.rou.xml就是定义车辆和它们怎么走的文件。
基本结构:
<?xml version="1.0" encoding="UTF-8"?>
<routes>
<vType id="car" accel="2.6" decel="4.5" sigma="0.5" length="4.5"
maxSpeed="50.0" color="1,0,0"/>
<vehicle id="veh0" type="car" depart="0.00">
<route edges="gneE0 gneE1 gneE2"/>
</vehicle>
<vehicle id="veh1" type="car" depart="5.00">
<route edges="gneE0 gneE2"/>
</vehicle>
</routes>
这里面分三层:
- vType:车辆类型。定义一类车的共同属性,比如加速度、减速度、车长、颜色。
- vehicle:具体车辆。指定它用哪个vType,什么时候出发。
- route:行驶路线。用一连串edge ID表示车辆要经过的道路。
我的习惯:我一般会把vType单独放在文件开头,vehicle放在后面。这样改车辆参数时,不用翻来翻去找。
你可能会问:如果车很多,难道要一个个写vehicle标签?当然不是。SUMO提供了flow标签,可以批量生成车辆。
<flow id="flow1" type="car" begin="0" end="3600" period="5">
<route edges="gneE0 gneE1 gneE2"/>
</flow>
这段代码的意思是:从第0秒到第3600秒,每5秒发一辆车。一小时就是720辆车。省事吧?
4.3 .sumocfg配置文件——仿真的"总控台"
这个文件不定义任何仿真元素,它只是告诉SUMO:你要用哪些文件、仿真多长时间、输出什么结果。
一个典型的配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<input>
<net-file value="mynet.net.xml"/>
<route-files value="myroutes.rou.xml"/>
<additional-files value="myadd.add.xml"/>
</input>
<time>
<begin value="0"/>
<end value="3600"/>
</time>
<output>
<tripinfo-output value="tripinfo.xml"/>
<summary-output value="summary.xml"/>
</output>
</configuration>
关键配置项:
| 配置项 | 作用 | 我的建议 |
|---|---|---|
| net-file | 指定路网文件 | 路径用相对路径,方便迁移 |
| route-files | 指定路线文件 | 可以写多个,用空格隔开 |
| begin/end | 仿真起止时间 | 单位是秒,3600=1小时 |
| tripinfo-output | 每辆车的详细信息 | 分析单辆车行为时用 |
| summary-output | 全局统计信息 | 看整体交通流时用 |
注意:我曾经犯过一个低级错误——配置文件里写错了路网文件路径,结果SUMO报错说找不到文件。排查了半天才发现是路径少了个点。所以,路径一定要仔细检查。
4.4 .add.xml附加文件——仿真的"调味料"
附加文件用来添加路网本身没有的元素。比如交通灯、检测器、公交站、停车场等。
常见附加元素:
<?xml version="1.0" encoding="UTF-8"?>
<additional>
<!-- 交通灯 -->
<tlLogic id="J1" type="static" programID="0" offset="0">
<phase duration="31" state="GGggrrrrGGggrrrr"/>
<phase duration="4" state="yyggrrrryyggrrrr"/>
<phase duration="6" state="rrrrGGggrrrrGGgg"/>
<phase duration="4" state="rrrryyggrrrryygg"/>
</tlLogic>
<!-- 感应线圈检测器 -->
<inductionLoop id="det1" lane="gneE0_0" pos="100" length="2"
freq="60" file="detector.xml"/>
<!-- 公交站 -->
<busStop id="stop1" lane="gneE0_0" startPos="200" endPos="250"/>
</additional>
附加文件的好处是:你可以随时添加或移除这些元素,而不需要修改路网文件本身。这就像做菜时最后加调料,灵活得很。
实用技巧:我习惯把不同类型的附加元素分开放。比如traffic_lights.add.xml专门放交通灯,detectors.add.xml专门放检测器。这样管理起来清晰多了。
4.5 四类文件的关系
这四类文件的关系,我用一张图来展示:
说白了,.sumocfg就是那个"胶水",把路网、路线和附加元素粘在一起。你运行SUMO时,只需要指定这个配置文件就行。
我的工作流:我一般先建好路网(.net.xml),然后写路线(.rou.xml),再根据需要加附加元素(.add.xml),最后用配置文件(.sumocfg)把它们串起来。这个顺序基本不会错。
4.6 避坑指南
做SUMO仿真这几年,我踩过不少坑。分享几个最常见的:
- 文件编码问题:SUMO只认UTF-8编码。如果你用记事本保存了ANSI编码的文件,SUMO会报解析错误。我建议用VS Code或Notepad++编辑。
- ID命名规范:所有ID不要用中文,不要用空格。最好用字母、数字和下划线。我习惯用"edge_01"、"veh_001"这种格式。
- 路径引用:配置文件里引用其他文件时,路径要写对。相对路径是推荐做法,方便整个项目文件夹迁移。
- 版本兼容:不同版本的SUMO,文件格式可能略有差异。我遇到过用旧版工具生成的路网,在新版SUMO里跑不了。所以,工具版本要统一。
特别提醒:我曾经在项目交付前一天,发现仿真结果不对。排查了半天,原来是.rou.xml里一个vehicle的depart时间写成了字符串"0",而不是数字0。SUMO把它当成了无效值,那辆车就没出现。这种小错误最坑人,检查时要格外仔细。
好了,这四类文件就讲到这里。理解它们各自的作用和关系,是做好SUMO仿真的第一步。实际项目中,你还会接触到更多细节,但掌握了这个框架,后面学起来就轻松多了。