GrabBag/SDK/Lidar/rslidar/rs_driver/test/decoder_test.cpp

297 lines
7.6 KiB
C++

#include <gtest/gtest.h>
#include <rs_driver/driver/decoder/decoder_mech.hpp>
#include <rs_driver/msg/point_cloud_msg.hpp>
#include <rs_driver/utility/dbg.hpp>
using namespace robosense::lidar;
typedef PointXYZI PointT;
typedef PointCloudT<PointT> PointCloud;
#pragma pack(push, 1)
struct MyMsopPkt
{
uint8_t id[8]{0};
};
struct MyDifopPkt
{
uint8_t id[8];
uint16_t rpm;
RSFOV fov;
RSCalibrationAngle vert_angle_cali[2];
RSCalibrationAngle horiz_angle_cali[2];
RSSN sn;
RSEthNetV2 eth;
RSVersionV2 version;
RSStatusV1 status;
};
#pragma pack(pop)
class MyDecoder : public DecoderMech<PointCloud>
{
public:
MyDecoder(const RSDecoderMechConstParam& const_param,
const RSDecoderParam& param)
: DecoderMech<PointCloud>(const_param, param)
{
}
virtual void decodeDifopPkt(const uint8_t* packet, size_t size)
{
const MyDifopPkt& pkt = *(const MyDifopPkt*)(packet);
this->template decodeDifopCommon<MyDifopPkt>(pkt);
}
virtual bool decodeMsopPkt(const uint8_t* pkt, size_t size)
{
return false;
}
};
static ErrCode errCode = ERRCODE_SUCCESS;
static void errCallback(const Error& err)
{
errCode = err.error_code;
}
TEST(TestDecoder, angles_from_file)
{
RSDecoderMechConstParam const_param;
const_param.base.LASER_NUM = 4;
RSDecoderParam param;
param.config_from_file = true;
param.angle_path = "../test/res/angle.csv";
errCode = ERRCODE_SUCCESS;
MyDecoder decoder(const_param, param);
decoder.regCallback(errCallback, nullptr);
ASSERT_EQ(errCode, ERRCODE_SUCCESS);
ASSERT_TRUE(decoder.angles_ready_);
}
TEST(TestDecoder, angles_from_file_fail)
{
RSDecoderMechConstParam const_param;
const_param.base.LASER_NUM = 4;
RSDecoderParam param;
param.config_from_file = true;
param.angle_path = "../test/res/non_exist.csv";
MyDecoder decoder(const_param, param);
decoder.regCallback(errCallback, nullptr);
ASSERT_FALSE(decoder.angles_ready_);
}
TEST(TestDecoder, processDifopPkt_fail)
{
RSDecoderMechConstParam const_param =
{
sizeof(MyMsopPkt) // msop len
, sizeof(MyDifopPkt) // difop len
, 8 // msop id len
, 8 // difop id len
, {0x55, 0xAA, 0x05, 0x0A, 0x5A, 0xA5, 0x50, 0xA0} // msop id
, {0xA5, 0xFF, 0x00, 0x5A, 0x11, 0x11, 0x55, 0x55} // difop id
};
RSDecoderParam param;
MyDecoder decoder(const_param, param);
decoder.regCallback(errCallback, nullptr);
// wrong difop length
MyDifopPkt pkt = {0};
errCode = ERRCODE_SUCCESS;
decoder.processDifopPkt((const uint8_t*)&pkt, 10);
ASSERT_EQ(errCode, ERRCODE_WRONGDIFOPLEN);
// wrong difop id
errCode = ERRCODE_SUCCESS;
decoder.processDifopPkt((const uint8_t*)&pkt, sizeof(pkt));
ASSERT_EQ(errCode, ERRCODE_WRONGDIFOPID);
}
TEST(TestDecoder, processDifopPkt)
{
RSDecoderMechConstParam const_param =
{
sizeof(MyMsopPkt) // msop len
, sizeof(MyDifopPkt) // difop len
, 8 // msop id len
, 8 // difop id len
, {0x55, 0xAA, 0x05, 0x0A, 0x5A, 0xA5, 0x50, 0xA0} // msop id
, {0xA5, 0xFF, 0x00, 0x5A, 0x11, 0x11, 0x55, 0x55} // difop id
, {0xFF, 0xEE} // block id
, 2 // laser number
, 1000 // blocks per packet
, 2 // channels per block
};
const_param.BLOCK_DURATION = 55.52f / 1000000;
RSDecoderParam param;
param.config_from_file = false;
MyDecoder decoder(const_param, param);
decoder.regCallback(errCallback, nullptr);
ASSERT_FALSE(decoder.angles_ready_);
//
// angles from difop. no angles in difop
//
uint8_t pkt_no_angles[] =
{
0xA5, 0xFF, 0x00, 0x5A, 0x11, 0x11, 0x55, 0x55 // difop id
, 0x02, 0x58 // rpm
, 0x23, 0x28 // start angle = 9000
, 0x46, 0x50 // end angle = 18000
, 0xFF, 0xFF, 0xFF // vert angles
, 0xFF, 0xFF, 0xFF
, 0xFF, 0xFF, 0xFF // horiz angles
, 0xFF, 0xFF, 0xFF
};
errCode = ERRCODE_SUCCESS;
decoder.processDifopPkt(pkt_no_angles, sizeof(MyDifopPkt));
errCode = ERRCODE_SUCCESS;
ASSERT_EQ(decoder.rps_, 10);
ASSERT_EQ(decoder.blks_per_frame_, 1801);
ASSERT_EQ(decoder.block_az_diff_, 20);
ASSERT_EQ(decoder.split_blks_per_frame_, 1801);
ASSERT_EQ(decoder.fov_blind_ts_diff_, 0.075); // 0.1 * 3/4
ASSERT_FALSE(decoder.angles_ready_);
ASSERT_EQ(decoder.chan_angles_.vert_angles_.size(), 2);
ASSERT_EQ(decoder.chan_angles_.vert_angles_[0], 0);
ASSERT_EQ(decoder.chan_angles_.horiz_angles_.size(), 2);
ASSERT_EQ(decoder.chan_angles_.horiz_angles_[0], 0);
//
// angles from difop. valid angels in difop.
//
uint8_t pkt[] =
{
0xA5, 0xFF, 0x00, 0x5A, 0x11, 0x11, 0x55, 0x55 // difop id
, 0x02, 0x58 // rpm
, 0x00, 0x00 // start angle = 0
, 0x8C, 0xA0 // end angle = 36000
, 0x00, 0x00, 0x10 // vert angles
, 0x01, 0x00, 0x20
, 0x00, 0x00, 0x01 // horiz angles
, 0x01, 0x00, 0x02
};
ASSERT_LT(decoder.getPacketDuration() - 55.52/1000, 0.00001);
errCode = ERRCODE_SUCCESS;
decoder.processDifopPkt(pkt, sizeof(MyDifopPkt));
ASSERT_EQ(errCode, ERRCODE_SUCCESS);
ASSERT_EQ(decoder.rps_, 10);
ASSERT_EQ(decoder.fov_blind_ts_diff_, 0.0f); // 0.1 * 3/4
ASSERT_TRUE(decoder.angles_ready_);
ASSERT_EQ(decoder.chan_angles_.vert_angles_.size(), 2);
ASSERT_EQ(decoder.chan_angles_.vert_angles_[0], 16);
ASSERT_EQ(decoder.chan_angles_.horiz_angles_.size(), 2);
ASSERT_EQ(decoder.chan_angles_.horiz_angles_[0], 1);
}
TEST(TestDecoder, processDifopPkt_invalid_rpm)
{
RSDecoderMechConstParam const_param =
{
sizeof(MyMsopPkt) // msop len
, sizeof(MyDifopPkt) // difop len
, 8 // msop id len
, 8 // difop id len
, {0x55, 0xAA, 0x05, 0x0A, 0x5A, 0xA5, 0x50, 0xA0} // msop id
, {0xA5, 0xFF, 0x00, 0x5A, 0x11, 0x11, 0x55, 0x55} // difop id
, {0xFF, 0xEE} // block id
, 32 // laser number
, 12 // blocks per packet
, 32 // channels per block
};
RSDecoderParam param;
MyDecoder decoder(const_param, param);
decoder.regCallback(errCallback, nullptr);
uint8_t pkt[] =
{
0xA5, 0xFF, 0x00, 0x5A, 0x11, 0x11, 0x55, 0x55 // difop len
, 0x00, 0x00 // rpm = 0
};
errCode = ERRCODE_SUCCESS;
decoder.processDifopPkt(pkt, sizeof(MyDifopPkt));
ASSERT_EQ(errCode, ERRCODE_SUCCESS);
ASSERT_EQ(decoder.rps_, 10);
}
TEST(TestDecoder, processMsopPkt)
{
RSDecoderMechConstParam const_param =
{
sizeof(MyMsopPkt) // msop len
, sizeof(MyDifopPkt) // difop len
, 8 // msop id len
, 8 // difop id len
, {0x55, 0xAA, 0x05, 0x0A, 0x5A, 0xA5, 0x50, 0xA0} // msop id
, {0xA5, 0xFF, 0x00, 0x5A, 0x11, 0x11, 0x55, 0x55} // difop id
};
MyMsopPkt pkt;
RSDecoderParam param;
MyDecoder decoder(const_param, param);
decoder.regCallback(errCallback, nullptr);
// wait_for_difop = true, angles not ready
decoder.param_.wait_for_difop = true;
decoder.angles_ready_ = false;
errCode = ERRCODE_SUCCESS;
decoder.processMsopPkt((const uint8_t*)&pkt, 2);
ASSERT_EQ(errCode, ERRCODE_SUCCESS);
#if 0
sleep(2);
errCode = ERRCODE_SUCCESS;
decoder.processMsopPkt((const uint8_t*)&pkt, 2);
ASSERT_EQ(errCode, ERRCODE_NODIFOPRECV);
#endif
decoder.param_.wait_for_difop = true;
decoder.angles_ready_ = true;
// wrong msop len
errCode = ERRCODE_SUCCESS;
decoder.processMsopPkt((const uint8_t*)&pkt, 2);
ASSERT_EQ(errCode, ERRCODE_WRONGMSOPLEN);
decoder.param_.wait_for_difop = false;
// wrong msop header
errCode = ERRCODE_SUCCESS;
decoder.processMsopPkt((const uint8_t*)&pkt, sizeof(pkt));
ASSERT_EQ(errCode, ERRCODE_WRONGMSOPID);
// valid msop
uint8_t id[] = {0x55, 0xAA, 0x05, 0x0A, 0x5A, 0xA5, 0x50, 0xA0};
memcpy (pkt.id, id, 8);
errCode = ERRCODE_SUCCESS;
decoder.processMsopPkt((const uint8_t*)&pkt, sizeof(pkt));
#ifdef ENABLE_CRC32_CHECK
ASSERT_EQ(errCode, ERRCODE_WRONGCRC32);
#else
ASSERT_EQ(errCode, ERRCODE_SUCCESS);
#endif
}