1.头文件简介
rplidar.h//一般情况下开发的项目中仅需要引入该头文件即可使用 RPLIDAR SDK 的所有功能。
rptypes.h//平台无关的结构和常量定义
rplidar_protocol.h//定义了 RPLIDAR 通讯协议文档中描述的底层相关数据结构和常量定义。
rplidar_cmd.h//定义了 RPLIDAR 通讯协议文档中描述的各类请求/应答相关的数据结构和常量定义。
rplidar_driver.h//定义了 SDK 核心驱动接口: RPlidarDriver 的类声明。
2.头文件解析(代码理解加部分英文单词翻译)
(1)rplidar_protocol.h
#pragma once(避免同一个文件被include多次)
// RP-Lidar Input Packets(输入数据包)
#define RPLIDAR_CMD_SYNC_BYTE 0xA5(十六进制0x开头)//请求报文开始字节
#define RPLIDAR_CMDFLAG_HAS_PAYLOAD 0x80 //请求报文负载
#define RPLIDAR_ANS_SYNC_BYTE1 0xA5 //应答报文起始标志1
#define RPLIDAR_ANS_SYNC_BYTE2 0x5A //应答报文起始标志2
#define RPLIDAR_ANS_PKTFLAG_LOOP 0x1 //多次应答模式
#define RPLIDAR_ANS_HEADER_SIZE_MASK 0x3FFFFFFF
#define RPLIDAR_ANS_HEADER_SUBTYPE_SHIFT (30)
#if defined(_WIN32)
#pragma pack(1)//每个结构成员都必须限制在1个字节之内
,也就是说储存在内存中是连续的
#endif
//请求报文格式
typedef struct _rplidar_cmd_packet_t {
_u8 syncByte; //must be RPLIDAR_CMD_SYNC_BYTE //起始标志
_u8 cmd_flag; //请求命令
_u8 size; //负载长度
_u8 data[0]; //请求负载数据
} __attribute__((packed)) rplidar_cmd_packet_t;//__attribute__ ((packed)) 的作用就是告诉编译器取消结构在编译过程中的优化对齐,按照实际占用字节数进行对齐
//使用之后才会是几字节就是几字节,否则就每个变量的字节长度都跟结构体中变量字节长度最长相同
//应答报文格式
typedef struct _rplidar_ans_header_t {
_u8 syncByte1; // must be RPLIDAR_ANS_SYNC_BYTE1(起始标志1)
_u8 syncByte2; // must be RPLIDAR_ANS_SYNC_BYTE2(起始标志2)
_u32 size_q30_subtype; // see _u32 size:30; _u32 subType:2;(应答报文长度)
_u8 type; //应答模式
} __attribute__((packed)) rplidar_ans_header_t;
#if defined(_WIN32)
#pragma pack()
#endif
//按照实际占用字节数进行对齐
(2)rplidar_cmd.h
#pragma once
#include "rplidar_protocol.h"
// Commands
//-----------------------------------------
// Commands without payload(负载) and response(响应)
#define RPLIDAR_CMD_STOP 0x25 //离开扫描模式,进入空闲状态
#define RPLIDAR_CMD_SCAN 0x20 //请求进入扫描采样状态
#define RPLIDAR_CMD_FORCE_SCAN 0x21 //请求进入扫描采样状态,强制数据输出
#define RPLIDAR_CMD_RESET 0x40 //测距核心软重启
// Commands without payload but have response
#define RPLIDAR_CMD_GET_DEVICE_INFO 0x50 //获取设备序列号等信息
#define RPLIDAR_CMD_GET_DEVICE_HEALTH 0x52 //获取设备健康状态
#define RPLIDAR_CMD_GET_SAMPLERATE 0x59 //added in fw 1.17获取单次激光测距的用时
// Commands with payload and have response
#define RPLIDAR_CMD_EXPRESS_SCAN 0x82 //added in fw 1.17请求进入扫描状态,幷工作在最高采样频率下
//add for A2 to set RPLIDAR motor pwm(脉宽调变) when using accessory board(开发系统)
#define RPLIDAR_CMD_SET_MOTOR_PWM 0xF0// 设置PWM
#define RPLIDAR_CMD_GET_ACC_BOARD_FLAG 0xFF//系统标志
#if defined(_WIN32)
#pragma pack(1)
#endif
// Payloads
// ------------------------------------------
#define RPLIDAR_EXPRESS_SCAN_MODE_NORMAL (正常模式) 0
#define RPLIDAR_EXPRESS_SCAN_MODE_FIXANGLE(固定角度) 1
typedef struct _rplidar_payload_express_scan_t { //带有负载的数据包
_u8 working_mode;
_u32 reserved;
} __attribute__((packed)) rplidar_payload_express_scan_t;
#define MAX_MOTOR_PWM 1023//电机脉宽最大值
#define DEFAULT_MOTOR_PWM 660//电机脉宽默认值
//电机PWM结构
typedef struct _rplidar_payload_motor_pwm_t {
_u16 pwm_value;
} __attribute__((packed)) rplidar_payload_motor_pwm_t;
//开发系统标志
typedef struct _rplidar_payload_acc_board_flag_t {
_u32 reserved;
} __attribute__((packed)) rplidar_payload_acc_board_flag_t;
// Response
// ------------------------------------------
#define RPLIDAR_ANS_TYPE_DEVINFO 0x4//设备信心获取 起始应答结尾
#define RPLIDAR_ANS_TYPE_DEVHEALTH 0x6//设备健康状态获取 起始应答结尾
#define RPLIDAR_ANS_TYPE_MEASUREMENT 0x81//普通采集
// Added in FW ver 1.17
#define RPLIDAR_ANS_TYPE_MEASUREMENT_CAPSULED 0x82//高速采集
// Added in FW ver 1.17
#define RPLIDAR_ANS_TYPE_SAMPLE_RATE 0x15
#define RPLIDAR_ANS_TYPE_ACC_BOARD_FLAG 0xFF
#define RPLIDAR_RESP_ACC_BOARD_FLAG_MOTOR_CTRL_SUPPORT_MASK (0x1)
typedef struct _rplidar_response_acc_board_flag_t {
_u32 support_flag;
} __attribute__((packed)) rplidar_response_acc_board_flag_t;
//设备状态
#define RPLIDAR_STATUS_OK 0x0
#define RPLIDAR_STATUS_WARNING 0x1
#define RPLIDAR_STATUS_ERROR 0x2
#define RPLIDAR_RESP_MEASUREMENT_SYNCBIT (0x1<<0)
#define RPLIDAR_RESP_MEASUREMENT_QUALITY_SHIFT 2
#define RPLIDAR_RESP_MEASUREMENT_CHECKBIT (0x1<<0)
#define RPLIDAR_RESP_MEASUREMENT_ANGLE_SHIFT 1
//激光测距用时获取数据包
typedef struct _rplidar_response_sample_rate_t {
_u16 std_sample_duration_us; //在标准扫描模式下,设备测距核心进行单次激光测距的耗时 单位:微秒
_u16 express_sample_duration_us;//在高速采样模式下,设备测距核心进行单次激光测距的耗时 单位:微妙
} __attribute__((packed)) rplidar_response_sample_rate_t;
//激光测距测量节点数据包
typedef struct _rplidar_response_measurement_node_t {
_u8 sync_quality; // syncbit:1;syncbit_inverse:1;quality:6;//信号质量
_u16 angle_q6_checkbit; // check_bit:1;angle_q6:15;//测距点相对于RPLIDAR朝向夹角 实际角度 = angle_q6 / 64.0 Deg
_u16 distance_q2;//测距点相对于RPLIDAR的距离 实际距离 = distance_q2 / 4.0 mm
} __attribute__((packed)) rplidar_response_measurement_node_t;
//[distance_sync flags]
#define RPLIDAR_RESP_MEASUREMENT_EXP_ANGLE_MASK (0x3)
#define RPLIDAR_RESP_MEASUREMENT_EXP_DISTANCE_MASK (0xFC)
// 激光测距小屋测量节点数据包
typedef struct _rplidar_response_cabin_nodes_t {
_u16 distance_angle_1; // see [distance_sync flags]
_u16 distance_angle_2; // see [distance_sync flags]
_u8 offset_angles_q3;
} __attribute__((packed)) rplidar_response_cabin_nodes_t;
#define RPLIDAR_RESP_MEASUREMENT_EXP_SYNC_1 0xA
#define RPLIDAR_RESP_MEASUREMENT_EXP_SYNC_2 0x5
#define RPLIDAR_RESP_MEASUREMENT_EXP_SYNCBIT (0x1<<15)
// 激光测距容器测量节点数据包
typedef struct _rplidar_response_capsule_measurement_nodes_t {
_u8 s_checksum_1; // see [s_checksum_1]
_u8 s_checksum_2; // see [s_checksum_1]
_u16 start_angle_sync_q6;
rplidar_response_cabin_nodes_t cabins[16];
} __attribute__((packed)) rplidar_response_capsule_measurement_nodes_t;
//设备信息数据报文
typedef struct _rplidar_response_device_info_t {
_u8 model;
_u16 firmware_version;
_u8 hardware_version;
_u8 serialnum[16];
} __attribute__((packed)) rplidar_response_device_info_t;
//设备健康信息数据报文
typedef struct _rplidar_response_device_health_t {
_u8 status;
_u16 error_code;
} __attribute__((packed)) rplidar_response_device_health_t;
#if defined(_WIN32)
#pragma pack()
#endif
(3)rplidar_driver.h
#pragma once
#ifndef __cplusplus
#error "The RPlidar SDK requires a C++ compiler to be built"
#endif
namespace rp { namespace standalone{ namespace rplidar {
class RPlidarDriver {
public:
enum {
DEFAULT_TIMEOUT = 2000, //枚举量默认超时时间2000 ms
};
enum {
DRIVER_TYPE_SERIALPORT = 0x0,//枚举量驱动程序类型串口为0x0(linux被驱动使用的连接类型)
};
public:
/// Create an RPLIDAR Driver Instance(实例)
/// This interface(接口) should be invoked(调用) first before any other operations(操作)
///
/// \param(参数) drivertype(驱动类型)( the connection type used by the driver.
static RPlidarDriver * CreateDriver(_u32 drivertype = DRIVER_TYPE_SERIALPORT);//静态创建对象接口
/// Dispose the RPLIDAR Driver Instance specified by the drv parameter
/// Applications should invoke this interface when the driver instance is no longer used in order to free memory
static void DisposeDriver(RPlidarDriver * drv);//处理驱动程序//静态接口函数析构RPlidar实例
public:
/// Open the specified serial port and connect to a target RPLIDAR device
///
/// \param port_path the device path of the serial port
/// e.g. on Windows, it may be com3 or \\.\com10
/// on Unix-Like OS, it may be /dev/ttyS1, /dev/ttyUSB2, etc
///
/// \param baudrate(波特率) the baudrate used
/// For most RPLIDAR models, the baudrate should be set to 115200
///
/// \param flag(标志) other flags
/// Reserved for future use, always set to Zero
virtual u_result connect(const char * port_path, _u32 baudrate, _u32 flag = 0) = 0;//设备连接函数,调用时会默认停止电机旋转,测试时需要使用startMotor启动电机旋转
/// Disconnect with the RPLIDAR and close the serial port(断开连接并关上串口端)
virtual void disconnect() = 0;//断开连接
/// Returns TRUE when the connection has been established(连接已建立)
virtual bool isConnected() = 0;
/// Ask the RPLIDAR core system to reset it self
/// The host system can use the Reset operation to help RPLIDAR escape the self-protection mode.
///
// \param timeout The operation timeout value (in millisecond) for the serial port communication
virtual u_result reset(_u32 timeout = DEFAULT_TIMEOUT) = 0;//超时重置
/// Retrieve(恢复) the health status of the RPLIDAR
/// The host system can use this operation to check whether RPLIDAR is in the self-protection mode.
///
/// \param health The health status info returned from the RPLIDAR
///
/// \param timeout The operation timeout value (in millisecond) for the serial port communication
virtual u_result getHealth(rplidar_response_device_health_t & health, _u32 timeout = DEFAULT_TIMEOUT) = 0;//获取 RPLIDAR 设备的健康状态
///
/// Get the device information of the RPLIDAR include the serial number, firmware version, device model etc.
///
/// \param info The device information returned from the RPLIDAR
///
/// \param timeout The operation timeout value (in millisecond) for the serial port communication
virtual u_result getDeviceInfo(rplidar_response_device_info_t & info, _u32 timeout = DEFAULT_TIMEOUT) = 0;//获取 RPLIDAR 设备序列号、固件版本等信息
/// Get the sample(样本) duration(持续时间) information of the RPLIDAR.
///
/// \param rateInfo The sample duration information returned from the RPLIDAR
///
/// \param timeout The operation timeout value (in millisecond) for the serial port communication
virtual u_result getSampleDuration_uS(rplidar_response_sample_rate_t & rateInfo, _u32 timeout = DEFAULT_TIMEOUT) = 0;//获取 RPLIDAR 分别在标准 Scan 以及 ExpressScan 模式下单次激光采样的用时。 单位为微秒(uS)
/// Set the RPLIDAR's motor pwm when using accessory board, currently valid for A2 only.
///
/// \param pwm(脉宽) The motor(电机) pwm value would like to set
virtual u_result setMotorPWM(_u16 pwm) = 0;//向开发套件的 USB 附件板发送特定的 PWM 占空比,控制RPLIDAR 扫描电机转速
/// Start RPLIDAR's motor when using accessory(附件) board
virtual u_result startMotor() = 0;//启动电机
/// Stop RPLIDAR's motor when using accessory board
virtual u_result stopMotor() = 0;//停止电机
/// Check whether the device support motor control.
/// Note: this API will disable grab.
///
/// \param support Return the result.
/// \param timeout The operation timeout value (in millisecond) for the serial port communication.
virtual u_result checkMotorCtrlSupport(bool & support, _u32 timeout = DEFAULT_TIMEOUT) = 0;//检测附件板是否支持电机 PWM 控制。
/// Calcuate(计算) RPLIDAR's current scanning frequency from the given scan data
/// Please refer to the application note doc for details
/// Remark: the calcuation will be incorrect if the specified scan data doesn't contains enough data
///
/// \param inExpressMode Indicate whether the RPLIDAR is in express mode(表达模式)
///
/// \param count The number of sample nodes inside the given buffer(缓冲区)
///
/// \param frequency The scanning frequency (in HZ) calcuated by the interface.
///
/// \param is4kmode Return whether the RPLIDAR is working on 4k sample rate mode.
virtual u_result getFrequency(bool inExpressMode, size_t count, float & frequency, bool & is4kmode) = 0;//从实现抓取的一圈扫描数据序列计算 RPLIDAR 的转速
/// Ask the RPLIDAR core system to enter the scan mode(Normal/Express, Express mode is 4k mode)
/// A background thread(后台线程) will be created by the RPLIDAR driver to fetch(获取) the scan data continuously.
/// User Application(应用) can use the grabScanData() interface to retrieved(恢复) the scan data cached(隐藏) previous by this background thread.
///
/// \param force Force the core system to output scan data regardless whether the scanning motor is rotating or not.(旋转与否)
///
/// \param autoExpressMode Force the core system to trying express mode first, if the system does not support express mode, it will use normal mode.
///
/// \param timeout The operation timeout value (in millisecond) for the serial port communication.
virtual u_result startScan(bool force = false, bool autoExpressMode = true) = 0;
virtual u_result startScanNormal(bool force, _u32 timeout = DEFAULT_TIMEOUT) = 0;
virtual u_result startScanExpress(bool fixedAngle, _u32 timeout = DEFAULT_TIMEOUT) = 0;
/// Check whether the device support express mode.
///
/// \param support Return the result.
///
/// \param timeout The operation timeout value (in millisecond) for the serial port communication.
virtual u_result checkExpressScanSupported(bool & support, _u32 timeout = DEFAULT_TIMEOUT) = 0;
/// Ask the RPLIDAR core system to stop the current scan operation and enter idle state(空闲状态). The background thread will be terminated(终止)
///
/// \param timeout The operation timeout value (in millisecond) for the serial port communication
virtual u_result stop(_u32 timeout = DEFAULT_TIMEOUT) = 0;
/// Wait and grab a complete 0-360 degree scan data previously received.
/// The grabbed scan data returned by this interface always has the following charactistics:
///
/// 1) The first node of the grabbed data array (nodebuffer[0]) must be the first sample of a scan, i.e. the start_bit == 1
/// 2) All data nodes are belong to exactly ONE complete 360-degrees's scan
/// 3) Note, the angle data in one scan may not be ascending(上升). You can use API(应用程序界面) ascendScanData to reorder the nodebuffer.
///
/// \param nodebuffer(存储扫描数据的缓冲区 ) Buffer provided by the caller application to store the scan data
///
/// \param count The caller must initialize this parameter to set the max data count of the provided buffer (in unit of rplidar_response_measurement_node_t).
/// Once the interface returns, this parameter will store the actual received data count.
///
/// \param timeout Max duration allowed to wait for a complete scan data, nothing will be stored to the nodebuffer if a complete 360-degrees' scan data cannot to be ready timely.
///
/// The interface will return RESULT_OPERATION_TIMEOUT to indicate that no complete 360-degrees' scan can be retrieved withing the given timeout duration(持续时间).
///
/// \The caller application can set the timeout value to Zero(0) to make this interface always returns immediately to achieve non-block operation.
virtual u_result grabScanData(rplidar_response_measurement_node_t * nodebuffer, size_t & count, _u32 timeout = DEFAULT_TIMEOUT) = 0;
/// Ascending the scan data according to the angle value in the scan.
///
/// \param nodebuffer Buffer provided by the caller application to do the reorder. Should be retrived(索取) from the grabScanData
///
/// \param count The caller must initialize this parameter to set the max data count of the provided buffer (in unit of rplidar_response_measurement_node_t).
/// Once the interface returns, this parameter will store the actual received data count.
/// The interface will return RESULT_OPERATION_FAIL when all the scan data is invalid.
virtual u_result ascendScanData(rplidar_response_measurement_node_t * nodebuffer, size_t count) = 0;
protected:
RPlidarDriver() {}
virtual ~RPlidarDriver() {}//此函数将在源文件中使用但不在此类中使用
};
}}}
(4)rptypes.h
#pragma once
#ifdef _WIN32
//fake stdint.h for VC only
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
#else
#include <stdint.h>//定义int8 uint8等类型
#endif
//based on stdint.h
typedef int8_t _s8;
typedef uint8_t _u8;
typedef int16_t _s16;
typedef uint16_t _u16;
typedef int32_t _s32;
typedef uint32_t _u32;
typedef int64_t _s64;
typedef uint64_t _u64;
#define __small_endian
#ifndef __GNUC__
#define __attribute__(x)
#endif
// The _word_size_t uses actual data bus width of the current CPU
#ifdef _AVR_
typedef _u8 _word_size_t;
#define THREAD_PROC
#elif defined (WIN64)
typedef _u64 _word_size_t;
#define THREAD_PROC __stdcall
#elif defined (WIN32)
typedef _u32 _word_size_t;
#define THREAD_PROC __stdcall
#elif defined (__GNUC__)
typedef unsigned long _word_size_t;
#define THREAD_PROC
#elif defined (__ICCARM__)
typedef _u32 _word_size_t;
#define THREAD_PROC
#endif
typedef uint32_t u_result;
#define RESULT_OK 0
#define RESULT_FAIL_BIT 0x80000000
#define RESULT_ALREADY_DONE 0x20
#define RESULT_INVALID_DATA (0x8000 | RESULT_FAIL_BIT)
#define RESULT_OPERATION_FAIL (0x8001 | RESULT_FAIL_BIT)
#define RESULT_OPERATION_TIMEOUT (0x8002 | RESULT_FAIL_BIT)
#define RESULT_OPERATION_STOP (0x8003 | RESULT_FAIL_BIT)
#define RESULT_OPERATION_NOT_SUPPORT (0x8004 | RESULT_FAIL_BIT)
#define RESULT_FORMAT_NOT_SUPPORT (0x8005 | RESULT_FAIL_BIT)
#define RESULT_INSUFFICIENT_MEMORY (0x8006 | RESULT_FAIL_BIT)
#define IS_OK(x) ( ((x) & RESULT_FAIL_BIT) == 0 )
#define IS_FAIL(x) ( ((x) & RESULT_FAIL_BIT) )
typedef _word_size_t (THREAD_PROC * thread_proc_t ) ( void * );
(5)rplidar.h
#pragma once
#include "rptypes.h"
#include "rplidar_protocol.h"
#include "rplidar_cmd.h"
#include "rplidar_driver.h"
#define RPLIDAR_SDK_VERSION "1.5.7"
由此可见,在编程rplidar的相关代码时只需调用rplidar.h即可,但必须清楚其中所包含的其他头文件所含参数的意义,不然无法看懂相关C++代码文件。。。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)