4. 路网编辑进阶:添加车道数、设置车道方向、配置限速和优先权规则

好,咱们继续。上一章我们把路网的基本骨架搭起来了,说白了就是画了几条路,让车能跑起来。但真实的路网哪有这么简单?你想想看,城市主干道至少双向四车道吧,有的路口只能右转,有的路段限速60,有的路口谁先走谁后走……这些才是自动驾驶仿真里真正要较真的细节。

我个人习惯,在SUMO里编辑路网,从来不用那个图形界面点点点——太慢了,而且不好复现。我更喜欢直接撸XML,或者用netedit配合命令行。今天咱们就聊聊,怎么给路网“加料”。

4.1 添加车道数:别让车堵在一条道上

默认情况下,你在SUMO里画一条边(edge),它只有一条车道。这在测试单车道乡村道路时没问题,但你要模拟城市快速路,一条车道肯定不够。

在.net.xml文件里,每条边由<edge>标签定义,车道信息藏在<lane>子标签里。但更直接的方式,是在定义边的时候指定numLanes属性。

核心参数:

  • numLanes:车道数量,整数。
  • speed:该车道允许的最大速度,单位m/s。
  • length:边的长度,单位米。

举个例子,我想建一条双向六车道的城市主干道,单向三车道,限速60km/h(约16.67m/s)。代码长这样:

<edge id="main_road_east" from="node1" to="node2" numLanes="3" speed="16.67" />
<edge id="main_road_west" from="node2" to="node1" numLanes="3" speed="16.67" />

嗯,这里要注意:SUMO里边的方向是单向的。你要做双向路,就得定义两条方向相反的边。我在项目里见过新手只定义了一条边,结果车全往一个方向跑,另一个方向空空如也——那仿真肯定不对。

小技巧: 如果你用netedit图形界面,选中一条边,在右侧属性面板里直接改numLanes就行。但我还是推荐写脚本批量生成,尤其是大路网,手点能点到手抽筋。

4.2 设置车道方向:哪个车道能左转?哪个只能直行?

车道方向,专业术语叫“转向连接”(turn connections)。它决定了车辆在路口能不能左转、右转、直行或者掉头。

我曾经在一个项目中,因为没配转向连接,所有车到了路口全部直行,死活不转弯。排查了半天,才发现是连接没定义。说白了,SUMO默认路口所有方向都禁止通行,你得手动“放行”。

转向连接定义在<connection>标签里,放在<edge>下面。基本语法:

<connection from="edge_in" to="edge_out" fromLane="0" toLane="0" dir="r" />

参数说明:

属性 含义 取值示例
from 进入路口的边ID main_road_east
to 离开路口的边ID side_road_north
fromLane 从哪条车道出来(从0开始) 0, 1, 2
toLane 进入目标边的哪条车道 0, 1
dir 转向方向 s(直行), l(左转), r(右转), t(掉头)

举个例子,一个十字路口,东向西方向最左侧车道(车道0)允许左转,中间车道(车道1)允许直行:

<connection from="east_in" to="north_out" fromLane="0" toLane="0" dir="l" />
<connection from="east_in" to="west_out" fromLane="1" toLane="0" dir="s" />

避坑指南: 我曾经犯过一个错——把fromLane和toLane搞反了。结果车从最右侧车道左转,直接骑到对向车道上去。记住:fromLane是当前边的车道编号,toLane是目标边的车道编号。车道编号都是从0开始,最右侧是0。

4.3 配置限速:不同车道不同速度

限速这事,在SUMO里可以精细到每条车道。你想想看,城市快速路最左侧车道限速100,最右侧因为有汇入车辆,限速80,这很常见吧?

在<lane>标签里直接设置speed属性即可。如果你用<edge>的speed属性,那所有车道速度都一样。要精细控制,就得显式写出每个<lane>。

<edge id="highway_east" from="n1" to="n2" numLanes="3">
  <lane index="0" speed="22.22" />  <!-- 最右侧,限速80km/h -->
  <lane index="1" speed="25.00" />  <!-- 中间,限速90km/h -->
  <lane index="2" speed="27.78" />  <!-- 最左侧,限速100km/h -->
</edge>

注意,SUMO里速度单位是m/s,别直接写80。换算公式:km/h ÷ 3.6 = m/s。80km/h ≈ 22.22m/s。我刚开始做的时候,直接写了个80,结果车跑得跟飞机一样快……

4.4 优先权规则:谁先走谁后走

优先权,说白了就是路权。没有信号灯的路口,谁该让谁?SUMO里用priority属性来控制。

优先权值越高,在该路口越有优先通行权。默认值是-1,表示未定义。通常主路优先权高,支路优先权低。

设置方式有两种:

  • 在<edge>上设置:该边所有车道统一优先权。
  • 在<junction>的<request>里设置:更精细,可以控制每个转向的优先级。

简单场景,我们直接在边上设:

<edge id="main_road" from="n1" to="n2" priority="3" />
<edge id="side_road" from="n3" to="n4" priority="1" />

这样,主路上的车在路口不用让行,支路上的车必须等主路没车了才能走。

实际项目经验: 我在做园区无人配送车仿真时,就靠这个优先权规则模拟了“主路先行”的场景。配送车从支路出来,遇到主路有车就自动停车等待,效果非常真实。但要注意,优先权只适用于无信号灯路口。如果有红绿灯,优先权设置会被覆盖。

4.5 知识体系总览

说了这么多,咱们用一张图把今天的内容串起来。这张图是我自己画的知识结构,你一看就明白这些参数之间的关系了。

路网编辑进阶 添加车道数 numLanes 属性 双向需定义两条边 车道方向 <connection> 标签 dir: s/l/r/t 配置限速 speed 属性 (m/s) 可精细到每条车道 优先权规则 priority 属性 值越高越优先 核心逻辑 车道数决定通行能力 方向决定路径选择 → 限速决定行驶速度 → 优先权决定路口通行规则

这张图把今天讲的四个核心点串起来了。你配置路网的时候,按这个顺序来,基本不会漏东西。

4.6 实战小练习

光看不练假把式。我给你留个小任务:

  1. 创建一个十字路口,东西方向是双向四车道主路(限速60km/h),南北方向是双向两车道支路(限速40km/h)。
  2. 配置转向连接:主路最左侧车道可以左转,中间两车道直行,最右侧车道右转。
  3. 设置优先权:主路优先权为3,支路为1。

做完这个练习,你对路网编辑的基本功就算扎实了。下次咱们聊信号灯和检测器,那又是另一番天地。

最后说一句: 路网编辑这事,熟能生巧。我刚开始也是对着XML一行行改,后来写了个Python脚本批量生成,效率高多了。等你把基础搞熟了,也可以试试自动化生成路网。

可可精品资料库