23static float g_fDistanceAcc = 0.1 * 0.01;
24static double cos30 = std::cos(
DEG2RAD(30));
25static double sin30 = std::sin(
DEG2RAD(30));
26static double sin60 = std::sin(
DEG2RAD(60));
29 LslidarParser(config), previous_packet_stamp_(0), gps_base_usec_(0) {
31 for (
int j = 0; j < 36000; ++j) {
32 double angle =
static_cast<double>(j) / 100.0 * M_PI / 180.0;
33 sin_table[j] = sin(angle);
34 cos_table[j] = cos(angle);
37 double mirror_angle[4]
39 for (
int i = 0; i < 4; ++i) {
40 cos_mirror_angle[i] = cos(
DEG2RAD(mirror_angle[i]));
41 sin_mirror_angle[i] = sin(
DEG2RAD(mirror_angle[i]));
48 const std::shared_ptr<LslidarScan> &scan_msg,
49 const std::shared_ptr<PointCloud> &out_msg) {
51 out_msg->mutable_header()->set_timestamp_sec(
52 scan_msg->basetime() / 1000000000.0);
53 out_msg->mutable_header()->set_module_name(
54 scan_msg->header().module_name());
55 out_msg->mutable_header()->set_frame_id(scan_msg->header().frame_id());
56 out_msg->set_height(1);
57 out_msg->set_measurement_time(scan_msg->basetime() / 1000000000.0);
58 out_msg->mutable_header()->set_sequence_num(
59 scan_msg->header().sequence_num());
60 gps_base_usec_ = scan_msg->basetime();
63 const unsigned char *difop_ptr
64 = (
const unsigned char *)scan_msg->difop_pkts(0).data().c_str();
66 if (difop_ptr[0] == 0x00 || difop_ptr[0] == 0xa5) {
67 if (difop_ptr[1] == 0xff && difop_ptr[2] == 0x00
68 && difop_ptr[3] == 0x5a) {
69 if (difop_ptr[231] == 64 || difop_ptr[231] == 65) {
73 int majorVersion = difop_ptr[1202];
74 int minorVersion1 = difop_ptr[1203] / 16;
77 if (1 > majorVersion || (1 == majorVersion && minorVersion1 > 1)) {
78 g_fAngleAcc_V = 0.0025;
83 float fInitAngle_V = difop_ptr[188] * 256 + difop_ptr[189];
84 if (fInitAngle_V > 32767) {
85 fInitAngle_V = fInitAngle_V - 65536;
87 this->
prism_angle[0] = fInitAngle_V * g_fAngleAcc_V;
89 fInitAngle_V = difop_ptr[190] * 256 + difop_ptr[191];
90 if (fInitAngle_V > 32767) {
91 fInitAngle_V = fInitAngle_V - 65536;
93 this->
prism_angle[1] = fInitAngle_V * g_fAngleAcc_V;
95 fInitAngle_V = difop_ptr[192] * 256 + difop_ptr[193];
96 if (fInitAngle_V > 32767) {
97 fInitAngle_V = fInitAngle_V - 65536;
99 this->
prism_angle[2] = fInitAngle_V * g_fAngleAcc_V;
101 fInitAngle_V = difop_ptr[194] * 256 + difop_ptr[195];
102 if (fInitAngle_V > 32767) {
103 fInitAngle_V = fInitAngle_V - 65536;
105 this->
prism_angle[3] = fInitAngle_V * g_fAngleAcc_V;
109 packets_size = scan_msg->firing_pkts_size();
110 packet_number_ = packets_size;
112 for (
size_t i = 0; i < packets_size; ++i) {
113 Unpack(
static_cast<int>(i),
114 scan_msg->firing_pkts(
static_cast<int>(i)),
119 if (frame_count >= 2) {
121 for (
int j = 0; j < cur_pc->point_size(); ++j) {
123 point3->set_timestamp(cur_pc->point(j).timestamp());
124 point3->set_intensity(cur_pc->point(j).intensity());
125 point3->set_x(cur_pc->point(j).x());
126 point3->set_y(cur_pc->point(j).y());
127 point3->set_z(cur_pc->point(j).z());
134 for (
int j = 0; j < cur_pc->point_size(); ++j) {
136 point3->set_timestamp(cur_pc->point(j).timestamp());
137 point3->set_intensity(cur_pc->point(j).intensity());
138 point3->set_x(cur_pc->point(j).x());
139 point3->set_y(cur_pc->point(j).y());
140 point3->set_z(cur_pc->point(j).z());
145 AINFO <<
"line: " << __LINE__ <<
"out_msg size: " << out_msg->point_size();
146 AINFO <<
"packets_size :" << packets_size;
147 if (out_msg->point().empty()) {
153 out_msg->set_width(out_msg->point_size());
154 out_msg->set_height(1);
161void LslidarLS128S2Parser::Unpack(
164 std::shared_ptr<PointCloud> out_msg) {
166 uint64_t packet_end_time;
167 const unsigned char *msop_ptr = (
const unsigned char *)pkt.
data().c_str();
169 packet_end_time = pkt.
stamp();
171 if (msop_ptr[1205] == 0x02) {
175 if (return_mode == 1) {
177 / (POINTS_PER_PACKET_SINGLE_ECHO / 8.0);
178 for (
size_t point_idx = 0; point_idx < POINTS_PER_PACKET_SINGLE_ECHO;
180 if ((msop_ptr[point_idx] == 0xff)
181 && (msop_ptr[point_idx + 1] == 0xaa)
182 && (msop_ptr[point_idx + 2] == 0xbb)
183 && (msop_ptr[point_idx + 3] == 0xcc)
184 && (msop_ptr[point_idx + 4] == 0xdd)) {
189 if (last_packet_time > 1e-6) {
190 point_time = packet_end_time
191 - packet_interval_time
192 * ((POINTS_PER_PACKET_SINGLE_ECHO
200 memset(&lidardata, 0,
sizeof(lidardata));
203 = msop_ptr[point_idx + 1] + (msop_ptr[point_idx] << 8);
204 if (fAngle_H > 32767) {
205 fAngle_H = (fAngle_H - 65536);
207 lidardata.azimuth = fAngle_H * 0.01;
209 int iTempAngle = msop_ptr[point_idx + 2];
210 int iChannelNumber = iTempAngle >> 6;
211 int iSymmbol = (iTempAngle >> 5) & 0x01;
212 double fAngle_V = 0.0;
214 int iAngle_V = msop_ptr[point_idx + 3]
215 + (msop_ptr[point_idx + 2] << 8);
217 fAngle_V = iAngle_V | 0xc000;
218 if (fAngle_V > 32767) {
219 fAngle_V = (fAngle_V - 65536);
222 int iAngle_Hight = iTempAngle & 0x3f;
223 fAngle_V = msop_ptr[point_idx + 3] + (iAngle_Hight << 8);
226 lidardata.vertical_angle = fAngle_V * g_fAngleAcc_V;
227 lidardata.channel_number = iChannelNumber;
229 = ((msop_ptr[point_idx + 4] << 16)
230 + (msop_ptr[point_idx + 5] << 8)
231 + msop_ptr[point_idx + 6]);
232 lidardata.intensity = msop_ptr[point_idx + 7];
233 lidardata.time = point_time;
234 lidardata.azimuth = fAngle_H * 0.01;
240 / (POINTS_PER_PACKET_DOUBLE_ECHO / 12.0);
241 for (
size_t point_idx = 0; point_idx < POINTS_PER_PACKET_DOUBLE_ECHO;
243 if ((msop_ptr[point_idx] == 0xff)
244 && (msop_ptr[point_idx + 1] == 0xaa)
245 && (msop_ptr[point_idx + 2] == 0xbb)
246 && (msop_ptr[point_idx + 3] == 0xcc)
247 && (msop_ptr[point_idx + 4] == 0xdd)) {
252 if (last_packet_time > 1e-6) {
253 point_time = packet_end_time
254 - packet_interval_time
255 * ((POINTS_PER_PACKET_DOUBLE_ECHO
262 memset(&lidardata, 0,
sizeof(lidardata));
265 = msop_ptr[point_idx + 1] + (msop_ptr[point_idx] << 8);
266 if (fAngle_H > 32767) {
267 fAngle_H = (fAngle_H - 65536);
269 lidardata.azimuth = fAngle_H * 0.01;
272 int iTempAngle = msop_ptr[point_idx + 2];
273 int iChannelNumber = iTempAngle >> 6;
274 int iSymmbol = (iTempAngle >> 5) & 0x01;
275 double fAngle_V = 0.0;
277 int iAngle_V = msop_ptr[point_idx + 3]
278 + (msop_ptr[point_idx + 2] << 8);
280 fAngle_V = iAngle_V | 0xc000;
281 if (fAngle_V > 32767) {
282 fAngle_V = (fAngle_V - 65536);
285 int iAngle_Hight = iTempAngle & 0x3f;
286 fAngle_V = msop_ptr[point_idx + 3] + (iAngle_Hight << 8);
289 lidardata.vertical_angle = fAngle_V * g_fAngleAcc_V;
290 lidardata.channel_number = iChannelNumber;
292 = ((msop_ptr[point_idx + 4] << 16)
293 + (msop_ptr[point_idx + 5] << 8)
294 + msop_ptr[point_idx + 6]);
295 lidardata.intensity = msop_ptr[point_idx + 7];
296 lidardata.time = point_time;
300 = ((msop_ptr[point_idx + 8] << 16)
301 + (msop_ptr[point_idx + 9] << 8)
302 + msop_ptr[point_idx + 10]);
303 lidardata.intensity = msop_ptr[point_idx + 11];
304 lidardata.time = point_time;
308 last_packet_time = packet_end_time;
324 double fAngle_H = 0.0;
325 double fAngle_V = 0.0;
330 double fSinV_angle = 0;
331 double fCosV_angle = 0;
334 double fGalvanometrtAngle = 0;
335 fGalvanometrtAngle = fAngle_V + 7.26;
337 while (fGalvanometrtAngle < 0.0) {
338 fGalvanometrtAngle += 360.0;
340 while (fAngle_H < 0.0) {
344 int table_index_V =
static_cast<int>(fGalvanometrtAngle * 100) % 36000;
345 int table_index_H =
static_cast<int>(fAngle_H * 100) % 36000;
347 double fAngle_R0 = cos30 * cos_mirror_angle[lidardata.
channel_number % 4]
348 * cos_table[table_index_V]
349 - sin_table[table_index_V]
352 fSinV_angle = 2 * fAngle_R0 * sin_table[table_index_V]
354 fCosV_angle = sqrt(1 - pow(fSinV_angle, 2));
356 double fSinCite = (2 * fAngle_R0 * cos_table[table_index_V] * sin30
359 double fCosCite = sqrt(1 - pow(fSinCite, 2));
361 double fSinCite_H = sin_table[table_index_H] * fCosCite
362 + cos_table[table_index_H] * fSinCite;
363 double fCosCite_H = cos_table[table_index_H] * fCosCite
364 - sin_table[table_index_H] * fSinCite;
366 double x_coord = 0.0, y_coord = 0.0, z_coord = 0.0;
367 x_coord = (lidardata.
distance * fCosV_angle * fSinCite_H) * g_fDistanceAcc;
368 y_coord = (lidardata.
distance * fCosV_angle * fCosCite_H) * g_fDistanceAcc;
369 z_coord = (lidardata.
distance * fSinV_angle) * g_fDistanceAcc;
377 point1->set_timestamp(lidardata.
time);
378 point1->set_intensity(lidardata.
intensity);
379 point1->set_x(y_coord);
380 point1->set_y(-x_coord);
381 point1->set_z(z_coord);
384 point2->set_timestamp(lidardata.
time);
385 point2->set_intensity(lidardata.
intensity);
386 point2->set_x(y_coord);
387 point2->set_y(-x_coord);
388 point2->set_z(z_coord);
394 std::shared_ptr<PointCloud> out_cloud) {
405 double fAngle_H = 0.0;
406 double fAngle_V = 0.0;
411 double fSinV_angle = 0;
412 double fCosV_angle = 0;
415 double fGalvanometrtAngle = 0;
416 fGalvanometrtAngle = fAngle_V + 7.26;
418 while (fGalvanometrtAngle < 0.0) {
419 fGalvanometrtAngle += 360.0;
421 while (fAngle_H < 0.0) {
425 int table_index_V =
static_cast<int>(fGalvanometrtAngle * 100) % 36000;
426 int table_index_H =
static_cast<int>(fAngle_H * 100) % 36000;
428 double fAngle_R0 = cos30 * cos_mirror_angle[lidardata.
channel_number % 4]
429 * cos_table[table_index_V]
430 - sin_table[table_index_V]
433 fSinV_angle = 2 * fAngle_R0 * sin_table[table_index_V]
435 fCosV_angle = sqrt(1 - pow(fSinV_angle, 2));
437 double fSinCite = (2 * fAngle_R0 * cos_table[table_index_V] * sin30
440 double fCosCite = sqrt(1 - pow(fSinCite, 2));
442 double fSinCite_H = sin_table[table_index_H] * fCosCite
443 + cos_table[table_index_H] * fSinCite;
444 double fCosCite_H = cos_table[table_index_H] * fCosCite
445 - sin_table[table_index_H] * fSinCite;
447 double x_coord = 0.0, y_coord = 0.0, z_coord = 0.0;
448 x_coord = (lidardata.
distance * fCosV_angle * fSinCite_H) * g_fDistanceAcc;
449 y_coord = (lidardata.
distance * fCosV_angle * fCosCite_H) * g_fDistanceAcc;
450 z_coord = (lidardata.
distance * fSinV_angle) * g_fDistanceAcc;
458 point1->set_timestamp(lidardata.
time);
459 point1->set_intensity(lidardata.
intensity);
460 point1->set_x(y_coord);
461 point1->set_y(-x_coord);
462 point1->set_z(z_coord);
465 point2->set_timestamp(lidardata.
time);
466 point2->set_intensity(lidardata.
intensity);
467 point2->set_x(y_coord);
468 point2->set_y(-x_coord);
469 point2->set_z(z_coord);
472 point3->set_timestamp(lidardata.
time);
473 point3->set_intensity(lidardata.
intensity);
474 point3->set_x(y_coord);
475 point3->set_y(-x_coord);
476 point3->set_z(z_coord);
LslidarLS128S2Parser(const Config &config)
void Order(std::shared_ptr< PointCloud > cloud)
void GeneratePointcloud(const std::shared_ptr< LslidarScan > &scan_msg, const std::shared_ptr< PointCloud > &out_msg)
int convertCoordinate(const struct Firing_LS128S2 &lidardata)
Lslidar data conversion class
uint64_t current_packet_time
These classes Unpack raw Lslidar LIDAR packets into several useful formats.
#define DEG2RAD(x)
Raw Lslidar packet constants and structures.
optional float bottom_left_y
optional float scan_end_angle
optional float top_right_x
optional float top_right_y
optional float bottom_left_x
optional float scan_start_angle