3、路网基础概念:节点(Node)与边(Edge)、车道(Lane)与连接(Connection)、路网文件格式(.net.xml)解析
好,咱们今天聊聊路网。很多刚接触仿真的人,上来就想着怎么让车跑起来,结果路网画得乱七八糟,仿真一跑就崩。我当年也踩过这个坑——花了一周搭的场景,最后发现是路网拓扑连错了,车全堵在路口出不去。
说白了,路网就是交通仿真的骨架。骨架歪了,肌肉再发达也没用。今天我把最核心的三个概念掰开揉碎讲清楚:节点与边、车道与连接,还有那个让人头疼的 .net.xml 文件。
3.1 节点(Node)与边(Edge)
先问个问题:一条路,在仿真里怎么表示?
答案是:节点 + 边。
- 节点(Node):路的端点,或者路口。你可以把它想象成一个点,记录着坐标 (x, y)。
- 边(Edge):连接两个节点的路段。它是有方向的,从起点节点指向终点节点。
举个例子。一条从 A 到 B 的直路,就是节点 A → 边 → 节点 B。一个十字路口,就是四条边汇聚到一个中心节点上。
核心要点:节点只负责定位,边只负责连接。车流是在边上跑的,但转向决策是在节点处完成的。
我个人习惯,在画路网之前,先把所有关键路口的位置标出来,作为节点。然后再用边把它们连起来。这样思路清晰,不容易乱。
3.2 车道(Lane)与连接(Connection)
一条边,可以包含多条车道。比如一条双向六车道的主干道,在仿真里就是两条边(方向相反),每条边包含三条车道。
车道本身有编号,从 0 开始,最右边是 0,往左依次递增。这个编号很重要,因为连接(Connection)就是基于车道编号来定义的。
连接,说白了就是告诉仿真:车从这条车道上开过来,到了路口,能拐到哪条车道上去?
举个例子,一个十字路口,南向北的直行车道(车道 1),到了路口可以直行到北向南的直行车道(车道 1),也可以左转到西向东的左转车道(车道 0)。
我的经验:连接是最容易出错的地方。我曾经因为漏配了一条左转连接,结果仿真里所有左转车都在路口原地打转,死活拐不过去。排查了整整一下午。
连接的定义,通常包含以下信息:
- 来自哪条边的哪个车道
- 去往哪条边的哪个车道
- 转向类型(直行、左转、右转、掉头)
- 是否允许变道
3.3 路网文件格式(.net.xml)解析
好了,理论讲完了,咱们看看实际的文件长什么样。SUMO 的路网文件是 .net.xml,说白了就是一个 XML 文件。你直接用文本编辑器打开就能看。
我带你快速过一遍核心结构:
<?xml version="1.0" encoding="UTF-8"?>
<net version="1.16" junctionCornerDetail="5" limitTurnSpeed="5.50">
<!-- 1. 位置信息 -->
<location netOffset="0.00,0.00" convBoundary="0.00,0.00,1000.00,500.00" />
<!-- 2. 边定义 -->
<edge id="edge_1" from="node_1" to="node_2" priority="1">
<lane id="edge_1_0" index="0" speed="13.89" length="200.00" shape="0.00,0.00 200.00,0.00"/>
<lane id="edge_1_1" index="1" speed="13.89" length="200.00" shape="0.00,3.20 200.00,3.20"/>
</edge>
<!-- 3. 节点定义 -->
<junction id="node_1" type="priority" x="0.00" y="0.00" incLanes="..." intLanes="..." shape="..."/>
<junction id="node_2" type="priority" x="200.00" y="0.00" incLanes="..." intLanes="..." shape="..."/>
<!-- 4. 连接定义 -->
<connection from="edge_1" to="edge_2" fromLane="0" toLane="0" dir="s" state="M"/>
<connection from="edge_1" to="edge_2" fromLane="1" toLane="1" dir="s" state="M"/>
</net>
咱们拆开来看:
| 标签 | 作用 | 关键属性 |
|---|---|---|
| <net> | 根节点,定义全局参数 | version, junctionCornerDetail |
| <location> | 路网的地理位置和偏移 | netOffset, convBoundary |
| <edge> | 定义一条边(路段) | id, from, to, priority |
| <lane> | 边上的具体车道 | id, index, speed, length, shape |
| <junction> | 定义节点(路口) | id, type, x, y, incLanes |
| <connection> | 定义车道之间的连接关系 | from, to, fromLane, toLane, dir |
注意:.net.xml 文件通常不是手写的,而是通过 SUMO 的 netedit 工具或者 netconvert 命令生成的。但理解它的结构,能帮你快速排查问题。比如车流不按预期走,十有八九是 connection 配错了。
嗯,这里还要提一句。shape 属性定义了车道的几何形状。如果是直线,就是两个点;如果是弯道,就是一系列点组成的折线。你想想看,如果 shape 写错了,车就会在路面上漂移,画面很诡异。
3.4 避坑指南
最后,分享几个我实战中遇到的坑:
- 节点坐标别乱填:两个节点距离太近,车道长度会变成负数,仿真直接报错。
- 连接别漏配:尤其是掉头连接,很多新手会忘。车到了路口想掉头,发现没路可走,直接卡死。
- 车道编号别搞混:记住,最右边是 0,往左递增。连接时 fromLane 和 toLane 要对齐,否则车会跨车道乱窜。
- 速度单位是 m/s:不是 km/h。我见过有人把 60 km/h 写成 60 m/s,结果车跑得跟火箭一样。
好了,路网基础就讲到这里。下一章咱们聊聊怎么用 netedit 可视化地画路网,比手写 XML 爽多了。