XML解析及其在OPENDRIVE高精地图中应用
三种信息标记形式
常用的三种信息标记方式包括JSON、XML、YAML,三种格式的对比如下表
格式 | 优势 | 劣势 | 应用领域 |
---|---|---|---|
XML | 可扩展标记语言,最早 | 繁琐 | Internet上信息交互 |
JSON | 信息有类型,适合程序处理,比XML简洁 | 无注释 | 移动应用云端和节点通信 |
YAML | 信息无类型,文本信息比例最高,有注释,可读性好 | 各类系统配置文件 |
本文主要关注XML格式解析及其在OPENDRIVE中应用。
XML格式介绍
XML中的主要信息通过标签来表示,标签又包括名字和属性,XML整体上呈现层次化结构。
XML的注释及空元素表示。
注释在OPENDRIVE中的应用,假如整个地图中分成了多条路,可以通过注释的方式只显示其中的部分道路,当然这么做可能需要处理JUNCTION相关道路的连接关系。
OPENDRIVE地图简要介绍
高精地图的格式包括SHP(矢量化文件)、NDS、Lanlet、OPENDRIVE,这几种高精地图格式的对比会另起文章分析。最近两年智能驾驶领域,对OPENDRIVE的推动较为积极,其已经慢慢进化到V1.6版本,包括主流自动驾驶仿真软件中对OPENDRIVE的支持也开始得到加强,但目前大多数仿真支持的是V1.4版本,当然随着版本更新,相信各大仿真软件将会支持较高版本。
关于OPENDRIVE地图的介绍网上有很多,而且不乏质量极高的介绍,同时,从官方网站或开源仿真LG-SVL网站上都可以下载地图示例。此处只做简要说明,OPENDRIVE地图的文件结构采用XML的表示方法,文件格式为XODR。
V1.4标准中OPENDRIVE的文件结构如下图(从手册中截出)
上表第一列信息是文件中元素的全集,在地图中这些信息是可以选择的,常见的地图中最少要包含Header、Road、Junction三个部分。其中,Road主要包含中心线(planview)、车道、和路面上的设施(包括Object+signal),当然,一个长度很长的地图必然会划分成多条road,所以road之间应该建立起前后连接关系(即link)。
每一项具体的解释可查阅手册。
XML解析在OPENDRIVE中的应用
利用Python有三种方法解析XML文件,包括SAX、DOM和ElementTree.
格式 | 优势 | 劣势 |
---|---|---|
SAX | 流式读取XML文件,速度快,占内存小 | 事件驱动,需实现回调函数 |
DOM | 将XML在内存中解析成树 | 比较慢,消耗内存大 |
ElementTree | 代码可用性好,速度快,消耗内存小 |
以下做一个简单案例,用SAX方法抽取OPENDRIVE文件中各条路的长度。代码如下
from xml import sax
class opendrivehandler(sax.ContentHandler):
def __init__(self):
self.CurrentData = ""
#开始标签时调用
def startElement(self, tag, attributes):
self.CurrentData = tag
if tag == "road":
r_id = attributes["id"]
r_length = attributes["length"]
print("*****Road*****")
print("the length of road {0} is {1}m".format(r_id, r_length))
#结束标签时调用
def endElement(self, tag):
self.CurrentData = ""
#内容事件处理
def characters(self, content):
pass
if __name__ == "__main__":
#创建一个新的XMLReader
parser = sax.make_parser()
#关闭namespaces
parser.setFeature(sax.handler.feature_namespaces, 0)
#重写Handler
Handler = opendrivehandler()
parser.setContentHandler(Handler)
parser.parse("test.xodr")
前文说到XML文件格式是繁琐的,阅读时并不直观,同样,可以用解析方法将道路中的Signal、Object的信息提取出来进行统计或者与GroundTruth进行比对。