4. 路网导入与转换

在自动驾驶仿真中,路网是交通流运行的物理基础。SUMO虽然自带路网编辑器(netedit),但手工绘制大规模城市级路网既不现实也无必要。业界标准做法是从OpenStreetMap(OSM)获取真实地理数据,再通过SUMO的netconvert工具转换为SUMO可识别的路网文件(.net.xml)。然而,OSM数据是面向导航与地图展示的,并非为微观交通仿真设计,因此转换过程中必然面临交叉口几何失真、车道连接缺失、拓扑逻辑错误等问题。本章将系统讲解OSM数据获取、netconvert转换参数调优、复杂交叉口处理策略以及拓扑错误修正的完整方法论。

OSM→SUMO路网转换与拓扑修正工程链路 ① OSM数据获取 Overpass API / Geofabrik 导出 .osm 原始XML 边界裁剪 / 过滤 ② netconvert转换 --osm-files road.osm --output-file road.net.xml --geometry.remove --roundabouts ③ 交叉口处理 环岛 / 错位交叉口 车道数不匹配 信号灯相位缺失 ④ 拓扑修正 netedit 手动修复 连接关系重建 车道属性校准 验证与迭代 SUMO-GUI加载检查 → 车辆插入测试 → 流量标定 常见拓扑错误类型 ● 断头路(连接缺失) ● 车道方向反转 ● 交叉口内部冲突点 修正工具链 ● netconvert 参数调整 ● netedit 手动编辑 ● Python脚本批量修复 最终交付物 road.net.xml + 交叉口修正记录 + 验证报告 发现问题 → 返回修正(迭代循环)

上图展示了从OSM原始数据到SUMO可用路网的完整工程链路。整个过程并非一次性线性完成,而是需要经过“转换→检查→修正→再验证”的多次迭代。下面我们将分模块深入讲解每个环节的核心原理与操作要点。

4.1 OSM数据获取:从开放地图到仿真输入

核心原理

OpenStreetMap采用节点(Node)、路径(Way)和关系(Relation)三种基本元素描述地理实体。道路在OSM中通常表示为带有highway标签的Way,其属性包括道路等级(如primary、residential)、车道数(lanes)、单向信息(oneway)、限速(maxspeed)等。SUMO的netconvert能够解析这些标签并映射为SUMO内部的路网属性,但映射规则并非一一对应,需要理解其转换逻辑。

OSM标签SUMO属性转换说明
highway=primarytype="highway.primary"映射为城市主干道,默认限速50km/h
lanes=4lane数=4双向道路默认均分,单向需配合oneway
oneway=yes单向道路只生成单方向车道
maxspeed=60speed="16.67"单位从km/h转换为m/s
junction=roundabout环岛逻辑自动生成环岛内车道连接

操作流程

  1. 确定下载范围:使用Overpass API(https://overpass-api.de/api/interpreter)按边界框(bounding box)下载,或从Geofabrik(https://download.geofabrik.de/)下载城市级预裁剪文件。
  2. 过滤必要标签:原始OSM文件包含建筑、水系、铁路等无关数据,建议使用osmfilter或osmium工具过滤,仅保留highway相关元素。
  3. 导出为.osm格式:SUMO的netconvert直接读取OSM XML格式,无需额外转换。
经验提醒:下载时建议设置合理的边界范围。范围过大会导致转换后路网文件庞大(超过100MB),影响SUMO-GUI加载速度;范围过小则可能截断道路,造成边缘断头路。一般以仿真区域外扩500米为宜。

4.2 netconvert转换:参数配置与常见问题

核心原理

netconvert是SUMO的核心路网转换工具,其本质是将不同格式的地理数据(OSM、Shapefile、MATsim等)抽象为SUMO的微观路网模型。转换过程包括:几何形状简化(geometry.remove)、车道生成、交叉口节点合并、连接关系(connection)建立、交通信号灯映射等。理解netconvert的默认行为是调优的基础。

# 基础转换命令
netconvert --osm-files beijing_road.osm --output-file beijing_road.net.xml

# 常用参数组合
netconvert --osm-files beijing_road.osm \
           --output-file beijing_road.net.xml \
           --geometry.remove \
           --roundabouts.guess \
           --ramps.guess \
           --junctions.join \
           --tls.detect-signals \
           --tls.guess-signals \
           --tls.ignore-unknown-signals \
           --remove-edges.by-type "railway,waterway"

关键参数解析

  • --geometry.remove:移除冗余几何点,简化道路形状,减少路网文件大小。
  • --roundabouts.guess:自动识别OSM中的环岛结构并生成正确的内环连接。
  • --junctions.join:合并距离过近的交叉口节点,避免出现“微型交叉口”导致仿真异常。
  • --tls.detect-signals:从OSM的交通信号灯节点(highway=traffic_signals)生成SUMO信号灯。
  • --remove-edges.by-type:按OSM类型过滤不需要的道路(如铁路、人行道)。
风险提示:过度使用--geometry.remove可能导致道路形状失真,尤其在弯道和匝道处。建议保留--geometry.max-angle默认值(45度),避免出现锐角转折。

4.3 复杂交叉口处理:环岛、错位交叉与车道不匹配

核心原理

复杂交叉口是OSM转SUMO中最容易出现拓扑错误的环节。OSM中的交叉口仅表示道路相交的几何点,而SUMO需要明确的内部车道连接(edge-to-edge connections)来定义车辆转向路径。对于环岛、错位交叉口(两个T型交叉口距离过近)、车道数突变的交叉口,netconvert的自动处理往往不够完善。

案例拆解:某城市环岛转换失败与修复

背景与约束:某测试场景需要仿真一个五路环岛,OSM数据中环岛由5条Way组成,每条Way的junction=roundabout标签完整。初始转换后,SUMO-GUI中环岛内部出现大量断头连接,车辆无法完成绕行。

初始现象:使用默认参数转换后,环岛内部出现5个独立的“微型交叉口”,每个交叉口只连接相邻两条道路,车辆进入环岛后无法继续前行。

分析判断:netconvert未能正确识别环岛的整体结构,原因在于OSM中环岛的Way被分割为多段,且每段长度较短,默认的--junctions.join距离阈值(默认10米)未能将这些节点合并。

实际操作步骤:

  1. 使用--junctions.join-dist 25增大合并距离,使环岛内所有节点合并为一个交叉口。
  2. 添加--roundabouts.guess强制识别环岛结构。
  3. 转换后使用netedit打开,检查环岛内部连接,手动删除多余连接并重建正确的环形路径。

结果对比:修复后车辆能够顺畅完成环岛绕行,平均延误从修复前的15秒降至3秒。

风险与代价:增大--junctions.join-dist可能导致相邻但独立的交叉口被错误合并,需在转换后仔细检查。

复盘经验:对于复杂交叉口,不要完全依赖netconvert自动处理。建议转换后使用netedit的“连接模式”逐条检查关键交叉口的连接关系,特别是转向车道(left/right turn lanes)的匹配。

4.4 修正路网拓扑错误:netedit手动修复与批量处理

核心原理

拓扑错误是指路网中节点与边的关系不符合SUMO的仿真逻辑,包括:断头路(边的一端没有连接任何交叉口)、车道方向错误(车辆逆行)、交叉口内部冲突点(两条连接线交叉但无信号控制)、孤立节点等。这些错误会导致车辆在仿真中“消失”或产生异常轨迹。

判断方法

错误类型检测方法修复工具
断头路SUMO-GUI中车辆行驶到某点后消失netedit连接模式,手动连接缺失边
车道方向反转车辆逆行或无法进入某条道路netedit选择边,右键反转方向
交叉口冲突两股车流在交叉口内交叉但无信号灯添加信号灯或设置让行规则
孤立节点节点周围无任何边连接删除节点或连接周边道路

批量修正技巧

对于大规模路网,手动修复效率低下。可以使用Python脚本结合sumolib库进行批量检测与修正。例如,检测所有入度或出度为零的边:

import sumolib
net = sumolib.net.readNet('beijing_road.net.xml')
for edge in net.getEdges():
    if edge.getFromNode() is None or edge.getToNode() is None:
        print(f"断头路: {edge.getID()}")
    if edge.getLaneNumber() == 0:
        print(f"无车道边: {edge.getID()}")
风险提示:使用脚本批量修改路网前,务必备份原始.net.xml文件。错误的批量操作可能导致路网整体损坏,且难以回滚。

4.5 验证与迭代:确保路网可用性

核心原理

路网转换完成后,必须经过验证才能用于仿真。验证包括三个层次:结构验证(路网能否被SUMO正常加载)、逻辑验证(车辆能否完成基本行驶)、性能验证(路网容量与通行效率是否符合预期)。

操作流程

  1. 加载测试:使用sumo-gui beijing_road.net.xml打开路网,检查是否有错误提示。
  2. 随机车流测试:使用randomTrips.py生成100辆随机车辆,观察是否有车辆无法生成或中途消失。
  3. 关键路径测试:手动设置OD(起点-终点)对,验证特定路径(如环岛、立交桥)的通行能力。
  4. 性能标定:对比真实交通流量数据,调整路网容量(如车道数、限速)以匹配实际情况。
经验提醒:建议在路网转换过程中保留中间文件(如转换日志、参数配置文件),便于问题回溯。同时,建立路网版本管理机制,每次修改后记录变更内容,方便对比不同版本的路网性能差异。

通过以上系统化的流程,可以将OSM的开放地理数据高效转化为SUMO可用的高质量仿真路网。实际项目中,路网转换与修正往往占据整个仿真项目30%以上的工作量,但这是保证仿真结果可信度的必要投入。掌握netconvert的参数调优和netedit的手动修复技巧,能够显著提升路网质量,为后续的交通流仿真和自动驾驶算法测试奠定坚实基础。