一.概念
LIDAR,全称Light Detection And Ranging,即激光检测和测距,通常称为激光雷达。其功能是利用激光检测物体以及测量与物体之间的距离。
二.分类
不同的分类标准,有不同的分类结果。通常有两类分类标准,按照线束可分为两类:一是单线激光雷达,二是多线激光雷达。单线激光雷达的数据可以看做是一定高度的一排点阵,多线激光雷达的数据包含高度信息,可以看做是一个面。按照机械性质又可分为机械激光雷达和固态激光雷达,目前主流市场以机械激光雷达为主。
三.原理
机械激光雷达原理可以简化理解为一个发射器,一个接收器和一个旋转镜面,发射器周期向旋转镜面发射光束,由镜面折射出去,此光束经过障碍物反射后,由接收器接收,统计时间,然后根据光速,计算距离。镜面不停旋转,镜面旋转一周,相当于激光雷达扫描一周,可以获取一帧激光雷达数据。
四.输出
激光雷达的直接输出主要包含两部分:一是距离点,代表物体与激光雷达之间的距离;二是反射强度,不同的物体其反射强度不同,在特定场景下,利用反射强度,可以识别物体,例如车道线检测。
五.作用
激光雷达与IMU和GPS在作用上有一个显著差异点,IMU与GPS测量自身信息,激光雷达测量的是环境信息,并可以根据环境信息,反推自身信息。在自动驾驶或者机器人领域,测量自身信息,在称之为定位,测量环境信息,称之为感知,建图本质上属于感知。
六.数据特性
在机器人和自动驾驶领域,基于激光雷达的方案比较成熟,这与其优势的数据特性有关。具体如下:
测量信息比较多:物体三维信息,包括位置和速度,形状,材料等。
不受光线影响:这点决定其可以全天候工作。其缺陷是易受天气影响,还有一点是相对于其他传感器,激光雷达成本比较高,不利于产品商业化量产,不过近几年,随着激光雷达技术的发展,其成本也逐渐降低。
七.ROS中LIDAR数据表示
- sensor_msgs/LaserScan
sensor_msgs/LaserScan是激光雷达基本数据类型,其所描述的是一次扫描的数据,包括扫描角度、时间以及扫描距离等,执行以下命令:
LaserScan是ROS定义的激光数据格式,消息定义在sensor_msgs/LaserScan.msg文件中,路径为:/opt/ros/indigo/share/sensor_msgs/msg.
LaserScan消息的示例如下:
<code>header:
seq: 101732
stamp:
secs: 1487324446
nsecs: 379890600
frame_id: laser
angle_min: -3.12413907051
angle_max: 3.14159274101
angle_increment: 0.0174532923847
time_increment: 1.55012827463e-07
scan_time: 5.56496015633e-05
range_min: 0.15000000596
range_max: 8.0
ranges: [inf, inf, 5.64900016784668, 2.875999927520752, inf, 5.743000030517578, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, 5.946000099182129, inf, inf, inf, 5.938000202178955, 5.849999904632568, inf, 5.8470001220703125, inf, inf, inf, inf, inf, inf, 6.646999835968018, inf, inf, inf, inf, inf, inf, 0.2150000035762787, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, 5.465000152587891, inf, 3.8970000743865967, inf, 0.16300000250339508, inf, inf, inf, inf, inf, inf, inf, inf, 0.8199999928474426, inf, 0.7910000085830688, 0.7450000047683716, inf, 0.7210000157356262, 0.7120000123977661, inf, 0.7160000205039978, inf, 0.7260000109672546, 0.7480000257492065, inf, 0.7749999761581421, inf, 0.7950000166893005, inf, 0.8240000009536743, 0.8500000238418579, inf, 0.8830000162124634, inf, 0.8759999871253967, 0.8539999723434448, inf, 0.8349999785423279, 0.8199999928474426, inf, 0.8059999942779541, inf, 0.7940000295639038, 0.781000018119812, inf, 0.7699999809265137, 0.7599999904632568, inf, 0.7519999742507935, inf, 0.7419999837875366, 0.7360000014305115, inf, 0.7300000190734863, 0.7239999771118164, inf, 0.7179999947547913, inf, 0.7149999737739563, 0.7120000123977661, inf, 0.7099999785423279, inf, 0.7110000252723694, 0.7120000123977661, inf, 0.7120000123977661, 0.7149999737739563, inf, inf, 0.9509999752044678, 0.9440000057220459, inf, 0.9459999799728394, 0.9459999799728394, inf, 0.9490000009536743, inf, 0.953000009059906, 0.9589999914169312, inf, 0.9639999866485596, inf, 0.968999981880188, 0.9769999980926514, inf, 0.9850000143051147, inf, 0.9940000176429749, 1.0049999952316284, inf, 1.0149999856948853, inf, 1.0269999504089355, 1.0410000085830688, inf, 1.4049999713897705, inf, 1.3600000143051147, inf, 1.468000054359436, 1.402999997138977, inf, 1.343999981880188, 1.2929999828338623, inf, 1.246000051498413, inf, 1.2039999961853027, 1.1670000553131104, inf, 1.1299999952316284, 1.100000023841858, inf, 1.0720000267028809, 1.0429999828338623, inf, 1.0190000534057617, inf, 0.996999979019165, 0.9729999899864197, inf, 0.9520000219345093, inf, 0.9340000152587891, 0.9240000247955322, inf, 0.9160000085830688, inf, inf, 0.859000027179718, inf, 0.8600000143051147, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, 0.7789999842643738, inf, 0.7879999876022339, inf, inf, inf, inf, 0.17100000381469727, inf, 0.17100000381469727, 0.1720000058412552, inf, 0.17299999296665192, inf, 0.17399999499320984, inf, inf, inf, inf, inf, inf, 0.8230000138282776, inf, 0.8320000171661377, inf, 0.8410000205039978, 0.8519999980926514, inf, inf, inf, inf, inf, inf, 0.9110000133514404, inf, 0.9240000247955322, 0.9419999718666077, inf, 0.9620000123977661, 0.9810000061988831, inf, 1.0069999694824219, inf, 1.0299999713897705, inf, 1.0579999685287476, 1.0850000381469727, inf, 1.1180000305175781, inf, 1.149999976158142, 1.187999963760376, inf, 1.225000023841858, inf, 1.2710000276565552, 1.3279999494552612, inf, 0.6050000190734863, inf, 0.5920000076293945, 0.5960000157356262, inf, inf, inf, 0.6000000238418579, 0.5929999947547913, inf, 0.5910000205039978, inf, 0.597000002861023, inf, 1.2589999437332153, inf, 1.2430000305175781, inf, 1.25, inf, inf, 1.184000015258789, inf, 1.2059999704360962, 0.1679999977350235, inf, 0.16599999368190765, inf, 1.597000002861023, inf, inf, inf, inf, inf, inf, inf, inf, inf, 0.5709999799728394, inf, inf, 0.21699999272823334, inf, inf, inf, inf, inf, inf, inf, 1.777999997138977, inf, inf, inf, 5.8379998207092285, inf, 5.841000080108643, 5.8470001220703125, inf, 6.051000118255615, inf, 6.051000118255615, 6.1570000648498535, inf, inf, inf, 7.072000026702881, 6.934999942779541, inf, inf, 7.072000026702881, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, 2.7119998931884766, inf]
intensities: [0.0, 0.0, 47.0, 47.0, 0.0, 47.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 47.0, 0.0, 0.0, 0.0, 47.0, 47.0, 0.0, 47.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 47.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 47.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 47.0, 0.0, 47.0, 0.0, 47.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 47.0, 0.0, 47.0, 47.0, 0.0, 47.0, 47.0, 0.0, 47.0, 0.0, 47.0, 47.0, 0.0, 47.0, 0.0, 47.0, 0.0, 47.0, 47.0, 0.0, 47.0, 0.0, 47.0, 47.0, 0.0, 47.0, 47.0, 0.0, 47.0, 0.0, 47.0, 47.0, 0.0, 47.0, 47.0, 0.0, 47.0, 0.0, 47.0, 47.0, 0.0, 47.0, 47.0, 0.0, 47.0, 0.0, 47.0, 47.0, 0.0, 47.0, 0.0, 47.0, 47.0, 0.0, 47.0, 47.0, 0.0, 0.0, 47.0, 47.0, 0.0, 47.0, 47.0, 0.0, 47.0, 0.0, 47.0, 47.0, 0.0, 47.0, 0.0, 47.0, 47.0, 0.0, 47.0, 0.0, 47.0, 47.0, 0.0, 47.0, 0.0, 47.0, 47.0, 0.0, 47.0, 0.0, 47.0, 0.0, 47.0, 47.0, 0.0, 47.0, 47.0, 0.0, 47.0, 0.0, 47.0, 47.0, 0.0, 47.0, 47.0, 0.0, 47.0, 47.0, 0.0, 47.0, 0.0, 47.0, 47.0, 0.0, 47.0, 0.0, 47.0, 47.0, 0.0, 47.0, 0.0, 0.0, 47.0, 0.0, 47.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 47.0, 0.0, 47.0, 0.0, 0.0, 0.0, 0.0, 47.0, 0.0, 47.0, 47.0, 0.0, 47.0, 0.0, 47.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 47.0, 0.0, 47.0, 0.0, 47.0, 47.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 47.0, 0.0, 47.0, 47.0, 0.0, 47.0, 47.0, 0.0, 47.0, 0.0, 47.0, 0.0, 47.0, 47.0, 0.0, 47.0, 0.0, 47.0, 47.0, 0.0, 47.0, 0.0, 47.0, 47.0, 0.0, 47.0, 0.0, 47.0, 47.0, 0.0, 0.0, 0.0, 47.0, 47.0, 0.0, 47.0, 0.0, 47.0, 0.0, 47.0, 0.0, 47.0, 0.0, 47.0, 0.0, 0.0, 47.0, 0.0, 47.0, 47.0, 0.0, 47.0, 0.0, 47.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 47.0, 0.0, 0.0, 47.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 47.0, 0.0, 0.0, 0.0, 47.0, 0.0, 47.0, 47.0, 0.0, 47.0, 0.0, 47.0, 47.0, 0.0, 0.0, 0.0, 47.0, 47.0, 0.0, 0.0, 47.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 47.0, 0.0]
</code>
下面对其中的参数进行逐个解释:
<code>Header header # Header也是一个结构体,包含了seq,stamp,frame_id,其中seq指的是扫描顺序增加的id,stamp包含了开始扫描的时间和与开始扫描的时间差,frame_id是扫描的参考系名称.注意扫描是逆时针从正前方开始扫描的.
float32 angle_min # 开始扫描的角度(角度)
float32 angle_max # 结束扫描的角度(角度)
float32 angle_increment # 每一次扫描增加的角度(角度)
float32 time_increment # 测量的时间间隔(s)
float32 scan_time # 扫描的时间间隔(s)
float32 range_min # 距离最小值(m)
float32 range_max # 距离最大值(m)
float32[] ranges # 距离数组(长度360)
float32[] intensities # 与设备有关,强度数组(长度360)
</code>
了解了LaserScan的数据格式,下面将编写一个订阅器用来接收LaserScan消息(假设roscore和laser都已经启动):
<code>
!/usr/bin/env python
import rospy
from sensor_msgs.msg import LaserScan
代码存放路径 your/workspace/src/packagename/scripts/listener.py
def callback(scan):
#LaserScan的数据结构
#std_msgs/Header header
#float32 angle_min
#float32 angle_max
#float32 angle_increment
#float32 time_increment
#float32 scan_time
#float32 range_min
#float32 range_max
#float32[] ranges
#float32[] intensities
rospy.loginfo('header: {0}'.format(scan))
def listener():
rospy.init_node('lasr_listener', anonymous=False)
rospy.Subscriber('scan', LaserScan,callback)
rospy.spin()
if name == 'main':
listener()
</code>
header项同前文GPS(ROS传感器之GPS简介), angle_min扫描起始角度, angle_max扫描结束角度, angle_increment两次扫描间隔的角度, time_increment两次扫描的时间间隔, scan_time此帧数据产生的时间,机械激光雷达数据点,是由旋转扫描产生,所以同一帧的每个点产生的时间都不一样, scan_time要表示整帧数据的时间,一般取第一帧和最后一帧的平均时间,或者使用GPS时间,这个后续再详细介绍。range_min最小有效距离, range_max最大有效距离, ranges所有扫描点的距离, intensities所有扫描点的反射强度。
- sensor_msgs/PointCloud2
sensor_msgs/PointCloud2代表点云数据,pcl是点云库,专门处理点云数据,通过将 sensor_msgs/LaserScan格式先转化为 sensor_msgs/PointCloud2格式,然后可以调用pcl算法,处理数据。执行以下命令:
rosmsg show sensor_msgs/PointCloud2
执行效果:
header项同前文GPS(ROS传感器之GPS简介),height表示高度,width表示宽度,可以把一帧点云数据看成图像数据,一个点对应一个像素,宽和高也与之对应。
is_bigendian
数据存储是否按照小端存储, point_step
表示一个点所占的字节数, row_step
表示一行点所占的字节数, is_dense
表示数据是否有效, data
实际存储点云数据, fields
表示每一个点云所包含的格式,可以按照 fields
区域把点云数据解析出来。以下是激光雷达 velodyne
的一帧点云数据,我们以此进一步说明此结构header代表本帧时间戳、序列号, frame_id设置为 velodyne;height为1, width为55823,所以此帧点云数:height×width=1×55823=55823, point_step为32,代表一个点占32字节, row_step为1786336,此数据代表一行所占的字节数:point_step×width=32×55823=1786336;此帧总的自己数:row_step×height=1786336×1=1786336, fields表示一个点的结构,x、y、z代表三维坐标, intensity代表反射强度, ring表示圈的序列号。fields中name代表 field name,offset代表一个点结构内的起始地址,datatype代表field数据类型,count代表field的个数。早期还有一个结构:sensor_msgs/PointCloud,也是表示点云数据,目前已经淘汰。