激光雷达工作时会先在当前位置发出激光并接收反射光束,解析得到距离信息,而后激光发射器会转过一个角度分辨率对应的角度再次重复这个过程。限于物理及机械方面的限制,激光雷达通常会有一部分“盲区”。使用激光雷达返回的数据通常可以描绘出一幅极坐标图,极点位于雷达扫描中心,0-360°整周圆由扫描区域及盲区组成。在扫描区域中激光雷达在每个角度分辨率对应位置解析出的距离值会被依次连接起来,这样,通过极坐标表示就能非常直观地看到周围物体的轮廓,激光雷达扫描范围示意图可以参见下图。

  激光雷达通常有四个性能衡量指标:测距分辨率、扫描频率(有时也用扫描周期)、角度分辨率及可视范围。测距分辨率衡量在一个给定的距离下测距的精确程度,通常与距离真实值相差在5-20mm;扫描频率衡量激光雷达完成一次完整扫描的快慢,通常在10Hz及以上;角度分辨率直接决定激光雷达一次完整扫描能返回多少个样本点;可视范围指激光雷达完整扫描的广角,可视范围之外即为盲区。

  目前,移动机器人的研究中已经大量使用激光雷达辅助机器人的避障导航。通常激光雷达会提供ROS驱动,如果没有的话我们也可以自己采集激光数据后按照ROS中定义的消息格式将信息发布出去。首先,输入下面的指令查看LaserScan消息结构:

rosmsg show sensor_msgs/LaserScan

  LaserScan消息结构如下:

std_msgs/Header header
  uint32 seq
  time stamp
  string frame_id    # 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 # start angle of the scan [rad]
float32 angle_max # end angle of the scan [rad]
float32 angle_increment # angular distance between measurements [rad] float32 time_increment # time between measurements [seconds] - if your scanner
# is moving, this will be used in interpolating position
# of 3d points
float32 scan_time # time between scans [seconds] float32 range_min # minimum range value [m]
float32 range_max # maximum range value [m] float32[] ranges # range data [m] (Note: values < range_min or > range_max should be discarded)
float32[] intensities # intensity data [device-specific units]. If your device does not provide intensities, please leave the array empty.

  以下图为例,该激光雷达扫描范围为270°,角度分辨率为0.25°,扫描距离为0~20m,每扫描一圈会得到1081个点:

  那么该激光雷达发布的LaserScan消息内容如下:

angle_min= - * (pi/);       //angle correspond to FIRST beam in scan ( in rad)
angle_max= * (pi/); //angle correspond to LAST beam in scan ( in rad)
angle_increment =0.25 * (pi/); // Angular resolution i.e angle between 2 beams // lets assume sensor gives 50 scans per second. i.e every 20 milli seconds 1 scan with 1081 beams.
// Each beam is measured in (20 ms/ 1081 ) ~ = 0.0185 ms
time_increment = ( / ) / (); scan_time = ; // scan is collected at which time
range_min = ; // in meters
range_max = ; // scan can measure upto this range
// ranges is array of 1081 floats for each laser beam
ranges[] = //distance measure corresponds to angle -135 deg
ranges[] = //distance measure corresponds to angle -134.75 deg
.
.
.
ranges[] = //distance measure corresponds to angle +135 deg // To understand Intensities
// if a laser beam hits reflective surface like glass it will have intensity 1.
// And if beam hit some surface which absorbs laser , then intensity is zero.
// Middle values are different surfaces in between.

  下面的代码模拟了激光雷达的数据,并将sensor_msgs/LaserScan消息发布到/scan话题上:

#include <ros/ros.h>
#include <sensor_msgs/LaserScan.h> int main(int argc, char** argv)
{
ros::init(argc, argv, "laser_scan_publisher");
ros::NodeHandle n; ros::Publisher scan_pub = n.advertise<sensor_msgs::LaserScan>("scan", ); unsigned int num_readings = ;
double laser_frequency = ;
double ranges[num_readings];
double intensities[num_readings];
int count = ; ros::Rate r(1.0); while(n.ok())
{
//generate some fake data for our laser scan
for(unsigned int i = ; i < num_readings; ++i)
{
ranges[i] = count;
intensities[i] = + count;
}
ros::Time scan_time = ros::Time::now(); //populate the LaserScan message
sensor_msgs::LaserScan scan;
scan.header.stamp = scan_time;
scan.header.frame_id = "base_link";
scan.angle_min = -1.57;
scan.angle_max = 1.57;
scan.angle_increment = 3.14 / num_readings;
scan.time_increment = ( / laser_frequency) / (num_readings);
scan.range_min = 0.0;
scan.range_max = 100.0;
scan.ranges.resize(num_readings);
scan.intensities.resize(num_readings);
for(unsigned int i = ; i < num_readings; ++i)
{
scan.ranges[i] = ranges[i];
scan.intensities[i] = intensities[i];
} scan_pub.publish(scan); ++count;
r.sleep();
}
}

  可以在rviz中将激光数据点显示出来:Fixed Frame修改为base_link,添加LaserScan并将Topic设为/scan

  如果Fixed Frame为map,为了能正确显示出激光扫描点来,需要发布map和base_link之间的坐标变换关系(因为我们的激光数据是相对于base_link坐标系描述的)。如果这两个参考系不发生相对位置变化,那么可以用static_transform_publisher工具发布两个参考系之间的静态坐标变换。

  命令的格式如下:

  • static_transform_publisher  x  y  z  yaw  pitch  roll  frame_id  child_frame_id  period_in_ms
  • static_transform_publisher  x  y  z  qx  qy  qz  qw  frame_id   child_frame_id  period_in_ms

  以上两种命令格式,需要设置坐标的偏移和旋转参数,偏移参数都使用相对于x、y、z三轴的坐标位移。旋转参数第一种命令格式使用以弧度为单位的 yaw/pitch/roll三个角度,第二种命令格式使用四元数表达旋转角度。发布频率以ms为单位,一般100ms比较合适。

  static_transform_publisher is designed both as a command-line tool for manual use, as well as for use within roslaunch files for setting static transforms. For example:

<launch>
  <node pkg="tf" type="static_transform_publisher" name="link1_broadcaster" args="1 0 0 0 0 0 1 link1_parent link1 100" />
</launch>

ROS中使用激光雷达(镭神智能)

  LS01C是深圳市镭神智能系统有限公司研发的激光三角测距系统 。在机械旋转模块的带动下,LS01C 的高频核心测距模块将进行顺时钟旋转,从而实现对周围环境进行360°扫描测距。LS01C通过uart 串口信号与外部系统通讯,默认每秒采样3600点、扫描频率10hz,最大扫描距离6m,角度分辨率为1度。

  将LS01C的ROS驱动文件(官网上没有下载连接,直接打电话给客服要的)解压重命名为talker后复制到catkin_ws/src下面,然后使用catkin_make进行编译

  插入USB后在终端中输入以下命令查看USB转串口设备:

  在发现ttyUSB0后在终端中输入下面命令给USB 转串口设置权限:

sudo chmod 666 /dev/ttyUSB0

  修改launch文件中的串口名,改为我们插入的ttyUSB0

<launch>
<node name="talker" pkg="talker" type="talker">
   <param name="scan_topic" value="scan"/> <!-- 设置激光数据topic名称 -->
   <param name="laser_link" value="laser_link"/> <!-- 激光坐标 -->
   <param name="serial_port" value="/dev/ttyUSB0"/> <!-- 雷达连接的串口 -->
</node>
</launch>

  然后执行launch文件

roslaunch talker talker.launch

  在终端中可以看到talker节点已经开启:

  打开rviz,添加LaserScan并设置topic和参考坐标系,可以动态的显示激光扫描点:

  还可以通过 rostopic hz命令查看激光数据发布频率,可以看出其频率为10Hz

参考:

ROS中发布IMU传感器消息

VREP中的二维激光雷达

激光雷达学习笔记(二)数据读取和显示

激光雷达学习笔记(三)特征提取

激光雷达学习笔记(四)定位

explanation on sensor_msgs/LaserScan

Learning ROS for Robotics Programming - Second Edition

ROS中发布激光扫描消息的更多相关文章

  1. ROS中发布IMU传感器消息

    下面使用SYD Dynamics的9轴AHRS(Attitude and heading reference system),来发布sensor_msgs/Imu类型的消息. 将传感器用USB转串口接 ...

  2. ROS中利用V-rep进行地图构建仿真

    V-rep中显示激光扫描点  在VREP自带的场景中找到practicalPathPlanningDemo.ttt文件,删除场景中多余的物体只保留静态的地图.然后在Model browser→comp ...

  3. 将ROS中的/sensor_msgs/NavSatFix数据导入google earth显示轨迹

    将ros中的gps_msg数据导入google earth显示轨迹 [TOC] 1. 获取GPS数据 将ros中发布的gps topic输出到文本中 rostopic echo -p /gpsData ...

  4. [实例]ROS使用OpenCV读取图像并发布图像消息在rviz中显示

    思路: (1)使用opencv读取本地图像 (2)调用cv_bridge::CvImage().toImageMsg()将本地图像发送给rviz显示 一.使用opencv读取本地图像并发布图像消息 ( ...

  5. ROS中的日志(log)消息

    学会使用日志(log)系统,做ROS大型项目的主治医生 通过显示进程的运行状态是好的习惯,但需要确定这样做不会影响到软件的运行效率和输出的清晰度.ROS 日志 (log) 系统的功能就是让进程生成一些 ...

  6. ROS开发--在订阅话题的回调函数中发布话题

    处理激光数据时,需要将处理后的激光数据再发布,需要保持一致的频率,所以必须在回调函数中发布激光数据信息. 代码参考:https://blog.csdn.net/heyijia0327/article/ ...

  7. [转]ROS中使用message_filters进行多传感器消息同步

    转:http://www.rosclub.cn/post-1030.html 最近实验室老师在做一个多传感器数据采集实验,涉及到了消息同步.所以就学习了ROS官网下的消息同步工具message_fil ...

  8. ROS主题发布订阅

    节点是一个可执行程序,它连接到了ROS的网络系统中.我们将会创建一个发布者,也就是说话者节点,它将会持续的广播一个信息. 改变目录到之前所建立的那个包下: cd ~/catkin_ws/src/beg ...

  9. 如何在ROS中使用PCL(2)

    记录关于我们运行roslaunch openni_launch openni.launch  命令时生成的话题以及这些话题的数据类型便于后期的处理,只有知道它们的数据结构,才能很好的对数据进行处理,我 ...

随机推荐

  1. 使用DebugView小工具调试已部署的.net程序 (转)

    DebugView for Windows能够捕捉Debug输出的信息在本地的操作系统上.如何你需要调试程序有网络访问推荐使用Wireshark和监听HTTP的工具Fiddler. 下载下来是一个ZI ...

  2. CSS-图片不变形设置

    不管网页做的美还是丑,有一个问题始终是无法躲避的,就是有的时候会遇到图片变形的问题,之前遇到过这种问题解决过,不过还是整体的重新研究了一下图片,其中主要涉及到的知识点就是max-width和max-h ...

  3. 混合开发 Hybird Ionic Angular Cordova web 跨平台 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  4. 基于Bootstrap+jQuery.validate Form表单验证实践

    基于Bootstrap jQuery.validate Form表单验证实践 项目结构 :     github 上源码地址:https://github.com/starzou/front-end- ...

  5. 超链接a标签的href与onclick中使用javascript的区别

    onclick中javascript的区别一般没用到都没注意,但出错时才有些郁闷,看文本章解释如下: 以前一直很随意,后来看.net里的linkbutton似乎是用在<a href=" ...

  6. 【算法】Java-Redis-Hash算法对比-参考资料

    Java-Redis-Hash算法对比-参考资料 redis java map 红黑树_百度搜索 java使用redis缓存(String,bean,list,map) - CSDN博客 redis ...

  7. Mongo = get size of single document

      Object.bsonsize(db.test.findOne({type:"auto"}))

  8. Sublime 3156 LICENSE key

    mac sublime3 3156 LICENSE 转自:http://blog.csdn.net/myboyliu2007/article/details/78748253 下载地址:https:/ ...

  9. DOM元素尺寸offsetWidth,scrollWidth,clientWidth等具体解释

    样例: <div id="div" style="height: 200px;width: 200px;border:solid 50px red;overflow ...

  10. SuperMap入门3——Hello World

    Hello World程序很重要,对于入门来说,它可以检测我们的环境.配置是否正确,感受程序的易用性等. 添加工具 由于我是使用的VS2017+ SuperMap iObject绿色免安装版,所以新建 ...