陈锦旗,陈添丁,林添成,黄 成
(闽南师范大学物理与信息工程学院,福建漳州363000)
三维激光雷达是一种通过发送激光束探测与目标方位的探测技术,可实现三维空间的全方位探测[1].三维激光雷达输出的是被测目标的距离和强度的点云信息,其通过距离与强度点云信息可以构建出三维空间的景深模型.通过构建模型可应用于自动驾驶、环境建模和三维成像等领域.本文采用Velodyne 公司的VLP-16 激光雷达,该雷达采用UDP 协议实时输出三维点云数据.雷达通过360°快速的旋转实时采集三维点云其数据量很大,输出的三维数据需要进行解析才能转化为三维空间距离与强度信息,再对解析完的数据进行显示与存储.雷达数据需要经过采集、解析完成之后才能进行环境建模、三维成像和自动驾驶等应用,因此,设计一套可靠的雷达数据处理系统对自动驾驶、环境建模和三维成像等具有重要的意义[2-3].
系统采用Visual C++2015 平台基于MFC 库实现了数据的高速采集与传输、解析、存储等,并结合OpenGL 库实现了三维点云数据的显示.数据处理系统可分为参数设置模块、数据接收端模块、数据存储模块、数据处理模块、显示模块与三维显示控制模块等.计算机通过网络与激光雷达连接,激光雷达采用UDP 协议把雷达的原始数据包传输给计算机,计算机接收到激光雷达数据需判断是否为点云数据,若是点云数据则接收存储.为了预防系统运行延迟丢失数据,数据接收端设计了先进先出的环形链表用于存储雷达原始数据包和已解析的三维点云数据包.数据处理端从数据接收端的环形链表中依次读取激光雷达原始数据包,接收到的数据通过计算解析出三维点云数据,再把解析完成的三维点云数据包暂存在数据处理模块的环形链表.系统调用显示模块线程把解析完的三维点云数据包进行拼帧操作,每个激光雷达的原始数据包只包含某一扇形区的数据,需要提取环形链表中的三维点云数据包然后根据相应的算法拼帧,每帧数据包包含激光雷达采集360°的点云数据.显示模块再调用OpenGL 库把一帧的三维点云数据显示出来,点动鼠标左键、右键和滚轮调用三维显示控制模块可实现三维视角切换.
计算机接收到的雷达数据包属于原始数据,需对原始数据包进行相应的解算和转换才能获得三维空间点云数据.如图1所示,图示左边为激光雷达与目标点三维空间关系示意图,其中Y轴正方向为激光雷达扫描的初始位置也就是旋转角度为0°方向,激光雷达水平扫描的方向从俯视图上看为逆时针方向,当前扫描位置与Y 轴所成的角度为α.从激光雷达侧视图看激光束与XY 平面的夹角为ω,VLP-16 激光雷达在垂直方向上扫描有16 束激光束,其角度分别为-15°,1°,-13°,-3°,-11°,5°,-9°,7°,-7°,9°,-5°,11°,-3°,13°,-1°,15°,在这垂直面上不同角度的16束激光360°转扫描就可以得到空间三维的点云数据.已知激光雷达与目标点的距离、垂直方向夹角ω和水平夹角α,通过以下公式(1)至公式(4)即可计算出激光雷达当前位置与目标点的位置关系.
激光雷达的原始数据包格式如图1所示,图示右边为激光雷达的原始数据包格式.VLP-16 激光雷达每个数据包分为12 数据分段Data Block1-Data Block12,每个数据分段包含2 组数据单元,数据包总共包含24组数据单元,每组数据单元包含16个目标点.每个数据分段开头包含一个标志位0xFFEE,标志位下一个信息为2字节的当前位置角度值Azimuth N(角度ɑ),当前位置角度值下一个信息为连续48个字节的16个目标点信息Channel 0 Data-Channel 15 Data,一个目标点信息占3个字节,再接下去为下一组16个目标点的信息Channel 0 Data-Channel 15 Data.同一个数据分段中只携带一个标志位和一个当前位置角度值Azimuth N,那么同一个数据分段第2 组单元的当前位置角度值Azimuth N+1 等于当前数据分段Azi‐muth N值与下一个数据分段Azimuth N+2值求和的平均值.
图1 激光雷达与目标点三维空间关系和原始数据包格式Fig.1 a)The relationship between LIDAR and 3D spatial of target point;b)The raw packet data of Lidar
计算机接收到激光雷达数据包只包含某一扇形区的数据,对激光雷达数据处理时需要完整一帧数据,这就要求系统需实时对零散的激光雷达数据包进行拼接,拼成完整的一帧数据.具体的算法流程如下图2所示,首先线程调用函数读取环形链表的激光雷达数据包,逐一读取数据包中的单元数据判断角度α是否小于阈值角度β,若小于阈值则可判定为帧头(VLP-16 激光雷达旋转一周角度变化0°~360°,旋转频率为10~20 Hz 可调,每转一圈采集3 600 次可计算得雷达水平分辨率为0.1°~0.2°,阈值角度β根据设定的频率旋转取相应的值).找到帧头记录该帧头信息把当前数据单元存储到LidarFrame变量中,继续从环形链表中读取数据包,并计算最后一个数据单元的角度α是否大于360°,若大于则说明帧尾信息在该数据包里面,需从该包中获取帧尾并把剩余的数据单元存入TempLidarDataStructure变量中以供查找下一帧的帧头.若最后一个数据单元的角度α介于(360-β)∘→360∘之间,则该数据单元为帧尾信息,到此已完成一个完整数据帧的拼接,否则继续从环形链表中读取数据包加载到变量LidarFrame中.
图2 雷达数据的拼接算法Fig.2 The reconfiguration algorithm of Lidar data
系统基于Visual C++2015 平台使用MFC 自带的Socket 库编程,实现读取激光雷达原始数据包[4].为了方便后续对原始数据进行处理与解析,系统中定义了两个结构体分别为组数据结构体和包数据结构体,如下图3所示,组数据结构体为包数据结构体的一个成员.其中组数据包_LidarDataMode包含了一个数据分组当前位置角度变量Azimuth,数据分段的时间戳变量TimeStamp,存储数据分组的二维数组变量LidarDataAxis[LidarLightBeam][3],其中LidarLightBeam 是宏定义代表每组16 个目标点数据,DataBlock 变量用于标记当前数据单元在数据包中的位置,angle变量存储数据单元角度α.包数据结构体_LidarFrame‐Structure 用于存在一帧激光雷达数据,CellSizeLidar 变量用于统计当前帧中数据单元的数目,FrameOrder变量用于累计帧的数量,DataMode用于标记数据类型是否是已解析还是未解析数据,ReturnType与Lidar‐Model变量为标记当前雷达的模式和参数,LidarDataMode为C++容器vector变量用于存储一帧激光雷达数据.
图3 组数据结构体与包数据结构体Fig.3 Sets of data structures and package data structures
系统基于Visual C++2015 平台可使用MFC 自带的CDC 库绘制三维点云数据[5],但在绘制复杂图像或者像素点比较多时会出现严重的卡顿现象.当VLP-16 激光雷达的旋转速率为10 Hz 输出的点云最密集,此时,雷达水平方向采集精度为0.1°,转一圈采集3 600 次,每次采集一组点云数据,每组有16个点云数据每个点云数据包含3个维度的数据量,每个维度由2个字节存储,所以每转一圈雷达输出的数据量为了345 600 B(3 600*16*3*2)字节信息量.如此大的信息量如果采用传统的显示方式必定会出现严重卡顿现象,为了解决绘制三维点云数据卡顿问题,本文利用多线程结合VBO 编程方式改善性能,VBO 是OpenGL提供的一种非立即模式下(立即模式使用glBegin/glEnd 方式)更新显示数据的方式,VBO 模式一般在显卡中开辟的一块存储区域把需要显示的数据存储在显卡中,这样能提高数据的刷新速率,使画面更加流畅,其多线程结合VBO编程流程如下图4所示.
图4 多线程结合VBO编程Fig.4 Multi-threading combined with VBO programming
激光雷达测距精度比较高,受外界温度、天气可见度影响小等.但实际运用中会出现系统噪声、离散化误差或激光雷达平台震动等因素,对数据精确度有一定的影响,为了消除影响需对原始数据进行滤波.常见的滤波方法有线性最小二乘滤波、均值滤波、移动平均滤波、中值滤波、Savitzky-Golay 滤波和高斯滤波等,依据文献[6]的结论中值滤波方法优于其他滤波方法能够对点云数据进行较好的平滑处理,且中值滤波器计算量小有利于是系统的实时性,所以本系统采用中值滤波器对原始数据进行平滑处理.
系统调试需要通过网线把VLP-16激光雷达接到计算机.打开数据处理软件之后具体操作:点击菜单栏“设置”按钮弹出对话框,并在该话框中设置雷达的IP 地址,可选择手动输入雷达IP 地址或自动获取雷达IP 地址,然后点击“启动”按钮,系统启动接收雷达数据.软件菜单栏中的“设置”按钮就是软件框架中的“参数设置模块”,该模块主要用于设置雷达IP地址、雷达端口编号、雷达旋转频率和启动雷达等.
系统启动之后可以看到软件界面扫描出当前环境的三维点云数据如下图5所示:图中黑色网格表示地面,雷达数据的高度信息以网格为参照,绿色箭头表示空间Z 轴坐标,红色箭头表示空间Y 轴坐标,蓝色箭头表示空间X 轴坐标.通过操作鼠标的左键、滚轮、右键等实现三维空间任意视角观察雷达数据,按住鼠标左键并上下拖动鼠标可实现改变俯仰视角若左右拖动鼠标则可实现视角的旋转,按住鼠标右键并上下方向拖动鼠标可实现Z 轴方向视角调整若左右方向拖动鼠标则可实现Y 轴方向视角调整,按住鼠标滚轮并上下拖动可实现X轴方向视角调整.该系统中三维点云数据的误差主要取决于激光雷达自身的精度,VLP-16 雷达官方手册提供的精度为±3 cm.图中红色的点即为激光雷达扫描周围环境的三维点云数据.
图5 激光雷达数据采集软件界面Fig.5 Software interface of data collection of Lidar
为了测试该系统数据处理的精度.本文采用1 个VLP-16 激光雷达、笔记本电脑和相机支架等设备,在大约宽为4 m,长度为8 m 的封闭实验室内利用相机支架架设激光雷达,然后在笔记本电脑上安装数据处理系统对雷达的数据进行采集与处理.激光雷达架设在室内8个不同位置,在这8个位置上实时对室内环境进行数据采集,然后通过采集出来的数据计算激光雷达与室内环境的空间位置关系,并与实际量测的数据进行分析得出采集数据的误差,如下图6所示.图中横坐标表示激光雷达与室内某一目标的距离,纵坐标记录激光雷达扫描该目标数据存在的方差,从该实验中可以得出数据处理系统对环境扫描误差控制在3 cm左右.
图6 量测距离与误差Fig.6 Measuring distance and error
本文设计了激光雷达的数据处理系统,数据处理系统可分为参数设置模块、数据接收端模块、数据存储模块、数据处理模块、显示模块与三维显示控制模块等.该系统采用Visual C++2015 平台基于MFC 库实现了数据的高速采集与传输、解析、存储,并结合OpenGL库实现了点云数据的显示,实验表明系统能够采集复杂环境的三维点云数据.激光雷达数据处理系统对后续研究自动驾驶、环境建模和三维成像等有着重要的意义.