Unity解析OpenDRIVE地图数据,并生成路网模型

本文介绍了如何使用Unity解析OpenDRIVE文件,详细解析了OpenDRIVE的重要节点,包括reference line和lane的width,展示了如何将解析得到的数据转化为道路模型,包括用Bezier曲线表示参考线和生成道路Mesh。此外,还讲述了如何沿着道路随机生成建筑物和给道路添加程序纹理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、引言

前置知识:

Unity解析OSM数据,并生成简单模型

这次参考了两个开源项目:

第二个项目比较好,是直接用的OpenDRIVE原本的格式。第一个项目用的数据经过处理,直接看不出来是怎么解析源数据的,生成模型的方法也许可以看看。

以下内容都是对OpenDrive-Unity-Renderer的解读。本次使用Unity解析OpenDRIVE生成路网的模型如下:

在这里插入图片描述
有路网和建筑模型,车跑上去效果还行,但是交叉口没有处理,还是模型重叠的状态。

二、OpenDrive概述

OpenDRIVE ®是一个开放的文件格式,用于道路网络的逻辑描述。它是由一组仿真专业人员开发并维护的,并得到了仿真行业的大力支持。它的首次公开露面是在2006年1月31日。

1.为什么要使用OpenDRIVE ®?

OpenDRIVE ®是独立于供应商,并且可以免费使用
OpenDRIVE ®包含了所有的主要功能路网
OpenDRIVE ®是一个具有广泛的国际用户群
OpenDRIVE ®是一个管理良好的格式,发展过程透明

OpenDRIVE被开发出来是为了创建一种标准的地图数据格式,方便在各种驾驶仿真模拟器中进行数据交换。

2. OpenDRIVE的特征:

  • XML格式
  • 层次结构
  • 道路几何形状的解析定义:(平面元素,横向/垂直轮廓,车道宽度等)
  • 各种类型的车道
  • 连接点和连接点组
  • 通道的逻辑互连
  • 标志和信号,包括 依存关系
  • 信号控制器(例如用于路口)
  • 路面特性(另请参见OpenCRG)
  • 道路和路边物体
  • 用户可定义的data beads
  • 等等

3. OSM和OpenDRIVE的比较:

可以看到,OpenDRIVE也是一种XML文件,是一种矢量地图。只不过,相比OSM地图,它包含的信息更多,结构也更复杂。

在这里插入图片描述
在这里插入图片描述
4.文件下载

这里可以下载OpenDRIVE的文件规范,对每个节点、每个节点的每个属性都做了详细的解释。还可以下载示例的OpenDRIVE数据。

三、OpenDrive重要节点介绍

这是我做的一个XML节点和属性的导图。“【】”表示这个节点一般有多个。

在这里插入图片描述
在OpenDRIVE中,所有的道路都由一条定义基本几何图形(弧线,直线等)的reference line组成。沿着reference line,可以定义道路的各种属性。例如:高程轮廓线、交通标志等。

在这里插入图片描述

可以在思维导图中看到,road节点是重点,其中geometry节点就定义了reference line,而lane节点重点定义了各车道的属性。

在这里插入图片描述
通过指定与reference line的横向距离来创建单独的车道。reference line通过连接clothoids(又名欧拉螺旋)或多项式来构建。

在这里插入图片描述

请注意圆弧段和直线是clothoids的特殊情况。使用clothoids的优点是,沿着reference line的曲率随路径长度线性变化,这就是为什么大多数道路都是由clothoids构造的。
在这里插入图片描述
三种线的曲率变化:

在这里插入图片描述

1.建模用到的主要节点及属性

在项目中直接把用到的属性划个重点,接下来我们主要就看看这些属性是什么意思。

在这里插入图片描述

  • geometry.x

  • geometry.y

  • geometry.length

  • geometry.hdg

  • geometry.arc.curvature

  • laneSection.right.lane[i].width.a

2.geometry节点

一连串道路 geometry的节点在x/y平面(plan view)上定义了道路reference line的layout。这些geometry节点必须按照升序排列(i.e. increasing s-position). 一个子节点包含了具体的geometric元素的数据。OpenDRIVE现在支持五种geometric元素:

  • straight lines
  • spirals
  • arcs
  • cubic polynomials
  • parametric cubic polynomials

geometry节点的属性:在这里插入图片描述
这里的s-coordinate是指:

在这里插入图片描述

inertial是指:

在这里插入图片描述

我们看一个具体的例子:

在这里插入图片描述
这里的reference line的类型是line,并且起始点的坐标是(x,y)=(512.5,-2250),它的heading朝向的弧度约是1.57,line的长度为583。我们知道了道路参考线的起点、朝向、长度就可以确定这个参考线的位置了。

3.lane的width节点

lanes节点由多个laneSection节点组成。若不定义新的lane section节点,它定义的数值就始终有效,适用于接下来的road(Each lane section is valid until the next lane section is defined)。所以每条road至少有一个从s=0.0m起始的lane section。

在这里插入图片描述
一个lane section至少包含left/center/right三种节点中的一个。lane节点被包含在left/center/right节点中。车道用数字ID来区分,这些ID有如下特点:

  • 唯一
  • 连续 (i.e. without gaps),
  • starting from 0 on the reference line
  • 向左侧递增 (positive t-direction)
  • 向右侧递减 (negative t-direction)

每条road的lane的数量是不限的。 reference line被定义为 lane zero,且不允许有width节点,因为它的宽度总为0。
在这里插入图片描述
除了center里面的lane,其他lane至少有一个width节点。和lane section一样,如果不定义下一个width节点的话,它定义的数值就一直适用于接下来的lane。如果一个lane有多个width节点,它们必须按照升序排列。

width节点的属性如下:

在这里插入图片描述

看看具体数据:

在这里插入图片描述

上述的lane的width节点中,只有属性“a”的值不为0。观察了下整个xml文件,发现几乎所有的width节点的属性都一样,只有a有值。那么a的含义是什么呢?

查文档后发现,在给定点处的实际宽度是用三阶多项式函数计算的,这个函数看起来像这样: w i d t h = a + b ∗ d s + c ∗ d s 2 + d ∗ d s 3 width = a + b*ds + c*ds^2 + d*ds^3 width=a+bds+cds2+dds3其中,width就是给定点(位于reference line上的点?)处的车道宽度。a,b,c,d是常数系数。ds是the distance along the reference line between the start of the entry and the actual position.总体来讲,如果车道宽度变化比较复杂,那么计算也比较复杂。但是在本xml文件中,对车道的宽度做了简化,所有宽度都为10,ds相乘的系数都为0。

在这里插入图片描述

四、根据解析得到的数据创建道路模型

对于每条道路,已知它们的参考线起点坐标、参考线方向、长度。在这个xml文件中只有两种参考线类型,line和arc。我们可以把line和arc都用贝塞尔曲线来表示。根据参考线的信息,得到相应贝塞尔曲线上点的坐标,从而确定最终的模型顶点,渲染出模型。

(PS:其实我们也可以不用贝塞尔曲线,使用和OSM数据生成模型一样的方法。因为不管是line还是arc,实际上都是由线段拼接表示的,我们得到线段的顶点后,完全可以直接用这些顶点生成Mesh。)

按照这个思路,我们可以创建一个脚本BezierCurvePath,用来单独绘制每条road。在绘制road时,分为两个步骤:首先把这条road的参考线转为贝塞尔曲线上的点;再根据贝塞尔曲线上的点确定模型顶点,进行渲染。

1.把reference line表示为Bezier曲线
(1)Bezier曲线介绍

这个网站可以调整控制点,并实时看到Bezier曲线的效果。

搬一个数学总结:

在这里插入图片描述

(2)获取一条road reference line的信息

public List<BezierCurveData> curveDatas = new List<BezierCurveData>();

void Start()
	{
   
		float length_s = 0f,x = 0f, y = 0f;
		float angle = 0f,curvature = 0f,patchWidth = 0f; int lanes = 0;		
		string path 
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值