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++代码文件。。。

RPlidar学习(三)——RPlidar源代码库相关推荐

  1. SQLite学习(三) - SQLite源代码文件结构

    SQLite Version3.3.6源代码文件结构   文件名称 大小byte 备注 API main.c 35414 SQLite Library的大部分接口   legacy.c 3734 sq ...

  2. 强化学习(三) - Gym库介绍和使用,Markov决策程序实例,动态规划决策实例

    强化学习(三) - Gym库介绍和使用,Markov决策程序实例,动态规划决策实例 1. 引言 在这个部分补充之前马尔科夫决策和动态规划部分的代码.在以后的内容我会把相关代码都附到相关内容的后面.本部 ...

  3. 微软企业库4.1学习笔记(三)企业库迁移和并行使用,以及企业库的扩展

    一.迁移和并行使用 通常来说,企业库是建立在.NET 2.0 的基础上,使用后续版本的企业库也不需要改变任何代码.不需要将引用更新到新的程序集,也不需要在配置文件中指明程序集的正确版本. 这个版本4. ...

  4. 多线程编程学习笔记——任务并行库(三)

    接上文 多线程编程学习笔记--任务并行库(一) 接上文 多线程编程学习笔记--任务并行库(二) 六.   实现取消选项 本示例学习如何实现基于Task的异步操作进行取消流程,以及在任务真正运行前如何知 ...

  5. 【开源】Caffe、TensorFlow、MXnet三个开源库对比

    from:http://www.wtoutiao.com/p/1cbxddO.html 最近Google开源了他们内部使用的深度学习框架TensorFlow[1],结合之前开源的MXNet[2]和Ca ...

  6. 3D视觉学习计划之PCL库的基础知识

    3D视觉学习计划之PCL库的基础知识 一.PCL库的概述 PCL是一个大型跨平台开源C++编程库,它在吸收了前人点云相关研究基础上建立起来,实现了大量点云相关的通用算法和高效数据结构,涉及到点云获取. ...

  7. 深度学习Deep Learning 相关库简介

    本文将从deep learning 相关工具库的使用者角度来介绍下github上stars数排在前面的几个库(tensorflow, keras, torch, theano, skflow, las ...

  8. 【技术综述】图像与CNN发家简史,集齐深度学习三巨头

    文章首发于微信公众号<有三AI> [技术综述]图像与CNN发家简史,集齐深度学习三巨头 没有一个经典的发现会是突然之间横空出世,它总是需要一些积淀. 提起卷积神经网络,我们总会从LeNet ...

  9. 多线程编程学习笔记——任务并行库(二)

    接上文 多线程编程学习笔记--任务并行库(一) 三.   组合任务 本示例是学习如何设置相互依赖的任务.我们学习如何创建一个任务的子任务,这个子任务必须在父任务执行结束之后,再执行. 1,示例代码如下 ...

  10. IOS学习:常用第三方库(GDataXMLNode:xml解析库)

    IOS学习:常用第三方库(GDataXMLNode:xml解析库) 解析 XML 通常有两种方式,DOM 和 SAX: DOM解析XML时,读入整个XML文档并构建一个驻留内存的树结构(节点树),通过 ...

最新文章

  1. Android微信智能心跳方案 Android微信智能心跳方案
  2. 关于软件工程课程的期望
  3. Webix 1.5发布:一个强大的JavaScript UI组件库
  4. String类及其构造器和常用方法
  5. cesium面板动态显示并跟随移动
  6. 限流算法(漏桶算法、令牌桶算法)对比
  7. 【报告分享】2021新青年国货消费研究报告:文化觉醒时代,宝藏国货迎复兴机遇.pdf(附下载链接)...
  8. 蓝桥杯 ALGO-42 算法训练 送分啦
  9. 1128. 等价多米诺骨牌对的数量
  10. Docker 容器的数据管理
  11. [Android动画] 补间动画-动画工具类( AnimationUtils)七
  12. .NET使用存储过程实现对数据库的增删改查
  13. 随机森林模型解释_随机森林解释
  14. 年终工作总结汇报和述职报告ppt模板,内含范文可参考,精选20套可下载
  15. JDK1.8 下载及安装步骤
  16. 怎么关闭vivo系统自检_MIUI11系统已发布,你怎么能不会这个一键关闭广告的功能呢!...
  17. c语言电话簿管理系统的,C语言 电话簿管理系统VC++6.0运行通过
  18. OpenStack | Placement组件
  19. 基于STM32之控制步进电机,学到即赚到!(含主代码)
  20. C++实现二叉树 前、中、后序遍历(递归与非递归)非递归实现过程最简洁版本

热门文章

  1. 修改django后台管理员密码
  2. 百度计算机视觉算法工程师面试题(秋招)
  3. 需求调研第二篇--调研准备阶段避免哪些错误
  4. MindMaster Pro 8.0.0 — 亿图思维导图
  5. 天正坐标标注怎么不显示_cad中坐标标注怎么显示不了xy的
  6. Unsupervised Deep Homography - Pytorch实现
  7. win7系统修复工具_win7系统如何修复
  8. 程序员的自我修养(收藏)
  9. 台式计算机网卡型号怎么查找,怎么确定台式机无线网卡驱动版本 台式机无线网卡驱动版本查看方法...
  10. w7计算机应用放大按键,设置Win7放大功能 老年人用电脑更方便