28 LslidarParser(config), previous_packet_stamp_(0), gps_base_usec_(0) {
34 for (
int i = 0; i < LSC16_SCANS_PER_FIRING; i++) {
36 = std::cos(scan_altitude_original_2[i]);
38 = std::sin(scan_altitude_original_2[i]);
42 for (
int i = 0; i < LSC16_SCANS_PER_FIRING; i++) {
44 = std::cos(scan_altitude_original_1[i]);
46 = std::sin(scan_altitude_original_1[i]);
51 for (uint16_t rot_index = 0; rot_index < ROTATION_MAX_UNITS; ++rot_index) {
52 float rotation = ROTATION_RESOLUTION
53 *
static_cast<float>(rot_index * M_PI) / 180.0f;
60 const std::shared_ptr<LslidarScan> &scan_msg,
61 const std::shared_ptr<PointCloud> &out_msg) {
63 out_msg->mutable_header()->set_timestamp_sec(
64 scan_msg->basetime() / 1000000000.0);
65 out_msg->mutable_header()->set_module_name(
66 scan_msg->header().module_name());
67 out_msg->mutable_header()->set_frame_id(scan_msg->header().frame_id());
68 out_msg->set_height(1);
69 out_msg->set_measurement_time(scan_msg->basetime() / 1000000000.0);
70 out_msg->mutable_header()->set_sequence_num(
71 scan_msg->header().sequence_num());
72 gps_base_usec_ = scan_msg->basetime();
74 const unsigned char *difop_ptr
75 = (
const unsigned char *)scan_msg->difop_pkts(0).data().c_str();
76 uint8_t version_data =
static_cast<uint8_t
>(difop_ptr[1202]);
79 if (2 == version_data) {
80 for (
int i = 0; i < 16; i++) {
81 uint16_t vert_angle =
static_cast<uint16_t
>(
82 difop_ptr[234 + 2 * i] * 256
83 + difop_ptr[234 + 2 * i + 1]);
85 if (vert_angle > 32767) {
86 vert_angle = vert_angle - 65535;
90 = (
static_cast<float>(vert_angle) / 100.f) *
DEG_TO_RAD;
115 for (
int i = 0; i < 16; i++) {
116 uint16_t vert_angle =
static_cast<uint16_t
>(
117 difop_ptr[245 + 2 * i] * 256
118 + difop_ptr[245 + 2 * i + 1]);
120 if (vert_angle > 32767) {
121 vert_angle = vert_angle - 65535;
125 = (
static_cast<float>(vert_angle) / 100.f) *
DEG_TO_RAD;
153 size_t packets_size = scan_msg->firing_pkts_size();
154 packet_number_ = packets_size;
157 for (
size_t i = 0; i < packets_size; ++i) {
158 Unpack(scan_msg->firing_pkts(
static_cast<int>(i)), out_msg, i);
163 if (out_msg->point().empty()) {
168 out_msg->set_width(out_msg->point_size());
175void Lslidar16Parser::Unpack(
177 std::shared_ptr<PointCloud> pc,
180 float azimuth = 0.0f;
181 uint32_t intensity = 0;
182 float azimuth_diff = 0.0f;
183 float azimuth_corrected_f = 0.0f;
184 int azimuth_corrected = 0;
186 uint64_t packet_end_time;
189 for (
int i = 0; i < LSC16_SCANS_PER_FIRING; i++) {
198 packet_end_time = pkt.
stamp();
200 packet_end_time = pkt.
stamp();
203 int point_count = -1;
204 for (
int block = 0; block < BLOCKS_PER_PACKET; block++, block_num++) {
205 if (UPPER_BANK != raw->blocks[block].header)
208 azimuth =
static_cast<float>(
209 256 * raw->blocks[block].rotation_2
210 + raw->blocks[block].rotation_1);
213 if (block < (BLOCKS_PER_PACKET - 2)) {
215 azi1 = 256 * raw->blocks[block + 2].rotation_2
216 + raw->blocks[block + 2].rotation_1;
217 azi2 = 256 * raw->blocks[block].rotation_2
218 + raw->blocks[block].rotation_1;
220 =
static_cast<float>((36000 + azi1 - azi2) % 36000);
223 azi1 = 256 * raw->blocks[block].rotation_2
224 + raw->blocks[block].rotation_1;
225 azi2 = 256 * raw->blocks[block - 2].rotation_2
226 + raw->blocks[block - 2].rotation_1;
228 =
static_cast<float>((36000 + azi1 - azi2) % 36000);
231 if (block < (BLOCKS_PER_PACKET - 1)) {
233 azi1 = 256 * raw->blocks[block + 1].rotation_2
234 + raw->blocks[block + 1].rotation_1;
235 azi2 = 256 * raw->blocks[block].rotation_2
236 + raw->blocks[block].rotation_1;
238 =
static_cast<float>((36000 + azi1 - azi2) % 36000);
241 azi1 = 256 * raw->blocks[block].rotation_2
242 + raw->blocks[block].rotation_1;
243 azi2 = 256 * raw->blocks[block - 1].rotation_2
244 + raw->blocks[block - 1].rotation_1;
246 =
static_cast<float>((36000 + azi1 - azi2) % 36000);
253 for (
int firing = 0, k = 0; firing < LSC16_FIRINGS_PER_BLOCK;
255 for (
int dsr = 0; dsr < LSC16_SCANS_PER_FIRING;
256 ++dsr, k += RAW_SCAN_SIZE) {
258 LaserCorrection &corrections
263 azimuth_corrected_f = azimuth
264 + azimuth_diff / (LSC16_SCANS_PER_FIRING * 2)
265 * (LSC16_SCANS_PER_FIRING * firing + dsr);
267 azimuth_corrected =
static_cast<int>(
268 round(fmod(azimuth_corrected_f, 36000.0)));
275 tmp.bytes[0] = raw->blocks[block].data[k];
276 tmp.bytes[1] = raw->blocks[block].data[k + 1];
277 int distance = tmp.uint;
280 intensity = raw->blocks[block].data[k + 2];
282 float distance2 = (distance * DISTANCE_RESOLUTION)
286 distance2 = distance2 + corrections.dist_correction;
289 float arg_horiz =
static_cast<float>(
290 azimuth_corrected_f * ROTATION_RESOLUTION);
291 arg_horiz = arg_horiz > 360 ? (arg_horiz - 360) : arg_horiz;
292 float arg_horiz_orginal = (14.67 - arg_horiz) * M_PI / 180;
298 - (SCANS_PER_PACKET - point_count - 1)
301 / (SCANS_PER_PACKET);
310 - (SCANS_PER_PACKET - point_count - 1)
313 / (SCANS_PER_PACKET);
322 if (packet_number == 0) {
323 if (azimuth_corrected > 30000) {
328 if (packet_number == packet_number_ - 1) {
329 if (azimuth_corrected < 10000) {
336 PointXYZIT *point = pc->add_point();
340 point->set_timestamp(point_time);
341 point->set_intensity(0);
343 PointXYZIT *point = pc->add_point();
344 point->set_timestamp(point_time);
346 point->set_intensity(intensity);
352 static_cast<uint16_t
>(azimuth_corrected),
358 +
R1_ *
cos(arg_horiz_orginal);
361 +
R1_ *
sin(arg_horiz_orginal);
372 point->set_timestamp(point_time);
373 point->set_intensity(0);
389 cloud->set_width(width);
390 int height = cloud->point_size() / cloud->width();
391 cloud->set_height(height);
393 std::shared_ptr<PointCloud> cloud_origin = std::make_shared<PointCloud>();
394 cloud_origin->CopyFrom(*cloud);
396 for (
int i = 0; i < width; ++i) {
399 for (
int j = 0; j < height; ++j) {
402 int target_index = j * width + i;
403 int origin_index = j * width + col;
404 cloud->mutable_point(target_index)
405 ->CopyFrom(cloud_origin->point(origin_index));
std::map< int, LaserCorrection > laser_corrections_
Lslidar16Parser(const Config &config)
void GeneratePointcloud(const std::shared_ptr< apollo::drivers::lslidar::LslidarScan > &scan_msg, const std::shared_ptr< apollo::drivers::PointCloud > &out_msg)
void Order(std::shared_ptr< apollo::drivers::PointCloud > cloud)
Lslidar data conversion class
float cos_azimuth_table[ROTATION_MAX_UNITS]
bool need_two_pt_correction_
double cos_scan_altitude_caliration[LSC32_SCANS_PER_FIRING]
uint64_t current_packet_time
uint64_t previous_packet_time
void ComputeCoords(const float &raw_distance, LaserCorrection *corrections, const uint16_t rotation, PointXYZIT *point)
float sin_azimuth_table[ROTATION_MAX_UNITS]
double sin_scan_altitude_caliration[LSC32_SCANS_PER_FIRING]
These classes Unpack raw Lslidar LIDAR packets into several useful formats.
struct apollo::drivers::lslidar::parser::raw_packet raw_packet_t
optional float bottom_left_y
optional uint32 return_mode
optional float scan_end_angle
optional float top_right_x
optional uint32 degree_mode
optional float top_right_y
optional bool calibration
optional float distance_unit
optional float bottom_left_x
optional bool time_synchronization
optional bool config_vert
optional float scan_start_angle