4、路网编辑进阶:道路类型与限速设置、交叉口转向规则与信号灯配置、公交专用道与自行车道添加、路网可视化与错误检查

好,咱们继续往下走。上一节我们把路网的基本骨架搭起来了,能跑车了。但说实话,那个路网太「素」了,像个毛坯房。这一节,咱们要做的就是精装修——把道路类型、限速、转向、信号灯、公交专用道、自行车道这些细节全部怼进去。

我个人的习惯是,先把路网文件用文本编辑器打开看一眼,心里有个底。但真正动手改,还是得靠 netedit 或者直接写 .net.xml 的配置。别怕,咱们一步步来。

4.1 道路类型与限速设置

SUMO 里的道路类型,说白了就是给路贴个标签。比如主干道、次干道、支路、高速。每种类型可以有自己的默认限速、车道数、甚至外观颜色。

为什么要区分道路类型? 你想想看,如果所有路都一个速度,那仿真出来的车流跟现实差太远了。现实中没人会在小区里开 80 码,对吧?

在 .net.xml 里,道路类型定义在 <type> 标签里。举个例子:

<type id="highway.primary" priority="3" numLanes="2" speed="22.22" />
<type id="highway.secondary" priority="2" numLanes="1" speed="13.89" />
<type id="highway.residential" priority="1" numLanes="1" speed="8.33" />

这里 speed 的单位是 m/s。22.22 m/s 换算一下就是 80 km/h。我刚开始做项目时,经常忘记换算单位,结果仿真出来的车都像蜗牛爬。后来我学乖了,直接在脑子里记:除以 3.6 就是 m/s。

小技巧: 在 netedit 里,你可以直接选中一条路,然后在右侧属性面板里改 speed 字段。改完后记得点「保存」,不然白干。

如果你想让某条路单独限速,而不是跟着类型走,可以在 <edge> 里单独指定 speed 属性。比如:

<edge id="my_slow_road" from="node1" to="node2" type="highway.residential" speed="5.56"/>

这样,即使它属于 residential 类型,实际限速也只有 20 km/h。嗯,这里要注意:单独指定的限速会覆盖类型默认值。

4.2 交叉口转向规则与信号灯配置

交叉口是路网里最容易出幺蛾子的地方。我记得有一次,仿真跑着跑着,所有车都在一个路口堵死了。排查了半天,发现是转向规则没配好——左转车和直行车抢道,谁也不让谁。

SUMO 里,交叉口的转向规则由 <connection> 标签控制。它定义了从哪条路、哪个车道,可以转到哪条路、哪个车道。举个例子:

<connection from="edge1" to="edge2" fromLane="0" toLane="0" dir="s" state="M"/>

这里的 dir 是方向:s 直行,l 左转,r 右转。state 是信号灯状态:M 表示主路有优先权,m 表示支路需要让行,G 是绿灯,r 是红灯。

信号灯配置 稍微复杂一点。你需要先定义一个 <tlLogic>,然后给它配相位(phase)。每个相位里,哪些方向是绿灯,哪些是红灯,清清楚楚。

<tlLogic id="my_traffic_light" type="static" programID="0" offset="0">
  <phase duration="30" state="GGGrrr"/>
  <phase duration="5"  state="yyyrrr"/>
  <phase duration="30" state="rrrGGG"/>
  <phase duration="5"  state="rrryyy"/>
</tlLogic>

你看,state 字符串里每个字符对应一个信号灯组。G 是绿灯,y 是黄灯,r 是红灯。顺序跟你定义的连接顺序一致。我曾经犯过一个低级错误:相位时长写成了 300 秒,结果仿真里车等了 5 分钟红灯……嗯,从那以后我每次配信号灯都会反复检查时长。

避坑指南: 信号灯的 state 字符串长度必须跟你定义的连接数一致。少一个字符,SUMO 直接报错,不跟你商量。

4.3 公交专用道与自行车道添加

现在很多城市都在推公交优先、绿色出行。仿真里也得体现出来。SUMO 支持在道路上划出专用车道,比如公交专用道、自行车道。

实现方式其实很简单:在 <lane> 标签里加一个 allow 或 disallow 属性,限制哪些车辆类型可以使用该车道。

<lane id="my_road_0" index="0" allow="bus" speed="13.89"/>
<lane id="my_road_1" index="1" allow="bicycle" speed="8.33"/>
<lane id="my_road_2" index="2" allow="private" speed="13.89"/>

上面这个例子,车道 0 只允许公交车走,车道 1 只允许自行车走,车道 2 只允许私家车走。你想想看,这样仿真出来的场景,是不是跟现实里的公交专用道一模一样?

我个人建议,在添加公交专用道时,最好同时设置 busStop。不然公交车光跑不停,那还叫公交吗?

<busStop id="stop1" lane="my_road_0" startPos="50" endPos="70" lines="101 202"/>

这里 startPos 和 endPos 是公交站台在车道上的起止位置,单位是米。lines 是停靠的公交线路号。

小技巧: 自行车道可以跟机动车道共用,但最好单独划一条。不然自行车跟汽车混在一起,仿真里的车速会很难看。

4.4 路网可视化与错误检查

路网建好了,别急着跑仿真。先可视化检查一遍。SUMO 自带的 netedit 就是最好的检查工具。

打开 netedit,加载你的 .net.xml 文件。然后你可以:

  • 放大缩小,看看有没有断头路、孤立的节点。
  • 选中一条路,看它的属性对不对,限速、车道数、类型。
  • 检查交叉口,看转向箭头是不是都画出来了,有没有缺失的连接。

SUMO 还提供了一个命令行工具 netcheck,可以自动检测路网里的问题。用法很简单:

netcheck --net-file my_network.net.xml --output-file errors.xml

它会生成一个错误报告,告诉你哪些地方有问题。比如:

  • 某条路的 from 节点不存在
  • 某个交叉口的连接数不匹配
  • 某条车道的 allow 属性写错了

我记得有一次,我导出一个很大的路网,跑 netcheck 出来 200 多个警告。当时头都大了。但一个个排查下来,发现大部分都是小问题——比如节点坐标重复、车道长度不一致。修完之后,仿真就顺畅多了。

避坑指南: 不要忽略警告(warning)。虽然 SUMO 不会因为警告而崩溃,但警告往往意味着你的路网跟现实有偏差。比如「某条路限速过高」,仿真出来的车速就会失真。

最后,我强烈建议你养成一个习惯:每次修改路网后,都跑一遍 netcheck。这就像写代码要编译一样,能帮你省下大量调试时间。

路网编辑进阶知识体系 路网编辑进阶 道路类型与限速 type标签、speed属性 交叉口转向与信号灯 connection、tlLogic、phase 公交专用道与自行车道 allow/disallow、busStop 可视化与错误检查 netedit、netcheck 核心目标:让路网更贴近现实,仿真更可信

好了,这一节的内容就到这儿。路网编辑进阶,说白了就是让仿真更真实。你想想看,如果连道路类型、限速、信号灯这些基础东西都没配好,那后面的交通流生成、路径规划,全都是空中楼阁。

下一节我们会进入更刺激的部分——交通需求生成。到时候你会看到,怎么让车流真正「活」起来。

本节要点回顾:
  • 道路类型用 <type> 定义,限速单位是 m/s
  • 交叉口转向用 <connection> 控制,信号灯用 <tlLogic> + <phase>
  • 公交专用道和自行车道通过 allow / disallow 实现
  • 可视化用 netedit,错误检查用 netcheck,两者结合效果最佳
可可精品资料库