3. SUMO基础概念:路网、车辆、交通流、路线、探测器

好,咱们正式开始接触SUMO的核心概念了。说实话,我刚接触SUMO那会儿,看着一堆英文术语也有点懵。但后来我发现,只要把几个关键概念搞明白,整个仿真系统就像搭积木一样清晰。

这一章,我就带你逐个拆解:路网(Network)、车辆(Vehicle)、交通流(Flow)、路线(Route)、探测器(Detector)。这些都是你以后天天打交道的对象。

SUMO 仿真核心 路网 Network 车辆 Vehicle 交通流 Flow 路线 Route 探测器 Detector 输出数据 Output 五个核心概念相互关联,构成完整的仿真流程

3.1 路网(Network)——仿真的骨架

路网是什么?说白了,就是车辆跑的那张「地图」。它由节点(Node/Junction)和边(Edge)组成。节点就是路口,边就是路段。

我个人习惯把路网文件想象成一张「交通骨架图」。你可以在SUMO里用 netedit 可视化工具直接画,也可以从OpenStreetMap导入真实路网。

路网文件(.net.xml)的核心结构:

<?xml version="1.0" encoding="UTF-8"?>
<net version="1.19" junctionCornerDetail="5">
    <edge id="edge1" from="node1" to="node2" priority="1" numLanes="2" speed="13.89"/>
    <edge id="edge2" from="node2" to="node3" priority="1" numLanes="1" speed="11.11"/>
    <junction id="node1" x="0.0" y="0.0" type="priority"/>
    <junction id="node2" x="500.0" y="0.0" type="priority"/>
    <junction id="node3" x="1000.0" y="0.0" type="priority"/>
</net>

这里要注意:speed 的单位是 m/s,不是km/h。13.89 m/s 换算过来就是 50 km/h。嗯,这个坑我刚开始踩过,仿真出来的车速怎么都不对,后来才发现是单位搞错了。

💡 我的小技巧: 如果你从OpenStreetMap导入路网,记得用 netconvert 工具做一次「清理」。真实路网有很多细碎的小路,仿真时反而会影响性能。我一般会过滤掉 residential 类型的道路。

3.2 车辆(Vehicle)——仿真的主角

车辆就是路上跑的那些小东西。在SUMO里,每辆车都有自己的ID、类型、出发时间和路线。

车辆类型(vType)可以定义很多参数:长度、最大速度、加速度、甚至驾驶行为(比如跟车模型)。

<vType id="car_passenger" length="4.5" maxSpeed="20.0" accel="2.6" decel="4.5" sigma="0.5"/>
<vehicle id="veh1" type="car_passenger" depart="0.0" route="route1"/>

你看,上面定义了一辆小轿车,长4.5米,最高速度20m/s(72km/h),加速度2.6m/s²。这个参数其实挺接近真实家用车的。

我记得有一次做高速公路仿真,默认的车辆长度是2.5米(自行车参数),结果车流密度算出来完全不对。后来改成4.5米,数据一下子就合理了。所以车辆参数一定要根据实际情况调。

3.3 路线(Route)——车辆怎么走

路线就是车辆从起点到终点经过的一系列路段(edge)。你可以手动指定,也可以让SUMO自动计算最短路径。

<route id="route1" edges="edge1 edge2 edge3"/>

上面这个路线,车辆会从 edge1 出发,经过 edge2,最后到 edge3。就这么简单。

但实际项目中,路线往往很复杂。比如一个城市路网可能有上千条路段,手动写路线不现实。这时候我会用 duarouter 工具,输入OD矩阵(起点-终点流量),自动生成所有车辆的路线。

⚠️ 避坑指南: 我曾经犯过一个错误——给车辆指定的路线里,路段之间没有连接(junction)。结果仿真报错,车辆卡在路口不动。记住:路线里的路段必须首尾相连,中间不能断开。

3.4 交通流(Flow)——批量生成车辆

如果你要仿真1000辆车,难道要写1000个 <vehicle> 标签?当然不用。这时候就用 Flow。

交通流可以定义:从哪里出发、走哪条路线、每小时多少辆车、从什么时候开始到什么时候结束。

<flow id="flow1" route="route1" begin="0" end="3600" vehsPerHour="600" type="car_passenger"/>

上面这个流,从第0秒到第3600秒(1小时),每小时生成600辆车,走 route1 路线。SUMO会自动在时间轴上均匀分布这些车辆的出发时间。

我个人觉得,Flow 是SUMO里最实用的概念之一。做交通仿真,你很少关心「某一辆车」,你关心的是「一群车」的整体行为。流量、密度、速度,这些宏观指标才是关键。

3.5 探测器(Detector)——收集数据

仿真跑完了,怎么知道结果?靠探测器。

SUMO里有好几种探测器,最常用的是感应线圈(E1 Detector)和路段探测器(E2 Detector)。

  • E1 Detector:放在某个位置,统计经过的车辆数、平均速度。
  • E2 Detector:覆盖一段路段,统计密度、流量、平均速度。
  • 出口探测器(E3 Detector):监控一个区域(比如停车场)的进出车辆。
<e1Detector id="det1" lane="edge1_0" pos="50.0" freq="60" file="output_det1.xml"/>

上面这个探测器放在 edge1 的第0车道,距离路段起点50米的位置。每60秒输出一次数据,保存到 output_det1.xml 文件里。

💡 我的经验: 探测器不要放得太密,否则输出文件会很大。我一般每200-300米放一个E1探测器,关键路段(比如匝道口)会加密到100米。另外,freq 参数我习惯设成60秒或300秒,太短了数据波动大,太长了看不出变化趋势。

3.6 它们怎么配合?

好,现在我们把五个概念串起来,看看一个完整的仿真流程是什么样的:

  1. 路网:先有路网,车辆才有地方跑。
  2. 路线:在路网上定义一条或多条路线。
  3. 车辆/交通流:让车辆按照路线行驶,可以用单个车辆,也可以用交通流批量生成。
  4. 探测器:在路网上放置探测器,收集仿真过程中的数据。
  5. 输出:仿真结束后,从探测器输出文件里提取数据,分析结果。

你看,逻辑其实很清晰。就像搭积木一样,一块一块拼起来。

一个完整的仿真配置文件(.sumocfg)示例:

<configuration>
    <input>
        <net-file value="mynet.net.xml"/>
        <route-files value="myroutes.rou.xml"/>
        <additional-files value="mydetectors.add.xml"/>
    </input>
    <time>
        <begin value="0"/>
        <end value="3600"/>
    </time>
</configuration>

这个配置文件告诉SUMO:用 mynet.net.xml 作为路网,用 myroutes.rou.xml 定义车辆和路线,用 mydetectors.add.xml 放置探测器,仿真从0秒跑到3600秒。

嗯,到这里,SUMO的五个核心概念你应该心里有数了。下一章我们会动手写第一个仿真文件,到时候这些概念都会用上。

⚠️ 最后提醒一句: 初学者最容易犯的错误是「路网和路线不匹配」。比如路网里根本没有叫 edge1 的路段,但路线里却写了。SUMO会直接报错退出。所以每次修改路网后,记得检查路线文件里的路段ID是否还存在。


可可精品资料库