42 #define min(a, b) (((a) < (b)) ? (a) : (b))
67 : _isConnected(false), _isScanning(false), _isSupportingMotorCtrl(false)
84 const char* port_path,
_u32 baudrate,
_u32 flag)
134 rplidar_response_device_health_t& healthinfo,
_u32 timeout)
150 rplidar_ans_header_t response_header;
164 if (header_size <
sizeof(rplidar_response_device_health_t))
175 reinterpret_cast<_u8*
>(&healthinfo),
sizeof(healthinfo));
181 rplidar_response_device_info_t& info,
_u32 timeout)
197 rplidar_ans_header_t response_header;
211 if (header_size <
sizeof(rplidar_response_device_info_t))
228 bool inExpressMode,
size_t count,
float& frequency,
bool& is4kmode)
232 frequency = 1000000.0f / (
count * sample_duration);
234 if (sample_duration <= 277)
265 rplidar_ans_header_t response_header;
279 if (header_size <
sizeof(rplidar_response_measurement_node_t))
295 bool& support,
_u32 timeout)
297 rplidar_response_device_info_t devinfo;
304 if (devinfo.firmware_version >= ((0x1 << 8) | 17))
307 rplidar_response_sample_rate_t sample_rate;
317 bool fixedAngle,
_u32 timeout)
328 rplidar_payload_express_scan_t scanReq;
329 scanReq.working_mode =
332 scanReq.reserved = 0;
342 rplidar_ans_header_t response_header;
356 if (header_size <
sizeof(rplidar_response_capsule_measurement_nodes_t))
374 bool isExpressModeSupported;
383 if (isExpressModeSupported)
411 rplidar_response_measurement_node_t local_buf[128];
414 size_t scan_count = 0;
416 memset(local_scan, 0,
sizeof(local_scan));
433 for (
size_t pos = 0; pos <
count; ++pos)
446 sizeof(rplidar_response_measurement_node_t));
453 local_scan[scan_count++] = local_buf[pos];
454 if (scan_count ==
_countof(local_scan))
463 const rplidar_response_capsule_measurement_nodes_t& capsule,
464 rplidar_response_measurement_node_t* nodebuffer,
size_t& nodeCount)
470 int currentStartAngle_q8 =
471 ((capsule.start_angle_sync_q6 & 0x7FFF) << 2);
472 int prevStartAngle_q8 =
475 diffAngle_q8 = (currentStartAngle_q8) - (prevStartAngle_q8);
476 if (prevStartAngle_q8 > currentStartAngle_q8)
478 diffAngle_q8 += (360 << 8);
481 int angleInc_q16 = (diffAngle_q8 << 3);
482 int currentAngle_raw_q16 = (prevStartAngle_q8 << 8);
497 int angle_offset1_q3 =
503 int angle_offset2_q3 =
511 ((currentAngle_raw_q16 - (angle_offset1_q3 << 13)) >> 10);
512 syncBit[0] = (((currentAngle_raw_q16 + angleInc_q16) %
513 (360 << 16)) < angleInc_q16)
516 currentAngle_raw_q16 += angleInc_q16;
519 ((currentAngle_raw_q16 - (angle_offset2_q3 << 13)) >> 10);
520 syncBit[1] = (((currentAngle_raw_q16 + angleInc_q16) %
521 (360 << 16)) < angleInc_q16)
524 currentAngle_raw_q16 += angleInc_q16;
526 for (
int cpos = 0; cpos < 2; ++cpos)
528 if (angle_q6[cpos] < 0) angle_q6[cpos] += (360 << 6);
529 if (angle_q6[cpos] >= (360 << 6)) angle_q6[cpos] -= (360 << 6);
531 rplidar_response_measurement_node_t node;
533 node.sync_quality = (syncBit[cpos] | ((!syncBit[cpos]) << 1));
538 node.angle_q6_checkbit = (1 | (angle_q6[cpos] << 1));
539 node.distance_q2 = dist_q2[cpos];
541 nodebuffer[nodeCount++] = node;
552 rplidar_response_capsule_measurement_nodes_t capsule_node;
553 rplidar_response_measurement_node_t local_buf[128];
556 size_t scan_count = 0;
558 memset(local_scan, 0,
sizeof(local_scan));
581 for (
size_t pos = 0; pos <
count; ++pos)
594 sizeof(rplidar_response_measurement_node_t));
601 local_scan[scan_count++] = local_buf[pos];
602 if (scan_count ==
_countof(local_scan))
612 rplidar_response_measurement_node_t* nodebuffer,
size_t&
count,
631 size_to_copy *
sizeof(rplidar_response_measurement_node_t));
632 count = size_to_copy;
644 rplidar_response_measurement_node_t* nodebuffer,
size_t count)
646 float inc_origin_angle = 360.0f /
count;
650 for (i = 0; i <
count && nodebuffer[i].distance_q2 == 0; i++)
659 float expect_angle = (nodebuffer[i + 1].angle_q6_checkbit >>
663 if (expect_angle < 0.0f) expect_angle = 0.0f;
666 nodebuffer[i].angle_q6_checkbit =
667 (((
_u16)(expect_angle * 64.0f))
673 for (i =
count - 1; nodebuffer[i].distance_q2 == 0; i--)
676 while (i != (
count - 1))
679 float expect_angle = (nodebuffer[i - 1].angle_q6_checkbit >>
683 if (expect_angle > 360.0f) expect_angle -= 360.0f;
686 nodebuffer[i].angle_q6_checkbit =
687 (((
_u16)(expect_angle * 64.0f))
693 float frontAngle = (nodebuffer[0].angle_q6_checkbit >>
696 for (i = 1; i <
count; i++)
700 float expect_angle = frontAngle + i * inc_origin_angle;
701 if (expect_angle > 360.0f) expect_angle -= 360.0f;
702 _u16 checkbit = nodebuffer[i].angle_q6_checkbit &
704 nodebuffer[i].angle_q6_checkbit =
705 (((
_u16)(expect_angle * 64.0f))
712 for (i = 0; i < (
count - 1); i++)
714 for (
size_t j = (i + 1); j <
count; j++)
719 rplidar_response_measurement_node_t temp = nodebuffer[i];
720 nodebuffer[i] = nodebuffer[j];
721 nodebuffer[j] = temp;
730 rplidar_response_measurement_node_t* node,
_u32 timeout)
734 _u8 recvBuffer[
sizeof(rplidar_response_measurement_node_t)];
735 _u8* nodeBuffer = (
_u8*)node;
738 while ((waitTime =
getms() - startTs) <= timeout)
741 sizeof(rplidar_response_measurement_node_t) - recvPos;
750 if (recvSize > remainSize) recvSize = remainSize;
754 for (
size_t pos = 0; pos < recvSize; ++pos)
756 _u8 currentByte = recvBuffer[pos];
761 _u8 tmp = (currentByte >> 1);
762 if ((tmp ^ currentByte) & 0x1)
786 nodeBuffer[recvPos++] = currentByte;
788 if (recvPos ==
sizeof(rplidar_response_measurement_node_t))
799 rplidar_response_measurement_node_t* nodebuffer,
size_t&
count,
808 size_t recvNodeCount = 0;
813 while ((waitTime =
getms() - startTs) <= timeout && recvNodeCount <
count)
815 rplidar_response_measurement_node_t node;
821 nodebuffer[recvNodeCount++] = node;
825 count = recvNodeCount;
830 rplidar_response_capsule_measurement_nodes_t& node,
_u32 timeout)
834 _u8 recvBuffer[
sizeof(rplidar_response_capsule_measurement_nodes_t)];
835 _u8* nodeBuffer = (
_u8*)&node;
838 while ((waitTime =
getms() - startTs) <= timeout)
841 sizeof(rplidar_response_capsule_measurement_nodes_t) - recvPos;
850 if (recvSize > remainSize) recvSize = remainSize;
854 for (
size_t pos = 0; pos < recvSize; ++pos)
856 _u8 currentByte = recvBuffer[pos];
861 _u8 tmp = (currentByte >> 4);
875 _u8 tmp = (currentByte >> 4);
889 nodeBuffer[recvPos++] = currentByte;
891 if (recvPos ==
sizeof(rplidar_response_capsule_measurement_nodes_t))
896 ((node.s_checksum_1 & 0xF) | (node.s_checksum_2 << 4));
898 rplidar_response_capsule_measurement_nodes_t,
901 sizeof(rplidar_response_capsule_measurement_nodes_t);
904 checksum ^= nodeBuffer[cpos];
906 if (recvChecksum == checksum)
909 if (node.start_angle_sync_q6 &
929 _u8 cmd,
const void* payload,
size_t payloadsize)
932 rplidar_cmd_packet_t*
header =
933 reinterpret_cast<rplidar_cmd_packet_t*
>(pkt_header);
938 if (payloadsize && payload)
953 checksum ^= (payloadsize & 0xFF);
956 for (
size_t pos = 0; pos < payloadsize; ++pos)
958 checksum ^= ((
_u8*)payload)[pos];
962 _u8 sizebyte = payloadsize;
980 _u8 recvBuffer[
sizeof(rplidar_ans_header_t)];
984 while ((waitTime =
getms() - startTs) <= timeout)
986 size_t remainSize =
sizeof(rplidar_ans_header_t) - recvPos;
995 if (recvSize > remainSize) recvSize = remainSize;
999 for (
size_t pos = 0; pos < recvSize; ++pos)
1001 _u8 currentByte = recvBuffer[pos];
1019 headerBuffer[recvPos++] = currentByte;
1021 if (recvPos ==
sizeof(rplidar_ans_header_t))
1038 rplidar_response_sample_rate_t& rateInfo,
_u32 timeout)
1044 rplidar_response_device_info_t devinfo;
1051 if (devinfo.firmware_version < ((0x1 << 8) | 17))
1066 rplidar_ans_header_t response_header;
1080 if (header_size <
sizeof(rplidar_response_sample_rate_t))
1096 bool& support,
_u32 timeout)
1108 rplidar_payload_acc_board_flag_t flag;
1118 rplidar_ans_header_t response_header;
1132 if (header_size <
sizeof(rplidar_response_acc_board_flag_t))
1142 rplidar_response_acc_board_flag_t acc_board_flag;
1144 reinterpret_cast<_u8*
>(&acc_board_flag),
sizeof(acc_board_flag));
1146 if (acc_board_flag.support_flag &
1158 rplidar_payload_motor_pwm_t motor_pwm;
1159 motor_pwm.pwm_value = pwm;
1167 sizeof(motor_pwm))))
unsigned long wait(unsigned long timeout=0xFFFFFFFF)
void set(bool isSignal=true)
Locker::LOCK_STATUS lock(unsigned long timeout=0xFFFFFFFF)
u_result join(unsigned long timeout=-1)
virtual void clearDTR()=0
virtual void flush(_u32 flags)=0
virtual int senddata(const unsigned char *data, size_t size)=0
virtual int waitfordata(size_t data_count, _u32 timeout=-1, size_t *returned_size=nullptr)=0
static serial_rxtx * CreateRxTx()
virtual bool bind(const char *portname, _u32 baudrate, _u32 flags=0)=0
virtual int recvdata(unsigned char *data, size_t size)=0
static void ReleaseRxTx(serial_rxtx *)
static void DisposeDriver(RPlidarDriver *drv)
Dispose the RPLIDAR Driver Instance specified by the drv parameter Applications should invoke this in...
static RPlidarDriver * CreateDriver(_u32 drivertype=DRIVER_TYPE_SERIALPORT)
Create an RPLIDAR Driver Instance This interface should be invoked first before any other operations.
virtual u_result startScanExpress(bool fixedAngle, _u32 timeout=DEFAULT_TIMEOUT)
virtual u_result checkMotorCtrlSupport(bool &support, _u32 timeout=DEFAULT_TIMEOUT)
Check whether the device support motor control.
virtual u_result getHealth(rplidar_response_device_health_t &, _u32 timeout=DEFAULT_TIMEOUT)
Retrieve the health status of the RPLIDAR The host system can use this operation to check whether RPL...
bool _is_previous_capsuledataRdy
virtual u_result getFrequency(bool inExpressMode, size_t count, float &frequency, bool &is4kmode)
Calcuate RPLIDAR's current scanning frequency from the given scan data Please refer to the applicatio...
u_result _waitScanData(rplidar_response_measurement_node_t *nodebuffer, size_t &count, _u32 timeout=DEFAULT_TIMEOUT)
u_result _waitCapsuledNode(rplidar_response_capsule_measurement_nodes_t &node, _u32 timeout=DEFAULT_TIMEOUT)
virtual u_result connect(const char *port_path, _u32 baudrate, _u32 flag)
Open the specified serial port and connect to a target RPLIDAR device.
virtual u_result stop(_u32 timeout=DEFAULT_TIMEOUT)
Ask the RPLIDAR core system to stop the current scan operation and enter idle state.
virtual u_result getSampleDuration_uS(rplidar_response_sample_rate_t &rateInfo, _u32 timeout=DEFAULT_TIMEOUT)
Get the sample duration information of the RPLIDAR.
virtual u_result ascendScanData(rplidar_response_measurement_node_t *nodebuffer, size_t count)
Ascending the scan data according to the angle value in the scan.
size_t _cached_scan_node_count
virtual u_result startMotor()
Start RPLIDAR's motor when using accessory board.
rplidar_response_capsule_measurement_nodes_t _cached_previous_capsuledata
virtual u_result setMotorPWM(_u16 pwm)
Set the RPLIDAR's motor pwm when using accessory board, currently valid for A2 only.
rplidar_response_measurement_node_t _cached_scan_node_buf[2048]
virtual u_result getDeviceInfo(rplidar_response_device_info_t &, _u32 timeout=DEFAULT_TIMEOUT)
Get the device information of the RPLIDAR include the serial number, firmware version,...
virtual u_result stopMotor()
Stop RPLIDAR's motor when using accessory board.
void _capsuleToNormal(const rplidar_response_capsule_measurement_nodes_t &capsule, rplidar_response_measurement_node_t *nodebuffer, size_t &nodeCount)
rp::hal::Thread _cachethread
u_result _waitResponseHeader(rplidar_ans_header_t *header, _u32 timeout=DEFAULT_TIMEOUT)
virtual ~RPlidarDriverSerialImpl()
bool _isSupportingMotorCtrl
virtual u_result startScanNormal(bool force, _u32 timeout=DEFAULT_TIMEOUT)
rp::hal::serial_rxtx * _rxtx
RPlidarDriverSerialImpl()
void _disableDataGrabbing()
u_result _sendCommand(_u8 cmd, const void *payload=nullptr, size_t payloadsize=0)
u_result _cacheCapsuledScanData()
u_result _waitNode(rplidar_response_measurement_node_t *node, _u32 timeout=DEFAULT_TIMEOUT)
u_result _cacheScanData()
virtual u_result checkExpressScanSupported(bool &support, _u32 timeout=DEFAULT_TIMEOUT)
Check whether the device support express mode.
virtual u_result grabScanData(rplidar_response_measurement_node_t *nodebuffer, size_t &count, _u32 timeout=DEFAULT_TIMEOUT)
Wait and grab a complete 0-360 degree scan data previously received.
virtual u_result reset(_u32 timeout=DEFAULT_TIMEOUT)
Ask the RPLIDAR core system to reset it self The host system can use the Reset operation to help RPLI...
virtual void disconnect()
Disconnect with the RPLIDAR and close the serial port.
virtual bool isConnected()
Returns TRUE when the connection has been established.
_u16 _cached_sampleduration_express
virtual u_result startScan(bool force=false, bool autoExpressMode=true)
Ask the RPLIDAR core system to enter the scan mode(Normal/Express, Express mode is 4k mode) A backgro...
_u16 _cached_sampleduration_std
GLuint GLuint GLsizei count
void memcpy(void *dest, size_t destSize, const void *src, size_t copyCount) noexcept
An OS and compiler independent version of "memcpy".
nv_oem6_header_t header
Novatel frame: NV_OEM6_BESTPOS.
#define RPLIDAR_RESP_MEASUREMENT_CHECKBIT
#define RPLIDAR_RESP_MEASUREMENT_SYNCBIT
#define RPLIDAR_CMD_GET_ACC_BOARD_FLAG
#define RPLIDAR_RESP_MEASUREMENT_QUALITY_SHIFT
#define RPLIDAR_CMD_GET_DEVICE_INFO
#define RPLIDAR_ANS_TYPE_DEVINFO
#define RPLIDAR_RESP_MEASUREMENT_EXP_SYNC_1
#define RPLIDAR_CMD_GET_SAMPLERATE
#define RPLIDAR_RESP_MEASUREMENT_EXP_SYNC_2
#define RPLIDAR_CMD_EXPRESS_SCAN
#define RPLIDAR_RESP_MEASUREMENT_EXP_SYNCBIT
#define DEFAULT_MOTOR_PWM
#define RPLIDAR_RESP_ACC_BOARD_FLAG_MOTOR_CTRL_SUPPORT_MASK
#define RPLIDAR_CMD_FORCE_SCAN
#define RPLIDAR_EXPRESS_SCAN_MODE_FIXANGLE
#define RPLIDAR_ANS_TYPE_ACC_BOARD_FLAG
#define RPLIDAR_ANS_TYPE_MEASUREMENT_CAPSULED
#define RPLIDAR_CMD_GET_DEVICE_HEALTH
#define RPLIDAR_ANS_TYPE_DEVHEALTH
#define RPLIDAR_ANS_TYPE_MEASUREMENT
#define RPLIDAR_CMD_RESET
#define RPLIDAR_CMD_SET_MOTOR_PWM
#define RPLIDAR_EXPRESS_SCAN_MODE_NORMAL
#define RPLIDAR_RESP_MEASUREMENT_ANGLE_SHIFT
#define RPLIDAR_ANS_TYPE_SAMPLE_RATE
#define RPLIDAR_ANS_SYNC_BYTE2
#define RPLIDAR_CMDFLAG_HAS_PAYLOAD
#define RPLIDAR_ANS_HEADER_SIZE_MASK
#define RPLIDAR_ANS_SYNC_BYTE1
#define RPLIDAR_CMD_SYNC_BYTE
#define RESULT_ALREADY_DONE
#define RESULT_INSUFFICIENT_MEMORY
#define RESULT_OPERATION_TIMEOUT
#define RESULT_OPERATION_FAIL
#define RESULT_INVALID_DATA
#define CLASS_THREAD(c, x)
#define offsetof(_structure, _field)