Apollo 10.0
自动驾驶开放平台
driver.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2017 The Apollo Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *****************************************************************************/
16
18
19namespace apollo {
20namespace drivers {
21namespace lslidar {
22namespace driver {
23
25 if (difop_thread_.joinable()) {
26 difop_thread_.join();
27 }
28}
29
31 int packets_rate;
32
34 packets_rate = 840;
35 } else if (config_.model() == LSLIDAR_C8_V4) {
36 packets_rate = 420;
37 } else if (config_.model() == LSLIDAR_C1_V4) {
38 packets_rate = 420;
39 } else if (config_.model() == LSLIDAR_C32_V4) {
40 packets_rate = 1693; // 64000/384
41 } else if (config_.model() == LSLIDAR32P) {
42 if (1 == config_.degree_mode())
43 packets_rate = 1693; // 65000/384
44 if (2 == config_.degree_mode())
45 packets_rate = 1700; // 64000/384
46 } else if (config_.model() == LSLIDAR_CH16) {
47 packets_rate = 3571;
48 } else if (config_.model() == LSLIDAR_CH32) {
49 packets_rate = 3512;
50 } else if (config_.model() == LSLIDAR_CH64) {
51 packets_rate = 3388;
52 } else if (config_.model() == LSLIDAR_CH64w) {
53 packets_rate = 11228;
54 } else if (config_.model() == LSLIDAR_CH128) {
55 packets_rate = 3571;
56 } else if (config_.model() == LSLIDAR_CH128X1) {
57 packets_rate = 6720;
58 } else if (config_.model() == LSLIDAR_LS128S2) {
59 packets_rate = 12440;
60 } else {
61 packets_rate = 4561;
62 }
63
64 // default number of packets for each scan is a single revolution
69 config_.set_npackets(static_cast<int>(
70 ceil(packets_rate * 60 / config_.rpm()) * config_.return_mode()
71 * 1.1));
72 else
73 config_.set_npackets(static_cast<int>(
74 ceil(packets_rate * 60 / config_.rpm() * 1.1)));
75
76 AERROR << "config_.pcap_path(): " << config_.pcap_path();
77
78 if (!config_.pcap_path().empty()) {
82 || config_.model() == LSLIDAR_C1_V4) {
83 // open Lslidar input device
84
85 input_.reset(new InputPCAP(
89 packets_rate,
90 config_.pcap_path())); // 数据包
94 1206,
95 1,
96 config_.pcap_path())); // 设备包
97 } else {
98 // open Lslidar input device
99 input_.reset(new InputPCAP(
103 packets_rate,
104 config_.pcap_path())); // 数据包
109 1,
110 config_.pcap_path())); // 设备包
111 }
112 } else {
116 || config_.model() == LSLIDAR_C1_V4) {
117 // open Lslidar input device
118 input_.reset(new InputSocket(
121 config_.packet_size())); // 数据包
125 1206)); // 设备包
126 } else {
127 // open Lslidar input device
128 input_.reset(new InputSocket(
131 config_.packet_size())); // 数据包
135 config_.packet_size())); // 设备包
136 }
137 }
138 difop_thread_ = std::thread(&LslidarDriver::difopPoll, this);
139}
140
146 const std::shared_ptr<apollo::drivers::lslidar::LslidarScan> &scan) {
147 // Allocate a new shared pointer for zero-copy sharing with other nodelets.
148 int poll_result = PollStandard(scan);
149 if (poll_result < 0)
150 return false;
151
152 if (scan->firing_pkts().empty()) {
153 AINFO << "Get an empty scan from port: " << config_.msop_port();
154 return false;
155 }
156 // publish message using time of last packet read
157 ADEBUG << "Publishing a full Lslidar scan.";
158 LslidarPacket *packet = scan->add_difop_pkts();
159 std::unique_lock<std::mutex> lock(mutex_);
160 packet->set_data(bytes, FIRING_DATA_PACKET_SIZE);
161 scan->mutable_header()->set_timestamp_sec(gps_time);
162 ADEBUG << "**************************************************************"
163 "GPS "
164 "time: "
165 << gps_time;
166 scan->mutable_header()->set_frame_id(config_.frame_id());
167 scan->set_model(config_.model());
168 scan->set_basetime(gps_time);
169 scan->mutable_header()->set_timestamp_sec(gps_time);
170 return true;
171}
172
174 std::shared_ptr<apollo::drivers::lslidar::LslidarScan> scan) {
175 // Since the lslidar delivers data at a very high rate, keep reading and
176 // publishing scans as fast as possible.
177
181 || config_.model() == LSLIDAR_C1_V4) {
182 // Find the 0 degree packet, in order to fix the 0 degree angle position
183 if (scan_fill) {
184 LslidarPacket *packet = scan->add_firing_pkts();
185 int PKT_DATA_LENGTH = 1212;
186 void *data_ptr = malloc(PKT_DATA_LENGTH);
187 memcpy(data_ptr,
188 reinterpret_cast<uint8_t *>(
189 const_cast<char *>(scan_start.data().c_str())),
190 PKT_DATA_LENGTH);
191 packet->set_data(data_ptr, PKT_DATA_LENGTH);
192 packet->set_stamp((scan_start.stamp()));
193 AINFO << "scan->firing_pkts_size(): " << scan->firing_pkts_size();
194 }
195
196 scan_fill = false;
197 int i = 1;
198 while (scan->firing_pkts_size() < config_.npackets()) {
199 // config_.npackets()
200 LslidarPacket *packet = scan->add_firing_pkts();
201 while (true) {
202 // keep reading until full packet received
203 int rc = input_->GetPacket(packet);
204
205 if (rc == 0) {
207 time_t t = time(NULL);
208 localtime_r(&t, &current_time);
209 current_time.tm_hour = current_time.tm_hour - 8;
210 packet_time_ns_ = 0;
212 } else {
213 uint8_t *data = reinterpret_cast<uint8_t *>(
214 const_cast<char *>(packet->data().c_str()));
215 if (config_.packet_size() == 1212) { // 1212字节雷达
216 if (0xff == data[1200]) { // ptp授时
217 // std::cout << "ptp";
219 = (data[1201] * pow(2, 32)
220 + data[1202] * pow(2, 24)
221 + data[1203] * pow(2, 16)
222 + data[1204] * pow(2, 8)
223 + data[1205] * pow(2, 0));
225 = (static_cast<uint16_t>(data[1206])
226 + static_cast<uint16_t>(data[1207])
227 * pow(2, 8)
228 + static_cast<uint16_t>(data[1208])
229 * pow(2, 16)
230 + static_cast<uint16_t>(data[1209])
231 * pow(2, 24));
232 } else { // gps授时
233 current_time.tm_year
234 = static_cast<uint16_t>(data[1200])
235 + 2000 - 1900;
236 current_time.tm_mon
237 = static_cast<uint16_t>(data[1201]) - 1;
238 current_time.tm_mday
239 = static_cast<uint16_t>(data[1202]);
240 current_time.tm_hour
241 = static_cast<uint16_t>(data[1203]);
242 current_time.tm_min
243 = static_cast<uint16_t>(data[1204]);
244
245 if (config_.model() == LSLIDAR16P
246 || config_.model() == LSLIDAR32P) {
247 current_time.tm_sec
248 = static_cast<uint16_t>(data[1205])
249 + 1;
251 = (static_cast<uint16_t>(data[1206])
252 + static_cast<uint16_t>(
253 data[1207])
254 * pow(2, 8)
255 + static_cast<uint16_t>(
256 data[1208])
257 * pow(2, 16)
258 + static_cast<uint16_t>(
259 data[1209])
260 * pow(2, 24))
261 * 1e3; // ns
262 } else if (
266 || config_.model() == LSLIDAR_C1_V4) {
267 current_time.tm_sec
268 = static_cast<uint16_t>(data[1205]);
270 = (static_cast<uint16_t>(data[1206])
271 + static_cast<uint16_t>(
272 data[1207])
273 * pow(2, 8)
274 + static_cast<uint16_t>(
275 data[1208])
276 * pow(2, 16)
277 + static_cast<uint16_t>(
278 data[1209])
279 * pow(2, 24));
280 }
281 basetime_ = static_cast<uint64_t>(
282 timegm(&current_time));
283 }
284 } else { // 1206字节雷达,V3.0
285 uint8_t *data = reinterpret_cast<uint8_t *>(
286 const_cast<char *>(packet->data().c_str()));
288 = (static_cast<uint16_t>(data[1200])
289 + static_cast<uint16_t>(data[1201])
290 * pow(2, 8)
291 + static_cast<uint16_t>(data[1202])
292 * pow(2, 16)
293 + static_cast<uint16_t>(data[1203])
294 * pow(2, 24))
295 * 1e3; // ns
296 basetime_ = static_cast<uint64_t>(
297 timegm(&current_time));
298 }
299 gps_time = basetime_ * 1000000000 + packet_time_ns_;
300 }
301 packet->set_stamp(gps_time);
302 break;
303 } else if (rc < 0) {
304 return rc;
305 }
306 }
307 packet->set_stamp(gps_time); // 設置包的時間
308
309 uint8_t *data = reinterpret_cast<uint8_t *>(
310 const_cast<char *>(packet->data().c_str()));
311 int azi1 = 256 * static_cast<uint16_t>(data[3])
312 + static_cast<uint16_t>(data[2]);
313 int azi2 = 256 * static_cast<uint16_t>(data[1103])
314 + static_cast<uint16_t>(data[1102]);
315
316 if (((azi1 > 35000 && azi2 < 1000)
317 || (azi1 < 500 && i > config_.npackets() / 2))) {
318 scan_fill = true;
319 scan_start = *packet;
320 break;
321 }
322 i++;
323 }
324 } else if (config_.model() == LSLIDAR_LS128S2) { // LS128S2
325 // Find the 0 degree packet, in order to fix the 0 degree angle position
326 scan_fill = false;
327 int i = 1;
328 bool is_found_frame_header = false;
329 while (scan->firing_pkts_size() < config_.npackets()
330 && !is_found_frame_header) {
331 LslidarPacket *packet = scan->add_firing_pkts();
332 while (true) {
333 // keep reading until full packet received
334 int rc = input_->GetPacket(packet);
335 AINFO << "[debug ] line: " << __LINE__
336 << " file: " << __FILE__;
337 if (rc == 0) {
339 time_t t = time(NULL);
340 localtime_r(&t, &current_time);
341 current_time.tm_hour = current_time.tm_hour - 8;
343 } else {
344 uint8_t *data = reinterpret_cast<uint8_t *>(
345 const_cast<char *>(packet->data().c_str()));
346 if (0xff
347 == static_cast<uint16_t>(data[1194])) { // ptp授时
349 = (static_cast<uint16_t>(data[1195]) * 0
350 + (static_cast<uint16_t>(data[1196])
351 << 24)
352 + (static_cast<uint16_t>(data[1197])
353 << 16)
354 + (static_cast<uint16_t>(data[1198])
355 << 8)
356 + static_cast<uint16_t>(data[1199])
357 * pow(2, 0));
359 = (static_cast<uint16_t>(data[1200]) << 24)
360 + (static_cast<uint16_t>(data[1201]) << 16)
361 + (static_cast<uint16_t>(data[1202]) << 8)
362 + (static_cast<uint16_t>(data[1203]));
363 gps_time = basetime_ * 1000000000 + packet_time_ns_;
364 } else { // gps授时
365 struct tm cur_time {};
366 memset(&cur_time, 0, sizeof(cur_time));
367 cur_time.tm_sec = static_cast<uint16_t>(data[1199]);
368 cur_time.tm_min = static_cast<uint16_t>(data[1198]);
369 cur_time.tm_hour
370 = static_cast<uint16_t>(data[1197]);
371 cur_time.tm_mday
372 = static_cast<uint16_t>(data[1196]);
373 cur_time.tm_mon
374 = static_cast<uint16_t>(data[1195]) - 1;
375 cur_time.tm_year = static_cast<uint16_t>(data[1194])
376 + 2000 - 1900;
378 = static_cast<uint64_t>(timegm(&cur_time));
379 packet_time_ns_ = static_cast<uint16_t>(data[1203])
380 + (static_cast<uint16_t>(data[1202]) << 8)
381 + (static_cast<uint16_t>(data[1201]) << 16)
382 + (static_cast<uint16_t>(data[1200])
383 << 24); // ns
384 gps_time = basetime_ * 1000000000 + packet_time_ns_;
385 }
386 }
387 break;
388 } else if (rc < 0) {
389 return rc;
390 }
391 }
392 packet->set_stamp(gps_time); // 設置包的時間
393 uint8_t *data = reinterpret_cast<uint8_t *>(
394 const_cast<char *>(packet->data().c_str()));
395 int return_mode = static_cast<uint16_t>(data[1205]);
396
397 if (return_mode == 1) {
398 for (size_t point_idx = 0;
399 point_idx < LS_POINTS_PER_PACKET_SINGLE_ECHO;
400 point_idx += 8) { // 一圈
401 if ((static_cast<uint16_t>(data[point_idx]) == 0xff)
402 && (static_cast<uint16_t>(data[point_idx + 1]) == 0xaa)
403 && (static_cast<uint16_t>(data[point_idx + 2]) == 0xbb)
404 && (static_cast<uint16_t>(data[point_idx + 3]) == 0xcc)
405 && (static_cast<uint16_t>(data[point_idx + 4])
406 == 0xdd)) {
407 scan_fill = false;
408 is_found_frame_header = true;
409
410 break;
411 }
412 }
413 } else {
414 for (size_t point_idx = 0;
415 point_idx < LS_POINTS_PER_PACKET_DOUBLE_ECHO;
416 point_idx += 12) { // 一圈
417 if ((static_cast<uint16_t>(data[point_idx]) == 0xff)
418 && (static_cast<uint16_t>(data[point_idx + 1]) == 0xaa)
419 && (static_cast<uint16_t>(data[point_idx + 2]) == 0xbb)
420 && (static_cast<uint16_t>(data[point_idx + 3]) == 0xcc)
421 && (static_cast<uint16_t>(data[point_idx + 4])
422 == 0xdd)) {
423 scan_fill = false;
424 is_found_frame_header = true;
425 AERROR << "\none circle! scan->firing_pkts_size(): "
426 << scan->firing_pkts_size();
427 break;
428 }
429 }
430 }
431 i++;
432 }
433 } else { // ch系列
434 // Find the 0 degree packet, in order to fix the 0 degree angle position
435 scan_fill = false;
436 int i = 1;
437 bool is_found_frame_header = false;
438 while (scan->firing_pkts_size() < config_.npackets()
439 && !is_found_frame_header) {
440 LslidarPacket *packet = scan->add_firing_pkts();
441 while (true) {
442 // keep reading until full packet received
443 int rc = input_->GetPacket(packet);
444 AINFO << "[debug ] line: " << __LINE__
445 << " file: " << __FILE__;
446 if (rc == 0) {
450 || config_.model() == LSLIDAR_CH32) {
452 time_t t = time(NULL);
453 localtime_r(&t, &current_time);
454 current_time.tm_hour = current_time.tm_hour - 8;
456 .Now()
457 .ToNanosecond();
458 } else {
459 uint8_t *data = reinterpret_cast<uint8_t *>(
460 const_cast<char *>(packet->data().c_str()));
461 current_time.tm_hour
462 = static_cast<uint16_t>(data[1197]);
463 current_time.tm_min
464 = static_cast<uint16_t>(data[1198]);
465 current_time.tm_sec
466 = static_cast<uint16_t>(data[1199]);
467 basetime_ = static_cast<uint64_t>(
468 timegm(&current_time));
469 if (time_service_mode == "gps") {
471 = (static_cast<uint16_t>(data[1203])
472 + static_cast<uint16_t>(data[1202])
473 * pow(2, 8)
474 + static_cast<uint16_t>(data[1201])
475 * pow(2, 16)
476 + static_cast<uint16_t>(data[1200])
477 * pow(2, 24))
478 * 1e3; // ns
479 } else if (time_service_mode == "gptp") {
481 = (static_cast<uint16_t>(data[1203])
482 + static_cast<uint16_t>(data[1202])
483 * pow(2, 8)
484 + static_cast<uint16_t>(data[1201])
485 * pow(2, 16)
486 + static_cast<uint16_t>(data[1200])
487 * pow(2, 24)); // ns
488 }
489 gps_time = basetime_ * 1000000000 + packet_time_ns_;
490 }
491 }
492 break;
493 } else if (rc < 0) {
494 return rc;
495 }
496 }
497 packet->set_stamp(gps_time); // 設置包的時間
498 uint8_t *data = reinterpret_cast<uint8_t *>(
499 const_cast<char *>(packet->data().c_str()));
500
501 for (size_t point_idx = 0; point_idx < POINTS_PER_PACKET;
502 point_idx += 7) { // 一圈
503 if ((static_cast<uint16_t>(data[point_idx]) == 0xff)
504 && (static_cast<uint16_t>(data[point_idx + 1]) == 0xaa)
505 && (static_cast<uint16_t>(data[point_idx + 2]) == 0xbb)
506 && (static_cast<uint16_t>(data[point_idx + 3]) == 0xcc)) {
507 scan_fill = false;
508 is_found_frame_header = true;
509 AERROR << "\none circle! scan->firing_pkts_size(): "
510 << scan->firing_pkts_size();
511 break;
512 }
513 }
514 i++;
515 }
516 }
517 return 0;
518}
519
521 while (!cyber::IsShutdown()) {
522 std::shared_ptr<apollo::drivers::lslidar::LslidarScan> scans
523 = std::make_shared<apollo::drivers::lslidar::LslidarScan>();
524 std::shared_ptr<LslidarPacket> packet
525 = std::make_shared<LslidarPacket>();
526 while (!cyber::IsShutdown()) {
527 int rc = positioning_input_->GetPacket(packet.get());
528 if (rc == 0) {
529 break; // got a full packet
530 }
531 if (rc < 0) {
532 return;
533 }
534 }
535 uint8_t *data = reinterpret_cast<uint8_t *>(
536 const_cast<char *>(packet->data().c_str()));
537 {
538 std::unique_lock<std::mutex> lock(mutex_);
539 memcpy(bytes, data, FIRING_DATA_PACKET_SIZE);
540 }
542 time_t t = time(NULL);
543 localtime_r(&t, &current_time);
544 current_time.tm_hour = current_time.tm_hour - 8;
545 } else {
546 if (data[0] == 0xA5 && data[1] == 0xFF && data[2] == 0x00
547 && data[3] == 0x5A) {
548 if (config_.model() == LSLIDAR_CH16
551 || config_.model() == LSLIDAR_CH64) {
552 current_time.tm_year
553 = static_cast<uint16_t>(data[36] + 100);
554 current_time.tm_mon = static_cast<uint16_t>(data[37] - 1);
555 current_time.tm_mday = static_cast<uint16_t>(data[38]);
556 current_time.tm_hour = static_cast<uint16_t>(data[39]);
557 current_time.tm_min = static_cast<uint16_t>(data[40]);
558 current_time.tm_sec = static_cast<uint16_t>(data[41]);
559 } else if (config_.model() == LSLIDAR_CH64w) {
560 current_time.tm_year
561 = static_cast<uint16_t>(data[52] + 100);
562 current_time.tm_mon = static_cast<uint16_t>(data[53] - 1);
563 current_time.tm_mday = static_cast<uint16_t>(data[54]);
564 if (data[44] == 0x00) { // gps授时
565 time_service_mode = "gps";
566 } else if (data[44] == 0x01) { // ptp授时
567 time_service_mode = "gptp";
568 }
569 } else if (config_.model() == LSLIDAR_CH120) {
570 current_time.tm_year
571 = static_cast<uint16_t>(data[36] + 100);
572 current_time.tm_mon = static_cast<uint16_t>(data[37] - 1);
573 current_time.tm_mday = static_cast<uint16_t>(data[38]);
574 } else if (config_.model() == LSLIDAR_CH128X1) {
575 current_time.tm_year
576 = static_cast<uint16_t>(data[52] + 100);
577 current_time.tm_mon = static_cast<uint16_t>(data[53] - 1);
578 current_time.tm_mday = static_cast<uint16_t>(data[54]);
579 if (data[44] == 0x00) { // gps授时
580 time_service_mode = "gps";
581 } else if (data[44] == 0x01) { // ptp授时
582 time_service_mode = "gptp";
583 }
584 } else if (
585 config_.packet_size() == 1206
586 && (config_.model() == LSLIDAR32P
587 || config_.model() == LSLIDAR16P)) {
588 current_time.tm_year
589 = static_cast<uint16_t>(data[52] + 100);
590 current_time.tm_mon = static_cast<uint16_t>(data[53] - 1);
591 current_time.tm_mday = static_cast<uint16_t>(data[54]);
592 current_time.tm_hour = static_cast<uint16_t>(data[55]);
593 current_time.tm_min = static_cast<uint16_t>(data[56]);
594 current_time.tm_sec = static_cast<uint16_t>(data[57]);
595 }
596 }
597 }
598 }
599}
600
602 LslidarDriver *driver = nullptr;
603 driver = new LslidarDriver(config);
604 return driver;
605}
606
607} // namespace driver
608} // namespace lslidar
609} // namespace drivers
610} // namespace apollo
Cyber has builtin time type Time.
Definition time.h:31
uint64_t ToNanosecond() const
convert time to nanosecond.
Definition time.cc:83
static Time Now()
get the current time.
Definition time.cc:57
lslidar input from PCAP dump file.
Definition input.h:69
Live lslidar input from socket.
Definition input.h:53
static LslidarDriver * CreateDriver(const Config &config)
Definition driver.cc:601
uint8_t bytes[FIRING_DATA_PACKET_SIZE]
Definition driver.h:91
int PollStandard(std::shared_ptr< apollo::drivers::lslidar::LslidarScan > scan)
Definition driver.cc:173
bool Poll(const std::shared_ptr< apollo::drivers::lslidar::LslidarScan > &scan)
poll the device
Definition driver.cc:145
std::unique_ptr< Input > positioning_input_
Definition driver.h:68
#define ADEBUG
Definition log.h:41
#define AERROR
Definition log.h:44
#define AINFO
Definition log.h:42
bool IsShutdown()
Definition state.h:46
class register implement
Definition arena_queue.h:37