4. OpenDRIVE文件结构

OpenDRIVE 文件本质上是一个遵循 XML 规范的文本文件,其全部道路网络信息都组织在一棵具有严格层级关系的元素树中。理解这棵树的根、主干与分支,是后续进行道路几何建模、交叉口设计、信号控制配置以及仿真验证的基础。本节从 XML 根元素出发,逐层剖析 header、road、junction、controller、station 等主要节点的作用、属性与嵌套关系,帮助读者建立“文件即结构、结构即语义”的整体认知。

一、核心原理:OpenDRIVE 的 XML 树形结构

OpenDRIVE 采用单一根元素 <OpenDRIVE> 包裹全部内容,根元素下通常包含 <header> 以及若干条 <road>、<junction>、<controller> 等顶层节点。这些顶层节点之间并非简单并列,而是通过 id、junction、link 等属性相互引用,形成一张“树 + 图”的混合结构:树形层级保证文件可解析,引用关系保证道路网络可连通。

从语义上看,<header> 描述整个数据集的身份与坐标基准;<road> 描述一条道路的参考线、车道、高程与附属物;<junction> 描述多条道路交汇形成的连接区域;<controller> 描述信号灯等控制设备的逻辑;<station> 则用于沿道路参考线定义里程桩号或特定位置。它们共同构成一个可被仿真器、规划器或可视化工具直接消费的道路网络描述。

关键理解:OpenDRIVE 的层级关系不是“谁包含谁”那么简单,而是“谁定义几何、谁定义连接、谁定义控制”的职责分离。road 负责几何与车道,junction 负责连接,controller 负责控制,header 负责全局基准。

二、主要节点层级与职责

下面按从根到叶的顺序,梳理各主要节点的层级关系与核心职责。

  • <OpenDRIVE>:根元素,声明文件版本与命名空间,所有其他元素均在其内部。
  • <header>:全局头信息,包含 revMajor、revMinor、name、version、date、north、south、east、west、geoReference 等属性,定义地图范围与坐标参考系。
  • <road>:道路主体,包含 planView(参考线几何)、elevationProfile(高程)、lateralProfile(横断面)、lanes(车道)、objects(附属物)、signals(信号)、surface(路面)等子节点。
  • <junction>:交叉口,包含 connection 子节点,每个 connection 通过 incomingRoad 与 connectingRoad 描述进入道路与连接道路,并通过 contactPoint 与 laneLink 描述车道级连接。
  • <controller>:控制器,通常与 junction 配合,包含 control 子节点,用于将信号灯组与具体控制逻辑关联。
  • <station>:里程桩号或站点,通常出现在 road 内部或作为独立节点,用于沿参考线定位特定位置,如公交站、检测点、事件点。

这些节点之间的引用关系可以概括为:header 提供全局坐标基准;road 通过 id 被 junction 的 connection 引用;controller 通过 control 引用 signal;station 通过 s 坐标定位在 road 上。理解这些引用,才能正确解析一个完整的 OpenDRIVE 文件。

OpenDRIVE 主要节点层级关系图 根元素 → header / road / junction / controller / station 的包含与引用关系 <OpenDRIVE> XML 根元素 · 版本与命名空间 <header> 全局基准 · geoReference <road> 几何 · 车道 · 高程 <junction> 连接 · connection <controller> 控制 · control <station> 里程 · s 坐标 planView 参考线几何 lanes 车道与宽度 elevationProfile 高程与坡度 connection incoming / connecting control signal 引用 s 坐标定位 沿参考线里程 road 通过 id 被引用 junction / controller / station 均指向 road 图例说明 根元素 header 全局基准 road 道路主体 junction 交叉口 controller 控制器 station 里程桩 引用关系(id / s 坐标)

三、方法流程:如何阅读一个 OpenDRIVE 文件

面对一个实际的 OpenDRIVE 文件,建议按以下流程逐层阅读,避免一开始就陷入几何细节。

  1. 先看根元素与 header:确认版本号、地图范围、geoReference 坐标参考系,判断该文件使用地理坐标还是局部投影坐标。
  2. 统计 road 数量与 id:每条 road 都有唯一 id,记录其长度、junction 属性(是否为交叉口内部道路)。
  3. 查看 junction 与 connection:理解哪些 road 在何处相交,connection 的 incomingRoad 与 connectingRoad 如何配对,laneLink 如何连接车道。
  4. 查看 controller 与 control:确认信号灯组与 junction 的关联,理解控制逻辑的归属。
  5. 查看 station 与 s 坐标:定位公交站、检测点、事件点等沿路设施的位置。
  6. 最后回到 road 内部:按需查看 planView、lanes、elevationProfile 等几何细节。

实用技巧:在文本编辑器中折叠 XML 节点,先展开 header 和所有 road 的 id 与 length,再展开 junction 的 connection,可以快速建立道路网络的拓扑骨架。

四、案例与场景:一个简单十字交叉口的文件结构

假设有一个由两条道路组成的十字交叉口,文件结构大致如下:

<OpenDRIVE>
  <header revMajor="1" revMinor="6" name="CrossDemo"
          version="1.0" date="2024-01-01"
          north="100.0" south="-100.0" east="100.0" west="-100.0">
    <geoReference><![CDATA[+proj=utm +zone=50 +ellps=WGS84]]></geoReference>
  </header>

  <road id="1" name="EastWest" length="200.0" junction="-1">
    <planView> ... </planView>
    <lanes> ... </lanes>
  </road>

  <road id="2" name="NorthSouth" length="200.0" junction="-1">
    <planView> ... </planView>
    <lanes> ... </lanes>
  </road>

  <junction id="100" name="MainCross">
    <connection id="1" incomingRoad="1" connectingRoad="2" contactPoint="start">
      <laneLink from="1" to="-1"/>
    </connection>
    <connection id="2" incomingRoad="2" connectingRoad="1" contactPoint="start">
      <laneLink from="1" to="-1"/>
    </connection>
  </junction>

  <controller id="200" name="SignalCtrl">
    <control signalId="300" type="0"/>
  </controller>

  <station id="400" name="BusStop" s="80.0" roadId="1"/>
</OpenDRIVE>

在这个例子中,road 1 与 road 2 是两条独立道路,junction 100 通过 connection 描述它们之间的连接关系,controller 200 负责信号控制,station 400 在 road 1 的 s=80.0 处标记了一个公交站。可以看到,所有节点都围绕 road 的 id 和 s 坐标展开,这正是 OpenDRIVE 结构设计的核心思想。

五、常见误区与复盘

误区表现正确理解
把 junction 当作道路在 junction 内直接写 planView 几何junction 只描述连接关系,几何由 connectingRoad 承担
忽略 header 的 geoReference坐标数值看似合理但无法与地图对齐geoReference 决定坐标基准,必须优先确认
controller 与 junction 脱节信号灯组未通过 control 关联到具体交叉口controller 需与 junction 配合,control 引用 signalId
station 位置理解错误把 station 当作独立道路节点station 是沿 road 参考线的 s 坐标定位点
road id 重复或缺失junction 引用不到对应道路每条 road 必须有唯一 id,且被正确引用

排障提示:如果仿真器报“找不到 incomingRoad”或“laneLink 无效”,优先检查 road 的 id 是否与 junction 中引用的 id 一致,以及 contactPoint 是否与道路方向匹配。多数结构类错误都源于 id 引用不一致,而非几何计算错误。

掌握 OpenDRIVE 的 XML 根元素、header、road、junction、controller、station 等主要节点及其层级关系,就相当于拿到了整张道路网络的“骨架图”。后续无论是进行道路几何编辑、交叉口渠化,还是信号配时与仿真验证,都可以在这棵结构树上找到对应的位置和操作入口。