激光雷达工作原理
激光雷达主要用来探测周围障碍物的状况,其按照测量的维度可以分为
- 单线雷达
- 多线雷达
按照测量的原理可以分为:
- 三角测距雷达
- TOF雷达
按照工作方式可以分为
- 机械旋转雷达
- 固态雷达
激光雷达在ROS中数据格式一般是一样。
下面以TOF激光雷达作为例子讲解:
激光雷法一般分为两个部分,一个是底座,一个是可旋转的头部结构。
左边一个红外激光发射器,右边一个红外激光接收器。
红外激光发射后遇到障碍物反弹回来,被红外激光接收器捕获。通过计时器测量激光发射和接收的间隔时长乘以光速就可以算出激光这一趟的飞行长度,飞行长度除以2就可以得到激光雷达到障碍物的距离。
激光雷达测量完一个方向的障碍物距离后,会旋转一个角度再射出一道红外激光,再接受返回来的红外激光。一直重复操作,直到雷达探测头旋转一整周,360度。
只要激光束探测的频率足够高,旋转的速度足够快就能实时的刷新周围障碍物的分布状况。于是在ROS中的rivz中可以看到一个障碍物轮廓的点阵分布图。
ROS中的激光雷达数据格式就是对于这么一个障碍物轮廓点阵的具体描述。
使用RViz(The Robot Visualization Tool)观测传感器数据
RViz可以视为是一个数据可视化工具。可以可视化机器人传感器上采集到的数据都可以显示出来。
又比如机器人完成了去往某个地点的路径规划,可以在RViz中将路径显示出来。
ROS系统中的激光雷达消息包格式
打开index.ros.org网站,搜索 sensor_msgs
.
angle_min: -3.14 意味着初始角度是顺时针转180度,就是机器人的正后方。
angle_max: 3.14 意味着最终角度是逆时针转180度,也是机器人的正后方,因此机器人将逆时针转一周。
强调一下ranges变量,这是一个数组,数组成员类型是32位浮点数,数组长度为360.
这里的360个浮点数就是激光雷达从起始角度旋转到终止角度这一过程中测量的距离个数。而雷达正好扫描了360度,因此,每旋转1度就进行一次测距行为。
ranges里的360个测距值对应的就是每一度方向的障碍物距离。这些测距值按照扫描的 起始角度 到 终止角度 的顺序排列。
注意:这360个测距值可能有的是无效的,因为可能障碍物的距离超出了雷达的测距范围,这时该测距值会显示为INF。
intensities数组长度也是360个,这个数组成员的大小代表的是每一次测距的信号强度,数值越大表示这次测距的信号强度越强,得到的测距数值更可信。
激光雷达数据包里的前几个数据一般都是固定的,用 rostopic echo
看一眼就行,真正有用的数值是里面的ranges数组。
在ROS中用C++实现获取激光雷达数据
激光雷达一般会有一个对应的节点,一般有激光雷达的厂商提供,只需要配置几个参数即可与电路系统连接。
电路系统将测距值发送给激光雷达节点,然后节点将其封装成一个消息包发送到雷达数据话题中,我们只需要订阅这个话题就能获取激光雷达的数据了。
思路和实现步骤:
- 构建一个新的软件包,包名叫做
lidar_pkg
。 - 在软件包新建一个节点,节点名叫做
lidar_node
。 - 在节点中,向ROS大管家NodeHandle申请订阅话题
/scan
,并设置回调函数为LidarCallback()
。 - 构建回调函数
LidarCallback()
,用来接受和处理雷达数据。 - 调用
ROS_INFO()
显示雷达检测到的前方障碍物距离。
终端输入
cd ~/catlin_ws/src
cd catkin_create_pkg lidar_pkg roscpp rospy sensor_msgs
来构建一个新的软件包
然后在软件包新建一个节点文件:lidar_node.cpp
在里面写入如下代码:
#include <ros/ros.h>
#include <sensor_msgs/LaserScan.h>
void LidarCallback(const sensor_msgs::LaserScan msg)
{
float fMidDist = msg.ranges[180]; // 机器人正前方的距离
ROS_INFO("前方测距 ranges[180] = %f 米", fMidDist);
}
int main(int argc, char *argv[])
{
setlocale(LC_ALL, "zh_CN.UTF-8");
ros::init(argc, argv, "lidar_node");
ros::NodeHandle n;
ros::Subscriber lidar_sub = n.subscribe("/scan", 10, LidarCallback);
ros::spin();
return 0;
}
在ROS中用Python实现获取激光雷达数据
实现思路和C++大致相同,需要在lidar_pkg
目录下新建一个文件夹scripts
。然后在该目录下新建一个节点文件lidar_node.py
。