4、交通需求建模:车辆类型定义(.vtype.xml)、交通流定义(.flow.xml)、路线定义(.rou.xml)

好,咱们进入第四章。这一章可以说是整个SUMO仿真的“灵魂”所在——交通需求建模。说白了,就是告诉SUMO:路上跑的是什么车?它们从哪来、到哪去?怎么个跑法?

我个人习惯把这三兄弟称为“铁三角”:.vtype.xml(车辆类型)、.flow.xml(交通流)、.rou.xml(路线)。缺一个,仿真就跑不起来。嗯,咱们一个一个拆开讲。

核心逻辑:车辆类型定义“车长什么样”,交通流定义“车怎么来”,路线定义“车往哪走”。三者通过ID关联,形成一个完整的交通需求。

车辆类型定义 .vtype.xml 交通流定义 .flow.xml 路线定义 .rou.xml 通过ID关联,形成完整交通需求 车辆类型 → 交通流 → 路线 → 仿真运行

4.1 车辆类型定义(.vtype.xml)

先说说车辆类型。你想想看,仿真里如果所有车都长一个样、跑一个速度,那还仿真个啥?所以我们需要定义不同类型的车辆。

我在项目中遇到过这样一个坑:有一次做交叉口仿真,所有车都用默认参数,结果仿真出来的排队长度跟实际差了30%。后来才发现,是没区分小轿车和公交车——公交车又长又慢,排队当然不一样。

<!-- vtype.xml 示例 -->
<vType id="car" length="4.5" maxSpeed="60" accel="2.6" decel="4.5" sigma="0.5" color="blue"/>
<vType id="bus" length="12.0" maxSpeed="40" accel="1.2" decel="3.0" sigma="0.3" color="red"/>
<vType id="truck" length="10.0" maxSpeed="50" accel="1.5" decel="3.5" sigma="0.4" color="green"/>

这里几个关键参数我解释一下:

  • length:车身长度,单位米。小轿车一般4.5米,公交车12米,卡车10米。
  • maxSpeed:最大速度,单位km/h。注意SUMO内部用的是m/s,但这里写km/h它会自动转换。
  • accel/decel:加速度和减速度。公交车加速慢,所以设小一点。
  • sigma:驾驶员的“不完美程度”。0表示完美驾驶,1表示随机乱开。我一般设0.5,比较真实。
  • color:仿真时车辆的颜色,方便区分。

小技巧:如果你做的是传感器仿真,建议给不同类型的车加上不同的“传感器配置”属性。比如自动驾驶轿车可以加激光雷达,普通车就不加。这个后面章节会细讲。

4.2 交通流定义(.flow.xml)

车辆类型定义好了,接下来就是告诉SUMO:这些车什么时候出现?出现多少?这就是交通流干的事。

说白了,交通流就是“车流的水龙头”。你拧多大、拧多久,决定了路上有多少车。

<!-- flow.xml 示例 -->
<flows>
    <flow id="flow_car_1" type="car" begin="0" end="3600" number="500" from="edge_in" to="edge_out"/>
    <flow id="flow_bus_1" type="bus" begin="300" end="3600" period="600" from="edge_in" to="edge_out"/>
    <flow id="flow_truck_1" type="truck" begin="0" end="3600" probability="0.1" from="edge_in" to="edge_out"/>
</flows>

这里有几个关键属性:

属性 含义 示例
begin / end 车流开始和结束时间(秒) begin="0" end="3600" 表示仿真第1小时
number 总共生成多少辆车 number="500" 表示生成500辆
period 每多少秒生成一辆车 period="600" 表示每10分钟一辆
probability 每秒生成的概率(0~1) probability="0.1" 表示每秒10%概率
from / to 起始边和目的边 from="edge_in" to="edge_out"

注意:number、period、probability这三个属性是互斥的,只能选一个。我曾经犯过同时写number和period的错,结果SUMO直接报错,排查了半天才发现。

4.3 路线定义(.rou.xml)

路线定义是最后一块拼图。它告诉SUMO:车辆从哪条路进去,经过哪些路段,最后从哪出去。

我个人习惯把路线定义和车辆类型、交通流分开写,这样结构清晰。当然你也可以全部写在一个文件里,但项目大了以后会很难维护。

<!-- rou.xml 示例 -->
<routes>
    <vType id="car" length="4.5" maxSpeed="60" accel="2.6" decel="4.5" sigma="0.5" color="blue"/>
    <vType id="bus" length="12.0" maxSpeed="40" accel="1.2" decel="3.0" sigma="0.3" color="red"/>

    <route id="route_main" edges="edge_in edge_mid edge_out"/>
    <route id="route_side" edges="edge_in edge_side edge_out"/>

    <flow id="flow_car_main" type="car" begin="0" end="3600" number="500" route="route_main"/>
    <flow id="flow_bus_main" type="bus" begin="300" end="3600" period="600" route="route_main"/>
    <flow id="flow_truck_side" type="truck" begin="0" end="3600" probability="0.1" route="route_side"/>
</routes>

看到没?这里我把vType、route、flow全部写在一个.rou.xml文件里了。这样做的好处是:一个文件搞定所有,适合小项目。但如果是大型仿真,我建议还是分开写,然后用<include>引入。

<!-- 使用include引入 -->
<routes>
    <include href="#" aria-disabled="true" data-keke-missing-local-link="1" onclick="return false"/>
    <include href="#" aria-disabled="true" data-keke-missing-local-link="1" onclick="return false"/>
    <route id="route_main" edges="edge_in edge_mid edge_out"/>
</routes>

4.4 实战:把三兄弟串起来

好,理论讲完了,咱们来点实际的。假设我们要仿真一个十字路口,有直行和左转两种车流,该怎么写?

我记得有一次做项目,甲方要求仿真早高峰的十字路口。我一开始只定义了直行车流,结果仿真出来的拥堵位置跟实际完全对不上。后来加了左转车流,才匹配上。你看,细节决定成败。

<!-- 完整示例:十字路口交通需求 -->
<routes>
    <!-- 车辆类型 -->
    <vType id="car" length="4.5" maxSpeed="60" accel="2.6" decel="4.5" sigma="0.5" color="blue"/>
    <vType id="suv" length="4.8" maxSpeed="55" accel="2.2" decel="4.0" sigma="0.4" color="green"/>

    <!-- 路线 -->
    <route id="route_straight" edges="north_entry north_mid south_mid south_exit"/>
    <route id="route_left" edges="north_entry north_mid west_mid west_exit"/>

    <!-- 交通流 -->
    <flow id="flow_straight" type="car" begin="0" end="3600" number="800" route="route_straight"/>
    <flow id="flow_left" type="suv" begin="0" end="3600" number="200" route="route_left"/>
</routes>

避坑指南:我曾经把路线里的边顺序写反了,结果车辆一出生就往反方向跑。所以写路线时,一定要按照车辆行驶的方向,从入口到出口依次列出边ID。

4.5 小结

这一章咱们把交通需求建模的“铁三角”讲透了。你想想看,有了车辆类型、交通流和路线,SUMO就知道路上跑什么车、什么时候来、往哪走了。这就是仿真的基础。

下一章咱们会讲如何把这些文件加载到SUMO里,以及如何用netedit可视化查看。嗯,到时候见。

核心要点回顾:

  • .vtype.xml:定义车辆物理属性和行为参数
  • .flow.xml:定义车流的时间分布和数量
  • .rou.xml:定义车辆的行驶路径
  • 三者通过ID关联,缺一不可
  • 大型项目建议用<include>拆分文件
可可精品资料库