sl_lidar_driver.cpp
Go to the documentation of this file.
1 /*
2  * Slamtec LIDAR SDK
3  *
4  * Copyright (c) 2014 - 2020 Shanghai Slamtec Co., Ltd.
5  * http://www.slamtec.com
6  *
7  */
8  /*
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
29  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  *
31  */
32 
33 #include "sdkcommon.h"
34 #include "hal/abs_rxtx.h"
35 #include "hal/thread.h"
36 #include "hal/types.h"
37 #include "hal/assert.h"
38 #include "hal/locker.h"
39 #include "hal/socket.h"
40 #include "hal/event.h"
41 #include "hal/waiter.h"
42 #include "hal/byteorder.h"
43 #include "sl_lidar_driver.h"
44 #include "sl_crc.h"
45 #include <algorithm>
46 #include <memory>
47 #include <atomic>
48 #include <deque>
49 
51 #include "sl_async_transceiver.h"
52 #include "sl_lidarprotocol_codec.h"
53 
54 
55 
56 #ifdef _WIN32
57 #define NOMINMAX
58 #undef min
59 #undef max
60 #endif
61 
62 #if defined(__cplusplus) && __cplusplus >= 201103L
63 #ifndef _GXX_NULLPTR_T
64 #define _GXX_NULLPTR_T
65 typedef decltype(nullptr) nullptr_t;
66 #endif
67 #endif /* C++11. */
68 
69 namespace sl {
70  static void printDeprecationWarn(const char* fn, const char* replacement)
71  {
72  fprintf(stderr, "*WARN* YOU ARE USING DEPRECATED API: %s, PLEASE MOVE TO %s\n", fn, replacement);
73  }
74 
75  static void convert(const sl_lidar_response_measurement_node_t& from, sl_lidar_response_measurement_node_hq_t& to)
76  {
77  to.angle_z_q14 = (((from.angle_q6_checkbit) >> SL_LIDAR_RESP_MEASUREMENT_ANGLE_SHIFT) << 8) / 90; //transfer to q14 Z-angle
78  to.dist_mm_q2 = from.distance_q2;
79  to.flag = (from.sync_quality & SL_LIDAR_RESP_MEASUREMENT_SYNCBIT); // trasfer syncbit to HQ flag field
80  to.quality = (from.sync_quality >> SL_LIDAR_RESP_MEASUREMENT_QUALITY_SHIFT) << SL_LIDAR_RESP_MEASUREMENT_QUALITY_SHIFT; //remove the last two bits and then make quality from 0-63 to 0-255
81  }
82 
83  static void convert(const sl_lidar_response_measurement_node_hq_t& from, sl_lidar_response_measurement_node_t& to)
84  {
86  to.angle_q6_checkbit = 1 | (((from.angle_z_q14 * 90) >> 8) << SL_LIDAR_RESP_MEASUREMENT_ANGLE_SHIFT);
87  to.distance_q2 = from.dist_mm_q2 > sl_u16(-1) ? sl_u16(0) : sl_u16(from.dist_mm_q2);
88  }
89 
90 
91  static inline float getAngle(const sl_lidar_response_measurement_node_t& node)
92  {
93  return (node.angle_q6_checkbit >> SL_LIDAR_RESP_MEASUREMENT_ANGLE_SHIFT) / 64.f;
94  }
95 
96  static inline void setAngle(sl_lidar_response_measurement_node_t& node, float v)
97  {
98  sl_u16 checkbit = node.angle_q6_checkbit & SL_LIDAR_RESP_MEASUREMENT_CHECKBIT;
99  node.angle_q6_checkbit = (((sl_u16)(v * 64.0f)) << SL_LIDAR_RESP_MEASUREMENT_ANGLE_SHIFT) | checkbit;
100  }
101 
102  static inline float getAngle(const sl_lidar_response_measurement_node_hq_t& node)
103  {
104  return node.angle_z_q14 * 90.f / 16384.f;
105  }
106 
107  static inline void setAngle(sl_lidar_response_measurement_node_hq_t& node, float v)
108  {
109  node.angle_z_q14 = sl_u32(v * 16384.f / 90.f);
110  }
111 
112  static inline sl_u16 getDistanceQ2(const sl_lidar_response_measurement_node_t& node)
113  {
114  return node.distance_q2;
115  }
116 
117  static inline sl_u32 getDistanceQ2(const sl_lidar_response_measurement_node_hq_t& node)
118  {
119  return node.dist_mm_q2;
120  }
121 
122  template <class TNode>
123  static bool angleLessThan(const TNode& a, const TNode& b)
124  {
125  return getAngle(a) < getAngle(b);
126  }
127 
128  template < class TNode >
129  static sl_result ascendScanData_(TNode * nodebuffer, size_t count)
130  {
131  float inc_origin_angle = 360.f / count;
132  size_t i = 0;
133 
134  //Tune head
135  for (i = 0; i < count; i++) {
136  if (getDistanceQ2(nodebuffer[i]) == 0) {
137  continue;
138  }
139  else {
140  while (i != 0) {
141  i--;
142  float expect_angle = getAngle(nodebuffer[i + 1]) - inc_origin_angle;
143  if (expect_angle < 0.0f) expect_angle = 0.0f;
144  setAngle(nodebuffer[i], expect_angle);
145  }
146  break;
147  }
148  }
149 
150  // all the data is invalid
151  if (i == count) return SL_RESULT_OPERATION_FAIL;
152 
153  //Tune tail
154  for (i = count - 1; i < count; i--) {
155  // To avoid array overruns, use the i < count condition
156  if (getDistanceQ2(nodebuffer[i]) == 0) {
157  continue;
158  }
159  else {
160  while (i != (count - 1)) {
161  i++;
162  float expect_angle = getAngle(nodebuffer[i - 1]) + inc_origin_angle;
163  if (expect_angle > 360.0f) expect_angle -= 360.0f;
164  setAngle(nodebuffer[i], expect_angle);
165  }
166  break;
167  }
168  }
169 
170  //Fill invalid angle in the scan
171  float frontAngle = getAngle(nodebuffer[0]);
172  for (i = 1; i < count; i++) {
173  if (getDistanceQ2(nodebuffer[i]) == 0) {
174  float expect_angle = frontAngle + i * inc_origin_angle;
175  if (expect_angle > 360.0f) expect_angle -= 360.0f;
176  setAngle(nodebuffer[i], expect_angle);
177  }
178  }
179 
180  // Reorder the scan according to the angle value
181  std::sort(nodebuffer, nodebuffer + count, &angleLessThan<TNode>);
182 
183  return SL_RESULT_OK;
184  }
185 
186  template<typename T>
188  {
189  public:
190  RawSampleNodeHolder(size_t maxcount = 8192)
191  : _max_count(maxcount)
192  {
193 
194  }
195  void clear()
196  {
198  _data_waiter.set(false);
199  _data_queue.clear();
200  }
201 
202  void pushNode(_u64 timestamp_uS, const T* node)
203  {
205  _data_queue.push_back(*node);
206  if (_data_queue.size() > _max_count) {
207  _data_queue.pop_front();
208  }
209  _data_waiter.set();
210  }
211 
212  size_t waitAndFetch(T* node, size_t maxcount, _u32 timeout)
213  {
215  {
217 
218  size_t copiedCount = 0;
219 
220  while (maxcount--) {
221  node[copiedCount++] = _data_queue.front();
222  _data_queue.pop_front();
223  }
224 
225  return copiedCount;
226  }
227  return 0;
228  }
229  protected:
230  size_t _max_count;
233  std::deque<T> _data_queue;
234 
235  };
236 
237  template<typename T>
239  {
240  public:
241  ScanDataHolder(size_t maxcount = 8192)
242  : _scan_node_buffer_size(maxcount)
244  , _new_scan_ready(false)
245  {
248 
250  }
251 
252  size_t getMaxCacheCount() const {
253  return _scan_node_buffer_size;
254  }
255 
256 
257  void reset() {
260  _new_scan_ready = false;
261  _scanbuffer[0].clear();
262  _scanbuffer[1].clear();
263  _data_waiter.set(false);
265  }
266 
268  {
269  return _new_scan_ready.exchange(false);
270  }
271 
272  void pushScanNodeData(_u64 currentSampleTsUs, const T* hqNode)
273  {
275 
276  int operationBufID = _getOperationBufferID_locked();
277  auto operationalBuf = &_scanbuffer[operationBufID];
278 
279  if (hqNode->flag & RPLIDAR_RESP_HQ_FLAG_SYNCBIT) {
280  if (operationalBuf->size()) {
281  operationBufID = _finishCurrentScanAndSwap_locked();
282  operationalBuf = &_scanbuffer[operationBufID];
283 
284  // publish the available scan
285  _new_scan_ready = true;
286  _data_waiter.set();
287 
288  }
289 
290  assert(operationalBuf->size() == 0);
291 
292  //store the timestamp info
293  _scan_begin_timestamp_uS[operationBufID] = currentSampleTsUs;
294  }
295  else {
296  if (operationalBuf->size() == 0) {
297  //discard the data, do not form partial scan
298  return;
299  }
300  }
301 
302  if (operationalBuf->size() >= _scan_node_buffer_size) {
303  //replace the last entry if buffer is full
304  operationalBuf->at(operationalBuf->size() - 1) = *hqNode;
305  }
306  else {
307  operationalBuf->push_back(*hqNode);
308  }
309 
310  }
311 
315  }
316 
317  std::vector<T>* waitAndLockAvailableScan(_u32 timeout, _u64 * out_timestamp_uS = nullptr)
318  {
320  {
321  _locker.lock();
322  assert(_scan_node_available_id >= 0);
323  _new_scan_ready = false;
324  if (out_timestamp_uS) {
326  }
328  }
329  else {
330  return nullptr;
331  }
332  }
333 
334  void unlockScan(std::vector<T>* scan) {
335  if (scan) {
336  _locker.unlock();
337  }
338  }
339 
340  protected:
343  int newOperationalID = 1 - _scan_node_available_id;
344 
345  _scanbuffer[newOperationalID].clear();
346  return newOperationalID;
347  }
348 
350  if (_scan_node_available_id < 0) return 0;
351  return 1 - _scan_node_available_id;
352  }
353 
355  {
357  }
358 
359 
362 
363 
364 
368  std::atomic<bool> _new_scan_ready;
369 
370  std::vector<T> _scanbuffer[2];
371  };
372 
374  public ILidarDriver, internal::IProtocolMessageListener, internal::LIDARSampleDataListener
375  {
376  public:
377  enum {
379  };
380 
381  enum {
384  };
385 
386 
387  enum {
392 
393 
395  };
396 
397  public:
399  : _isConnected(false)
401  , _op_locker(true)
405  {
406  _protocolHandler = std::make_shared< internal::RPLidarProtocolCodec>();
407  _transeiver = std::make_shared< internal::AsyncTransceiver>(*_protocolHandler);
408  _dataunpacker.reset(internal::LIDARSampleDataUnpacker::CreateInstance(*this));
409 
410  _protocolHandler->setMessageListener(this);
411 
412  memset(&_cached_DevInfo, 0, sizeof(_cached_DevInfo));
413  }
414 
415 
417  {
418  disconnect();
419  _protocolHandler->setMessageListener(nullptr);
420  }
421 
422 
423  LIDARTechnologyType getLIDARTechnologyType(const sl_lidar_response_device_info_t* devInfo)
424  {
426  if (!devInfo) {
427  devInfo = &_cached_DevInfo;
428  }
429 
430  return ParseLIDARTechnologyTypeByModelID(devInfo->model);
431  }
432 
433  LIDARMajorType getLIDARMajorType(const sl_lidar_response_device_info_t* devInfo)
434  {
436  if (!devInfo) {
437  devInfo = &_cached_DevInfo;
438  }
439 
440  return ParseLIDARMajorTypeByModelID(devInfo->model);
441 
442  }
443 
444  sl_result getModelNameDescriptionString(std::string& out_description, bool fetchAliasName, const sl_lidar_response_device_info_t* devInfo, sl_u32 timeout)
445  {
447  u_result ans;
448  // fetch alias (commerical) name if asked:
449  if (fetchAliasName) {
450  std::vector<_u8> replyData;
451  ans = getLidarConf(SL_LIDAR_CONF_MODEL_NAME_ALIAS, replyData, nullptr, 0, timeout);
452  if (IS_OK(ans) && replyData.size()) {
453  out_description.resize(replyData.size() + 1);
454  memcpy(&out_description[0], &replyData[0], replyData.size());
455  out_description[replyData.size()] = '\0';
456  if (out_description != "") {
457  return SL_RESULT_OK;
458  }
459  }
460  }
461 
462 
463  if (!devInfo) {
464  devInfo = &_cached_DevInfo;
465  }
466 
467 
468  out_description = GetModelNameStringByModelID(devInfo->model);
469 
470  return SL_RESULT_OK;
471  }
472 
474  {
476  if (!channel) return SL_RESULT_OPERATION_FAIL;
477  if (isConnected()) return SL_RESULT_ALREADY_DONE;
478 
480 
481  sl_result ans;
482 
483 
484  ans = (sl_result)_transeiver->openChannelAndBind(channel);
485 
486  if (IS_OK(ans)) {
487  _isConnected = true;
488  // the first dev info local cache will be taken here
490  }
491 
492  return ans;
493  }
494 
495  void disconnect()
496  {
498  if (_isConnected) {
500 
501  _transeiver->unbindAndClose();
502  _isConnected = false;
503  }
504  }
505 
506  bool isConnected()
507  {
508  return _isConnected;
509  }
510 
511  sl_result reset(sl_u32 timeoutInMs = DEFAULT_TIMEOUT)
512  {
514  // send reset message
516  }
517 
518  sl_result getAllSupportedScanModes(std::vector<LidarScanMode>& outModes, sl_u32 timeoutInMs = DEFAULT_TIMEOUT)
519  {
521 
523 
525  bool confProtocolSupported = false;
526  ans = checkSupportConfigCommands(confProtocolSupported, timeoutInMs);
527  if (!ans) return SL_RESULT_INVALID_DATA;
528 
529  if (confProtocolSupported) {
530  // 1. get scan mode count
531  sl_u16 modeCount;
532  ans = getScanModeCount(modeCount, timeoutInMs);
533  if (!ans) return ans;
534  // 2. for loop to get all fields of each scan mode
535  for (sl_u16 i = 0; i < modeCount; i++) {
536  LidarScanMode scanModeInfoTmp;
537  memset(&scanModeInfoTmp, 0, sizeof(scanModeInfoTmp));
538  scanModeInfoTmp.id = i;
539  ans = getLidarSampleDuration(scanModeInfoTmp.us_per_sample, i, timeoutInMs);
540  if (!ans) return ans;
541  ans = getMaxDistance(scanModeInfoTmp.max_distance, i, timeoutInMs);
542  if (!ans) return ans;
543  ans = getScanModeAnsType(scanModeInfoTmp.ans_type, i, timeoutInMs);
544  if (!ans) return ans;
545  ans = getScanModeName(scanModeInfoTmp.scan_mode, sizeof(scanModeInfoTmp.scan_mode), i, timeoutInMs);
546  if (!ans) return ans;
547  outModes.push_back(scanModeInfoTmp);
548 
549  }
550  return ans;
551  }
552 
553  return ans;
554  }
555 
556  sl_result getTypicalScanMode(sl_u16& outMode, sl_u32 timeoutInMs = DEFAULT_TIMEOUT)
557  {
560 
562  std::vector<sl_u8> answer;
563  bool lidarSupportConfigCmds = false;
564  ans = checkSupportConfigCommands(lidarSupportConfigCmds);
565  if (!ans) return ans;
566 
567  if (lidarSupportConfigCmds) {
568  ans = getLidarConf(SL_LIDAR_CONF_SCAN_MODE_TYPICAL, answer, nullptr, 0, timeoutInMs);
569  if (!ans) return ans;
570  if (answer.size() < sizeof(sl_u16)) {
571  return SL_RESULT_INVALID_DATA;
572  }
573  const sl_u16 *p_answer = reinterpret_cast<const sl_u16*>(&answer[0]);
574  outMode = *p_answer;
575  return ans;
576  }
577  //old version of triangle lidar
578  else {
580  return ans;
581  }
582  return ans;
583 
584  }
585 
586  sl_result startScan(bool force, bool useTypicalScan, sl_u32 options = 0, LidarScanMode* outUsedScanMode = nullptr)
587  {
590 
592  bool ifSupportLidarConf = false;
593  LidarScanMode localMode;
594 
595  if (!isConnected()) return SL_RESULT_OPERATION_FAIL;
596  stop();
597 
598  if (!outUsedScanMode) outUsedScanMode = &localMode;
599 
600 
601  ans = checkSupportConfigCommands(ifSupportLidarConf);
602  if (!ans) return ans;
603  if (useTypicalScan){
604  sl_u16 typicalMode;
605  ans = getTypicalScanMode(typicalMode);
606  if (!ans) return ans;
607 
608  //call startScanExpress to do the job
609  return startScanExpress(false, typicalMode, 0, outUsedScanMode);
610  }
611 
612  // 'useTypicalScan' is false, just use normal scan mode
613 
614 
615  return startScanNormal_commonpath(force, ifSupportLidarConf , *outUsedScanMode, DEFAULT_TIMEOUT);
616  }
617 
618 
619  // this path make sure the working mode has always been retrieved
620  sl_result startScanNormal_commonpath(bool force, bool ifSupportLidarConf, LidarScanMode& outUsedScanMode, sl_u32 timeout)
621  {
622 
624 
625  if (ifSupportLidarConf) {
626 
627  outUsedScanMode.id = SL_LIDAR_CONF_SCAN_COMMAND_STD;
628  ans = getLidarSampleDuration(outUsedScanMode.us_per_sample, outUsedScanMode.id);
629  if (!ans) return ans;
630  ans = getMaxDistance(outUsedScanMode.max_distance, outUsedScanMode.id);
631  if (!ans) return ans;
632  ans = getScanModeAnsType(outUsedScanMode.ans_type, outUsedScanMode.id);
633  if (!ans) return ans;
634  ans = getScanModeName(outUsedScanMode.scan_mode, sizeof(outUsedScanMode.scan_mode), outUsedScanMode.id);
635  if (!ans) return ans;
636 
637  }
638  else {
639  // a legacy device
640  rplidar_response_sample_rate_t sampleRateTmp;
641  ans = _getLegacySampleDuration_uS(sampleRateTmp, timeout);
642 
643  if (!ans) return SL_RESULT_INVALID_DATA;
644  outUsedScanMode.us_per_sample = sampleRateTmp.std_sample_duration_us;
645  outUsedScanMode.max_distance = 16;
646  outUsedScanMode.ans_type = SL_LIDAR_ANS_TYPE_MEASUREMENT;
647  strcpy(outUsedScanMode.scan_mode, "Standard");
648  }
649 
650 
652 
653  startMotor();
654 
655  _scanHolder.reset();
656  _dataunpacker->enable();
657 
658  ans = _sendCommandWithoutResponse(force ? SL_LIDAR_CMD_FORCE_SCAN : SL_LIDAR_CMD_SCAN, nullptr, 0, true);
659  if (ans) delay(10); // wait rplidar to handle it
660  return ans;
661  }
662 
663 
664  sl_result startScanNormal(bool force, sl_u32 timeout = DEFAULT_TIMEOUT)
665  {
668 
669 
670  LidarScanMode localMode;
671  bool ifSupportLidarConf;
672 
673  if (!isConnected()) return SL_RESULT_OPERATION_FAIL;
674  stop();
675 
676  Result<nullptr_t> ans = checkSupportConfigCommands(ifSupportLidarConf);
677  if (!ans) return ans;
678 
679  return startScanNormal_commonpath(force, ifSupportLidarConf, localMode, timeout);
680  }
681 
682  sl_result startScanExpress(bool force, sl_u16 scanMode, sl_u32 options = 0, LidarScanMode* outUsedScanMode = nullptr, sl_u32 timeout = DEFAULT_TIMEOUT)
683  {
686 
687 
689  if (!isConnected()) return SL_RESULT_OPERATION_FAIL;
690  stop(); //force the previous operation to stop
691 
692  LidarScanMode localMode;
693 
694  if (!outUsedScanMode) outUsedScanMode = &localMode;
695 
696  bool ifSupportLidarConf = false;
697  ans = checkSupportConfigCommands(ifSupportLidarConf);
698  if (!ans) return SL_RESULT_INVALID_DATA;
699 
700 
701 
702  outUsedScanMode->id = scanMode;
703  if (ifSupportLidarConf) {
704  ans = getLidarSampleDuration(outUsedScanMode->us_per_sample, outUsedScanMode->id);
705  if (!ans) return SL_RESULT_INVALID_DATA;
706 
707  ans = getMaxDistance(outUsedScanMode->max_distance, outUsedScanMode->id);
708  if (!ans) return SL_RESULT_INVALID_DATA;
709 
710  ans = getScanModeAnsType(outUsedScanMode->ans_type, outUsedScanMode->id);
711  if (!ans) return SL_RESULT_INVALID_DATA;
712 
713  ans = getScanModeName(outUsedScanMode->scan_mode, sizeof(outUsedScanMode->scan_mode), outUsedScanMode->id);
714  if (!ans) return SL_RESULT_INVALID_DATA;
715  }
716  else {
717  // legacy device support
718  if (scanMode != RPLIDAR_CONF_SCAN_COMMAND_STD) {
719  rplidar_response_sample_rate_t sampleRateTmp;
720  ans = _getLegacySampleDuration_uS(sampleRateTmp, timeout);
721  if (!ans) return RESULT_INVALID_DATA;
722 
723  outUsedScanMode->us_per_sample = sampleRateTmp.express_sample_duration_us;
724  outUsedScanMode->max_distance = 16;
725  outUsedScanMode->ans_type = SL_LIDAR_ANS_TYPE_MEASUREMENT_CAPSULED;
726  strcpy(outUsedScanMode->scan_mode, "Express");
727  }
728  else {
729  outUsedScanMode->ans_type = SL_LIDAR_ANS_TYPE_MEASUREMENT;
730  }
731  }
732 
733  if (outUsedScanMode->ans_type == SL_LIDAR_ANS_TYPE_MEASUREMENT)
734  {
735  // redirect to the correct function...
736  return startScanNormal(force, timeout);
737  }
738 
739  _updateTimingDesc(_cached_DevInfo, outUsedScanMode->us_per_sample);
740  startMotor();
741 
742  _scanHolder.reset();
743  _dataunpacker->enable();
744 
745  sl_lidar_payload_express_scan_t scanReq;
746  memset(&scanReq, 0, sizeof(scanReq));
747 
748  if (!ifSupportLidarConf) {
750  scanReq.working_mode = sl_u8(scanMode);
751  }
752  else
753  scanReq.working_mode = sl_u8(scanMode);
754 
755  scanReq.working_flags = options;
756 
757  ans = _sendCommandWithoutResponse(SL_LIDAR_CMD_EXPRESS_SCAN, &scanReq, sizeof(scanReq), true);
758  if (ans) delay(10); // wait rplidar to handle it
759  return ans;
760 
761  }
762 
763  sl_result stop(sl_u32 timeout = DEFAULT_TIMEOUT)
764  {
766 
767 
768  u_result ans = SL_RESULT_OK;
771 
772  if (IS_FAIL(ans)) return ans;
773 
774 
775  delay(100);
776 
778  setMotorSpeed(0);
779 
780  return SL_RESULT_OK;
781  }
782 
783  sl_result grabScanDataHqWithTimeStamp(sl_lidar_response_measurement_node_hq_t* nodebuffer, size_t& count, sl_u64& timestamp_uS, sl_u32 timeout = DEFAULT_TIMEOUT)
784  {
786 
787  if (!nodebuffer)
788  return SL_RESULT_INVALID_DATA;
789 
790  auto availBuffer = _scanHolder.waitAndLockAvailableScan(timeout, &timestamp_uS);
791  if (!availBuffer) return SL_RESULT_OPERATION_TIMEOUT;
792 
793  count = std::min<size_t>(count, availBuffer->size());
794 
795  std::copy(availBuffer->begin(), availBuffer->begin() + count, nodebuffer);
796 
797  _scanHolder.unlockScan(availBuffer);
798 
799  return RESULT_OK;
800  }
801 
803  {
804  _u64 localTS;
805  return grabScanDataHqWithTimeStamp(nodebuffer, count, localTS, timeout);
806  }
807 
808  sl_result getDeviceInfo(sl_lidar_response_device_info_t& info, sl_u32 timeout = DEFAULT_TIMEOUT)
809  {
812 
813 
814  u_result ans;
815  internal::message_autoptr_t ans_frame;
816 
818 
819  if (IS_FAIL(ans)) return ans;
820  if (ans_frame->getPayloadSize() < sizeof(rplidar_response_device_info_t))
821  {
822  return RESULT_INVALID_DATA;
823  }
824  info = *(rplidar_response_device_info_t*)ans_frame->getDataBuf();
825 #ifdef _CPU_ENDIAN_BIG
826  info.firmware_version = le16_to_cpu(info.firmware_version);
827 #endif
828 
829  _cached_DevInfo = info;
830  return (sl_result)ans;
831  }
832 
834  {
837 
839  support = MotorCtrlSupportNone;
841 
842  {
843  sl_lidar_response_device_info_t devInfo;
844  ans = getDeviceInfo(devInfo, 500);
845  if (!ans) return ans;
846  sl_u8 majorId = devInfo.model >> 4;
847  if (majorId >= BUILTIN_MOTORCTL_MINUM_MAJOR_ID) {
848  support = MotorCtrlSupportRpm;
849  return ans;
850  }
851  else if(majorId >= A2A3_LIDAR_MINUM_MAJOR_ID){
852 
854  sl_lidar_payload_acc_board_flag_t flag;
855  flag.reserved = 0;
856  internal::message_autoptr_t ans_frame;
857 
859  if (!ans) return ans;
860 
861  if (ans_frame->getPayloadSize() < sizeof(rplidar_response_acc_board_flag_t))
862  {
863  return RESULT_INVALID_DATA;
864  }
865 
866  const sl_lidar_response_acc_board_flag_t* acc_board_flag
867  = reinterpret_cast<const sl_lidar_response_acc_board_flag_t*>(ans_frame->getDataBuf());
868 
869  if (acc_board_flag->support_flag & SL_LIDAR_RESP_ACC_BOARD_FLAG_MOTOR_CTRL_SUPPORT_MASK) {
870  support = MotorCtrlSupportPwm;
871  }
872  return ans;
873  }
874 
875  }
876  return SL_RESULT_OK;
877 
878  }
879 
880  sl_result getFrequency(const LidarScanMode& scanMode, const sl_lidar_response_measurement_node_hq_t* nodes, size_t count, float& frequency)
881  {
882  float sample_duration = scanMode.us_per_sample;
883  frequency = 1000000.0f / (count * sample_duration);
884  return SL_RESULT_OK;
885  }
886 
887  sl_result setLidarIpConf(const sl_lidar_ip_conf_t& conf, sl_u32 timeout)
888  {
891 
892  sl_result ans = setLidarConf(SL_LIDAR_CONF_LIDAR_STATIC_IP_ADDR, &conf, sizeof(sl_lidar_ip_conf_t), timeout);
893  return ans;
894  }
895 
896  sl_result getLidarIpConf(sl_lidar_ip_conf_t& conf, sl_u32 timeout)
897  {
900 
901 
903  std::vector<sl_u8> reserve(2); //keep backward compatibility
904 
905  std::vector<sl_u8> answer;
906  ans = getLidarConf(SL_LIDAR_CONF_LIDAR_STATIC_IP_ADDR, answer, &reserve[0], 2, timeout);
907  size_t len = answer.size();
908  if (0 == len) return SL_RESULT_INVALID_DATA;
909  memcpy(&conf, &answer[0], len);
910  return ans;
911  }
912 
913  sl_result getHealth(sl_lidar_response_device_health_t& health, sl_u32 timeout = DEFAULT_TIMEOUT)
914  {
917 
918 
919  u_result ans;
920  internal::message_autoptr_t ans_frame;
921 
923 
924  if (IS_FAIL(ans)) return ans;
925  if (ans_frame->getPayloadSize() < sizeof(rplidar_response_device_health_t))
926  {
927  return SL_RESULT_INVALID_DATA;
928  }
929  health = *(rplidar_response_device_health_t*)ans_frame->getDataBuf();
930 #ifdef _CPU_ENDIAN_BIG
931  health.error_code = le16_to_cpu(health.error_code);
932 #endif
933 
934  return ans;
935  }
936 
937  sl_result getDeviceMacAddr(sl_u8* macAddrArray, sl_u32 timeoutInMs)
938  {
941 
942 
943  u_result ans;
944 
945  std::vector<_u8> answer(6, 0);
946  ans = getLidarConf(SL_LIDAR_CONF_LIDAR_MAC_ADDR, answer, NULL, 0, timeoutInMs);
947  if (IS_FAIL(ans))
948  {
949  return ans;
950  }
951  size_t len = answer.size();
952  if (0 == len) return SL_RESULT_INVALID_DATA;
953  memcpy(macAddrArray, &answer[0], len);
954  return ans;
955  }
956 
958  {
959  return ascendScanData_<sl_lidar_response_measurement_node_hq_t>(nodebuffer, count);
960  }
961 
963  {
964  count = _rawSampleNodeHolder.waitAndFetch(nodebuffer, count, 0);
965  return SL_RESULT_OK;
966  }
967 
969  {
972 
973 
975 
976  if(speed == DEFAULT_MOTOR_SPEED){
977  sl_lidar_response_desired_rot_speed_t desired_speed;
978  ans = getDesiredSpeed(desired_speed);
979  if (ans) {
981  speed = desired_speed.pwm_ref;
982  else
983  speed = desired_speed.rpm;
984  }
985  else {
986  //set a dummy default value
987  speed = 600;
988  }
989  }
990  switch (_isSupportingMotorCtrl)
991  {
993  if (_transeiver->getBindedChannel()->getChannelType() == CHANNEL_TYPE_SERIALPORT) {
994  ISerialPortChannel* serialChanel = (ISerialPortChannel*)_transeiver->getBindedChannel();
995  if (!speed) {
996  serialChanel->setDTR(true);
997  }else{
998  serialChanel->setDTR(false);
999  }
1000  }
1001  break;
1002  case MotorCtrlSupportPwm:
1003  sl_lidar_payload_motor_pwm_t motor_pwm;
1004  motor_pwm.pwm_value = speed;
1005 
1006 
1007  ans = _sendCommandWithoutResponse(SL_LIDAR_CMD_SET_MOTOR_PWM, &motor_pwm, sizeof(motor_pwm), true);
1008  if (!ans) return ans;
1009  delay(10);
1010  break;
1011  case MotorCtrlSupportRpm:
1012  sl_lidar_payload_motor_pwm_t motor_rpm;
1013  motor_rpm.pwm_value = speed;
1014 
1015  ans = _sendCommandWithoutResponse(SL_LIDAR_CMD_HQ_MOTOR_SPEED_CTRL, &motor_rpm, sizeof(motor_rpm), true);
1016  if (!ans) return ans;
1017  delay(10);
1018  break;
1019  }
1020  return SL_RESULT_OK;
1021  }
1022 
1023  sl_result getMotorInfo(LidarMotorInfo &motorInfo, sl_u32 timeoutInMs)
1024  {
1028 
1029 
1030  {
1031  std::vector<sl_u8> answer;
1032 
1034  if (!ans) return ans;
1035 
1036  const sl_u16 *min_answer = reinterpret_cast<const sl_u16*>(&answer[0]);
1037  motorInfo.min_speed = *min_answer;
1038 
1039 
1041  if (!ans) return ans;
1042 
1043  const sl_u16 *max_answer = reinterpret_cast<const sl_u16*>(&answer[0]);
1044  motorInfo.max_speed = *max_answer;
1045 
1046  sl_lidar_response_desired_rot_speed_t desired_speed;
1047  ans = getDesiredSpeed(desired_speed);
1048  if (!ans) return ans;
1049  if(motorInfo.motorCtrlSupport == MotorCtrlSupportPwm)
1050  motorInfo.desired_speed = desired_speed.pwm_ref;
1051  else
1052  motorInfo.desired_speed = desired_speed.rpm;
1053 
1054  }
1055  return SL_RESULT_OK;
1056  }
1057 
1058  sl_result negotiateSerialBaudRate(sl_u32 requiredBaudRate, sl_u32* baudRateDetected)
1059  {
1060  // ask the LIDAR to stop working first...
1061  stop();
1062 
1064 
1065  IChannel* cachedChannel = _transeiver->getBindedChannel();
1066  if (!cachedChannel) return SL_RESULT_OPERATION_FAIL;
1067  if (cachedChannel->getChannelType() != CHANNEL_TYPE_SERIALPORT)
1068  {
1069  // only works for UART connection
1071  }
1072 
1073  // disable the transeiver as it may interrupt the operation...
1074  _transeiver->unbindAndClose();
1075 
1076  sl_result ans = SL_RESULT_OK;
1077 
1078  do {
1079  // reopen the channel...
1080 
1081  if (!cachedChannel->open()) {
1082  // failed to reopen
1083  // try to revert back...
1085  break;
1086  }
1087 
1088  cachedChannel->flush();
1089 
1090  // wait for a while
1091  delay(10);
1092  cachedChannel->clearReadCache();
1093 
1094  // sending magic byte to let the target LIDAR start baudrate measurement
1095  // More than 100 bytes per second datarate is required to trigger the measurements
1096  {
1097 
1098 
1099  sl_u8 magicByteSeq[16];
1100 
1101  memset(magicByteSeq, SL_LIDAR_AUTOBAUD_MAGICBYTE, sizeof(magicByteSeq));
1102 
1103  sl_u64 startTS = getms();
1104 
1105  while (getms() - startTS < 1500) //lasting for 1.5sec
1106  {
1107  if (cachedChannel->write(magicByteSeq, sizeof(magicByteSeq)) < 0)
1108  {
1110  break;
1111  }
1112 
1113  size_t dataCountGot;
1114  if (cachedChannel->waitForData(1, 1, &dataCountGot)) {
1115  //got reply, stop
1116  ans = SL_RESULT_OK;
1117  break;
1118  }
1119  }
1120  }
1121 
1122  if (IS_FAIL(ans)) break;
1123 
1124  // getback the bps measured
1125  _u32 bpsDetected = 0;
1126  size_t dataCountGot;
1127  if (cachedChannel->waitForData(4, 500, &dataCountGot)) {
1128  //got reply, stop
1129  cachedChannel->read(&bpsDetected, 4);
1130  if (baudRateDetected) *baudRateDetected = bpsDetected;
1131 
1132 
1133  cachedChannel->close();
1134  // restart the transiever
1135  ans = _transeiver->openChannelAndBind(cachedChannel);
1136  if (IS_FAIL(ans)) return ans;
1137 
1138 
1139  // send a confirmation to the LIDAR, otherwise, the previous baudrate will be reverted back
1140  sl_lidar_payload_new_bps_confirmation_t confirmation;
1141  confirmation.flag = 0x5F5F;
1142  confirmation.required_bps = requiredBaudRate;
1143  confirmation.param = 0;
1144 
1145 
1146  ans = _sendCommandWithoutResponse(SL_LIDAR_CMD_NEW_BAUDRATE_CONFIRM, &confirmation, sizeof(confirmation));
1147 
1148  return ans;
1149  }
1150  } while (0);
1151 
1152  _transeiver->openChannelAndBind(cachedChannel);
1153 
1154  return ans;
1155  }
1156 
1157  protected:
1159  {
1161  }
1162 
1163  u_result getDesiredSpeed(sl_lidar_response_desired_rot_speed_t & motorSpeed, sl_u32 timeoutInMs = DEFAULT_TIMEOUT)
1164  {
1165  u_result ans;
1166  std::vector<sl_u8> answer;
1167  ans = getLidarConf(SL_LIDAR_CONF_DESIRED_ROT_FREQ, answer, nullptr, 0, timeoutInMs);
1168 
1169  if (IS_FAIL(ans)) return ans;
1170 
1171  const sl_lidar_response_desired_rot_speed_t *p_answer = reinterpret_cast<const sl_lidar_response_desired_rot_speed_t*>(&answer[0]);
1172  motorSpeed = *p_answer;
1173  return RESULT_OK;
1174  }
1175 
1176  u_result checkSupportConfigCommands(bool& outSupport, sl_u32 timeoutInMs = DEFAULT_TIMEOUT)
1177  {
1178  u_result ans;
1180  ans = getDeviceInfo(devinfo, timeoutInMs);
1181  if (IS_FAIL(ans)) {
1182  outSupport = false;
1183  return ans;
1184  }
1185 
1186 
1187  if (_checkNDMagicNumber(devinfo.model)) {
1188 
1189  outSupport = true;
1190  }
1191  else {
1192  // if lidar firmware >= 1.24
1193  outSupport = (devinfo.firmware_version >= ((0x1 << 8) | 24));
1194  }
1195  return RESULT_OK;
1196  }
1197 
1198 
1199  u_result getScanModeCount(sl_u16& modeCount, sl_u32 timeoutInMs = DEFAULT_TIMEOUT)
1200  {
1201  u_result ans;
1202  std::vector<_u8> answer;
1204  if (IS_FAIL(ans)) {
1205  return ans;
1206  }
1207  if (answer.size() < sizeof(_u16)) {
1208  return RESULT_INVALID_DATA;
1209  }
1210  const _u16* p_answer = reinterpret_cast<const _u16*>(&answer[0]);
1211  modeCount = *p_answer;
1212  return ans;
1213  }
1214 
1215  u_result setLidarConf(_u32 type, const void* payload, size_t payloadSize, _u32 timeout)
1216  {
1217  if (type < 0x00010000 || type >0x0001FFFF)
1218  return SL_RESULT_INVALID_DATA;
1219 
1220 
1221  std::vector<sl_u8> requestPkt;
1222  requestPkt.resize(sizeof(sl_lidar_payload_set_scan_conf_t) + payloadSize);
1223  if (!payload) payloadSize = 0;
1224  sl_lidar_payload_set_scan_conf_t* query = reinterpret_cast<sl_lidar_payload_set_scan_conf_t*>(&requestPkt[0]);
1225 
1226  query->type = type;
1227 
1228  if (payloadSize)
1229  memcpy(&query[1], payload, payloadSize);
1230 
1231  sl_result ans;
1232  internal::message_autoptr_t ans_frame;
1233  ans = _sendCommandWithResponse(SL_LIDAR_CMD_SET_LIDAR_CONF, SL_LIDAR_ANS_TYPE_SET_LIDAR_CONF, ans_frame, timeout, &requestPkt[0], requestPkt.size());
1234 
1235  if (IS_FAIL(ans)) {
1236  return ans;
1237  }
1238 
1239  //check if returned size is even less than sizeof(type)
1240  if (ans_frame->getPayloadSize() < sizeof(rplidar_response_set_lidar_conf_t)) {
1241  return RESULT_INVALID_DATA;
1242  }
1243 
1245  reinterpret_cast<const rplidar_response_set_lidar_conf_t*>(ans_frame->getDataBuf());
1246 
1247 
1248  if (ans_frame->getPayloadSize() == 4) {
1249  // legacy device?
1250  return *(const u_result*)(ans_frame->getDataBuf());
1251  }
1252  else {
1253  if (response->type != type) {
1254  return RESULT_INVALID_DATA;
1255  }
1256 
1257  return (u_result)response->result;
1258  }
1259  }
1260 
1261  u_result getLidarConf(_u32 type, std::vector<_u8>& outputBuf, const void* payload = NULL, size_t payloadSize = 0, _u32 timeout = DEFAULT_TIMEOUT)
1262  {
1263  std::vector<_u8> requestPkt;
1264 
1265  if (!payload) payloadSize = 0;
1266  requestPkt.resize(sizeof(rplidar_payload_get_scan_conf_t) + payloadSize);
1267  rplidar_payload_get_scan_conf_t* query = reinterpret_cast<rplidar_payload_get_scan_conf_t*>(&requestPkt[0]);
1268 
1269  query->type = type;
1270 
1271  if (payloadSize)
1272  memcpy(&query[1], payload, payloadSize);
1273 
1274  u_result ans;
1275  internal::message_autoptr_t ans_frame;
1276  ans = _sendCommandWithResponse(SL_LIDAR_CMD_GET_LIDAR_CONF, SL_LIDAR_ANS_TYPE_GET_LIDAR_CONF, ans_frame, timeout, &requestPkt[0], requestPkt.size());
1277  if (IS_FAIL(ans)) {
1278  return ans;
1279  }
1280  //check if returned size is even less than sizeof(type)
1281  if (ans_frame->getPayloadSize() < offsetof(rplidar_response_get_lidar_conf_t, payload)) {
1282  return SL_RESULT_INVALID_DATA;
1283  }
1284 
1285  //check if returned type is same as asked type
1286  const rplidar_response_get_lidar_conf_t* replied =
1287  reinterpret_cast<const rplidar_response_get_lidar_conf_t*>(ans_frame->getDataBuf());
1288 
1289 
1290  if (replied->type != type) {
1291  return SL_RESULT_INVALID_DATA;
1292  }
1293  //copy all the payload into &outputBuf
1294  int payLoadLen = (int)ans_frame->getPayloadSize() - (int)offsetof(rplidar_response_get_lidar_conf_t, payload);
1295  //do consistency check
1296  if (payLoadLen < 0) {
1297  return SL_RESULT_INVALID_DATA;
1298  }
1299  //copy all payLoadLen bytes to outputBuf
1300  outputBuf.resize(payLoadLen);
1301  if (payLoadLen)
1302  memcpy(&outputBuf[0], replied->payload, payLoadLen);
1303  return ans;
1304  }
1305 
1306  u_result getLidarSampleDuration(float& sampleDurationRes, sl_u16 scanModeID, sl_u32 timeoutInMs = DEFAULT_TIMEOUT)
1307  {
1308  u_result ans;
1309 
1310  std::vector<_u8> answer;
1311  ans = getLidarConf(SL_LIDAR_CONF_SCAN_MODE_US_PER_SAMPLE, answer, &scanModeID, sizeof(_u16), timeoutInMs);
1312  if (IS_FAIL(ans))
1313  {
1314  return ans;
1315  }
1316  if (answer.size() < sizeof(_u32))
1317  {
1318  return SL_RESULT_INVALID_DATA;
1319  }
1320  const _u32* result = reinterpret_cast<const _u32*>(&answer[0]);
1321  sampleDurationRes = (float)(*result / 256.0);
1322  return ans;
1323  }
1324 
1325  u_result getMaxDistance(float &maxDistance, sl_u16 scanModeID, sl_u32 timeoutInMs = DEFAULT_TIMEOUT)
1326  {
1327  u_result ans;
1328 
1329 
1330  std::vector<_u8> answer;
1331  ans = getLidarConf(SL_LIDAR_CONF_SCAN_MODE_MAX_DISTANCE, answer, &scanModeID, sizeof(_u16), timeoutInMs);
1332  if (IS_FAIL(ans))
1333  {
1334  return ans;
1335  }
1336  if (answer.size() < sizeof(_u32))
1337  {
1338  return SL_RESULT_INVALID_DATA;
1339  }
1340  const _u32* result = reinterpret_cast<const _u32*>(&answer[0]);
1341  maxDistance = (float)(*result >> 8);
1342  return ans;
1343  }
1344 
1345  u_result getScanModeAnsType(sl_u8 &ansType, sl_u16 scanModeID, sl_u32 timeoutInMs = DEFAULT_TIMEOUT)
1346  {
1347  u_result ans;
1348 
1349  std::vector<_u8> answer;
1350  ans = getLidarConf(SL_LIDAR_CONF_SCAN_MODE_ANS_TYPE, answer, &scanModeID, sizeof(_u16), timeoutInMs);
1351  if (IS_FAIL(ans))
1352  {
1353  return ans;
1354  }
1355  if (answer.size() < sizeof(_u8))
1356  {
1357  return SL_RESULT_INVALID_DATA;
1358  }
1359  const _u8* result = reinterpret_cast<const _u8*>(&answer[0]);
1360  ansType = *result;
1361  return ans;
1362  }
1363 
1364  u_result getScanModeName(char* modeName, size_t stringSize, _u16 scanModeID, _u32 timeoutInMs = DEFAULT_TIMEOUT)
1365  {
1366  u_result ans;
1367 
1368  std::vector<_u8> answer;
1369  ans = getLidarConf(SL_LIDAR_CONF_SCAN_MODE_NAME, answer, &scanModeID, sizeof(_u16), timeoutInMs);
1370  if (IS_FAIL(ans))
1371  {
1372  return ans;
1373  }
1374  size_t len = std::min<size_t>(answer.size(), stringSize);
1375  if (0 == len) return SL_RESULT_INVALID_DATA;
1376 
1377  memcpy(modeName, &answer[0], len);
1378  return ans;
1379  }
1380 
1381 
1383  {
1384  _u8 majorModelID = (modelID >> 4);
1385  // FIXME: stupid implementation here
1386  if (majorModelID < NEWDESIGN_MINUM_MAJOR_ID) {
1388  }
1389  else {
1390  return LIDAR_TECHNOLOGY_DTOF;
1391  }
1392  }
1393 
1395  {
1396  _u8 majorModelID = (modelID >> 4);
1397 
1398 
1399  if (majorModelID >= TOF_M_SERIAL_MINUM_MAJOR_ID) {
1401  }
1402  else if (majorModelID >= TOF_T_SERIAL_MINUM_MAJOR_ID) {
1404  }
1405  else if (majorModelID >= TOF_S_SERIAL_MINUM_MAJOR_ID) {
1407  }
1408  else if (majorModelID >= TOF_C_SERIAL_MINUM_MAJOR_ID) {
1410  }
1411  else {
1413  }
1414  }
1415 
1416  static std::string GetModelNameStringByModelID(_u8 modelID)
1417  {
1418 
1419  char stringBuffer[100];
1420  auto majorType = ParseLIDARMajorTypeByModelID(modelID);
1421 
1422 
1423  switch (majorType) {
1425  sprintf(stringBuffer, "A%dM%d", (modelID >> 4), (modelID & 0xF));
1426 
1427  break;
1428 
1430  sprintf(stringBuffer, "S%dM%d", (modelID >> 4) - (TOF_S_SERIAL_MINUM_MAJOR_ID)+1, (modelID & 0xF));
1431 
1432  break;
1433 
1435  sprintf(stringBuffer, "T%dM%d", (modelID >> 4) - (TOF_T_SERIAL_MINUM_MAJOR_ID)+1, (modelID & 0xF));
1436 
1437  break;
1438 
1440  sprintf(stringBuffer, "M%dM%d", (modelID >> 4) - (TOF_M_SERIAL_MINUM_MAJOR_ID)+1, (modelID & 0xF));
1441 
1442  break;
1443 
1445  sprintf(stringBuffer, "C%dM%d", (modelID >> 4) - (TOF_C_SERIAL_MINUM_MAJOR_ID)+1, (modelID & 0xF));
1446 
1447  break;
1448 
1449 
1450  default:
1451  sprintf(stringBuffer, "unknown(%x)", modelID);
1452  }
1453 
1454  return std::string(stringBuffer);
1455  }
1456 
1457  protected:
1458 
1460  {
1461  _dataunpacker->disable();
1462  _protocolHandler->exitLoopMode(); // exit loop mode
1463  }
1464 
1465 
1466 
1468  {
1469  return ((model >> 4) >= NEWDESIGN_MINUM_MAJOR_ID);
1470  }
1471 
1472 
1473 
1474 
1476  {
1477 
1478  LIDARMajorType majorType = ParseLIDARMajorTypeByModelID(devInfo.model);
1479 
1480  switch (majorType) {
1484 
1485  outputType = LIDAR_INTERFACE_UART;
1486  return SL_RESULT_OK;
1487 
1488 
1490  outputType = LIDAR_INTERFACE_ETHERNET;
1491  return SL_RESULT_OK;
1492 
1494  {
1495  // ethernet version exists, check whether it is
1496  _u8 macAddr[6];
1497  u_result ans = getDeviceMacAddr(macAddr, timeout);
1498  if (IS_FAIL(ans)) {
1499  // cannot retrieve the device mac address, consider a UART interface version
1500  outputType = LIDAR_INTERFACE_UART;
1501  }
1502  else {
1503  outputType = LIDAR_INTERFACE_ETHERNET;
1504  }
1505  return SL_RESULT_OK;
1506  }
1507 
1508 
1510  default:
1511  outputType = LIDAR_INTERFACE_UNKNOWN;
1512  return SL_RESULT_OK;
1513  }
1514  }
1515 
1517  {
1518  _u8 majorModelID = (devInfo.model >> 4);
1519  switch (majorModelID)
1520  {
1521  case 1:
1522  case 2:
1523  case 3: //A1..A3 series
1524  return (devInfo.hardware_version >= 6) ? 256000 : 115200;
1525  case 4: //C series
1526  return 460800;
1527  case 6: //model ID of S1
1528  return 256000;
1529  case 7: //model ID of S2
1530  case 8: //model ID of S3
1531  if (devInfo.model == (0x82)) return 460800;
1532  return 1000000;
1533  default:
1534  return 0; //0 as unknown
1535  }
1536  }
1537 
1538  bool _updateTimingDesc(const rplidar_response_device_info_t& devInfo, float selectedSampleDuration)
1539  {
1542 
1543  _timing_desc.sample_duration_uS = (_u64)(selectedSampleDuration + 0.5f);
1544 
1545  //FIXME: will be changed in future releases
1548 
1549 
1550  // notify the data unpacker
1551  _dataunpacker->updateUnpackerContext(internal::LIDARSampleDataUnpacker::UNPACKER_CONTEXT_TYPE_LIDAR_TIMING ,&_timing_desc, sizeof(_timing_desc));
1552  return true;
1553 
1554  }
1555 
1557  {
1558 
1559  static const _u32 LEGACY_SAMPLE_DURATION = 476;
1560 
1562  // 1. fetch the device version first...
1563  u_result ans = getDeviceInfo(devinfo, timeout);
1564 
1565  rateInfo.express_sample_duration_us = LEGACY_SAMPLE_DURATION;
1566  rateInfo.std_sample_duration_us = LEGACY_SAMPLE_DURATION;
1567 
1568  if (IS_FAIL(ans)) {
1569  return ans;
1570  }
1571 
1572  if (getLIDARMajorType(&devinfo) == LIDAR_MAJOR_TYPE_A_SERIES) {
1573  if (devinfo.firmware_version < ((0x1 << 8) | 17)) {
1574  // very very rare and old model found!!
1575  return SL_RESULT_OK;
1576  }
1577  }
1578 
1579 
1580  internal::message_autoptr_t ans_frame;
1581 
1583 
1584  if (IS_FAIL(ans)) return ans;
1585  if (ans_frame->getPayloadSize() < sizeof(rplidar_response_sample_rate_t))
1586  {
1587  return RESULT_INVALID_DATA;
1588  }
1589  memcpy(&rateInfo, ans_frame->getDataBuf(), sizeof(rateInfo));
1590 
1591 #ifdef _CPU_ENDIAN_BIG
1592  rateInfo.express_sample_duration_us = le16_to_cpu(rateInfo.express_sample_duration_us);
1593  rateInfo.std_sample_duration_us = le16_to_cpu(rateInfo.std_sample_duration_us);
1594 #endif
1595 
1596  return ans;
1597  }
1598 
1599 
1600  u_result _sendCommandWithoutResponse(_u8 cmd, const void* payload = NULL, size_t payloadsize = 0, bool noForceStop = false)
1601  {
1602  if (!noForceStop) {
1604  }
1605  _response_waiter.set(false);
1606 
1607  internal::message_autoptr_t message(new internal::ProtocolMessage(cmd, (const _u8*)payload, payloadsize));
1608  return _transeiver->sendMessage(message);
1609 
1610  }
1611 
1612  u_result _sendCommandWithResponse(_u8 cmd, _u8 responseType, internal::message_autoptr_t& ansPkt, _u32 timeout = DEFAULT_TIMEOUT, const void* payload = NULL, size_t payloadsize = 0)
1613  {
1614  u_result ans;
1615 
1616  _data_locker.lock();
1617 
1618  internal::message_autoptr_t message(new internal::ProtocolMessage(cmd, (const _u8*)payload, payloadsize));
1620  _waiting_packet_type = responseType;
1621  _response_waiter.set(false);
1622  _data_locker.unlock();
1623 
1624  ans = _transeiver->sendMessage(message);
1625 
1626  if (IS_FAIL(ans)) return ans;
1627 
1628  do {
1629  switch (_response_waiter.wait(timeout)) {
1631  return RESULT_OPERATION_TIMEOUT;
1633  _data_locker.lock();
1634  ansPkt = _lastAnsPkt;
1635  _data_locker.unlock();
1636  return RESULT_OK;
1637  default:
1638  return RESULT_OPERATION_FAIL;
1639  }
1640  } while (1);
1641  }
1642 
1643  public:
1644 
1645  virtual void onHQNodeDecoded(_u64 timestamp_uS, const rplidar_response_measurement_node_hq_t* node)
1646  {
1647  _scanHolder.pushScanNodeData(timestamp_uS, node);
1648  _rawSampleNodeHolder.pushNode(timestamp_uS, node);
1649  }
1650 
1651  virtual void onHQNodeScanResetReq() {
1653  }
1654 
1656  {
1657  internal::message_autoptr_t message = std::make_shared<internal::ProtocolMessage>(msg);
1658 
1659  if (_dataunpacker->onSampleData(message->cmd, message->getDataBuf(), message->getPayloadSize()))
1660  {
1661  return;
1662  }
1663 
1664  if (message->cmd == _waiting_packet_type) {
1665  _data_locker.lock();
1666  _lastAnsPkt = message;
1667  _response_waiter.setResult(message->cmd);
1668  _data_locker.unlock();
1669  }
1670 
1671 
1672  }
1673  private:
1674 
1675  std::shared_ptr<internal::RPLidarProtocolCodec> _protocolHandler;
1676  std::shared_ptr<internal::AsyncTransceiver> _transeiver;
1677  std::shared_ptr<internal::LIDARSampleDataUnpacker> _dataunpacker;
1678 
1680 
1682 
1683 
1687 
1692 
1693  sl_lidar_response_device_info_t _cached_DevInfo;
1695 
1696  };
1697 
1699  {
1700  return new SlamtecLidarDriver();
1701  }
1702 }
sl::ScanDataHolder::_getOperationalBuffer_locked
std::vector< T > & _getOperationalBuffer_locked()
Definition: sl_lidar_driver.cpp:354
SL_RESULT_ALREADY_DONE
#define SL_RESULT_ALREADY_DONE
Definition: sl_types.h:73
_u16
uint16_t _u16
Definition: rptypes.h:66
response
const std::string response
sl::LIDARInterfaceType
LIDARInterfaceType
Definition: sl_lidar_driver.h:146
sdkcommon.h
sl::IChannel::waitForData
virtual bool waitForData(size_t size, sl_u32 timeoutInMs=-1, size_t *actualReady=nullptr)=0
sl::ScanDataHolder::_scan_node_buffer_size
size_t _scan_node_buffer_size
Definition: sl_lidar_driver.cpp:366
sl::printDeprecationWarn
static void printDeprecationWarn(const char *fn, const char *replacement)
Definition: sl_lidar_driver.cpp:70
sl::SlamtecLidarDriver::getScanModeName
u_result getScanModeName(char *modeName, size_t stringSize, _u16 scanModeID, _u32 timeoutInMs=DEFAULT_TIMEOUT)
Definition: sl_lidar_driver.cpp:1364
u_result
uint32_t u_result
Definition: rptypes.h:100
SL_LIDAR_CMD_SCAN
#define SL_LIDAR_CMD_SCAN
Definition: sl_lidar_cmd.h:51
sl::RawSampleNodeHolder
Definition: sl_lidar_driver.cpp:187
sl::ScanDataHolder::_data_waiter
rp::hal::Event _data_waiter
Definition: sl_lidar_driver.cpp:361
sl::MotorCtrlSupportPwm
@ MotorCtrlSupportPwm
Definition: sl_lidar_driver.h:279
sl::SlamtecLidarDriver::TOF_M_SERIAL_MINUM_MAJOR_ID
@ TOF_M_SERIAL_MINUM_MAJOR_ID
Definition: sl_lidar_driver.cpp:391
sl_lidarprotocol_codec.h
sl::SlamtecLidarDriver::startScanExpress
sl_result startScanExpress(bool force, sl_u16 scanMode, sl_u32 options=0, LidarScanMode *outUsedScanMode=nullptr, sl_u32 timeout=DEFAULT_TIMEOUT)
Definition: sl_lidar_driver.cpp:682
sl::SlamtecLidarDriver::_getLegacySampleDuration_uS
u_result _getLegacySampleDuration_uS(rplidar_response_sample_rate_t &rateInfo, _u32 timeout)
Definition: sl_lidar_driver.cpp:1556
sl::SlamtecLidarDriver::_rawSampleNodeHolder
RawSampleNodeHolder< sl_lidar_response_measurement_node_hq_t > _rawSampleNodeHolder
Definition: sl_lidar_driver.cpp:1689
sl_lidar_response_measurement_node_hq_t
Definition: sl_lidar_cmd.h:272
sl::SlamtecLidarDriver::_op_locker
rp::hal::Locker _op_locker
Definition: sl_lidar_driver.cpp:1684
sl::IChannel::close
virtual void close()=0
SL_LIDAR_AUTOBAUD_MAGICBYTE
#define SL_LIDAR_AUTOBAUD_MAGICBYTE
Definition: sl_lidar_cmd.h:47
sl::ScanDataHolder::unlockScan
void unlockScan(std::vector< T > *scan)
Definition: sl_lidar_driver.cpp:334
sl::LidarMotorInfo::min_speed
sl_u16 min_speed
Definition: sl_lidar_driver.h:303
sl::SlamtecLidarDriver::getLidarIpConf
sl_result getLidarIpConf(sl_lidar_ip_conf_t &conf, sl_u32 timeout)
Definition: sl_lidar_driver.cpp:896
rp::hal::Locker::unlock
void unlock()
Definition: locker.h:117
sl::SlamtecLidarDriver::_timing_desc
SlamtecLidarTimingDesc _timing_desc
Definition: sl_lidar_driver.cpp:1694
SL_LIDAR_CONF_SCAN_COMMAND_EXPRESS
#define SL_LIDAR_CONF_SCAN_COMMAND_EXPRESS
Definition: sl_lidar_cmd.h:290
sl::LidarScanMode::us_per_sample
float us_per_sample
Definition: sl_lidar_driver.h:79
sl::SlamtecLidarDriver::ParseLIDARMajorTypeByModelID
static LIDARMajorType ParseLIDARMajorTypeByModelID(_u8 modelID)
Definition: sl_lidar_driver.cpp:1394
SL_LIDAR_CMD_EXPRESS_SCAN
#define SL_LIDAR_CMD_EXPRESS_SCAN
Definition: sl_lidar_cmd.h:68
RESULT_INVALID_DATA
#define RESULT_INVALID_DATA
Definition: rptypes.h:105
sl::SlamtecLidarDriver::getDeviceInfo
sl_result getDeviceInfo(sl_lidar_response_device_info_t &info, sl_u32 timeout=DEFAULT_TIMEOUT)
Definition: sl_lidar_driver.cpp:808
types.h
sl::SlamtecLidarDriver::getScanModeCount
u_result getScanModeCount(sl_u16 &modeCount, sl_u32 timeoutInMs=DEFAULT_TIMEOUT)
Definition: sl_lidar_driver.cpp:1199
sl::IChannel
Definition: sl_lidar_driver.h:171
sl::ascendScanData_
static sl_result ascendScanData_(TNode *nodebuffer, size_t count)
Definition: sl_lidar_driver.cpp:129
sl::SlamtecLidarDriver::grabScanDataHq
sl_result grabScanDataHq(sl_lidar_response_measurement_node_hq_t *nodebuffer, size_t &count, sl_u32 timeout=DEFAULT_TIMEOUT)
Definition: sl_lidar_driver.cpp:802
sl::ScanDataHolder
Definition: sl_lidar_driver.cpp:238
sl::LidarMotorInfo
Definition: sl_lidar_driver.h:292
sl::LIDAR_MAJOR_TYPE_S_SERIES
@ LIDAR_MAJOR_TYPE_S_SERIES
Definition: sl_lidar_driver.h:140
sl::SlamtecLidarDriver::getDesiredSpeed
u_result getDesiredSpeed(sl_lidar_response_desired_rot_speed_t &motorSpeed, sl_u32 timeoutInMs=DEFAULT_TIMEOUT)
Definition: sl_lidar_driver.cpp:1163
sl::SlamtecLidarDriver::getModelNameDescriptionString
sl_result getModelNameDescriptionString(std::string &out_description, bool fetchAliasName, const sl_lidar_response_device_info_t *devInfo, sl_u32 timeout)
Definition: sl_lidar_driver.cpp:444
type
sl_u32 type
Definition: sl_lidar_cmd.h:2
byteorder.h
sl::SlamtecLidarDriver::_updateTimingDesc
bool _updateTimingDesc(const rplidar_response_device_info_t &devInfo, float selectedSampleDuration)
Definition: sl_lidar_driver.cpp:1538
RPLIDAR_CONF_SCAN_COMMAND_STD
#define RPLIDAR_CONF_SCAN_COMMAND_STD
Definition: rplidar_cmd.h:166
rplidar_response_acc_board_flag_t
sl_lidar_response_acc_board_flag_t rplidar_response_acc_board_flag_t
Definition: rplidar_cmd.h:122
SL_LIDAR_CONF_SCAN_MODE_US_PER_SAMPLE
#define SL_LIDAR_CONF_SCAN_MODE_US_PER_SAMPLE
Definition: sl_lidar_cmd.h:304
getms
#define getms()
Definition: linux/timer.h:57
sl::RawSampleNodeHolder::RawSampleNodeHolder
RawSampleNodeHolder(size_t maxcount=8192)
Definition: sl_lidar_driver.cpp:190
SL_LIDAR_CONF_MAX_ROT_FREQ
#define SL_LIDAR_CONF_MAX_ROT_FREQ
Definition: sl_lidar_cmd.h:300
RESULT_OK
#define RESULT_OK
Definition: rptypes.h:102
SL_LIDAR_ANS_TYPE_SET_LIDAR_CONF
#define SL_LIDAR_ANS_TYPE_SET_LIDAR_CONF
Definition: sl_lidar_cmd.h:159
SL_RESULT_OPERATION_NOT_SUPPORT
#define SL_RESULT_OPERATION_NOT_SUPPORT
Definition: sl_types.h:78
sl::LidarScanMode::scan_mode
char scan_mode[64]
Definition: sl_lidar_driver.h:88
IS_OK
#define IS_OK(x)
Definition: rptypes.h:113
sl::LIDAR_MAJOR_TYPE_A_SERIES
@ LIDAR_MAJOR_TYPE_A_SERIES
Definition: sl_lidar_driver.h:139
sl::SlamtecLidarDriver::grabScanDataHqWithTimeStamp
sl_result grabScanDataHqWithTimeStamp(sl_lidar_response_measurement_node_hq_t *nodebuffer, size_t &count, sl_u64 &timestamp_uS, sl_u32 timeout=DEFAULT_TIMEOUT)
Definition: sl_lidar_driver.cpp:783
sl::ILidarDriver
Definition: sl_lidar_driver.h:306
sl::SlamtecLidarDriver::MAX_SCANNODE_CACHE_COUNT
@ MAX_SCANNODE_CACHE_COUNT
Definition: sl_lidar_driver.cpp:378
sl::SlamtecLidarDriver::getLidarConf
u_result getLidarConf(_u32 type, std::vector< _u8 > &outputBuf, const void *payload=NULL, size_t payloadSize=0, _u32 timeout=DEFAULT_TIMEOUT)
Definition: sl_lidar_driver.cpp:1261
assert.h
sl::SlamtecLidarDriver::checkMotorCtrlSupport
sl_result checkMotorCtrlSupport(MotorCtrlSupport &support, sl_u32 timeout=DEFAULT_TIMEOUT)
Definition: sl_lidar_driver.cpp:833
sl::ScanDataHolder::_getOperationBufferID_locked
int _getOperationBufferID_locked()
Definition: sl_lidar_driver.cpp:349
sl::SlamtecLidarDriver::_cached_DevInfo
sl_lidar_response_device_info_t _cached_DevInfo
Definition: sl_lidar_driver.cpp:1693
sl::LIDAR_MAJOR_TYPE_T_SERIES
@ LIDAR_MAJOR_TYPE_T_SERIES
Definition: sl_lidar_driver.h:141
offsetof
#define offsetof(_structure, _field)
Definition: util.h:55
_u8
uint8_t _u8
Definition: rptypes.h:63
SL_RESULT_OK
#define SL_RESULT_OK
Definition: sl_types.h:71
sl::LidarScanMode::id
sl_u16 id
Definition: sl_lidar_driver.h:76
sl::SlamtecLidarDriver::_data_locker
rp::hal::Locker _data_locker
Definition: sl_lidar_driver.cpp:1685
sl::SlamtecLidarDriver::negotiateSerialBaudRate
sl_result negotiateSerialBaudRate(sl_u32 requiredBaudRate, sl_u32 *baudRateDetected)
Definition: sl_lidar_driver.cpp:1058
sl::internal::IProtocolMessageListener
Definition: sl_lidarprotocol_codec.h:41
SL_LIDAR_CONF_MIN_ROT_FREQ
#define SL_LIDAR_CONF_MIN_ROT_FREQ
Definition: sl_lidar_cmd.h:299
sl::SlamtecLidarTimingDesc::native_interface_type
LIDARInterfaceType native_interface_type
Definition: sl_lidar_driver.h:163
sl::SlamtecLidarDriver::getScanModeAnsType
u_result getScanModeAnsType(sl_u8 &ansType, sl_u16 scanModeID, sl_u32 timeoutInMs=DEFAULT_TIMEOUT)
Definition: sl_lidar_driver.cpp:1345
SL_LIDAR_RESP_ACC_BOARD_FLAG_MOTOR_CTRL_SUPPORT_MASK
#define SL_LIDAR_RESP_ACC_BOARD_FLAG_MOTOR_CTRL_SUPPORT_MASK
Definition: sl_lidar_cmd.h:164
sl::LIDAR_TECHNOLOGY_DTOF
@ LIDAR_TECHNOLOGY_DTOF
Definition: sl_lidar_driver.h:132
sl::LidarScanMode
Definition: sl_lidar_driver.h:73
sl::SlamtecLidarDriver::_response_waiter
rp::hal::Waiter< _u32 > _response_waiter
Definition: sl_lidar_driver.cpp:1686
SL_LIDAR_CMD_NEW_BAUDRATE_CONFIRM
#define SL_LIDAR_CMD_NEW_BAUDRATE_CONFIRM
Definition: sl_lidar_cmd.h:56
sl::ScanDataHolder::reset
void reset()
Definition: sl_lidar_driver.cpp:257
sl::getDistanceQ2
static sl_u16 getDistanceQ2(const sl_lidar_response_measurement_node_t &node)
Definition: sl_lidar_driver.cpp:112
sl::SlamtecLidarDriver::connect
sl_result connect(IChannel *channel)
Definition: sl_lidar_driver.cpp:473
sl::SlamtecLidarDriver::_checkNDMagicNumber
bool _checkNDMagicNumber(_u8 model)
Definition: sl_lidar_driver.cpp:1467
sl::LIDARMajorType
LIDARMajorType
Definition: sl_lidar_driver.h:137
rp::hal::Waiter::setResult
void setResult(ResultT result)
Definition: waiter.h:34
SL_LIDAR_CMD_SET_MOTOR_PWM
#define SL_LIDAR_CMD_SET_MOTOR_PWM
Definition: sl_lidar_cmd.h:73
sl::LidarMotorInfo::motorCtrlSupport
MotorCtrlSupport motorCtrlSupport
Definition: sl_lidar_driver.h:294
delay
#define delay(x)
Definition: win32/timer.h:39
sl::ScanDataHolder::getMaxCacheCount
size_t getMaxCacheCount() const
Definition: sl_lidar_driver.cpp:252
sl::MotorCtrlSupport
MotorCtrlSupport
Definition: sl_lidar_driver.h:276
IS_FAIL
#define IS_FAIL(x)
Definition: rptypes.h:114
sl::SlamtecLidarDriver::_getNativeBaudRate
_u32 _getNativeBaudRate(const rplidar_response_device_info_t &devInfo)
Definition: sl_lidar_driver.cpp:1516
sl::SlamtecLidarDriver::BUILTIN_MOTORCTL_MINUM_MAJOR_ID
@ BUILTIN_MOTORCTL_MINUM_MAJOR_ID
Definition: sl_lidar_driver.cpp:383
f
f
sl::LidarScanMode::max_distance
float max_distance
Definition: sl_lidar_driver.h:82
SL_LIDAR_CMD_SET_LIDAR_CONF
#define SL_LIDAR_CMD_SET_LIDAR_CONF
Definition: sl_lidar_cmd.h:71
sl::LIDARTechnologyType
LIDARTechnologyType
Definition: sl_lidar_driver.h:129
sl::SlamtecLidarDriver::checkSupportConfigCommands
u_result checkSupportConfigCommands(bool &outSupport, sl_u32 timeoutInMs=DEFAULT_TIMEOUT)
Definition: sl_lidar_driver.cpp:1176
SL_LIDAR_CMD_FORCE_SCAN
#define SL_LIDAR_CMD_FORCE_SCAN
Definition: sl_lidar_cmd.h:52
sl::SlamtecLidarDriver::disconnect
void disconnect()
Definition: sl_lidar_driver.cpp:495
sl::SlamtecLidarDriver::SlamtecLidarDriver
SlamtecLidarDriver()
Definition: sl_lidar_driver.cpp:398
sl::IChannel::flush
virtual void flush()=0
sl::LidarMotorInfo::desired_speed
sl_u16 desired_speed
Definition: sl_lidar_driver.h:297
sl::SlamtecLidarDriver::_detectLIDARNativeInterfaceType
u_result _detectLIDARNativeInterfaceType(LIDARInterfaceType &outputType, const rplidar_response_device_info_t &devInfo, sl_u32 timeout=DEFAULT_TIMEOUT)
Definition: sl_lidar_driver.cpp:1475
sl::SlamtecLidarDriver::A2A3_LIDAR_MINUM_MAJOR_ID
@ A2A3_LIDAR_MINUM_MAJOR_ID
Definition: sl_lidar_driver.cpp:382
sl::SlamtecLidarDriver::getLIDARMajorType
LIDARMajorType getLIDARMajorType(const sl_lidar_response_device_info_t *devInfo)
Definition: sl_lidar_driver.cpp:433
SL_LIDAR_CONF_LIDAR_STATIC_IP_ADDR
#define SL_LIDAR_CONF_LIDAR_STATIC_IP_ADDR
Definition: sl_lidar_cmd.h:317
sl::SlamtecLidarDriver::getAllSupportedScanModes
sl_result getAllSupportedScanModes(std::vector< LidarScanMode > &outModes, sl_u32 timeoutInMs=DEFAULT_TIMEOUT)
Get all scan modes that supported by lidar.
Definition: sl_lidar_driver.cpp:518
SL_LIDAR_RESP_MEASUREMENT_CHECKBIT
#define SL_LIDAR_RESP_MEASUREMENT_CHECKBIT
Definition: sl_lidar_cmd.h:180
sl::MotorCtrlSupportRpm
@ MotorCtrlSupportRpm
Definition: sl_lidar_driver.h:280
sl::SlamtecLidarTimingDesc::native_baudrate
sl_u32 native_baudrate
Definition: sl_lidar_driver.h:159
locker.h
sl::ScanDataHolder::rewindCurrentScanData
void rewindCurrentScanData()
Definition: sl_lidar_driver.cpp:312
rp::hal::Waiter< _u32 >
sl::LidarMotorInfo::max_speed
sl_u16 max_speed
Definition: sl_lidar_driver.h:300
sl_crc.h
result
sl_u32 result
Definition: sl_lidar_cmd.h:3
waiter.h
SL_RESULT_OPERATION_TIMEOUT
#define SL_RESULT_OPERATION_TIMEOUT
Definition: sl_types.h:76
sl::SlamtecLidarDriver::ParseLIDARTechnologyTypeByModelID
static LIDARTechnologyType ParseLIDARTechnologyTypeByModelID(_u8 modelID)
Definition: sl_lidar_driver.cpp:1382
sl::SlamtecLidarDriver::setLidarConf
u_result setLidarConf(_u32 type, const void *payload, size_t payloadSize, _u32 timeout)
Definition: sl_lidar_driver.cpp:1215
sl::internal::ProtocolMessage
Definition: sl_async_transceiver.h:41
rp::hal::Event
Definition: event.h:38
payload
sl_u8 payload[0]
Definition: sl_lidar_cmd.h:3
sl::SlamtecLidarDriver::_isConnected
bool _isConnected
Definition: sl_lidar_driver.cpp:1679
sl_lidar_response_measurement_node_hq_t::quality
sl_u8 quality
Definition: sl_lidar_cmd.h:276
SL_LIDAR_CONF_MODEL_NAME_ALIAS
#define SL_LIDAR_CONF_MODEL_NAME_ALIAS
Definition: sl_lidar_cmd.h:313
sl::SlamtecLidarDriver::getTypicalScanMode
sl_result getTypicalScanMode(sl_u16 &outMode, sl_u32 timeoutInMs=DEFAULT_TIMEOUT)
Get typical scan mode of lidar.
Definition: sl_lidar_driver.cpp:556
rp::hal::Event::EVENT_OK
@ EVENT_OK
Definition: event.h:44
rplidar_response_set_lidar_conf_t
sl_lidar_response_set_lidar_conf_t rplidar_response_set_lidar_conf_t
Definition: rplidar_cmd.h:194
rp::hal::Locker
Definition: locker.h:38
sl::SlamtecLidarDriver::getLidarSampleDuration
u_result getLidarSampleDuration(float &sampleDurationRes, sl_u16 scanModeID, sl_u32 timeoutInMs=DEFAULT_TIMEOUT)
Definition: sl_lidar_driver.cpp:1306
sl::LIDAR_INTERFACE_ETHERNET
@ LIDAR_INTERFACE_ETHERNET
Definition: sl_lidar_driver.h:148
SL_LIDAR_ANS_TYPE_ACC_BOARD_FLAG
#define SL_LIDAR_ANS_TYPE_ACC_BOARD_FLAG
Definition: sl_lidar_cmd.h:162
SL_LIDAR_RESP_MEASUREMENT_ANGLE_SHIFT
#define SL_LIDAR_RESP_MEASUREMENT_ANGLE_SHIFT
Definition: sl_lidar_cmd.h:181
SL_LIDAR_CONF_SCAN_MODE_COUNT
#define SL_LIDAR_CONF_SCAN_MODE_COUNT
Definition: sl_lidar_cmd.h:303
sl_lidar_response_measurement_node_hq_t::dist_mm_q2
sl_u32 dist_mm_q2
Definition: sl_lidar_cmd.h:275
sl::SlamtecLidarDriver::_dataunpacker
std::shared_ptr< internal::LIDARSampleDataUnpacker > _dataunpacker
Definition: sl_lidar_driver.cpp:1677
RESULT_OPERATION_TIMEOUT
#define RESULT_OPERATION_TIMEOUT
Definition: rptypes.h:107
sl::SlamtecLidarDriver::TOF_C_SERIAL_MINUM_MAJOR_ID
@ TOF_C_SERIAL_MINUM_MAJOR_ID
Definition: sl_lidar_driver.cpp:388
SL_RESULT_INVALID_DATA
#define SL_RESULT_INVALID_DATA
Definition: sl_types.h:74
rp::hal::AutoLocker
Definition: locker.h:188
sl
Definition: sl_crc.h:38
sl::SlamtecLidarDriver::stop
sl_result stop(sl_u32 timeout=DEFAULT_TIMEOUT)
Definition: sl_lidar_driver.cpp:763
SL_LIDAR_CMD_RESET
#define SL_LIDAR_CMD_RESET
Definition: sl_lidar_cmd.h:53
RPLIDAR_RESP_HQ_FLAG_SYNCBIT
#define RPLIDAR_RESP_HQ_FLAG_SYNCBIT
Definition: rplidar_cmd.h:131
rp::hal::Event::set
void set(bool isSignal=true)
Definition: event.h:78
sl::SlamtecLidarDriver::TOF_S_SERIAL_MINUM_MAJOR_ID
@ TOF_S_SERIAL_MINUM_MAJOR_ID
Definition: sl_lidar_driver.cpp:389
rplidar_payload_get_scan_conf_t
sl_lidar_payload_get_scan_conf_t rplidar_payload_get_scan_conf_t
Definition: rplidar_cmd.h:94
sl::SlamtecLidarDriver::getLIDARTechnologyType
LIDARTechnologyType getLIDARTechnologyType(const sl_lidar_response_device_info_t *devInfo)
Definition: sl_lidar_driver.cpp:423
SL_LIDAR_CMD_GET_DEVICE_HEALTH
#define SL_LIDAR_CMD_GET_DEVICE_HEALTH
Definition: sl_lidar_cmd.h:60
SL_LIDAR_CMD_GET_ACC_BOARD_FLAG
#define SL_LIDAR_CMD_GET_ACC_BOARD_FLAG
Definition: sl_lidar_cmd.h:74
SL_LIDAR_ANS_TYPE_MEASUREMENT
#define SL_LIDAR_ANS_TYPE_MEASUREMENT
Definition: sl_lidar_cmd.h:144
sl::LIDAR_INTERFACE_UNKNOWN
@ LIDAR_INTERFACE_UNKNOWN
Definition: sl_lidar_driver.h:153
event.h
SL_LIDAR_CONF_SCAN_COMMAND_STD
#define SL_LIDAR_CONF_SCAN_COMMAND_STD
Definition: sl_lidar_cmd.h:289
sl::SlamtecLidarTimingDesc
Definition: sl_lidar_driver.h:156
sl::ScanDataHolder::waitAndLockAvailableScan
std::vector< T > * waitAndLockAvailableScan(_u32 timeout, _u64 *out_timestamp_uS=nullptr)
Definition: sl_lidar_driver.cpp:317
sl::angleLessThan
static bool angleLessThan(const TNode &a, const TNode &b)
Definition: sl_lidar_driver.cpp:123
sl_lidar_response_measurement_node_hq_t::angle_z_q14
sl_u16 angle_z_q14
Definition: sl_lidar_cmd.h:274
sl::RawSampleNodeHolder::_max_count
size_t _max_count
Definition: sl_lidar_driver.cpp:230
sl::MotorCtrlSupportNone
@ MotorCtrlSupportNone
Definition: sl_lidar_driver.h:278
sl::SlamtecLidarDriver::_sendCommandWithResponse
u_result _sendCommandWithResponse(_u8 cmd, _u8 responseType, internal::message_autoptr_t &ansPkt, _u32 timeout=DEFAULT_TIMEOUT, const void *payload=NULL, size_t payloadsize=0)
Definition: sl_lidar_driver.cpp:1612
sl::SlamtecLidarDriver::_transeiver
std::shared_ptr< internal::AsyncTransceiver > _transeiver
Definition: sl_lidar_driver.cpp:1676
sl::SlamtecLidarTimingDesc::linkage_delay_uS
sl_u32 linkage_delay_uS
Definition: sl_lidar_driver.h:161
sl::SlamtecLidarDriver::startScan
sl_result startScan(bool force, bool useTypicalScan, sl_u32 options=0, LidarScanMode *outUsedScanMode=nullptr)
Definition: sl_lidar_driver.cpp:586
sl::CHANNEL_TYPE_SERIALPORT
@ CHANNEL_TYPE_SERIALPORT
Definition: sl_lidar_driver.h:284
sl::SlamtecLidarDriver::startScanNormal_commonpath
sl_result startScanNormal_commonpath(bool force, bool ifSupportLidarConf, LidarScanMode &outUsedScanMode, sl_u32 timeout)
Definition: sl_lidar_driver.cpp:620
SL_LIDAR_CONF_DESIRED_ROT_FREQ
#define SL_LIDAR_CONF_DESIRED_ROT_FREQ
Definition: sl_lidar_cmd.h:297
sl::SlamtecLidarDriver::GetModelNameStringByModelID
static std::string GetModelNameStringByModelID(_u8 modelID)
Definition: sl_lidar_driver.cpp:1416
SL_LIDAR_RESP_MEASUREMENT_QUALITY_SHIFT
#define SL_LIDAR_RESP_MEASUREMENT_QUALITY_SHIFT
Definition: sl_lidar_cmd.h:176
sl::IChannel::read
virtual int read(void *buffer, size_t size)=0
sl::LIDAR_MAJOR_TYPE_M_SERIES
@ LIDAR_MAJOR_TYPE_M_SERIES
Definition: sl_lidar_driver.h:142
rplidar_response_get_lidar_conf_t
sl_lidar_response_get_lidar_conf_t rplidar_response_get_lidar_conf_t
Definition: rplidar_cmd.h:193
rp::hal::Locker::lock
Locker::LOCK_STATUS lock(unsigned long timeout=0xFFFFFFFF)
Definition: locker.h:60
sl::SlamtecLidarDriver::_waiting_packet_type
_u32 _waiting_packet_type
Definition: sl_lidar_driver.cpp:1690
sl::SlamtecLidarDriver::getFrequency
sl_result getFrequency(const LidarScanMode &scanMode, const sl_lidar_response_measurement_node_hq_t *nodes, size_t count, float &frequency)
Definition: sl_lidar_driver.cpp:880
dataunpacker.h
sl::SlamtecLidarDriver::onProtocolMessageDecoded
virtual void onProtocolMessageDecoded(const internal::ProtocolMessage &msg)
Definition: sl_lidar_driver.cpp:1655
sl::SlamtecLidarDriver::onHQNodeScanResetReq
virtual void onHQNodeScanResetReq()
Definition: sl_lidar_driver.cpp:1651
sl::LidarScanMode::ans_type
sl_u8 ans_type
Definition: sl_lidar_driver.h:85
rplidar_response_device_info_t
sl_lidar_response_device_info_t rplidar_response_device_info_t
Definition: rplidar_cmd.h:195
sl::internal::message_autoptr_t
std::shared_ptr< ProtocolMessage > message_autoptr_t
Definition: sl_async_transceiver.h:82
sl::SlamtecLidarDriver::getHealth
sl_result getHealth(sl_lidar_response_device_health_t &health, sl_u32 timeout=DEFAULT_TIMEOUT)
Definition: sl_lidar_driver.cpp:913
abs_rxtx.h
sl::ScanDataHolder::_scan_begin_timestamp_uS
_u64 _scan_begin_timestamp_uS[2]
Definition: sl_lidar_driver.cpp:365
SL_LIDAR_CONF_SCAN_MODE_TYPICAL
#define SL_LIDAR_CONF_SCAN_MODE_TYPICAL
Definition: sl_lidar_cmd.h:308
sl::ScanDataHolder::checkNewScanSignalAndReset
bool checkNewScanSignalAndReset()
Definition: sl_lidar_driver.cpp:267
RESULT_OPERATION_NOT_SUPPORT
#define RESULT_OPERATION_NOT_SUPPORT
Definition: rptypes.h:109
sl::SlamtecLidarDriver::_lastAnsPkt
internal::message_autoptr_t _lastAnsPkt
Definition: sl_lidar_driver.cpp:1691
sl::SlamtecLidarDriver::setLidarIpConf
sl_result setLidarIpConf(const sl_lidar_ip_conf_t &conf, sl_u32 timeout)
Definition: sl_lidar_driver.cpp:887
sl::SlamtecLidarDriver::getDeviceMacAddr
sl_result getDeviceMacAddr(sl_u8 *macAddrArray, sl_u32 timeoutInMs)
Definition: sl_lidar_driver.cpp:937
flag
sl_u8 flag
Definition: sl_lidar_cmd.h:2
sl::LIDAR_MAJOR_TYPE_UNKNOWN
@ LIDAR_MAJOR_TYPE_UNKNOWN
Definition: sl_lidar_driver.h:138
sl::ScanDataHolder::_scan_node_available_id
int _scan_node_available_id
Definition: sl_lidar_driver.cpp:367
sl::ISerialPortChannel
Definition: sl_lidar_driver.h:243
RESULT_OPERATION_FAIL
#define RESULT_OPERATION_FAIL
Definition: rptypes.h:106
SL_RESULT_OPERATION_FAIL
#define SL_RESULT_OPERATION_FAIL
Definition: sl_types.h:75
sl::SlamtecLidarDriver::reset
sl_result reset(sl_u32 timeoutInMs=DEFAULT_TIMEOUT)
Definition: sl_lidar_driver.cpp:511
sl::RawSampleNodeHolder::_locker
rp::hal::Locker _locker
Definition: sl_lidar_driver.cpp:231
sl::IChannel::open
virtual bool open()=0
sl::SlamtecLidarDriver::_isSupportingMotorCtrl
MotorCtrlSupport _isSupportingMotorCtrl
Definition: sl_lidar_driver.cpp:1681
sl::setAngle
static void setAngle(sl_lidar_response_measurement_node_t &node, float v)
Definition: sl_lidar_driver.cpp:96
sl::SlamtecLidarDriver::_scanHolder
ScanDataHolder< sl_lidar_response_measurement_node_hq_t > _scanHolder
Definition: sl_lidar_driver.cpp:1688
sl::convert
static void convert(const sl_lidar_response_measurement_node_t &from, sl_lidar_response_measurement_node_hq_t &to)
Definition: sl_lidar_driver.cpp:75
SL_LIDAR_CONF_LIDAR_MAC_ADDR
#define SL_LIDAR_CONF_LIDAR_MAC_ADDR
Definition: sl_lidar_cmd.h:307
sl::SlamtecLidarDriver::startScanNormal
sl_result startScanNormal(bool force, sl_u32 timeout=DEFAULT_TIMEOUT)
Definition: sl_lidar_driver.cpp:664
sl::SlamtecLidarDriver::isConnected
bool isConnected()
Definition: sl_lidar_driver.cpp:506
SL_LIDAR_CMD_GET_DEVICE_INFO
#define SL_LIDAR_CMD_GET_DEVICE_INFO
Definition: sl_lidar_cmd.h:59
SL_LIDAR_CONF_SCAN_MODE_NAME
#define SL_LIDAR_CONF_SCAN_MODE_NAME
Definition: sl_lidar_cmd.h:309
sl::SlamtecLidarDriver::_sendCommandWithoutResponse
u_result _sendCommandWithoutResponse(_u8 cmd, const void *payload=NULL, size_t payloadsize=0, bool noForceStop=false)
Definition: sl_lidar_driver.cpp:1600
sl::IChannel::write
virtual int write(const void *data, size_t size)=0
sl::ScanDataHolder::_finishCurrentScanAndSwap_locked
int _finishCurrentScanAndSwap_locked()
Definition: sl_lidar_driver.cpp:341
sl::LIDAR_TECHNOLOGY_TRIANGULATION
@ LIDAR_TECHNOLOGY_TRIANGULATION
Definition: sl_lidar_driver.h:131
sl::RawSampleNodeHolder::_data_waiter
rp::hal::Event _data_waiter
Definition: sl_lidar_driver.cpp:232
sl_async_transceiver.h
sl::ScanDataHolder::_locker
rp::hal::Locker _locker
Definition: sl_lidar_driver.cpp:360
sl::RawSampleNodeHolder::clear
void clear()
Definition: sl_lidar_driver.cpp:195
sl::SlamtecLidarDriver
Definition: sl_lidar_driver.cpp:373
sl::RawSampleNodeHolder::_data_queue
std::deque< T > _data_queue
Definition: sl_lidar_driver.cpp:233
SL_LIDAR_ANS_TYPE_MEASUREMENT_CAPSULED
#define SL_LIDAR_ANS_TYPE_MEASUREMENT_CAPSULED
Definition: sl_lidar_cmd.h:146
SL_LIDAR_ANS_TYPE_GET_LIDAR_CONF
#define SL_LIDAR_ANS_TYPE_GET_LIDAR_CONF
Definition: sl_lidar_cmd.h:158
sl::ScanDataHolder::ScanDataHolder
ScanDataHolder(size_t maxcount=8192)
Definition: sl_lidar_driver.cpp:241
_u64
uint64_t _u64
Definition: rptypes.h:72
socket.h
SL_LIDAR_CONF_SCAN_MODE_MAX_DISTANCE
#define SL_LIDAR_CONF_SCAN_MODE_MAX_DISTANCE
Definition: sl_lidar_cmd.h:305
SL_LIDAR_CMD_GET_LIDAR_CONF
#define SL_LIDAR_CMD_GET_LIDAR_CONF
Definition: sl_lidar_cmd.h:70
sl::SlamtecLidarDriver::NEWDESIGN_MINUM_MAJOR_ID
@ NEWDESIGN_MINUM_MAJOR_ID
Definition: sl_lidar_driver.cpp:394
sl::RawSampleNodeHolder::pushNode
void pushNode(_u64 timestamp_uS, const T *node)
Definition: sl_lidar_driver.cpp:202
SL_LIDAR_CMD_STOP
#define SL_LIDAR_CMD_STOP
Definition: sl_lidar_cmd.h:50
sl_result
uint32_t sl_result
Definition: sl_types.h:69
sl::SlamtecLidarDriver::getMaxDistance
u_result getMaxDistance(float &maxDistance, sl_u16 scanModeID, sl_u32 timeoutInMs=DEFAULT_TIMEOUT)
Definition: sl_lidar_driver.cpp:1325
rplidar_response_sample_rate_t
sl_lidar_response_sample_rate_t rplidar_response_sample_rate_t
Definition: rplidar_cmd.h:135
sl::getAngle
static float getAngle(const sl_lidar_response_measurement_node_t &node)
Definition: sl_lidar_driver.cpp:91
sl_lidar_response_measurement_node_hq_t::flag
sl_u8 flag
Definition: sl_lidar_cmd.h:277
sl::Result
Definition: sl_lidar_driver.h:92
SL_LIDAR_ANS_TYPE_SAMPLE_RATE
#define SL_LIDAR_ANS_TYPE_SAMPLE_RATE
Definition: sl_lidar_cmd.h:155
sl::IChannel::getChannelType
virtual int getChannelType()=0
sl::SlamtecLidarDriver::TOF_T_SERIAL_MINUM_MAJOR_ID
@ TOF_T_SERIAL_MINUM_MAJOR_ID
Definition: sl_lidar_driver.cpp:390
sl::LIDAR_INTERFACE_UART
@ LIDAR_INTERFACE_UART
Definition: sl_lidar_driver.h:147
SL_LIDAR_ANS_TYPE_DEVINFO
#define SL_LIDAR_ANS_TYPE_DEVINFO
Definition: sl_lidar_cmd.h:141
SL_LIDAR_CMD_GET_SAMPLERATE
#define SL_LIDAR_CMD_GET_SAMPLERATE
Definition: sl_lidar_cmd.h:62
sl::createLidarDriver
Result< ILidarDriver * > createLidarDriver()
Definition: sl_lidar_driver.cpp:1698
sl::SlamtecLidarDriver::~SlamtecLidarDriver
virtual ~SlamtecLidarDriver()
Definition: sl_lidar_driver.cpp:416
sl::SlamtecLidarTimingDesc::sample_duration_uS
sl_u32 sample_duration_uS
Definition: sl_lidar_driver.h:158
sl::SlamtecLidarDriver::_disableDataGrabbing
void _disableDataGrabbing()
Definition: sl_lidar_driver.cpp:1459
_u32
uint32_t _u32
Definition: rptypes.h:69
sl::IChannel::clearReadCache
virtual void clearReadCache()=0
thread.h
SL_LIDAR_ANS_TYPE_DEVHEALTH
#define SL_LIDAR_ANS_TYPE_DEVHEALTH
Definition: sl_lidar_cmd.h:142
sl::ScanDataHolder::pushScanNodeData
void pushScanNodeData(_u64 currentSampleTsUs, const T *hqNode)
Definition: sl_lidar_driver.cpp:272
sl::SlamtecLidarDriver::getMotorInfo
sl_result getMotorInfo(LidarMotorInfo &motorInfo, sl_u32 timeoutInMs)
Definition: sl_lidar_driver.cpp:1023
sl::RawSampleNodeHolder::waitAndFetch
size_t waitAndFetch(T *node, size_t maxcount, _u32 timeout)
Definition: sl_lidar_driver.cpp:212
sl::ScanDataHolder::_scanbuffer
std::vector< T > _scanbuffer[2]
Definition: sl_lidar_driver.cpp:370
sl::ILidarDriver::DEFAULT_TIMEOUT
@ DEFAULT_TIMEOUT
Definition: sl_lidar_driver.h:332
rplidar_response_device_health_t
sl_lidar_response_device_health_t rplidar_response_device_health_t
Definition: rplidar_cmd.h:196
sl::ScanDataHolder::_new_scan_ready
std::atomic< bool > _new_scan_ready
Definition: sl_lidar_driver.cpp:368
le16_to_cpu
#define le16_to_cpu(x)
Definition: byteorder.h:46
sl::SlamtecLidarDriver::ascendScanData
sl_result ascendScanData(sl_lidar_response_measurement_node_hq_t *nodebuffer, size_t count)
Definition: sl_lidar_driver.cpp:957
sl::SlamtecLidarDriver::onHQNodeDecoded
virtual void onHQNodeDecoded(_u64 timestamp_uS, const rplidar_response_measurement_node_hq_t *node)
Definition: sl_lidar_driver.cpp:1645
sl::ISerialPortChannel::setDTR
virtual void setDTR(bool dtr)=0
sl::SlamtecLidarDriver::startMotor
sl_result startMotor()
Definition: sl_lidar_driver.cpp:1158
rp::hal::Event::wait
unsigned long wait(unsigned long timeout=0xFFFFFFFF)
Definition: event.h:106
sl::SlamtecLidarTimingDesc::native_timestamp_support
bool native_timestamp_support
Definition: sl_lidar_driver.h:165
SL_LIDAR_CMD_HQ_MOTOR_SPEED_CTRL
#define SL_LIDAR_CMD_HQ_MOTOR_SPEED_CTRL
Definition: sl_lidar_cmd.h:64
sl_lidar_driver.h
DEFAULT_MOTOR_SPEED
#define DEFAULT_MOTOR_SPEED
Definition: sl_lidar_cmd.h:116
sl::SlamtecLidarDriver::getScanDataWithIntervalHq
sl_result getScanDataWithIntervalHq(sl_lidar_response_measurement_node_hq_t *nodebuffer, size_t &count)
Definition: sl_lidar_driver.cpp:962
model
sl_u8 model
Definition: sl_lidar_cmd.h:2
sl::SlamtecLidarDriver::setMotorSpeed
sl_result setMotorSpeed(sl_u16 speed=DEFAULT_MOTOR_SPEED)
Definition: sl_lidar_driver.cpp:968
sl::SlamtecLidarDriver::_protocolHandler
std::shared_ptr< internal::RPLidarProtocolCodec > _protocolHandler
Definition: sl_lidar_driver.cpp:1675
SL_LIDAR_CONF_SCAN_MODE_ANS_TYPE
#define SL_LIDAR_CONF_SCAN_MODE_ANS_TYPE
Definition: sl_lidar_cmd.h:306
rp::hal::Event::EVENT_TIMEOUT
@ EVENT_TIMEOUT
Definition: event.h:45
SL_LIDAR_RESP_MEASUREMENT_SYNCBIT
#define SL_LIDAR_RESP_MEASUREMENT_SYNCBIT
Definition: sl_lidar_cmd.h:175
sl::LIDAR_MAJOR_TYPE_C_SERIES
@ LIDAR_MAJOR_TYPE_C_SERIES
Definition: sl_lidar_driver.h:143


rplidar_ros
Author(s):
autogenerated on Fri Aug 2 2024 08:42:14