4. 交通需求建模:.rou.xml 文件深度解析

各位同学,今天我们来聊聊交通需求建模。说白了,就是告诉仿真软件:路上跑的都是什么车?从哪来?到哪去?这些信息都写在 .rou.xml 文件里。我个人习惯把这个文件叫做「剧本」——它定义了整个仿真世界的「演员」和「剧情」。

核心要点:.rou.xml 文件 = 车辆类型定义 + 车流生成器 + 路径定义 + 随机路径

4.1 文件结构长什么样?

先看一个最简单的 .rou.xml 骨架:

<?xml version="1.0" encoding="UTF-8"?>
<routes>
    <!-- 车辆类型定义 -->
    <vType id="car" accel="2.6" decel="4.5" maxSpeed="50" />
    
    <!-- 路径定义 -->
    <route id="route1" edges="edge1 edge2 edge3" />
    
    <!-- 车流生成器 -->
    <flow id="flow1" type="car" route="route1" begin="0" end="3600" vehsPerHour="600" />
</routes>

嗯,这里要注意:<routes> 是根标签,所有定义都包在里面。我见过新手把标签名写错成 <route>,结果仿真器直接报错——这种低级错误排查起来最浪费时间。

4.2 车辆类型定义:给车「画像」

车辆类型用 <vType> 标签定义。为什么需要这个?你想想看,路上跑的小轿车和公交车,加速能力、最大速度、车身长度能一样吗?

属性 说明 典型值(小轿车)
id 类型名称,唯一标识 "car"
accel 最大加速度 (m/s²) 2.6
decel 最大减速度 (m/s²) 4.5
maxSpeed 最大速度 (m/s) 50(约180km/h)
length 车身长度 (m) 5.0
sigma 驾驶随机性(0=完美,1=随机) 0.5

我的经验:sigma 参数很多人忽略。我曾经调一个拥堵仿真,怎么跑都不堵车,后来把 sigma 从 0.1 调到 0.5,瞬间就真实了——因为现实中司机不可能都完美驾驶。

定义多种车辆类型也很简单:

<vType id="car" accel="2.6" decel="4.5" maxSpeed="50" length="5.0" sigma="0.5" />
<vType id="bus" accel="1.2" decel="3.0" maxSpeed="30" length="12.0" sigma="0.3" />
<vType id="truck" accel="1.0" decel="2.5" maxSpeed="25" length="15.0" sigma="0.4" />

4.3 车流生成器:让车「流」起来

手动一辆一辆发车?太傻了。用 <flow> 标签,一句话就能生成上千辆车。

<flow id="flow_main" type="car" route="route1" begin="0" end="3600" vehsPerHour="1200" />

参数解读:

  • id:这个车流的名字,方便后面引用或修改
  • type:引用上面定义的车辆类型
  • route:引用下面定义的路径
  • begin / end:发车时间窗口(秒),0 到 3600 就是仿真开始后第一小时
  • vehsPerHour:每小时发车数,1200 就是平均 3 秒一辆

避坑指南:我曾经把 vehsPerHour 写成 10000,结果仿真器直接卡死——车太多,路网根本消化不了。建议先从小流量开始调试,逐步增加。

还可以用 probability 替代 vehsPerHour,按概率发车:

<flow id="flow_random" type="car" route="route1" begin="0" end="3600" probability="0.1" />

这个 0.1 表示每个仿真步(默认 1 秒)有 10% 的概率发一辆车。适合模拟随机到达的交通流。

4.4 路径定义:给车指路

路径用 <route> 标签定义。说白了就是告诉车:按什么顺序经过哪些路段。

<route id="route_A_to_B" edges="edge1 edge2 edge3 edge4" />
<route id="route_A_to_C" edges="edge1 edge5 edge6" />

这里 edges 属性里写的是路网文件中定义的路段 ID,用空格分隔。车会从第一个路段进入,依次经过,最后在最后一个路段消失。

我建议路径命名要有规律,比如 route_起点_终点,不然几十条路径混在一起,后期维护起来想哭。

4.5 随机路径:让车自己「选路」

有时候我们不想指定具体路径,想让车在路网中随机游走。这时候用 <routeDistribution> 或者直接在 flow 里用 from 和 to 属性。

方法一:路径分布

<routeDistribution id="random_routes">
    <route id="r1" edges="edge1 edge2 edge3" probability="0.5" />
    <route id="r2" edges="edge1 edge4 edge5" probability="0.3" />
    <route id="r3" edges="edge1 edge6" probability="0.2" />
</routeDistribution>

<flow id="flow_random" type="car" route="random_routes" begin="0" end="3600" vehsPerHour="600" />

方法二:只指定起终点(需要路网支持)

<flow id="flow_od" type="car" from="edge1" to="edge5" begin="0" end="3600" vehsPerHour="800" />

仿真器会自动计算最短路径。嗯,这里要注意:如果路网中有拥堵,最短路径可能不是最优的——但这是另一个话题了。

4.6 知识体系总览

下面这张图帮你理清本章的核心逻辑:

交通需求建模核心结构 .rou.xml 文件 车辆类型定义 <vType> 车流生成器 <flow> 路径定义 <route> accel/decel maxSpeed sigma vehsPerHour probability begin/end 固定路径 随机路径 OD对 三者组合使用,即可构建任意复杂的交通需求场景 vType + flow + route = 完整的交通需求模型

4.7 实战小贴士

最后分享几个我踩过的坑:

  • ID 不要用中文:XML 解析器对中文支持不好,老老实实用英文或拼音
  • 先验证再跑仿真:用 sumo -c your.sumocfg --validate 检查文件语法
  • 流量从低到高:先跑 100 vehsPerHour 看看路网能不能通,再逐步加到目标值
  • 路径别写错:edges 里的路段 ID 必须在 .net.xml 中存在,否则车发不出来

我的习惯:每次修改 .rou.xml 后,先用 sumo-gui 打开跑 10 秒看看效果。肉眼确认没问题了,再跑批量仿真。这比盯着日志文件找错误高效多了。

好了,这一章的内容就到这里。记住:交通需求建模是仿真的灵魂——路网再漂亮,车流定义错了,结果全是废的。下一章我们聊聊如何用 Python 动态生成 .rou.xml,实现更灵活的交通需求控制。

可可精品资料库