lslidar_c16_decoder.h
Go to the documentation of this file.
1 /*
2  * This file is part of lslidar_c16 driver.
3  *
4  * The driver is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * The driver is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with the driver. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef LSLIDAR_C16_DECODER_H
19 #define LSLIDAR_C16_DECODER_H
20 
21 #define DEG_TO_RAD 0.017453292
22 #define RAD_TO_DEG 57.29577951
23 
24 #include <cmath>
25 #include <vector>
26 #include <string>
27 #include <boost/shared_ptr.hpp>
28 
29 #include <ros/ros.h>
30 #include <sensor_msgs/PointCloud2.h>
31 #include <sensor_msgs/LaserScan.h>
32 #include <std_msgs/Int8.h>
34 #include <pcl_ros/point_cloud.h>
35 #include <pcl/point_types.h>
36 
37 #include <lslidar_c16_msgs/LslidarC16Packet.h>
38 #include <lslidar_c16_msgs/LslidarC16Point.h>
39 #include <lslidar_c16_msgs/LslidarC16Scan.h>
40 #include <lslidar_c16_msgs/LslidarC16Sweep.h>
41 #include <lslidar_c16_msgs/LslidarC16Layer.h>
42 
43 
45 
46 // Raw lslidar packet constants and structures.
47 static const int SIZE_BLOCK = 100;
48 static const int RAW_SCAN_SIZE = 3;
49 static const int SCANS_PER_BLOCK = 32;
50 static const int BLOCK_DATA_SIZE =
51  (SCANS_PER_BLOCK * RAW_SCAN_SIZE);
52 
53 // According to Bruce Hall DISTANCE_MAX is 65.0, but we noticed
54 // valid packets with readings up to 130.0.
55 static const double DISTANCE_MAX = 130.0;
56 static const double DISTANCE_RESOLUTION = 0.01;
57 static const double DISTANCE_MAX_UNITS =
58  (DISTANCE_MAX / DISTANCE_RESOLUTION + 1.0);
59 
61 static const uint16_t UPPER_BANK = 0xeeff;
62 static const uint16_t LOWER_BANK = 0xddff;
63 
65 static const int FIRINGS_PER_BLOCK = 2;
66 static const int SCANS_PER_FIRING = 16;
67 static const double BLOCK_TDURATION = 110.592; // [µs]
68 static const double DSR_TOFFSET = 2.304; // [µs]
69 static const double FIRING_TOFFSET = 55.296; // [µs]
70 
71 static const int PACKET_SIZE = 1206;
72 static const int BLOCKS_PER_PACKET = 12;
73 static const int PACKET_STATUS_SIZE = 4;
74 static const int SCANS_PER_PACKET =
75  (SCANS_PER_BLOCK * BLOCKS_PER_PACKET);
76 static const int FIRINGS_PER_PACKET =
77  FIRINGS_PER_BLOCK * BLOCKS_PER_PACKET;
78 
79 // Pre-compute the sine and cosine for the altitude angles.
80 static const double scan_altitude[16] = {
81  -0.2617993877991494, 0.017453292519943295,
82  -0.22689280275926285, 0.05235987755982989,
83  -0.19198621771937624, 0.08726646259971647,
84  -0.15707963267948966, 0.12217304763960307,
85  -0.12217304763960307, 0.15707963267948966,
86  -0.08726646259971647, 0.19198621771937624,
87  -0.05235987755982989, 0.22689280275926285,
88  -0.017453292519943295, 0.2617993877991494
89 };
90 
91 static const double cos_scan_altitude[16] = {
92  std::cos(scan_altitude[ 0]), std::cos(scan_altitude[ 1]),
93  std::cos(scan_altitude[ 2]), std::cos(scan_altitude[ 3]),
94  std::cos(scan_altitude[ 4]), std::cos(scan_altitude[ 5]),
95  std::cos(scan_altitude[ 6]), std::cos(scan_altitude[ 7]),
96  std::cos(scan_altitude[ 8]), std::cos(scan_altitude[ 9]),
97  std::cos(scan_altitude[10]), std::cos(scan_altitude[11]),
98  std::cos(scan_altitude[12]), std::cos(scan_altitude[13]),
99  std::cos(scan_altitude[14]), std::cos(scan_altitude[15]),
100 };
101 
102 static const double sin_scan_altitude[16] = {
103  std::sin(scan_altitude[ 0]), std::sin(scan_altitude[ 1]),
104  std::sin(scan_altitude[ 2]), std::sin(scan_altitude[ 3]),
105  std::sin(scan_altitude[ 4]), std::sin(scan_altitude[ 5]),
106  std::sin(scan_altitude[ 6]), std::sin(scan_altitude[ 7]),
107  std::sin(scan_altitude[ 8]), std::sin(scan_altitude[ 9]),
108  std::sin(scan_altitude[10]), std::sin(scan_altitude[11]),
109  std::sin(scan_altitude[12]), std::sin(scan_altitude[13]),
110  std::sin(scan_altitude[14]), std::sin(scan_altitude[15]),
111 };
112 
113 typedef struct{
114  double distance;
115  double intensity;
116 }point_struct;
117 
118 struct PointXYZIT {
119  PCL_ADD_POINT4D
120  uint8_t intensity;
121  double timestamp;
122  EIGEN_MAKE_ALIGNED_OPERATOR_NEW // make sure our new allocators are aligned
123 } EIGEN_ALIGN16;
124 // enforce SSE padding for correct memory alignment
125 
127 public:
128 
130  LslidarC16Decoder(const LslidarC16Decoder&) = delete;
131  LslidarC16Decoder operator=(const LslidarC16Decoder&) = delete;
132  ~LslidarC16Decoder() {return;}
133 
134  bool initialize();
135 
138 
139 private:
140 
141  union TwoBytes {
142  uint16_t distance;
143  uint8_t bytes[2];
144  };
145 
146  struct RawBlock {
147  uint16_t header;
148  uint16_t rotation;
149  uint8_t data[BLOCK_DATA_SIZE];
150  };
151 
152  struct RawPacket {
154  uint32_t time_stamp;
155  uint8_t factory[2];
156  };
157 
158  struct Firing {
159  // Azimuth associated with the first shot within this firing.
161  double azimuth[SCANS_PER_FIRING];
164  };
165 
166  // Intialization sequence
167  bool loadParameters();
168  bool createRosIO();
169 
170 
171  // Callback function for a single lslidar packet.
172  bool checkPacketValidity(const RawPacket* packet);
173  void decodePacket(const RawPacket* packet);
174  void layerCallback(const std_msgs::Int8Ptr& msg);
175  void packetCallback(const lslidar_c16_msgs::LslidarC16PacketConstPtr& msg);
176  // Publish data
177  void publishPointCloud();
178  void publishChannelScan();
179  // Publish scan Data
180  void publishScan();
181 
182  // Check if a point is in the required range.
183  bool isPointInRange(const double& distance) {
184  return (distance >= min_range && distance <= max_range);
185  }
186 
187  double rawAzimuthToDouble(const uint16_t& raw_azimuth) {
188  // According to the user manual,
189  // azimuth = raw_azimuth / 100.0;
190  return static_cast<double>(raw_azimuth) / 100.0 * DEG_TO_RAD;
191  }
192 
193  // calc the means_point
194  point_struct getMeans(std::vector<point_struct> clusters);
195 
196  // configuration degree base
198  double angle_base;
199 
200  // Configuration parameters
201  double min_range;
202  double max_range;
207  double frequency;
212  double cos_azimuth_table[6300];
213  double sin_azimuth_table[6300];
214 
216  double last_azimuth;
221 
222  // ROS related parameters
225 
226  //std::string fixed_frame_id;
227  std::string frame_id;
228 
229  lslidar_c16_msgs::LslidarC16SweepPtr sweep_data;
230  lslidar_c16_msgs::LslidarC16LayerPtr multi_scan;
231  sensor_msgs::PointCloud2 point_cloud_data;
232 
239 
240 };
241 
245 typedef pcl::PointCloud<VPoint> VPointCloud;
246 
247 } // end namespace lslidar_c16_decoder
248 
249 
250 POINT_CLOUD_REGISTER_POINT_STRUCT(lslidar_c16_decoder::PointXYZIT,
251  (float, x, x)(float, y, y)(float, z, z)(
252  uint8_t, intensity,
253  intensity)(double, timestamp, timestamp))
254 #endif
static const double DISTANCE_RESOLUTION
uint16_t rotation
0-35999, divide by 100 to get degrees
static const int PACKET_STATUS_SIZE
LslidarC16Decoder::LslidarC16DecoderConstPtr LslidarC16DecoderConstPtr
#define DEG_TO_RAD
pcl::PointCloud< VPoint > VPointCloud
ROSCONSOLE_DECL void initialize()
static const double DISTANCE_MAX
bool isPointInRange(const double &distance)
static const int FIRINGS_PER_BLOCK
static const int BLOCK_DATA_SIZE
TFSIMD_FORCE_INLINE tfScalar distance(const Vector3 &v) const
boost::shared_ptr< const LslidarC16Decoder > LslidarC16DecoderConstPtr
static const double cos_scan_altitude[16]
static const int FIRINGS_PER_PACKET
static const double FIRING_TOFFSET
static const double DISTANCE_MAX_UNITS
double rawAzimuthToDouble(const uint16_t &raw_azimuth)
static const int SCANS_PER_BLOCK
lslidar_c16_msgs::LslidarC16LayerPtr multi_scan
static const uint16_t LOWER_BANK
boost::shared_ptr< LslidarC16Decoder > LslidarC16DecoderPtr
static const double scan_altitude[16]
static const int RAW_SCAN_SIZE
lslidar_c16_msgs::LslidarC16SweepPtr sweep_data
static const int SCANS_PER_FIRING
static const int SCANS_PER_PACKET
static const double BLOCK_TDURATION
struct lslidar_c16_decoder::PointXYZIT EIGEN_ALIGN16
static const double sin_scan_altitude[16]
LslidarC16Decoder::LslidarC16DecoderPtr LslidarC16DecoderPtr
static const double DSR_TOFFSET
static const int BLOCKS_PER_PACKET
static const int PACKET_SIZE
PCL_ADD_POINT4D uint8_t intensity
static const uint16_t UPPER_BANK
static const int SIZE_BLOCK


lslidar_c16_decoder
Author(s): Yutong
autogenerated on Thu Aug 22 2019 03:51:41