4、SUMO基础入门:路网文件(.net.xml)结构解析、路线文件(.rou.xml)编写、SUMO-GUI可视化操作
各位同学,欢迎来到SUMO基础入门这一章。说实话,很多做自动驾驶仿真的朋友,一开始都被SUMO的XML文件给劝退了。我当年第一次打开.net.xml文件时,看着满屏的标签,心里也是一万个问号。但别怕,这东西说白了就是个结构化数据,摸清规律后你会觉得它挺可爱的。
本章核心脉络:理解SUMO路网文件的结构 → 学会编写路线文件 → 掌握GUI可视化操作。这三步走通了,你就能自己搭建仿真场景了。
4.1 路网文件(.net.xml)结构解析
先聊聊路网文件。你想想看,SUMO里的路网本质上就是个有向图。节点是路口,边是道路。就这么简单。
核心标签就三个:
<net>:根标签,包含版本信息<edge>:定义一条道路(边)<junction>:定义路口(节点)
我刚开始学的时候,总以为路网文件要手写。后来才发现,SUMO提供了netconvert和netedit工具,可以从OSM数据或shapefile转换。但理解原始结构依然很重要——调试时你得知道问题出在哪。
我的小技巧:遇到路网加载失败时,先检查<junction>的坐标是否合理。我曾经有一次把经度纬度写反了,结果车全跑到海里去,找了半天才找到原因。
来看一个典型的.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,500.00,500.00"
origBoundary="0.00,0.00,500.00,500.00" projParameter="!"/>
<edge id="edge1" from="node1" to="node2" priority="1" numLanes="2" speed="13.89">
<lane id="edge1_0" index="0" shape="0.00,0.00 500.00,0.00"/>
<lane id="edge1_1" index="1" shape="0.00,3.20 500.00,3.20"/>
</edge>
<junction id="node1" type="priority" x="0.00" y="0.00" incLanes="" intLanes="" shape="0.00,0.00 0.00,3.20 3.20,3.20 3.20,0.00"/>
<junction id="node2" type="priority" x="500.00" y="0.00" incLanes="" intLanes="" shape="497.00,0.00 497.00,3.20 500.00,3.20 500.00,0.00"/>
</net>
注意看<edge>里的numLanes和speed属性。numLanes=2表示双向2车道?不对,这里容易搞混——它指的是单向车道数。如果你想要双向4车道,需要定义两条edge,一条正向一条反向。
| 属性 | 含义 | 示例值 |
|---|---|---|
| id | 道路唯一标识 | "edge1" |
| from / to | 起点和终点节点ID | "node1" / "node2" |
| numLanes | 车道数(单向) | 2 |
| speed | 限速(m/s) | 13.89(约50km/h) |
| priority | 优先级(越大越优先) | 1 |
注意:SUMO中的速度单位是m/s,不是km/h。13.89 m/s ≈ 50 km/h。我见过有人直接写50,结果车跑得飞快,仿真完全失真。
4.2 路线文件(.rou.xml)编写
路网搭好了,接下来就是让车跑起来。路线文件就是告诉SUMO:什么车、从哪出发、走哪条路、什么时候出发。
核心标签就两个:<vType>和<vehicle>。前者定义车辆类型(颜色、长度、加速度等),后者定义具体车辆实例。
我个人习惯把车辆类型单独写在一个文件里,方便复用。比如做高速公路仿真时,我会定义轿车、卡车、公交车三种类型,然后分别生成不同的流量。
<?xml version="1.0" encoding="UTF-8"?>
<routes>
<vType id="car" accel="2.6" decel="4.5" sigma="0.5" length="4.5" maxSpeed="20.0" color="1,0,0"/>
<vType id="truck" accel="1.2" decel="3.0" sigma="0.3" length="10.0" maxSpeed="15.0" color="0,0,1"/>
<vehicle id="veh1" type="car" depart="0.0">
<route edges="edge1 edge2 edge3"/>
</vehicle>
<vehicle id="veh2" type="truck" depart="5.0">
<route edges="edge1 edge3"/>
</vehicle>
</routes>
这里有个坑,我踩过好几次——depart属性是出发时间,单位是秒。如果你想让车流均匀分布,可以用flow标签代替一个个写vehicle。比如:
<flow id="flow_car" type="car" begin="0" end="3600" period="2">
<route edges="edge1 edge2 edge3"/>
</flow>
这样每2秒发一辆车,持续1小时。省事多了。
避坑指南:我曾经在写路线时,把edge的顺序写反了。比如车从node1到node2,但路线里写的是"edge2 edge1"。结果SUMO报错说找不到路径。记住:路线必须按照道路连接顺序写,不能跳着写。
4.3 SUMO-GUI可视化操作
终于到了最直观的部分。SUMO-GUI是SUMO的图形界面,你可以在这里加载路网、运行仿真、查看车辆轨迹。
基本操作流程:
- 打开SUMO-GUI(命令行输入
sumo-gui) - 点击File → Open Network,选择你的.net.xml文件
- 再加载路线文件:File → Load Additional Files,选择.rou.xml
- 点击运行按钮(绿色三角)开始仿真
嗯,这里要注意:SUMO-GUI默认不会自动加载路线文件。我第一次用的时候,只加载了路网,点了半天运行按钮,一辆车都没有。后来才发现还要单独加载.rou.xml。
常用快捷键:
| 快捷键 | 功能 |
|---|---|
| Ctrl + D | 切换延迟模式(放慢仿真速度) |
| Ctrl + T | 切换交通灯显示 |
| 鼠标滚轮 | 缩放视图 |
| 按住鼠标中键拖动 | 平移视图 |
| Ctrl + Shift + I | 显示车辆信息面板 |
我个人最喜欢的功能是车辆信息追踪。在仿真运行时,双击任意一辆车,右侧面板会显示它的速度、加速度、位置、当前道路等信息。调试时特别好用。
实战建议:刚开始学的时候,先用SUMO自带的示例路网练手。在SUMO_HOME/docs/examples/sumo/目录下有很多现成的文件。加载进去,看看别人是怎么写的,再对照着改。我就是这么学会的。
还有一个实用技巧:在GUI里可以导出当前视图为图片。点击File → Export → Current View as Image,保存为PNG。做汇报或写文档时很有用。
注意:如果你的路网很大(比如整个城市),加载可能会慢。建议先用netconvert裁剪出感兴趣的区域。我做过一个全市路网仿真,加载花了5分钟,后来只截取了5km×5km的区域,10秒就加载完了。
好了,这一章的内容就到这里。路网文件、路线文件、GUI操作,这三样东西是SUMO仿真的基本功。你想想看,路网是舞台,路线是剧本,GUI就是导演监视器。三者配合好了,你的仿真就能演一出好戏。
记住:多动手,多试错。SUMO的报错信息其实挺友好的,仔细看都能找到问题所在。下一章我们会深入SUMO与CARLA的联合仿真配置,到时候这些基础都会用上。