ROS:二维激光雷达

本文最后更新于:2020年8月5日 下午

1. LaserScan

1
$ rosmsg show sensor_msgs/LaserScan
1
2
3
4
5
6
7
8
9
10
11
12
13
std_msgs/Header header
uint32 seq
time stamp
string frame_id
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

1.1 ROS Message Headers

To standardize how this information is sent, the Header message type is used as a field in all such messages.

  • seq: an identifier that automatically increases as Messages are sent from a given publisher
  • stamp: time information that should be associated with data in a Message
  • frame_id: tf frame information that should be associated with data in a message.

In the case of a laser scan

  • the stamp might correspond to the time at which the scan was taken
  • the frame_id would be set to the frame in which the scan was taken.
1
2
3
4
5
6
7
8
9
10
11
12
#Standard metadata for higher-level flow data types
#sequence ID: consecutively increasing ID
uint32 seq
#Two-integer timestamp that is expressed as:
# * stamp.secs: seconds (stamp_secs) since epoch
# * stamp.nsecs: nanoseconds since stamp_secs
# time-handling sugar is provided by the client library
time stamp
#Frame this data is associated with
# 0: no frame
# 1: global frame
string frame_id

1.2 The LaserScan Message

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#
# Laser scans angles are measured counter clockwise, with 0 facing forward
# (along the x-axis) of the device frame
#

Header header
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]
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]

2. Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#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", 50);

// set up storage for the dummy data that we're going to use to populate our scan
// A real application would pull this data from their laser driver
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::Time::now();

//populate the LaserScan message
sensor_msgs::LaserScan scan;
scan.header.stamp = scan_time;
scan.header.frame_id = "laser_frame";
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];
}

//Publish the message over ROS.
scan_pub.publish(scan);
++count;
r.sleep();
}
}

3. rplidar

The rplidar ros package, support rplidar A2/A1 and A3/S1

3.1 Overview

RPLIDAR

  • a low cost LIDAR sensor suitable for indoor robotic SLAM application
  • 360 degree scan field
  • 5.5hz/10hz rotating frequency
  • 8 meter ranger distance, current more than 16m for A2 and 25m for A3
  • RPLIDAR A3 performs high speed distance measurement with more than 16K samples per second
  • RPLIDAR A2 performs high speed distance measurement with more than 4K/8K samples per second
  • RPLIDAR A1 supports 2K/4K samples per second

3.2 rplidarNode

rplidarNode is a driver for RPLIDAR. It reads RPLIDAR raw scan result using RPLIDAR’s SDK and convert to ROS LaserScan message.

Published Topics

scan sensor_msgs/LaserScan it publishes scan topic from the laser.
- - -

Services

stop_motor std_srvs/Empty Call the serive to stop the motor of rplidar.
start_motor std_srvs/Empty Call the service to start the motor of rplidar.

Parameters

serial_port string, default: /dev/ttyUSB0 serial port name used in your system.
serial_baudrate int, default: 115200 serial port baud rate.
frame_id string, default: laser_frame frame ID for the device.
inverted bool, default: false indicated whether the LIDAR is mounted inverted.
angle_compensate bool, default: false indicated whether the driver needs do angle compensation.
scan_mode string, default: std::string() the scan mode of lidar.

4. References