4、交通需求生成:创建车辆类型(vType)、定义路线(routes)与流量(flows)

好,咱们继续。上一章我们把路网搭好了,但路上没车,这仿真就没意义。这一章,我们就来给这条路“注入灵魂”——生成交通需求。

说白了,就是告诉SUMO:什么样的车、走哪条路、什么时候出发、发多少辆。这三个要素,对应着三个核心概念:车辆类型(vType)、路线(route)和流量(flow)。

我个人习惯把这三者比作“演员、剧本和排期”。vType是演员的长相和性格,route是剧本规定的走位,flow就是排期表——什么时候上场、上场多少人。

4.1 车辆类型(vType)——定义车的“性格”

先说说vType。它不只是定义车长什么样,更重要的是定义车的驾驶行为。你想想看,一辆小轿车和一辆大卡车的加速能力、跟车距离能一样吗?

在SUMO里,vType通过一个XML文件来定义。我通常把它单独放在一个叫 vtypes.xml 的文件里,方便管理。

<!-- vtypes.xml -->
<vType id="passenger_car" 
       accel="2.6" 
       decel="4.5" 
       sigma="0.5" 
       length="4.5" 
       maxSpeed="50.0" 
       color="1,0,0"/>

<vType id="truck" 
       accel="1.2" 
       decel="3.0" 
       sigma="0.3" 
       length="12.0" 
       maxSpeed="30.0" 
       color="0,0,1"/>

这里有几个关键参数,我挑重要的说一下:

  • accel / decel:最大加/减速度。单位是m/s²。卡车肯定比小车慢半拍。
  • sigma:驾驶员的“不完美系数”。0是完美驾驶,1是随机摇摆。我一般设0.5,模拟真实路况。
  • length:车身长度。这个会影响跟车模型,别小看。
  • maxSpeed:最高速度。注意单位是m/s,不是km/h。50m/s就是180km/h,够用了。
  • color:RGB颜色。方便在仿真界面里区分车型。
我的小习惯: 我会把vType的id命名得清晰一点,比如“passenger_car”而不是“car1”。项目大了你就知道,命名规范能救你一命。

4.2 定义路线(routes)——画好“剧本”

路线就是车辆从哪出发、经过哪些路段、最终到哪。在SUMO里,路线由一系列边(edge)的ID组成。

还记得上一章我们建的简单路网吗?假设我们有两条边:edge1 和 edge2。那么一条从edge1到edge2的路线就是:

<!-- routes.xml -->
<route id="route_1_2" edges="edge1 edge2"/>

就这么简单?嗯,对于单条路线来说确实简单。但真实项目里,路线往往很复杂。我曾经在一个城市路网项目里,一条路线有30多个edge,手写能写到崩溃。

所以,我建议你用工具生成。SUMO自带的 duarouter 或 flowrouter 可以根据OD矩阵自动生成路线。后面章节我们会专门讲。

注意: 路线里的edge顺序必须连续,不能跳着走。比如你不能从edge1直接跳到edge3,如果它们不相连的话。SUMO会报错,而且报错信息有时候不太友好。我曾经被这个坑过,排查了半天。

4.3 流量(flows)——安排“排期”

有了演员和剧本,接下来就是排期了。流量(flow)定义的是:在某个时间段内,每隔多少秒发一辆车。

看个例子:

<!-- flows.xml -->
<flow id="flow_passenger" 
      type="passenger_car" 
      route="route_1_2" 
      begin="0" 
      end="3600" 
      vehsPerHour="600"/>

<flow id="flow_truck" 
      type="truck" 
      route="route_1_2" 
      begin="0" 
      end="3600" 
      probability="0.1"/>

这里有两个关键参数:

  • vehsPerHour:每小时车辆数。600veh/h就是平均6秒一辆。
  • probability:每秒钟发车的概率。0.1就是10%的概率。这个适合模拟随机车流。

你可能会问:这两个参数能混用吗?当然可以。我个人习惯:固定流量用vehsPerHour,随机流量用probability。比如主干道用固定流量,支路用随机流量,更真实。

核心要点: flow的begin和end是仿真时间,单位是秒。begin=0表示仿真一开始就发车,end=3600表示到第3600秒(1小时)停止发车。注意,已经发出的车会继续跑完。

4.4 整合文件——让一切跑起来

最后,我们需要一个主文件,把vType、route、flow都引进来。SUMO通常用 .rou.xml 作为后缀。

<!-- demand.rou.xml -->
<routes>
    <!-- 引入vType -->
    <include href="vtypes.xml"/>

    <!-- 定义路线 -->
    <route id="route_1_2" edges="edge1 edge2"/>

    <!-- 定义流量 -->
    <flow id="flow_passenger" 
          type="passenger_car" 
          route="route_1_2" 
          begin="0" 
          end="3600" 
          vehsPerHour="600"/>

    <flow id="flow_truck" 
          type="truck" 
          route="route_1_2" 
          begin="0" 
          end="3600" 
          probability="0.1"/>
</routes>

然后,在SUMO的配置文件 .sumocfg 里,把 demand.rou.xml 指定为输入文件即可。

避坑指南: 我曾经犯过一个低级错误——把vType定义写在了route定义之后。SUMO解析时是按顺序的,如果vType还没定义就引用,会报错。所以,vType一定要放在最前面。

4.5 知识体系图

为了让你更直观地理解这三者的关系,我画了一张图:

交通需求生成核心结构 vType 车辆类型 加速/减速/长度 颜色/最高速度 Route 行驶路线 边ID序列 edge1 → edge2 Flow 交通流量 开始/结束时间 vehsPerHour/概率 demand.rou.xml 最终输入SUMO仿真 三者缺一不可,共同构成完整的交通需求

从图上可以看得很清楚:vType和Route是Flow的“原料”,Flow把它们组合起来,加上时间参数,就生成了最终的交通需求文件。这个文件,就是SUMO仿真的“剧本”。

好了,这一章的内容就到这里。你只要记住:vType定义车、Route定义路、Flow定义量,三者配合,就能生成你想要的任何交通场景。

可可精品资料库