激光雷达的配置和ROS消息

配置雷达

我用的雷达是sick LMS511,配置步骤可以参考SICK激光雷达LMS511笔记

连接直流电源24V,将雷达网线连接到无线路由器。准备一个windows电脑,连接到雷达的同一个无线网,开启雷达配送的调试工具Sick sensor intellingence,搜索设备获得雷达,记住IP:192.168.10.100,双击设备图标进入配置页面。

在另一台Ubuntu电脑上进行驱动配置,也是连到同一个无线网,先测试能否ping通,如不能则按上面步骤配置。

使用驱动lms511_laser_node,下载后放到某工作空间中,先在lms5xx_node.cpp中,在ip_add修改雷达的IP,然后使用catkin_make --pkg laser_node编译。

数据表示

激光雷达获取的数据是以以雷达为中心的极坐标系表示, 激光雷达以数据帧的方式返还数据
2020-05-31_105134.png
2020-05-31_105250.png

雷达的消息和参数

消息成员

启动roscore后,用rosrun laser_node laser_node启动驱动程序,会有很多输出信息。
使用命令rosnode list查看运行的节点列表,发现了sicklms5xx

使用rostopic list查看主题,发现了主题scan,信息如下:

其消息类型是sensor_msgs/LaserScan,发布者是sicklidar,其消息成员如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
Header header            # 时间戳是收到第一束激光的时间
# in frame frame_id, angles are measured around
# the positive Z axis (counterclockwise, if Z is up)
# with zero angle being forward along the x axis
float32 angle_min # 扫描起始角度[rad]
float32 angle_max # 扫描结束角度[rad]
float32 angle_increment # 角分辨率,相邻扫描点的角度增量,[弧度]
float32 time_increment # 每个数据点的时间间隔 [秒]
float32 scan_time # 当前帧数据与下一帧数据的时间间隔 [秒]
float32 range_min # 最小的扫描距离 [m]
float32 range_max # 最大的扫描距离 [m]
float32[] ranges # 各个方向的扫描数据 [m]
float32[] intensities # 雷达的强度数据,思岚有,有些SICK雷达没有

使用命令rostopic echo scan可查看雷达扫描到的数据:

扫描角度

1
2
angle_min: -1.65806281567
angle_max: 1.65806281567

经过换算,其实就是-95°~95°,而雷达的扫描范围是190°,显然扫描范围是个对称的扇形。雷达角度范围是-1.658~1.658, 角分辨率是0.00872, 这样算出来大概是380, 也就是380个激光束射出。

雷达有旋转方向的问题,大部分雷达都是逆时针旋转,这和ROS中的习惯一致,少数雷达是顺时针,这就会对建图和定位产生问题。比如EAI YDLIDAR G4既可正转也可反转。

判断angle_minangle_max的大小,就能知道雷达扫描的方向,因为雷达的扫描角度都是从angle_min到angle_max变化的。如果angle_min<angle_max,就是逆时针。这样雷达数据从极坐标系转换到笛卡尔右手系时,才能使用公式angle = angle_min + (i * angle_increment)。某些雷达已经在驱动里处理过了,即使顺时针旋转,也可以直接用此公式。

换句话说,angle_min应该叫开始角度angle_max应该叫结束角度

扫描距离

激光传感器在每次扫描都会返回几百个数据,这就是ranges数组。每秒钟还要扫描很多次,这是由scan_time描述,也就是每秒扫出一个扇形(一帧),对每个扫描束都必须处理一个ray-tracing操作.

需要保证range数组中元素的存储顺序与扫描到顺序一致:

  • ranges数组中第一个元素存的scan中第一个扫描到点
  • ranges数组中最后一个元素存的scan中最后一个扫描到的点

如果我们有个rosbag文件,使用rosbag info可以看到这样的结果:
scan消息.png
这里面有360个msg,也就是雷达扫描了360次,注意这不是ranges数组的大小

ranges是个float32类型数组,但不同雷达的ranges大小不同,获得数组大小的方法是 rostopic echo --noarr /scan/ranges,会不断显示<array type: float32, length: 381>,可以看到ranges的大小是381,和激光束的数量基本对应。

A2的量程是0.15-12/18,还是基于白色高反光物体测得。 使用A2时,不能离障碍物太近,否则会出现ranges数组很多个0的情况,这一点在导航时要注意

LMS511最大检测81m,所以说适合室外。这个参数一般是在良好的反射率情况下得到的,对黑色物体的检测量程没这么大。


有时的ranges会出现很多inf和nan的情况,这个对不同雷达的处理可能不同,对于A2,可以看一下源码是这样的:

1
2
if (read_value == 0.0)
scan_msg.ranges[node_count-1-i] = std::numeric_limits<float>::infinity();

也就是读取距离为0时,输出inf

对于北洋雷达,距离超过测量范围时候的两种情况是INF,其余由于强度或其他原因导致的数据错误会输出。

强度

雷达数据强度是反映生成某点的激光雷达脉冲回波强度的一种测量指标(针对每个点而采集)。 雷达强度数据跟激光的反射情况有关,如果射向黑色物体,可能不会有反馈 数组intensities与ranges中的数据是一一对应的,描述的是每个测量数据的强度。

雷达在室外跟室内区别, 基本的点就是光照条件的区别

问题

  • 启动地图后,移动机器人,雷达轨迹跟随移动

先看雷达安装朝上还是朝下,程序中要保持一致。如果没问题,把所有程序关闭再启动,一般会恢复正常

  • 启动雷达,雷达未分配到IP,导致无法使用;运行雷达节点时,突然报错,雷达无法扫描到数据,然后雷达IP丢失

  1. 雷达扫描的结果比实际偏一定角度

偏移的scan.png
正常scan.png
再三试验,应当是rviz视角问题

参考:
Turtlebot3中级教程-应用-自动泊车
EAI的YDLIDAR-X4激光雷达在ROS下使用方法