rs_driver v1.5.7 源代码解析(二)

2022-09-29  本文已影响0人  RonZheng2010

rs_driver 是RoboSense雷达的基本驱动程序。本文是rs_driver的源代码解析文档,原文地址在:
https://github.com/RoboSense-LiDAR/rs_driver/blob/v1.5.7/doc/src_intro/rs_driver_intro_CN.md

4 Packet解析

4.1 MSOP格式

这里说明MSOP格式中的字段。

其中前五个与点云直接相关。

MSOP格式中的点是极坐标系的坐标,包括极径和极角。距离就是这里的极径。从距离和角度可计算直角坐标系的坐标,也就是点云使用的坐标。

4.1.1 Distance

Distance用两个字节表示。它乘以一个解析度得到真实距离。

uint16_t distance;

4.1.2 角度

4.1.3 intensity

intensity保存在1个字节中。

uint8_t intensity;

4.1.4 ring

ring在后面的ChanAngles章节说明。

4.1.5 timestamp

RoboSense雷达使用了几种时间戳格式。

4.1.5.1 YMD 格式

YMD格式定义如下,parseTimeYMD()负责解析这种时间戳格式。遵循这种格式的有RS16/RS32/RSBP等。

typedef struct 
{ 
  uint8_t year; 
  uint8_t month; 
  uint8_t day; 
  uint8_t hour; 
  uint8_t minute; 
  uint8_t second; 
  uint16_t ms; 
  uint16_t us; 
} RSTimestampYMD; 
4.1.5.2 UTC 格式

UTC格式定义如下。

typedef struct 
{ 
  uint8_t sec[6];
  uint8_t ss[4];
} RSTimestampUTC;

4.1.6 temperature

RoboSense雷达使用了几种温度格式。

4.1.6.1 用解析度表示温度

一种是用2字节表示温度值,这个值乘以一个解析度得到真实温度。

typedef struct 
{ 
  uint8_t tt[2];
} RSTemperature;
4.1.6.2 相对温度

另一类用1个字节表示温度。这个值加上一个初始值得到真实温度。遵循这种格式的有RSM1。

int8_t temperature;

4.1.7 echo_mode

雷达内部有多种回波模式。

MSOP格式中用一个字节表示:

int8_t return_mode;

但rs_driver并不在意是回波是“最强的”,还是“最后的”。因为影响MSOP解析的只是:有几个回波?

如下是才是rs_driver关心的回波模式。

enum RSEchoMode
{
  ECHO_SINGLE = 0,
  ECHO_DUAL
};

不同雷达有不同的回波模式return_mode。每个Decoder实现自己的解析函数getEchoMode(),得到rs_driver的回波模式。

回波模式会影响MSOP Packet中数据的布局,还可能影响点云的分帧。

4.2 ChanAngles

4.2.1 垂直角/水平角的修正

如前面MSOP格式的章节所说,理论上,从distance、垂直角、水平角就可以计算点的直角坐标系的坐标。

但在生产实践中,装配雷达总是无可避免地有细微的误差,导致雷达的角度不精确,需要进行修正。雷达装配后的参数标定过程,会找出相关的修正值,写入雷达的寄存器。标定后,使用修正值调整点,就可以使其精度达到要求。

MEMS雷达的角度修正,在雷达内部完成,所以rs_driver不需要做什么;机械式雷达的角度修正,由rs_driver在电脑主机端完成。

这里说明机械式雷达的垂直角/水平角修正。

对于机械式雷达,每个通道的垂直角是固定的。以RSBP举例,它的理论垂直角如下。(这里有32个值,对应RSBP的32个通道)

  89.5,    81.0625, 78.25,   72.625,  67,      61.375,  55.75,   50.125, 
  86.6875, 83.875,  75.4375, 69.8125, 64.1875, 58.5625, 52.9375, 47.3125, 
  44.5,    38.875,  33.25,   27.625,  22,      16.375,  10.75,   5.125, 
  41.6875, 36.0625, 30.4375, 24.8125, 19.1875, 13.5625, 7.9375,  2.3125

装配过程中的误差,导致雷达的垂直角不是这里列出的理论值,水平角azimuth也不是从零开始。标定过程找出两组修正值,一组针对垂直角,一组针对水平角。

还是以RSBP为例。标定过程后,实际的垂直角可能是这样的。这里修正值已经累加了原来的垂直角。

  89.4375, 81.0625, 78.25,   72.625,  67,      61.375,  55.75,   50.125, 
  86.8125, 83.875,  75.4375, 69.8125, 64.1875, 58.5,    52.9375, 47.3125, 
  44.5625, 38.875,  33.25,   27.625,  22,      16.375,  10.75,   5.125, 
  41.6875, 36.1875, 30.4375, 24.8125, 19.0625, 13.5625, 7.9375,  2.3125

类似的,水平角修正值的例子如下。(这里也有32个值,对应RSBP的32个通道)

   0.0625,  0.0625, -0.25,    0.625,  0,      -0.375,   0.75,   -0.125, 
  -0.3125,  0.875,  -0.4375,  0.8125, 0.1875,  0.5,    -0.9375,  0.3125, 
   0.0,    -0.875,   0.25,   -0.625,  0,      -0.375,   0.75,    0.125, 
   0.125,   0.1875,  0.4375,  0.8125, 0.0625,  0.5625,  0.9375,  0.3125

这两组修正值在参数标定过程中写入雷达寄存器,它们也包含在DIFOP Packet中。

4.2.2 ChanAngles定义

ChanAngles从DIFOP Packet读入机械式雷达的垂直角/水平角的修正值。如果雷达修正值无效,也可以从外部文件读入。

如前面所说,只有机械式雷达需要ChanAngles。

class_chan_angles

4.2.3 ChanAngles::loadFromDifop()

loadFromDifop()从DIFOP Packet读入角度修正值,写入成员vert_angles_[]horiz_angles_[]

typedef struct
{
  uint8_t sign;
  uint16_t value;
} RSCalibrationAngle;

对于RSBP, MSOP Packet中的修正值保存在成员vert_angle_cali[]horiz_angle_cali[]中。

typedef struct
{
  ...

  RSCalibrationAngle vert_angle_cali[32];
  RSCalibrationAngle horiz_angle_cali[32];

  ...
} RSBPDifopPkt;

4.2.4 早期雷达适配ChanAngles

4.2.5 ChanAngles::loadFromFile()

有些场景下,雷达可能还没有写入有效的修正值,或者是因为还没有标定,或者是由于雷达故障。这时可以从外部文件读入角度修正值。

文件格式如下。

89.5,0.125
81.0625,-0.025
78.25,0
72.625,0
...
30.4375,0.625
24.8125,0
19.1875,-0.25
13.5625,0
7.9375,-0.1
2.3125,0

loadFromFile() 解析这个文件得到修正值,写入成员vert_angles_[]horiz_angles_[]

4.2.6 ChanAngles::horizAdjust()

horizAdjust()对参数给出的水平角作修正

4.2.7 ChanAngles::vertAdjust()

vertAdjust()根据内部通道编号,得到修正后的垂直角。

4.2.8 点云的ring值

点云中的ring值是从用户角度看的通道编号,它来自于ChanAngles的成员变量user_chans_

回到RSBP的例子。如下是它的垂直角,它们按照雷达内部通道编号排列,而不是降序或升序排列。换句话说,雷达内部通道不是按照垂直角的升序/降序编号的。

 89.5,    81.0625, 78.25,   72.625,  67,      61.375,  55.75,   50.125, 
 86.6875, 83.875,  75.4375, 69.8125, 64.1875, 58.5625, 52.9375, 47.3125, 
 44.5,    38.875,  33.25,   27.625,  22,      16.375,  10.75,   5.125, 
 41.6875, 36.0625, 30.4375, 24.8125, 19.1875, 13.5625, 7.9375,  2.3125

但用户希望看到通道编号按照垂直角按升序/降序排列。

ChanAngles的成员变量user_chans保存的是按升序排列的编号,也就是角度小的通道在前。

4.2.9 ChanAngles::genUserChan()

genUserChan()根据成员变量vert_angles_[]中的角度值,计算升序排列的用户通道编号数组。

4.2.10 ChanAngles::toUserChan()

toUserChan(),从给出的雷达内部通道编号,得到用户通道编号。

4.3 Trigon

4.3.1 查表计算三角函数值

如前面所说,MSOP Packet中的点是极坐标系的坐标。rs_driver将点坐标,从极坐标系转换为用户使用的直角坐标系。这时需要计算角度的sin/cos值。

调用三角函数又耗时又耗CPU资源,优化的方式是查表。

4.3.2 Trigon定义

Trigon用于计算指定范围内的sin/cos值,并用于查询。

class_trigon trigon_sinss

4.3.3 Trigon::Trigon()

Trigon的构造函数Trigon() 负责初始化o_sins_[]o_coss_[]

4.3.4 Trigon::sin()

sin()查表返回角度的sin值。

4.3.5 Trigon::cos()

cos()查表返回角度的cos值。

4.4 BlockIterator

这一节"BlockIterator",仅针对机械式雷达。

4.4.1 Packet、Block、Channel

在MSOP格式中,每个Packet中有BLOCKS_PER_PKT个Block,每个Block中有CHANNELS_PER_BLOCK个Channel。

对于机械式雷达,雷达持续旋转,垂直方向上的每一轮激光发射,在MSOP Packet中对应一个Block。
以RSBP雷达为例,

msop_packet

雷达的每轮激光发射时序包括充能、发射等步骤。虽然每轮发射的持续时间(也是相邻两轮发射的时间差)相同,但在每轮发射内,每次发射的时间不是均匀分布。

以RSBP为例,

  0.00,  2.56,  5.12,  7.68, 10.24, 12.80, 15.36, 17.92, 
 25.68, 28.24, 30.80, 33.36, 35.92, 38.48, 41.04, 43.60,
  1.28,  3.84,  6.40,  8.96, 11.52, 14.08, 16.64, 19.20,
 26.96, 29.52, 32.08, 34.64, 37.20, 39.76, 42.32, 44.88

4.4.2 Channel的时间戳

MSOP格式中,Packet头部包含一个时间戳。

如RSBP雷达,Packet的时间戳如下。

RSTimestampYMD timestamp;

通过如下方式可以计算Channel的时间戳。

Block的时间戳 = Packet的时间戳 + Block的持续时间 * Block数
Channel的时间戳 = 所在Block的时间戳  + Channel对Block的相对时间

4.4.3 Channel的角度

在MSOP格式中,Block的成员中包括水平角azimuth

雷达的旋转当然不是匀速的,但放到一个Block这么短的时间内看,认为旋转是匀速的,还是合理的。

所以,通过Channel占Block的时间比例,可以估计Channel对Block的相对水平角。

Channel的水平角 = Block的水平角 + 当前Block与下一个Block的水平角差 * Channel对Block的相对时间 / Block的持续时间

4.4.4 双回波模式的影响

双回波模式下,虽然一个Packet还是塞了同样数目的Block,但是第二个回波的Block,其水平角/时间戳与第一个回波相同。

如下是双回波模式下,RSBP的MSOP格式。

5.png

这样,遍历Block序列时,计算Block时间戳/角度差的方式就不一样了。

4.4.5 BlockIterator定义

引入BlockIterator的目的,是定义一个接口来计算:

BlockIterator的成员如下。

class_block_iterator
4.4.5.1 BlockIterator::get()

成员函数get()从成员az_diffs[]和tss[],得到Block的时间戳和水平角差。BlockIterator的派生类应该计算这两个数组中的值。

4.4.6 SingleReturnBlockIterator

SingleReturnBlockIterator实现单回波模式下的BlockIterator接口。

4.4.6.1 SingleReturnBlockIterator()

单回波模式下。
在构造函数中,遍历Packet中的block,并计算az_diffs[]和tss[]。

4.4.7 DualReturnBlockIterator

DualReturnBlockIterator实现双回波模式下的BlockIterator接口。

4.4.7.1 DualReturnBlockIterator()

双回波模式下,Block两两成对。
在构造函数中,遍历Packet中的Block,并计算az_diffs[]和tss[]。遍历时步进值为2。

4.4.8 ABReturnBlockIterator

双回波模式下,Ruby128是个特殊情况。

Ruby128的每个Block有128个Channel,每个Block占的空间太大,以至于每个packet只能放下3个Block。这样一次扫描的两个Block可能在不同的Packet中。相邻的两个packet格式如下图。

msop_ruby128

ABReturnBlockIterator类用于计算Ruby128的双回波模式的时间戳和角度。

4.4.8.1 ABDualReturnBlockIterator()

根据第0个Block和第1个Block的角度是否相同,判断这是一个AAB Packet还是BAA Packet。

Block水平角差 = 第三个Block的水平角 - 第一个Block的水平角

4.4.9 RS16的Packet格式

为了充分利用MSOP Packet的空间,16线雷达(如RS16)的Packet格式与其他机械式雷达不同。

在单回波模式下,一组16通道数据包含一个回波,将相邻两组的回波数据放在同一Block中。如下图所示。

rs16_msop_single_return

在双回波模式下,一组16通道数据就有两个回波,将两个回波的数据放在同一Block中。如下图所示。

rs16_msop_dual_return

这样的结果是,

uint16_t laser = chan % 16;

RS16SingleReturnBlockIterator和RS16DualReturnBlockIterator,分别处理RS16单回波模式和双回波模式的情况。

classes_rs16_block_iterator

4.4.9 RS16SingleReturnBlockIteratore

4.4.9.1 Rs16SingleReturnBlockIterator()

在构造函数中,遍历Packet中的Block,并计算az_diffs[]和tss[]。

与SingleReturnBlockIterator()中不同的地方是:单回波模式下,一个Block中包括相邻的两个通道数据。

4.4.9.2 RS16SingleReturnBlockIterator::calcChannel()

calcChannel()计算单回波模式下,32个Channel的角度占比,和时间戳偏移。

4.4.10 RS16DualReturnBlockIterator

4.4.10.1 Rs16DualReturnBlockIterator()

在构造函数中,遍历Packet中的Block,并计算az_diffs[]和tss[]。

与Rs16DualReturnBlockIterator不同的地方是:双回波模式下,一个Block中包括两个回波的数据。

4.4.10.2 RS16SingleReturnBlockIterator::calcChannel()

calcChannel()计算双回波模式下,32个Channel的角度占比,和时间戳偏移。

4.5 FOV

机械式雷达的扫描角度是[0,360),这也是雷达输出点的角度范围。

也可以对雷达进行设置,限制它的输出角度,如下图。

fov

4.5.1 FOV设置

FOV可以从DIFOP Packet得到。

  RSFOV fov;

RSFOV的定义如下。

typedef struct
{ 
  uint16_t start_angle;
  uint16_t end_angle;
} RSFOV;

在DecoderMech::decodeDifopCommon()中解析DIFOP Packet得到FOV。

void DecoderMech<T_PointCloud>::decodeDifopCommon(const T_Difop& pkt);

4.5.2 FOV对BlockIterator的影响

在BlockIterator的各种实现中,需要考虑Packet的相邻两个Block跨过FOV盲区的情况。
如果跨过盲区,则:

4.6 分帧

机械式雷达和MEMS雷达的分帧策略不同。

4.6.1 机械式雷达的分帧模式

机械式雷达持续旋转,输出点,驱动在某个分割位置分割前后帧。有三种分帧模式。

split_angle
 每圈Block数 = 每圈秒数 / Block持续时间g 

4.6.2 SplitStrategy

SplitStrategy定义机械式雷达的分帧模式接口。

classes_split_strategy

4.6.3 SplitStrategyByAngle

SplitStrategyByAngle按Block角度分帧。

4.6.3.1 SplitStrategyByAngle::newBlock()

当前一个Block的角度prev_angle_split_angle_之前,而当前Block的角度在split_angles_之后,则认为当前Block跨越了split_angles_,返回true

4.6.4 SplitStrategyByNum

SplitStrategyByNum实现按Block数分帧。

4.6.4.1 SplitStrategyByAngle::newBlock()

newBlock()简单地累加Block数到成员blks_,当blk_达到max_blks_时,则返回true

4.6.5 MEMS雷达的分帧模式

MEMS雷达的分帧是在雷达内部确定的。

4.6.6 SplitStrategyByPktSeq

SplitStrategyBySeq按Packet编号分帧。

class_split_strategy_by_seq
4.6.6.1 SplitStrategyByPktSeq::newPacket()

使用者用MSOP Packet的编号值,调用newPacket()。如果分帧,返回true

MSOP使用UDP协议,理论上Packet可能丢包、乱序。

先讨论没有安全区间时,如何处理丢包、乱序。

为了在一定程度上包容可能的Packet丢包、乱序情况,引入安全区间的概念。

safe_seq_min_ = prev_seq_ - RANGE
safe_seq_max_ = prev_seq_ + RANGE
safe_range

4.7 点云的有效性校验

4.7.1 AzimuthSection

AzimuthSection检查水平角是否在有效范围内。

class_azimuth_section
4.7.1.1 AzimuthSection::in()

in()检查指定的角度angle是否在有效范围内。

4.7.2 DistanceSection

DistanceSection检查指定的distance是否在有效范围内。

class_distance_section
4.7.2.1 DistanceSection::in()

in()检查指定的distance是否在有效范围内。

4.8 Decoder

Decoder解析雷达MSOP/DIFOP Packet,得到点云。

DecoderMech派生于Decoder,给机械式雷达完成一些通用的功能,如解析DIFOP Packet。

每个机械式雷达分别派生自DecoderMech的类,如DecoderRS16、DecoderRS32、DecoderBP、DecoderRSHELIOS、DecoderRS80、DecoderRS128等。

MEMS雷达的类,如DecoderRSM1,直接派生自Decoder。

DecoderFactory根据指定的雷达类型,生成Decoder实例。

classes_decoder

4.8.1 Decoder定义

如下图是Decoder的详细定义。

#define SIN(angle) this->trigon_.sin(angle)
#define COS(angle) this->trigon_.cos(angle)
class_decoder
4.8.1.1 RSDecoderConstParam

RSDecoderConstParam是雷达配置参数,这些参数都是特定于雷达的常量

struct RSDecoderConstParam
{
  // packet len
  uint16_t MSOP_LEN;
  uint16_t DIFOP_LEN;

  // packet identity
  uint8_t MSOP_ID_LEN;
  uint8_t DIFOP_ID_LEN;
  uint8_t MSOP_ID[8];
  uint8_t DIFOP_ID[8];
  uint8_t BLOCK_ID[2];

  // packet structure
  uint16_t LASER_NUM;
  uint16_t BLOCKS_PER_PKT;
  uint16_t CHANNELS_PER_BLOCK;

  // distance & temperature
  float DISTANCE_MIN;
  float DISTANCE_MAX;
  float DISTANCE_RES;
  float TEMPERATURE_RES;
};
4.8.1.2 Decoder::processDifopPkt()

processDifopPkt()处理DIFOP Packet。

4.8.1.3 Decoder::processMsopPkt()

processMsopPkt()处理MSOP Packet。

4.8.1.4 Decoder::transformPoint()

transformPoint() 对点做坐标变换。它基于第三方开源库Eigen。

默认情况下,transformPoint()功能不开启。要启用这个特性,编译时使用-DENABLE_TRANSFORM选项。

cmake -DENABLE_TRANSFORM .

4.8.2 DecoderMech

DecoderMech处理机械式雷达的共同特性,如转速,分帧角度、光心补偿等。

class_decoder_mech
4.8.2.1 RSDecoderMechConstParam

RSDecoderMechConstParam基于RSDecoderConstParam,增加机械式雷达特有的参数。

struct RSDecoderMechConstParam
{
  RSDecoderConstParam base;

  // lens center
  float RX;
  float RY;
  float RZ;

  // firing_ts/chan_ts
  double BLOCK_DURATION;
  double CHAN_TSS[128];
  float CHAN_AZIS[128];
};
  0.00,  2.56,  5.12,  7.68, 10.24, 12.80, 15.36, 17.92, 
 25.68, 28.24, 30.80, 33.36, 35.92, 38.48, 41.04, 43.60,
  1.28,  3.84,  6.40,  8.96, 11.52, 14.08, 16.64, 19.20,
 26.96, 29.52, 32.08, 34.64, 37.20, 39.76, 42.32, 44.88
4.8.2.2 DecoderMech::decodeDifopCommon()

decodeDifopCommon()解析DIFOP Packet。

 uint16_t rpm;
每帧Block数 = (1/rps) / Block的持续时间
Block间的角度差 = 360 / 每帧Block数

4.8.3 DecoderRSBP

以RSBP举例说明机械式雷达的Decoder。

class_decoder_rsbp
4.8.3.1 RSDecoderConstParam设置
常量参数 说明
MSOP_LEN 1248 MSOP Packet字节数
DIFOP_LEN 1248 DIFOP Packet字节数
MSOP_ID[] {0x55, 0xAA, 0x05, 0x0A, 0x5A, 0xA5, 0x50, 0xA0} MSOP Packet标志字节,长度为8
MSOP_ID_LEN 8 MSOP_LEN[]中标志字节的长度
DIFOP_ID[] {0xA5, 0xFF, 0x00, 0x5A, 0x11, 0x11, 0x55, 0x55} DIFOP Packet标志字节,长度为8
DIFOP_ID_LEN 8 DIFOP_LEN[]中的字节长度
BLOCK_ID[] {0xFF, 0xEE} block标志字节,长度为2
LASER_NUM 32 32通道
BLOCKS_PER_PKT 12 每Packet中12个Block
CHANNEL_PER_BLOCK 32 RSBP为32线雷达
DISTANCE_MIN 0.1 测距最小值,单位米
DISTANCE_MAX 100.0 测距最大值,单位米
DISTANCE_RES 0.005 Packet中distance的解析度,单位米
TEMPERATURE_RES 0.0625 Packet中的温度的解析度
4.8.3.2 RSDecoderMechConstParam设置
常量参数 说明
RX 0.01473 光心相对于物理中心的X坐标
RY 0.0085 光心相对于物理中心的Y坐标
RZ 0.09427 光心相对于物理中心的Z坐标
BLOCK_DURATION 55.52 Block的持续时间,单位纳秒
CHAN_TSS[] - 从发射时间列表得到
CHAN_AZIS[] - 从发射时间列表得到
4.8.3.2 DecoderRSBP::getEchoMode()

getEchoMode()解析回波模式。

4.8.3.3 DecoderRSBP::decodeDifopPkt()

decodeDifopPkt() 解析DIFOP Packet。

4.8.3.4 DecoderRSBP::decodeMsopPkt()

decodeMsopPkt()使用不同的模板参数调用internDecodeMsopPkt()。

4.8.3.5 DecoderRSBP::internDecodeMsopPkt()

如果合法,

如果不合法,

4.8.4 DecoderRS16

RS16的处理与其他机械式雷达有差异,请先参考前面的“RS16的Packet格式”等章节。

4.8.4.1 DecoderRS16::internDecodeMsopPkt()

在internDecoderPkt()的处理中,

4.8.5 DecoderRSM1

RSM1是MEMS雷达。这里说明RSM1的Decoder。

class_decoder_rsm1
4.8.5.1 RSDecoderConstParam设置
常量参数 说明
MSOP_LEN 1210 MSOP Packet字节数
DIFOP_LEN 256 DIFOP Packet字节数
MSOP_ID[] {0x55, 0xAA, 0x5A, 0xA5} MSOP Packet标志字节,长度为4
MSOP_ID_LEN 4 MSOP_LEN[]中标志字节的长度
DIFOP_ID[] {0xA5, 0xFF, 0x00, 0x5A, 0x11, 0x11, 0x55, 0x55} DIFOP Packet标志字节,长度为8
DIFOP_ID_LEN 8 DIFOP_LEN[]中的字节长度
BLOCK_ID[] {0xFF, 0xEE} block标志字节,长度为2
LASER_NUM 5 5通道
BLOCKS_PER_PKT 25 每Packet中25个Block
CHANNEL_PER_BLOCK 5 RSM1有5个通道
DISTANCE_MIN 0.2 测距最小值,单位米
DISTANCE_MAX 200.0 测距最大值,单位米
DISTANCE_RES 0.005 Packet中distance的解析度,单位米
TEMPERATURE_RES 80 雷达温度的初始值
4.8.5.2 DecoderRSM1::decodeDifopPkt()

decodeDifopPkt() 解析DIFOP Packet。

4.8.5.3 DecodeRSM1::decodeMsopPkt()

decodeMsopPkt()解析MSOP Packet。

4.8.6 DecoderFactory

DecoderFactory是创建Decoder实例的工厂。

class_decoder_factory

Decoder/雷达的类型如下。

num LidarType
{
  RS16 = 1,
  RS32,
  RSBP,
  RS128,
  RS80,
  RSHELIOS,
  RSROCK,
  RSM1 = 10
};
4.8.6.1 DecoderFactory::creatDecoder()

createDecoder() 根据指定的雷达类型,创建Decdoer实例。

4.9 LidarDriverImpl - 组合Input与Decoder

LidarDriverImpl组合Input部分和Decoder部分。

class_lidar_driver_impl
typedef struct RSDriverParam
{ 
  LidarType lidar_type = LidarType::RS16;  ///< Lidar type
  InputType input_type = InputType::ONLINE_LIDAR; ///< Input type
  RSInputParam input_param;
  RSDecoderParam decoder_param;
} RSDriverParam;

组合Input,

组合Decoder,

4.9.1 LidarDriverImpl::getPointCloud()

LidarriverImpl的成员cb_get_cloud_是rs_driver的使用者提供的。getPointCloud(对它加了一层包装,以便较验它是否合乎要求。
在循环中,

4.9.2 LidarDriverImpl::init()

init()初始化LidarDriverImpl实例。

初始化Decoder部分,

初始化Input部分,

4.9.3 LidarDriverImpl::start()

start()开始处理MSOP/DIFOP Packet。

4.9.4 LidarDriverImpl::packetGet()

packetGet()分配空闲的Buffer。

4.9.5 LidarDriverImpl::packetPut()

packetPut()将收到的Packet,放入队列pkt_queue_

4.9.6 LidarDriverImpl::processPacket()

processMsop()是MSOP Packet处理线程的函数。在循环中,

4.9.7 LidarDriverImpl::splitFrame()

splitFrame()在Decoder通知分帧时,派发点云。

4.9.8 LidarDriverImpl::getTemperature()

getTemperature()调用Decoder::getTemperature(), 得到雷达温度。

上一篇 下一篇

猜你喜欢

热点阅读