CARLA OpenDriveParser 说明文档

本文件定义了 CARLA 模拟器中用于解析 OpenDRIVE 地图数据的 OpenDriveParser 类。该类位于 carla::opendrive 命名空间中,主要职责是从 OpenDRIVE XML 文件中读取道路网络数据,并将其转换为 CARLA 内部表示形式。

什么是 OpenDRIVE?

点击这里访问ASAM OpenDRIVE

OpenDRIVE 是由 VIRES Simulationstechnologie GmbH 提出的开放标准,用于描述道路网络的结构化信息,广泛用于驾驶仿真系统(如 CARLA、SUMO、VTD 等)。

该标准使用 XML 格式,详细描述以下内容:

🔹 道路几何形状:包括直线、弧线、样条曲线等,用于定义道路的空间布局;

🔹 车道信息:如车道数量、宽度、类型(普通车道、路缘、应急车道等);

🔹 拓扑结构:包括道路之间的连接、交叉口定义、优先级等;

🔹 交通元素:如交通灯、路标、限速牌、信号控制器等;

🔹 参考坐标系:地理定位支持(支持 UTM、WGS84 投影)。

文件扩展名:.xodr

OpenDRIVE 文件通常以 .xodr 为扩展名,是一个标准的 XML 文件,主要结构包括:

<OpenDRIVE>
  <header>...</header>
  <road>...</road>
  <junction>...</junction>
  <controller>...</controller>
</OpenDRIVE>

应用场景

🔹 自动驾驶仿真平台(如 CARLA)

🔹 路径规划和地图验证

🔹 高精地图(HD Map)生成

🔹 道路网络分析与可视化

OpenDRIVE 提供了一种灵活、高度结构化的方式,帮助开发者在模拟世界中构建真实感强的交通环境。

命名空间

namespace carla {
  namespace opendrive {
    ...
  }
}
该类位于 carla::opendrive 命名空间下。

类定义详解:OpenDriveParser

class OpenDriveParser

简介

OpenDriveParser 是 CARLA 模拟器中 carla::opendrive 命名空间下的一个核心类,专门用于解析 OpenDRIVE(.xodr)格式的地图文件。 它被设计为 纯静态工具类 —— 即类中所有成员函数都是 static,无需也不应创建该类的实例。

这个类是 CARLA 将现实交通规则与地形数据导入其仿真环境的桥梁。其目标是将 OpenDRIVE 文件转换为 CARLA 使用的 Map 数据结构,并保留道路几何、车道属性、连接关系等关键信息。

类特点

🔹 纯静态类:不允许实例化,所有方法为 static。

🔹 工具类设计:提供“加载”和“解析”两个核心能力。

🔹 封装解析细节:使用 XML 解析库(如 pugixml )来处理底层文件格式。

🔹 模块化输出:返回标准化 Map 对象,供 CARLA 路网系统使用。

为什么使用静态类?

将其设计为静态类的好处:

1.避免了频繁创建/销毁对象带来的性能负担;

2.明确该类仅提供“功能”,没有“状态”;

3.更易于在不同模块中通用调用。

类接口概览

函数名 说明
static Map Load(std::string opendrive_file) 从 OpenDRIVE 文件内容中解析出一份完整的 Map 对象
static std::string GetXodrHeader(const std::string &opendrive_file) 获取 OpenDRIVE 文件头信息

虽然目前暴露的函数不多,但它们背后隐藏了大量对 XML 元素的处理逻辑,包括道路定义、几何形状、交叉口、连接、规则等。

类依赖关系

输入依赖:OpenDRIVE .xodr 文件内容(纯文本格式 XML)

输出依赖:返回 carla::opendrive::Map 类的实例

外部库依赖:使用 pugixml 处理 XML 文件内容

主要静态方法

1.Map Load(std::string opendrive_file)

功能:从 OpenDRIVE XML 字符串加载地图。

参数: opendrive_file: OpenDRIVE 文件内容字符串(不是文件路径)。

返回值:一个构造完成的 Map 对象。

异常:可能会抛出 std::runtime_error。

2.std::string GetXodrHeader(const std::string &opendrive_file)

功能:提取 OpenDRIVE 文件头部信息。

参数:完整的 OpenDRIVE XML 文件内容。

返回值:文件头内容的字符串。

数据结构说明:Map

简要介绍

Map 是 CARLA 仿真平台中处理道路网络的核心数据结构之一。虽然在 OpenDriveParser.h 中没有展开其定义,但该结构通常定义在 carla/opendrive/Map.h 文件中,并由 carla::opendrive::OpenDriveParser::Load 方法返回。

这个数据结构是 OpenDRIVE 文件经过解析后的高层封装,包含了描述交通网络的全部信息,包括但不限于:

道路(Roads), 车道(Lanes) ,交叉口(Junctions) ,几何信息(Geometries) ,拓扑连接(LaneLinks / RoadLinks) ,信号灯和交通规则(Signals / Controllers)

Map 的作用

功能 说明
仿真世界构建 提供构建 CARLA 仿真环境的蓝图(如道路网格)
路径规划 为车辆行为模块提供路径信息
感知模拟 为传感器生成提供几何和拓扑依据
可视化 支持地图在模拟器界面中的渲染展示
路网分析 供外部工具提取道路属性、生成路线、计算可行驶区域等

结构组成(典型字段)

以下为 Map 常见字段的逻辑结构说明:

class Map {
public:
  std::vector<Road> roads;            // 所有道路信息
  std::vector<Junction> junctions;    // 所有交叉口
  std::vector<Signal> signals;        // 所有交通信号灯/标志
  Header header;                      // 地图头部信息(来自 OpenDRIVE <header>)
};

1.roads

包含所有 OpenDRIVE 节点的信息,每一条道路包含以下内容:

道路ID与名称, 道路长度. 几何段(直线、圆弧、样条线), 车道信息(分布、宽度、类型)

2.junctions

包含 节点,描述多个道路交汇处的连接方式:

哪些车道互通? 如何在交叉口内转弯? 交通优先权。

3.signals

表示地图中定义的交通灯、限速标志、停车标志等信息:

类型(如红绿灯、限速牌),安装位置,控制关系(与道路或车道绑定)

4.header

存储 OpenDRIVE

元素的信息,如: 地图名称与版本号, 创建时间, 原始坐标系统(可用于坐标投影)。

与 OpenDriveParser 的关系

1.Map 是 OpenDriveParser::Load() 的直接返回结果。

2.OpenDriveParser 完整解析 OpenDRIVE XML 文件,重建出结构化的 Map 对象,供 CARLA 世界使用。

换言之,OpenDriveParser 是“入口”,而 Map 是“出口”。

使用示例

std::string xodr_data = LoadFile("Town04.xodr");
carla::opendrive::Map map = OpenDriveParser::Load(xodr_data);
// 获取第一个道路信息
const Road& road = map.GetRoad(0);
std::cout << "Road ID: " << road.id << std::endl;

内部可能涉及到诸如:

1.将坐标从 OpenDRIVE 的参考线转换为 CARLA 世界坐标;

2.将道路元素(如车道、交叉口)转换为 CARLA 的可用形式;

3.构建车道之间的连接逻辑;

4.计算几何信息、样条插值等。

注意事项

输入是字符串格式的完整 OpenDRIVE 文件内容,不是文件路径。

使用前请确认该字符串已正确读取整个 XML 文件。

若输入格式有误或内容缺失,解析可能会失败。

示例代码

#include"carla/opendrive/OpenDriveParser.h"
std::string xodr_contents = ReadFile("Town01.xodr");
carla::opendrive::Map map = carla::opendrive::OpenDriveParser::Load(xodr_contents);

OpenDriveParser.cpp 源文件说明(CARLA)

该文件实现了 CARLA 项目中 OpenDRIVE 格式地图解析的核心模块:OpenDriveParser。它负责从 OpenDRIVE XML 字符串中解析并构建 CARLA 中的道路网络地图对象(road::Map)。


文件位置

carla/opendrive/OpenDriveParser.cpp
点击这里访问opendirve


主要功能详解

该文件(OpenDriveParser.cpp)的核心职责是:解析 OpenDRIVE 地图数据。其中最重要的函数是:

boost::optional<road::Map> OpenDriveParser::Load(const std::string &opendrive);

函数说明

OpenDriveParser::Load

函数原型

boost::optional<road::Map> OpenDriveParser::Load(const std::string &opendrive);

输入参数

参数名 类型 描述
opendrive const std::string & 包含 OpenDRIVE 地图完整 XML 内容的字符串。可以是从 .xodr 文件读取的文本内容

返回值: 返回类型为 boost::optional

如果解析成功:返回一个包含完整地图结构的 road::Map 对象;

如果解析失败(如格式错误、缺少必要字段):返回空(boost::none)。

函数职责

该函数的主要职责是将输入的 XML 字符串(符合 OpenDRIVE 标准)解析成 CARLA 中用于导航与仿真的地图结构 road::Map,其包含:

道路几何信息(曲线、直线、坐标)

车道结构(宽度、类型、连接关系)

交叉口信息(连接规则、优先级)

道路标志(红绿灯、限速标志、指示牌)

道路拓扑信息(如何从一个车道连接到另一个)

函数内部工作流程

以下为该函数的典型处理步骤(在 OpenDriveParser.cpp 中实现):

1.初始化 XML 解析器(pugixml)

将输入的字符串 opendrive 加载进 pugi::xml_document

2.检查 OpenDRIVE根元素是否存在

如果找不到,立即返回空值(无效的输入)

3.解析 header 元素

解析并构造 road::Map::Header,包含地图版本号、供应商信息、原点坐标、投影类型等

4.调用子模块进行结构化解析

该函数并不直接处理所有解析细节,而是通过调用多个专用子解析器模块实现解耦和职责分离。

调用的子解析器模块

解析器名称 文件位置 作用
GeometryParser parser/GeometryParser.h 解析 段(包括直线、弧线、样条)为曲线段数据结构
LaneOffsetParser parser/LaneOffsetParser.h 解析 信息,即道路车道中心线的横向偏移量变化
LaneWidthParser parser/LaneWidthParser.h 解析 元素,获取车道宽度的多段变化
LaneParser parser/LaneParser.h 解析 ,包含车道类型、连接、宽度等
LaneSectionParser parser/LaneSectionParser.h 解析 ,构建各个车道组合成的横截面结构
RoadLinkParser parser/RoadLinkParser.h 解析 信息,建立道路之间的连接
JunctionParser parser/JunctionParser.h 解析 交叉口结构,处理优先级、连接等
SignalParser parser/SignalParser.h 解析 ,包括限速牌、信号灯、路面标识
ControllerParser parser/ControllerParser.h 解析 ,关联信号与控制器

每个解析器都实现了一个 static Parse(...) 方法,接收相应的 XML 节点,返回结构化数据。

成功返回示例

auto result = OpenDriveParser::Load(xodr_data);
if (result) {
    std::cout << "加载成功!道路数量:" << result->GetRoadCount() << std::endl;
}

错误处理机制

1.解析失败不会抛出异常,而是返回 boost::none

2.用户应检查 optional 是否有值再继续访问

3.内部某些子解析器会打印出错误日志,有助于调试格式问题的 OpenDRIVE 文件

与其他模块协作

模块 用途
pugixml XML DOM 解析
road::Map 存储解析后的地图数据
各种 *Parser 子模块 解析不同级别的 OpenDRIVE 结构

依赖模块

依赖模块图

#include "carla/opendrive/OpenDriveParser.h"
#include "carla/Logging.h"
#include "carla/opendrive/parser/*.h"
#include "carla/road/MapBuilder.h"
#include <pugixml/pugixml.hpp>
  • ✅ 使用 pugixml 加载和解析 XML
  • ✅ 使用各类 parser 对不同部分进行解析(道路、信号、控制器等)
  • ✅ 使用 MapBuilder 构建最终地图对象

函数解析:OpenDriveParser::Load

boost::optional<road::Map> OpenDriveParser::Load(const std::string &opendrive)

函数流程:

  1. 加载 XML 数据

    pugi::xml_document xml;
    pugi::xml_parse_result result = xml.load_string(opendrive.c_str());
    
    利用 pugixml 从字符串中读取 XML 文档

  2. 错误处理

    if (parse_result == false) {
      log_error("unable to parse the OpenDRIVE XML string");
      return {};
    }
    

  3. 初始化构建器

    carla::road::MapBuilder map_builder;
    

  4. 解析各个部分(按顺序)

    地理参考(坐标系)

    parser::GeoReferenceParser::Parse(xml, map_builder);
    
    道路(road)
    parser::RoadParser::Parse(xml, map_builder);
    
    路口(junction)
    parser::JunctionParser::Parse(xml, map_builder);
    
    几何数据(geometry)
    parser::GeometryParser::Parse(xml, map_builder);
    
    车道(lane)
    parser::LaneParser::Parse(xml, map_builder);
    
    属性配置(profile:如坡度/曲率)
    parser::ProfilesParser::Parse(xml, map_builder);
    
    交通分组(公交/非机动车等)
    parser::TrafficGroupParser::Parse(xml, map_builder);
    
    信号(交通灯、标志等)
    parser::SignalParser::Parse(xml, map_builder);
    
    静态对象(建筑、栏杆等)
    parser::ObjectParser::Parse(xml, map_builder);
    
    控制器(如红绿灯控制逻辑)
    parser::ControllerParser::Parse(xml, map_builder);
    

  5. 构建最终 Map

    return map_builder.Build();
    


模块调用关系

OpenDriveParser.cpp的引用(include)关系图

OpenDriveParser::Load(string)
  ├── XML 加载(pugixml)
  ├── GeoReferenceParser
  ├── RoadParser
  ├── JunctionParser
  ├── GeometryParser
  ├── LaneParser
  ├── ProfilesParser
  ├── TrafficGroupParser
  ├── SignalParser
  ├── ObjectParser
  ├── ControllerParser
  └── MapBuilder::Build()


类图概念(简化)

OpenDriveParser
  └── static Load(opendrive: string) : optional<road::Map>
  • 所有逻辑集中在 Load 函数中,内部组合各解析器模块进行 XML 内容解析

特性小结

特性 描述
模块化 各解析功能分离为独立模块(parser)
错误安全 使用 boost::optional 表达失败
扩展性 新增解析器模块时易于集成
性能良好 基于轻量级 pugixml 实现
支持蓝图间接调用 被上层封装(如 Unreal 的 UOpenDrive 类)

使用场景

  • 加载 .xodr 地图字符串到 CARLA 引擎中
  • 在地图工具链中进行道路、交叉口、交通信号等解析
  • 用于运行时生成或验证地图网络结构

点击此处访问CARLA OpenDrive模块说明文档