ROS中发布激光扫描消息

描述

 


	

激光雷达工作时会先在当前位置发出激光并接收反射光束,解析得到距离信息,而后激光发射器会转过一个角度分辨率对应的角度再次重复这个过程。

 

限于物理及机械方面的限制,激光雷达通常会有一部分“盲区”。使用激光雷达返回的数据通常可以描绘出一幅极坐标图,极点位于雷达扫描中心,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 pointsfloat32 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= -135 * (pi/180);       
//angle correspond to FIRST beam in scan ( in rad)angle_max= 135 * (pi/180);        
//angle correspond to LAST beam in scan ( in rad)angle_increment =0.25 * (pi/180); 
// 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 mstime_increment  = (1 / 50) / (1081); 
scan_time = ;    
// scan is collected at which timerange_min =0 ;   
// in metersrange_max = 20;  
// scan can measure upto this range// ranges is array of 1081 floats for each laser beamranges[0] =      
//distance measure corresponds to angle -135 degranges[1] =      
//distance measure corresponds to angle -134.75 deg    
.    
.    
.ranges[1080] =   
//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 #include 
int main(int argc, char** argv){    
ros::init(argc, argv, "laser_scan_publisher");    
ros::NodeHandle n;
    ros::Publisher scan_pub = n.advertise("scan", 50);
    unsigned int num_readings = 100;    
double laser_frequency = 40;   
 double ranges[num_readings];    
double intensities[num_readings];    
int count = 0;
    ros::Rate r(1.0);
    while(n.ok())    
{        
//generate some fake data for our laser scan        
for(unsigned int i = 0; i < num_readings; ++i)        
{            
ranges[i] = count;            
intensities[i] = 100 + count;        
}        
ros::Time scan_time = ros::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 = (1 / 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 = 0; 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_msstatic_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:

 

  "tf" type="static_transform_publisher" 
name="link1_broadcaster" 
args="1 0 0 0 0 0 1 link1_parent link1 100" />

 

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

 

    "talker" pkg="talker" type="talker">         
 "scan_topic" value="scan"/>                     "laser_link" value="laser_link"/>              
 "serial_port" value="/dev/ttyUSB0"/>      

 

然后执行launch文件

 

roslaunch talker talker.launch

 

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

 

激光扫描

 

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

 

激光扫描

 

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

 

激光扫描  

审核编辑 :李倩


打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分