Rplidar学习(二)—— SDK库文件学习

SDK头文件介绍

1、头文件简介:

rplidar.h             //一般情况下开发的项目中仅需要引入该头文件即可使用 RPLIDAR SDK 的所有功能。
rplidar_driver.h      //定义了 SDK 核心驱动接口: RPlidarDriver 的类声明。
rplidar_protocol.h    //定义了 RPLIDAR 通讯协议文档中描述的底层相关数据结构和常量定义。
rplidar_cmd.h         //定义了 RPLIDAR 通讯协议文档中描述的各类请求/应答相关的数据结构和常量定义。
rptypes.h             //平台无关的结构和常量定义

2、头文件解析

(1)rplidar_protocol.h

#pragma once

// RP-Lidar Input Packets

#define RPLIDAR_CMD_SYNC_BYTE        0xA5       //请求报文开始字节
#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)
#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
#define RPLIDAR_CMD_GET_ACC_BOARD_FLAG 0xFF

#if defined(_WIN32)     //如果是win32下编译则执行
#pragma pack(1)         //结构体边界设置为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          //电机PWM最大值
#define DEFAULT_MOTOR_PWM           660           //电机PWM默认值

//电机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,
    };
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.
   
//开始扫描,(正常模式,还有一个特别模式2.0能用)
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() {}
};


}}}
param timeout The operation timeout value (in millisecond) for the serial port communication. virtual u_result startScan(bool force = false, bool autoExpressMode = true) = 0; //请求 RPLIDAR 核心开始进行测距扫描,开始输出数据 //如 RPLIDAR 支持 ExpressScan 模式,且程序使用默认参数调用 //startScan()时,SDK 将自动使用 ExpressScan 模式 virtual u_result startScanNormal(bool force, _u32 timeout = DEFAULT_TIMEOUT) = 0; //强制以标准 Scan 模式进行测距扫描 virtual u_result startScanExpress(bool fixedAngle, _u32 timeout = DEFAULT_TIMEOUT) = 0; //强制进行高速扫描测距(ExpressScan)模式 //如果 RPLIDAR 固件不支持 ExpressScan 模式,该函数将执行失败。 /// 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; //检查 RPLIDAR 是否支持 ExpressScan 模式 /// 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; //请求 RPLIDAR 核心停止测距扫描 /// 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; //对通过 grabScanData()获取的扫描数据按照角度递增排序。 protected: RPlidarDriver() {} virtual ~RPlidarDriver() {} }; }}}

3、ultra_simlpe

原文地址:https://www.cnblogs.com/BlueMountain-HaggenDazs/p/6523235.html