43 #define min(a, b) (((a) < (b)) ? (a) : (b)) 81 const char* port_path,
_u32 baudrate,
_u32 flag)
131 rplidar_response_device_health_t& healthinfo,
_u32 timeout)
147 rplidar_ans_header_t response_header;
161 if (header_size <
sizeof(rplidar_response_device_health_t))
172 reinterpret_cast<_u8*>(&healthinfo),
sizeof(healthinfo));
178 rplidar_response_device_info_t& info,
_u32 timeout)
194 rplidar_ans_header_t response_header;
208 if (header_size <
sizeof(rplidar_response_device_info_t))
219 _rxtx->
recvdata(reinterpret_cast<_u8*>(&info),
sizeof(info));
225 bool inExpressMode,
size_t count,
float& frequency,
bool& is4kmode)
229 frequency = 1000000.0f / (
count * sample_duration);
231 if (sample_duration <= 277)
262 rplidar_ans_header_t response_header;
276 if (header_size <
sizeof(rplidar_response_measurement_node_t))
292 bool& support,
_u32 timeout)
294 rplidar_response_device_info_t devinfo;
301 if (devinfo.firmware_version >= ((0x1 << 8) | 17))
304 rplidar_response_sample_rate_t sample_rate;
314 bool fixedAngle,
_u32 timeout)
325 rplidar_payload_express_scan_t scanReq;
326 scanReq.working_mode =
329 scanReq.reserved = 0;
339 rplidar_ans_header_t response_header;
353 if (header_size <
sizeof(rplidar_response_capsule_measurement_nodes_t))
371 bool isExpressModeSupported;
380 if (isExpressModeSupported)
408 rplidar_response_measurement_node_t local_buf[128];
411 size_t scan_count = 0;
413 memset(local_scan, 0,
sizeof(local_scan));
430 for (
size_t pos = 0; pos <
count; ++pos)
443 sizeof(rplidar_response_measurement_node_t));
450 local_scan[scan_count++] = local_buf[pos];
451 if (scan_count ==
_countof(local_scan))
460 const rplidar_response_capsule_measurement_nodes_t& capsule,
461 rplidar_response_measurement_node_t* nodebuffer,
size_t& nodeCount)
467 int currentStartAngle_q8 =
468 ((capsule.start_angle_sync_q6 & 0x7FFF) << 2);
469 int prevStartAngle_q8 =
472 diffAngle_q8 = (currentStartAngle_q8) - (prevStartAngle_q8);
473 if (prevStartAngle_q8 > currentStartAngle_q8)
475 diffAngle_q8 += (360 << 8);
478 int angleInc_q16 = (diffAngle_q8 << 3);
479 int currentAngle_raw_q16 = (prevStartAngle_q8 << 8);
486 dist_q2[0] = (cabin.distance_angle_1 & 0xFFFC);
487 dist_q2[1] = (cabin.distance_angle_2 & 0xFFFC);
489 int angle_offset1_q3 =
490 ((cabin.offset_angles_q3 & 0xF) |
491 ((cabin.distance_angle_1 & 0x3) << 4));
492 int angle_offset2_q3 =
493 ((cabin.offset_angles_q3 >> 4) |
494 ((cabin.distance_angle_2 & 0x3) << 4));
497 ((currentAngle_raw_q16 - (angle_offset1_q3 << 13)) >> 10);
498 syncBit[0] = (((currentAngle_raw_q16 + angleInc_q16) %
499 (360 << 16)) < angleInc_q16)
502 currentAngle_raw_q16 += angleInc_q16;
505 ((currentAngle_raw_q16 - (angle_offset2_q3 << 13)) >> 10);
506 syncBit[1] = (((currentAngle_raw_q16 + angleInc_q16) %
507 (360 << 16)) < angleInc_q16)
510 currentAngle_raw_q16 += angleInc_q16;
512 for (
int cpos = 0; cpos < 2; ++cpos)
514 if (angle_q6[cpos] < 0) angle_q6[cpos] += (360 << 6);
515 if (angle_q6[cpos] >= (360 << 6)) angle_q6[cpos] -= (360 << 6);
517 rplidar_response_measurement_node_t node;
519 node.sync_quality = (syncBit[cpos] | ((!syncBit[cpos]) << 1));
524 node.angle_q6_checkbit = (1 | (angle_q6[cpos] << 1));
525 node.distance_q2 = dist_q2[cpos];
527 nodebuffer[nodeCount++] = node;
538 rplidar_response_capsule_measurement_nodes_t capsule_node;
539 rplidar_response_measurement_node_t local_buf[128];
542 size_t scan_count = 0;
544 memset(local_scan, 0,
sizeof(local_scan));
567 for (
size_t pos = 0; pos <
count; ++pos)
580 sizeof(rplidar_response_measurement_node_t));
587 local_scan[scan_count++] = local_buf[pos];
588 if (scan_count ==
_countof(local_scan))
598 rplidar_response_measurement_node_t* nodebuffer,
size_t&
count,
617 size_to_copy *
sizeof(rplidar_response_measurement_node_t));
618 count = size_to_copy;
630 rplidar_response_measurement_node_t* nodebuffer,
size_t count)
632 float inc_origin_angle = 360.0f /
count;
636 for (i = 0; i <
count && nodebuffer[i].distance_q2 == 0; i++)
645 float expect_angle = (nodebuffer[i + 1].angle_q6_checkbit >>
649 if (expect_angle < 0.0f) expect_angle = 0.0f;
652 nodebuffer[i].angle_q6_checkbit =
653 (((
_u16)(expect_angle * 64.0f))
659 for (i =
count - 1; nodebuffer[i].distance_q2 == 0; i--)
662 while (i != (
count - 1))
665 float expect_angle = (nodebuffer[i - 1].angle_q6_checkbit >>
669 if (expect_angle > 360.0f) expect_angle -= 360.0f;
672 nodebuffer[i].angle_q6_checkbit =
673 (((
_u16)(expect_angle * 64.0f))
679 float frontAngle = (nodebuffer[0].angle_q6_checkbit >>
682 for (i = 1; i <
count; i++)
686 float expect_angle = frontAngle + i * inc_origin_angle;
687 if (expect_angle > 360.0f) expect_angle -= 360.0f;
688 _u16 checkbit = nodebuffer[i].angle_q6_checkbit &
690 nodebuffer[i].angle_q6_checkbit =
691 (((
_u16)(expect_angle * 64.0f))
698 for (i = 0; i < (
count - 1); i++)
700 for (
size_t j = (i + 1); j <
count; j++)
705 rplidar_response_measurement_node_t temp = nodebuffer[i];
706 nodebuffer[i] = nodebuffer[j];
707 nodebuffer[j] = temp;
716 rplidar_response_measurement_node_t* node,
_u32 timeout)
720 _u8 recvBuffer[
sizeof(rplidar_response_measurement_node_t)];
721 _u8* nodeBuffer = (
_u8*)node;
724 while ((waitTime =
getms() - startTs) <= timeout)
727 sizeof(rplidar_response_measurement_node_t) - recvPos;
736 if (recvSize > remainSize) recvSize = remainSize;
740 for (
size_t pos = 0; pos < recvSize; ++pos)
742 _u8 currentByte = recvBuffer[pos];
747 _u8 tmp = (currentByte >> 1);
748 if ((tmp ^ currentByte) & 0x1)
772 nodeBuffer[recvPos++] = currentByte;
774 if (recvPos ==
sizeof(rplidar_response_measurement_node_t))
785 rplidar_response_measurement_node_t* nodebuffer,
size_t&
count,
794 size_t recvNodeCount = 0;
799 while ((waitTime =
getms() - startTs) <= timeout && recvNodeCount <
count)
801 rplidar_response_measurement_node_t node;
807 nodebuffer[recvNodeCount++] = node;
811 count = recvNodeCount;
816 rplidar_response_capsule_measurement_nodes_t& node,
_u32 timeout)
820 _u8 recvBuffer[
sizeof(rplidar_response_capsule_measurement_nodes_t)];
821 _u8* nodeBuffer = (
_u8*)&node;
824 while ((waitTime =
getms() - startTs) <= timeout)
827 sizeof(rplidar_response_capsule_measurement_nodes_t) - recvPos;
836 if (recvSize > remainSize) recvSize = remainSize;
840 for (
size_t pos = 0; pos < recvSize; ++pos)
842 _u8 currentByte = recvBuffer[pos];
847 _u8 tmp = (currentByte >> 4);
861 _u8 tmp = (currentByte >> 4);
875 nodeBuffer[recvPos++] = currentByte;
877 if (recvPos ==
sizeof(rplidar_response_capsule_measurement_nodes_t))
882 ((node.s_checksum_1 & 0xF) | (node.s_checksum_2 << 4));
884 rplidar_response_capsule_measurement_nodes_t,
887 sizeof(rplidar_response_capsule_measurement_nodes_t);
890 checksum ^= nodeBuffer[cpos];
892 if (recvChecksum == checksum)
895 if (node.start_angle_sync_q6 &
915 _u8 cmd,
const void* payload,
size_t payloadsize)
918 auto*
header =
reinterpret_cast<rplidar_cmd_packet_t*
>(pkt_header);
923 if (payloadsize && payload)
938 checksum ^= (payloadsize & 0xFF);
941 for (
size_t pos = 0; pos < payloadsize; ++pos)
943 checksum ^= ((
_u8*)payload)[pos];
947 _u8 sizebyte = payloadsize;
965 _u8 recvBuffer[
sizeof(rplidar_ans_header_t)];
969 while ((waitTime =
getms() - startTs) <= timeout)
971 size_t remainSize =
sizeof(rplidar_ans_header_t) - recvPos;
980 if (recvSize > remainSize) recvSize = remainSize;
984 for (
size_t pos = 0; pos < recvSize; ++pos)
986 _u8 currentByte = recvBuffer[pos];
1004 headerBuffer[recvPos++] = currentByte;
1006 if (recvPos ==
sizeof(rplidar_ans_header_t))
1023 rplidar_response_sample_rate_t& rateInfo,
_u32 timeout)
1029 rplidar_response_device_info_t devinfo;
1036 if (devinfo.firmware_version < ((0x1 << 8) | 17))
1051 rplidar_ans_header_t response_header;
1065 if (header_size <
sizeof(rplidar_response_sample_rate_t))
1075 _rxtx->
recvdata(reinterpret_cast<_u8*>(&rateInfo),
sizeof(rateInfo));
1081 bool& support,
_u32 timeout)
1093 rplidar_payload_acc_board_flag_t flag;
1103 rplidar_ans_header_t response_header;
1117 if (header_size <
sizeof(rplidar_response_acc_board_flag_t))
1127 rplidar_response_acc_board_flag_t acc_board_flag;
1129 reinterpret_cast<_u8*>(&acc_board_flag),
sizeof(acc_board_flag));
1131 if (acc_board_flag.support_flag &
1143 rplidar_payload_motor_pwm_t motor_pwm;
1144 motor_pwm.pwm_value = pwm;
1152 sizeof(motor_pwm))))
virtual int recvdata(unsigned char *data, size_t size)=0
#define offsetof(_structure, _field)
#define RPLIDAR_RESP_MEASUREMENT_CHECKBIT
#define CLASS_THREAD(c, x)
#define RPLIDAR_RESP_MEASUREMENT_EXP_SYNCBIT
virtual bool bind(const char *portname, _u32 baudrate, _u32 flags=0)=0
RPlidarDriverSerialImpl()
bool _isSupportingMotorCtrl
GLuint GLuint GLsizei count
#define RPLIDAR_CMD_FORCE_SCAN
#define RPLIDAR_EXPRESS_SCAN_MODE_FIXANGLE
u_result stopMotor() override
Stop RPLIDAR's motor when using accessory board.
_u16 _cached_sampleduration_express
u_result checkMotorCtrlSupport(bool &support, _u32 timeout=DEFAULT_TIMEOUT) override
Check whether the device support motor control.
u_result startScanNormal(bool force, _u32 timeout=DEFAULT_TIMEOUT) override
u_result stop(_u32 timeout=DEFAULT_TIMEOUT) override
Ask the RPLIDAR core system to stop the current scan operation and enter idle state.
#define RPLIDAR_RESP_MEASUREMENT_ANGLE_SHIFT
#define RPLIDAR_ANS_TYPE_MEASUREMENT_CAPSULED
u_result setMotorPWM(_u16 pwm) override
Set the RPLIDAR's motor pwm when using accessory board, currently valid for A2 only.
void _capsuleToNormal(const rplidar_response_capsule_measurement_nodes_t &capsule, rplidar_response_measurement_node_t *nodebuffer, size_t &nodeCount)
u_result startMotor() override
Start RPLIDAR's motor when using accessory board.
#define RPLIDAR_ANS_TYPE_SAMPLE_RATE
size_t _cached_scan_node_count
void set(bool isSignal=true)
#define RPLIDAR_ANS_HEADER_SIZE_MASK
#define RPLIDAR_CMD_GET_DEVICE_INFO
#define RPLIDAR_ANS_TYPE_DEVHEALTH
#define RPLIDAR_CMD_SYNC_BYTE
#define RPLIDAR_RESP_MEASUREMENT_SYNCBIT
u_result ascendScanData(rplidar_response_measurement_node_t *nodebuffer, size_t count) override
Ascending the scan data according to the angle value in the scan.
virtual int senddata(const unsigned char *data, size_t size)=0
static serial_rxtx * CreateRxTx()
#define RESULT_INSUFFICIENT_MEMORY
#define RPLIDAR_ANS_SYNC_BYTE1
u_result getHealth(rplidar_response_device_health_t &, _u32 timeout=DEFAULT_TIMEOUT) override
Retrieve the health status of the RPLIDAR The host system can use this operation to check whether RPL...
#define RPLIDAR_CMD_GET_SAMPLERATE
static void ReleaseRxTx(serial_rxtx *)
rplidar_response_capsule_measurement_nodes_t _cached_previous_capsuledata
u_result _cacheCapsuledScanData()
u_result join(unsigned long timeout=-1)
#define RPLIDAR_CMD_RESET
nv_oem6_header_t header
Novatel frame: NV_OEM6_BESTPOS.
#define RPLIDAR_RESP_ACC_BOARD_FLAG_MOTOR_CTRL_SUPPORT_MASK
#define RPLIDAR_CMDFLAG_HAS_PAYLOAD
#define RPLIDAR_ANS_TYPE_ACC_BOARD_FLAG
bool _is_previous_capsuledataRdy
#define RPLIDAR_CMD_SET_MOTOR_PWM
#define RPLIDAR_CMD_EXPRESS_SCAN
u_result getFrequency(bool inExpressMode, size_t count, float &frequency, bool &is4kmode) override
Calcuate RPLIDAR's current scanning frequency from the given scan data Please refer to the applicatio...
rp::hal::serial_rxtx * _rxtx
Locker::LOCK_STATUS lock(unsigned long timeout=0xFFFFFFFF)
u_result _waitResponseHeader(rplidar_ans_header_t *header, _u32 timeout=DEFAULT_TIMEOUT)
#define RESULT_OPERATION_TIMEOUT
u_result _waitNode(rplidar_response_measurement_node_t *node, _u32 timeout=DEFAULT_TIMEOUT)
u_result grabScanData(rplidar_response_measurement_node_t *nodebuffer, size_t &count, _u32 timeout=DEFAULT_TIMEOUT) override
Wait and grab a complete 0-360 degree scan data previously received.
#define RPLIDAR_ANS_TYPE_MEASUREMENT
#define RPLIDAR_CMD_GET_ACC_BOARD_FLAG
u_result checkExpressScanSupported(bool &support, _u32 timeout=DEFAULT_TIMEOUT) override
Check whether the device support express mode.
u_result startScan(bool force=false, bool autoExpressMode=true) override
Ask the RPLIDAR core system to enter the scan mode(Normal/Express, Express mode is 4k mode) A backgro...
u_result reset(_u32 timeout=DEFAULT_TIMEOUT) override
Ask the RPLIDAR core system to reset it self The host system can use the Reset operation to help RPLI...
u_result _sendCommand(_u8 cmd, const void *payload=nullptr, size_t payloadsize=0)
#define RPLIDAR_RESP_MEASUREMENT_QUALITY_SHIFT
virtual void clearDTR()=0
void disconnect() override
Disconnect with the RPLIDAR and close the serial port.
bool isConnected() override
Returns TRUE when the connection has been established.
rplidar_response_measurement_node_t _cached_scan_node_buf[2048]
u_result _cacheScanData()
unsigned long wait(unsigned long timeout=0xFFFFFFFF)
u_result _waitCapsuledNode(rplidar_response_capsule_measurement_nodes_t &node, _u32 timeout=DEFAULT_TIMEOUT)
#define RPLIDAR_RESP_MEASUREMENT_EXP_SYNC_1
#define DEFAULT_MOTOR_PWM
_u16 _cached_sampleduration_std
#define RESULT_OPERATION_FAIL
#define RESULT_ALREADY_DONE
virtual void flush(_u32 flags)=0
~RPlidarDriverSerialImpl() override
#define RPLIDAR_RESP_MEASUREMENT_EXP_SYNC_2
#define RPLIDAR_CMD_GET_DEVICE_HEALTH
void _disableDataGrabbing()
static RPlidarDriver * CreateDriver(_u32 drivertype=DRIVER_TYPE_SERIALPORT)
Create an RPLIDAR Driver Instance This interface should be invoked first before any other operations...
u_result getDeviceInfo(rplidar_response_device_info_t &, _u32 timeout=DEFAULT_TIMEOUT) override
Get the device information of the RPLIDAR include the serial number, firmware version, device model etc.
u_result getSampleDuration_uS(rplidar_response_sample_rate_t &rateInfo, _u32 timeout=DEFAULT_TIMEOUT) override
Get the sample duration information of the RPLIDAR.
#define RPLIDAR_EXPRESS_SCAN_MODE_NORMAL
u_result startScanExpress(bool fixedAngle, _u32 timeout=DEFAULT_TIMEOUT) override
#define RPLIDAR_ANS_SYNC_BYTE2
rp::hal::Thread _cachethread
virtual int waitfordata(size_t data_count, _u32 timeout=-1, size_t *returned_size=nullptr)=0
u_result connect(const char *port_path, _u32 baudrate, _u32 flag) override
Open the specified serial port and connect to a target RPLIDAR device.
#define RESULT_INVALID_DATA
static void DisposeDriver(RPlidarDriver *drv)
Dispose the RPLIDAR Driver Instance specified by the drv parameter Applications should invoke this in...
void memcpy(void *dest, size_t destSize, const void *src, size_t copyCount) noexcept
An OS and compiler independent version of "memcpy".
#define RPLIDAR_ANS_TYPE_DEVINFO
u_result _waitScanData(rplidar_response_measurement_node_t *nodebuffer, size_t &count, _u32 timeout=DEFAULT_TIMEOUT)