一种在Unity中高效模拟激光雷达的方法与流程

文档序号:18106411发布日期:2019-07-06 11:41阅读:2905来源:国知局
一种在Unity中高效模拟激光雷达的方法与流程

本发明涉及一种计算机模拟激光雷达的方法,具体而言是一种在unity中高效模拟激光雷达的方法,属于自动驾驶与数据处理技术领域。



背景技术:

激光雷达(lidar)是一种向指定方向发射激光束并检测返回光束来获取目标位置等数据的装置。自动驾驶领域常用的激光雷达为多线束机械旋转式激光雷达,由于其定位精准,算法实现难度低,不受昼夜影响等诸多优点,成为自动驾驶核心定位与检测设备之一。

在自动驾驶汽车的开发过程中,需要在各种行驶条件下,对无人驾驶技术进行不断的验证测试,从确保无人驾驶技术的安全程度能够高于人类驾驶员的操作,有时候还需要在实际道路上对自动驾驶汽车进行测试。但现阶段激光雷达制造难度较大,无法实现自动化生产,随着线束的增多,雷达的价格也呈指数增长。同时机械式激光雷达有高速旋转的机械结构,长时间工作势必导致设备过度损耗。在这种环境下,通过计算机模拟激光雷达,成为自动驾驶仿真领域一项刚需。

另外,虚拟道路测试也是积累无人驾驶汽车测试里程的重要手段之一。虚拟道路测试能够有效对危险或不常见的驾驶场景进行测试,其灵活性和多用性,使其在自动驾驶技术开发中发挥着重要作用。在虚拟道路测试中,无法或者不便利用激光雷达传感器进行探测。然而,激光雷达传感器的点云数据又对自动驾驶汽车系统的研究具有重要的意义。

目前常见的模拟激光雷达的方法,是在渲染过程中取深度数据,再通过深度数据计算出各个点的位置信息。然而这样做存在不少问题,比较明显的有:

1)相机视角最高不能超过180度,而机械式激光雷达的扫描范围为360度,这样在一帧之内,只渲染一次将无法得到完整的激光雷达数据,要获得完整的数据又得在一帧内渲染多次画面,显著增大了性能压力。

2)深度数据位于显存中,每次渲染后均需要从显存中读取数据到内存,这种回读的行为不仅打断正常的渲染流程,还存在无法消除的时间损耗。



技术实现要素:

发明目的:为了克服现有深度渲染法所存在的不足,结合unity引擎的优势,本发明提供一种在unity引擎中高效模拟激光雷达的方法。

技术方案:为解决上述技术问题,本发明提供的模拟方法,包括以下步骤:

步骤1、数据初始化

首先对激光雷达在世界坐标系中的位置lidarposition、激光雷达在世界坐标系中的朝向lidardirection以及激光雷达射线扫描距离scanerage进行初始化;然后对激光雷达的每条射线建立以下数组,包括射线端点数组raylocalstarts、射线方向数组raylocaldirections、射线指令数组raycastcommands和射线返回值数组raycasthits,其中射线指令数组raycastcommands用于存放unity引擎中批量射线检测方法raycastcommand.schedulebatch需要的射线指令,射线返回值数组raycasthits用于存放unity引擎中批量射线检测方法raycastcommand.schedulebatch的直接返回值;

步骤2、更新射线指令

依次向raycastcommands数组中更新当前射线在世界坐标系中的端点位置与朝向;

步骤3、批量射线检测

调用unity批量射线检测方法raycastcommand.schedulebatch进行碰撞检测,碰撞检测时传入raycastcommands数组的数据,将碰撞检测的结果distance依次返回到raycasthits数组中;

步骤4、筛选有效射线

找到raycasthits数组中distance大于0的射线作为有效射线;

步骤5、变换输出数据

将所有有效射线的位置从世界坐标系转换到lidar坐标系下,即得到当前所需的激光雷达数据;

步骤6、返回执行步骤2,直到进入预设的结束流程释放资源。

需要说明的是,unity引擎是由unitytechnologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。unity引擎为开发者提供了便捷的图像与物理接口,可以方便地创建各种视觉与物理模拟环境并进行各种自定义拓展,在自动驾驶仿真领域有广泛应用。

本发明提供了一种针对unity引擎模拟车载激光雷达的实现方案,充分利用unity引擎中的优化特性高速生成射线数据流,在低碰撞数目环境下,处理流程在1ms以内,远低于采用深度法过程中渲染多帧图像的开销,在高碰撞开销的耗时亦低于现有技术。由于数据来源是碰撞器可与图形数据分离,可定制程度更高,为自动驾驶仿真试验平台提供了高效费比的解决方案。

上述技术方案的进一步改进是:步骤2中使用继承于jobsystem中的ijobparallelfor接口的并行处理方法更新射线指令。jobsystem允许采用多线程处理任务,从而实现高性能体验,它不仅能改善帧率,而且特别适合用来处理多个需要长时间运行的任务。

上述技术方案的再进一步改进是:步骤4中筛选有效射线时,采用基于nativelist的并行索引插入方法scheduleappend在多线程中进行有效射线的判断,并将有效射线的索引插入nativelist中。nativelis为unity引擎中的一个collection,能够在并行计算时充分利用cpu的cache命中率提高局部代码执行速度。

除以上所述的本发明解决的技术问题、构成技术方案的技术特征以及由这些技术方案的技术特征所带来的优点外。为使本发明目的、技术方案和有益效果更加清楚,下面将结合本发明实施例中的附图,对本发明所能解决的其他技术问题、技术方案中包含的其他技术特征以及这些技术特征带来的优点做更为清楚、完整的描述。

附图说明

图1是本发明实施例的流程图;

图2是本发明实施例的算法示意流程;

图3是本发明实施例中模拟低碰撞开销的处理时间示意;

图4是本发明实施例中模拟高碰撞开销的处理时间示意。

具体实施方式

实施例:

unity作为通用图形引擎,内部集成了第三方物理引擎,能够满足自动驾驶领域的物理与图像仿真需求。近年来的unity更是通过面向数据流计算的优化补丁,性能进一步提高。比如在unity2018版本中,新增了一些功能增补丁,主要包括:1)collections,在c#中创建类似c++中数组结构的原生容器,将有效数据连续紧密排列,在并行计算时充分利用cpu的cache命中率提高局部代码执行速度。以下方法将使用到其中的nativearray、nativelist、nativequeue、nativehashmaps、nativemutihashmaps等。2)jobs,独立封装的代码块结构,通过预先设计数据排列方式,其中的代码可以并行在多个线程上处理,手法上类似openmp。以下方法将使用到ijobparallelfor、ijobparallelforfilter、ijobnativemultihashmapmergedsharedkeyindices格式的jobs并行代码。3)mathematics,在c#中提供simd数学库的支持,使用向量指令集加速矩阵的计算。4)brust,提供以上三者的编译器级支持,对jobs中代码编译成非托管高速代码。

得益于这些优势,我们可以在较新版本的unity中实现高效获取激光雷达点云的新方法,其实施总流程如图1所示,包括以下步骤:

步骤1、数据初始化

初始化阶段,需要事先创建各种数据类型。lidar有大量射线,因此将每条射线需要的数据存放到不同的数组中。

1.射线端点数组(raylocalstarts)

配置各射线局部位置,这个位置处于lidar坐标系下,是lidar硬件参数。数组索引代表射线序号,同序号的不同数据对应关联,共同组成某个射线的参数。

2.射线方向数组(raylocaldirections)

配置各射线局部方向,同样处于lidar坐标系下,是lidar硬件参数。机械式雷达的射线一般沿yaw轴呈发射状分布一圈。如图2所示

3.射线指令数组(raycastcommands)

unity批量射线检测方法raycastcommand.schedulebatch需要的参数数组,存放配置好的射线指令,配置过程需要每帧执行。

4.射线返回数组(raycasthits)

unity批量射线检测方法raycastcommand.schedulebatch的直接返回值,成功射线检测的数组元素将返回distance大于0的结果。

除以上数组外,还需要另一些相关参数,如图2所示:

lidar在世界坐标系中位置(lidarposition),lidar在世界坐标系中朝向(lidardirection),这两个数据随着lidar在世界坐标系中的运动实时更新。lidar射线扫描距离(scanerage):由雷达性能决定的常量,一般数百米。

有了这些数据之后,初始化过程完成,进入循环工作流程。

步骤2、更新射线指令

依次向raycastcommands数组中更新当前射线在世界坐标系中的端点位置与朝向,数组元素按照序号一一对应,因而使用继承于ijobparallelfor接口的并行处理方法,伪码如下,rayindex为当前射线序号:

raystart=lidarposition+rotate(lidardirection,raylocalstarts[rayindex]);

raydirection=rotate(lidardirection,raylocaldirections[rayindex]);

raycastcommands[rayindex]=newraycastcommand(raystart,raydirection,scanerage)。

步骤3、批量射线检测

调用unity批量射线检测方法raycastcommand.schedulebatch进行碰撞检测,碰撞检测时传入raycastcommands数组的数据,将碰撞检测的结果distance依次返回到raycasthits数组中。

该过程耗时由场景碰撞复杂度与硬件性能决定,因为是异步指令,可以封装到协程中,待计算完成时继续处理结果。

步骤4、筛选有效射线

找到raycasthits数组中distance大于0的射线作为有效射线。

raycasthits数组中既含有有效碰撞又含有无效碰撞,无效碰撞即在设定的碰撞距离内,射线没有遇到任何碰撞物,此时distance将为0,必须进行进一步处理方可作为结果输出。针对nativelist的并行索引插入方法scheduleappend可以在多线程中进行有效值的判断并将有效值索引插入nativelist。并行伪码如下:

returnraycasthits[rayindex].distance>0;

有效的碰撞结果显示碰撞距离为正值,将该正值的索引插入tempindexlist中。

步骤5、变换输出数据

将所有有效射线的位置从世界坐标系转换到lidar坐标系下,即得到当前所需的激光雷达数据。

从tempindexlist得到的有效索引,可以查询到raycasthits中对应的有效结果。由于结果中的位置是世界坐标系下的位置,必须将坐标转换到lidar坐标系下才是lidar本应输出的点云数据。逆变换按照如下伪码进行:

localpoints[rayindex]=rotate(inverse(lidardirection),raycasthits[rayindex].point-lidarposition);

得到的localpoints数组即为激光雷达在本次工作中扫描的结果数据。

步骤6、返回执行步骤2,直到进入预设的结束流程释放资源。

本流程提供了一种针对unity模拟车载激光雷达的实现方案,充分利用新版本unity中的优化特性,高速生成射线数据流。如图3所示,在低碰撞数目环境下,处理流程在1ms以内(包括网格生成步骤总耗时1.5ms左右),远低于采用深度法过程中渲染多帧图像的开销。如图4所示,在高碰撞开销时,耗时集中在并行射线碰撞阶段,其他处理步骤相对而言耗时极短。而并行检测这个过程又是异步过程,可以在下一帧调用之前完成而不对主渲染线程不产生影响。高碰撞开销时,并行射线耗时随碰撞数目增大明显增加(5000个collider与64000条射线,碰撞耗时15ms左右)。另外,由于数据来源是碰撞器,可以与图形数据分离,可定制程度更高,例如将远处的碰撞器关闭以加速并行碰撞计算过程。

本发明为自动驾驶仿真领域的激光雷达模拟提供了一种全新的思路与方法,具体实现该技术方案的方法和途径很多,所描述的实施例是本发明一部分实施例,而不是全部的实施例。通常在此处附图中描述和示出的本发明实施例的组件可以以各种不同的配置来布置和设计。因此,对附图中提供的本发明的实施例的详细描述并非旨在限制要求保护的本发明的范围,而是仅仅表示本发明的选定实施例。基于本发明中的实施例,本领域普通技术人员在没有作出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1