25 LslidarParser(config), previous_packet_stamp_(0), gps_base_usec_(0) {
29 is_get_scan_altitude_ =
false;
30 AERROR <<
"vertical_angle_ " << vertical_angle_;
34 for (
int i = 0; i < 16; ++i) {
35 sin_scan_altitude[i] = sin(c16_vertical_angle[i] *
DEG_TO_RAD);
36 cos_scan_altitude[i] = cos(c16_vertical_angle[i] *
DEG_TO_RAD);
41 for (
int i = 0; i < 8; ++i) {
42 sin_scan_altitude[i] = sin(c8_vertical_angle[i] *
DEG_TO_RAD);
43 cos_scan_altitude[i] = cos(c8_vertical_angle[i] *
DEG_TO_RAD);
48 for (
int i = 0; i < 8; ++i) {
49 sin_scan_altitude[i] = sin(c1_vertical_angle[i] *
DEG_TO_RAD);
50 cos_scan_altitude[i] = cos(c1_vertical_angle[i] *
DEG_TO_RAD);
55 AERROR <<
"Vertical angle: 32 degrees";
56 for (
int i = 0; i < 32; ++i) {
63 AERROR <<
"Vertical angle: 70 degrees";
64 for (
int k = 0; k < 32; ++k) {
71 AERROR <<
"Vertical angle: 90 degrees";
72 for (
int k = 0; k < 32; ++k) {
82 for (
int j = 0; j < 36000; ++j) {
83 double angle =
static_cast<double>(j) / 100.0 *
DEG_TO_RAD;
84 sin_azimuth_table[j] = sin(angle);
85 cos_azimuth_table[j] = cos(angle);
93 for (
size_t b_idx = 0; b_idx < BLOCKS_PER_PACKET; ++b_idx) {
97 for (
size_t block_idx = 0; block_idx < BLOCKS_PER_PACKET; ++block_idx) {
100 int32_t azimuth_diff_b = 0;
102 if (block_idx < BLOCKS_PER_PACKET - 1) {
105 azimuth_diff_b = azimuth_diff_b < 0 ? azimuth_diff_b + 36000
112 azimuth_diff_b = azimuth_diff_b < 0 ? azimuth_diff_b + 36000
117 if (block_idx < BLOCKS_PER_PACKET - 2) {
120 azimuth_diff_b = azimuth_diff_b < 0 ? azimuth_diff_b + 36000
127 azimuth_diff_b = azimuth_diff_b < 0 ? azimuth_diff_b + 36000
133 for (
size_t scan_fir_idx = 0; scan_fir_idx < SCANS_PER_FIRING_C32;
135 size_t byte_idx = RAW_SCAN_SIZE * scan_fir_idx;
137 firings.
azimuth[block_idx * 32 + scan_fir_idx]
139 + scan_fir_idx * azimuth_diff_b / FIRING_TOFFSET_C32;
140 firings.
azimuth[block_idx * 32 + scan_fir_idx]
141 = firings.
azimuth[block_idx * 32 + scan_fir_idx] % 36000;
146 firings.
distance[block_idx * 32 + scan_fir_idx]
147 =
static_cast<double>(raw_distance.distance)
148 * DISTANCE_RESOLUTION * distance_unit_;
151 firings.
intensity[block_idx * 32 + scan_fir_idx]
159 for (
size_t blk_idx = 0; blk_idx < BLOCKS_PER_PACKET; ++blk_idx) {
168 const std::shared_ptr<LslidarScan> &scan_msg,
169 const std::shared_ptr<PointCloud> &out_msg) {
171 out_msg->mutable_header()->set_timestamp_sec(
172 scan_msg->basetime() / 1000000000.0);
173 out_msg->mutable_header()->set_module_name(
174 scan_msg->header().module_name());
175 out_msg->mutable_header()->set_frame_id(scan_msg->header().frame_id());
176 out_msg->set_height(1);
177 out_msg->set_measurement_time(scan_msg->basetime() / 1000000000.0);
178 out_msg->mutable_header()->set_sequence_num(
179 scan_msg->header().sequence_num());
180 gps_base_usec_ = scan_msg->basetime();
182 const unsigned char *difop_ptr
183 = (
const unsigned char *)scan_msg->difop_pkts(0).data().c_str();
184 if (difop_ptr[0] == 0xa5 && difop_ptr[1] == 0xff && difop_ptr[2] == 0x00
185 && difop_ptr[3] == 0x5a) {
186 AINFO <<
"设备包,暂时用不上...";
189 size_t packets_size = scan_msg->firing_pkts_size();
191 packet_number_ = packets_size;
193 AINFO <<
"packets_size :" << packets_size;
195 for (
size_t i = 0; i < packets_size; ++i) {
196 Unpack(scan_msg->firing_pkts(
static_cast<int>(i)), out_msg, i);
201 if (out_msg->point().empty()) {
207 out_msg->set_width(out_msg->point_size());
214void LslidarCXV4Parser::Unpack(
216 std::shared_ptr<PointCloud> pc,
221 uint8_t *data =
reinterpret_cast<uint8_t *
>(
222 const_cast<char *
>(pkt.
data().c_str()));
231 if (!is_get_scan_altitude_
232 &&
static_cast<uint16_t
>(data[1211]) == 0x46) {
233 AERROR <<
"byte[1211] == 0x46: old C32W";
234 is_new_c32w_ =
false;
235 for (
int k = 0; k < 32; ++k) {
236 sin_scan_altitude[k] = sin(c32_70_vertical_angle[k] *
DEG_TO_RAD);
237 cos_scan_altitude[k] = cos(c32_70_vertical_angle[k] *
DEG_TO_RAD);
239 is_get_scan_altitude_ =
true;
242 for (
size_t fir_idx = 0; fir_idx < SCANS_PER_PACKET; ++fir_idx) {
243 if (!is_new_c32w_ && vertical_angle_ == 70) {
244 if (fir_idx % 32 == 29 || fir_idx % 32 == 6 || fir_idx % 32 == 14
245 || fir_idx % 32 == 22 || fir_idx % 32 == 30 || fir_idx % 32 == 7
246 || fir_idx % 32 == 15 || fir_idx % 32 == 23) {
247 firings.
azimuth[fir_idx] += 389;
249 if (firings.
azimuth[fir_idx] > 36000)
250 firings.
azimuth[fir_idx] -= 36000;
253 size_t table_idx = firings.
azimuth[fir_idx];
254 double cos_azimuth = cos_azimuth_table[table_idx];
255 double sin_azimuth = sin_azimuth_table[table_idx];
256 double x_coord, y_coord, z_coord;
257 bool coordinate_opt =
true;
259 if (vertical_angle_ == 90) {
261 }
else if (is_new_c32w_) {
266 double conversionAngle = (vertical_angle_ == 90)
267 ? CX4_conversionAngle_90
268 : CX4_conversionAngle_;
269 if (coordinate_opt) {
271 * cos_scan_altitude[fir_idx % lidar_number_]
274 *
cos((conversionAngle
275 - firings.
azimuth[fir_idx] * 0.01)
277 y_coord = -firings.
distance[fir_idx]
278 * cos_scan_altitude[fir_idx % lidar_number_]
281 *
sin((conversionAngle
282 - firings.
azimuth[fir_idx] * 0.01)
285 * sin_scan_altitude[fir_idx % lidar_number_];
290 * cos_scan_altitude[fir_idx % lidar_number_]
297 * cos_scan_altitude[fir_idx % lidar_number_]
304 * sin_scan_altitude[fir_idx % lidar_number_];
308 if (last_packet_time > 1e-6) {
311 * (SCANS_PER_PACKET - fir_idx - 1)
319 PointXYZIT *point = pc->add_point();
323 point->set_timestamp(point_time);
324 point->set_intensity(0);
329 if (packet_number == 0) {
330 if (firings.
azimuth[fir_idx] > 30000) {
335 if (packet_number == packet_number_ - 1) {
336 if (firings.
azimuth[fir_idx] < 10000) {
341 PointXYZIT *point = pc->add_point();
342 point->set_timestamp(point_time);
344 point->set_intensity(firings.
intensity[fir_idx]);
352 point->set_timestamp(point_time);
353 point->set_intensity(0);
355 point->set_x(y_coord);
356 point->set_y(-x_coord);
357 point->set_z(z_coord);
366 cloud->set_width(width);
367 int height = cloud->point_size() / cloud->width();
368 cloud->set_height(height);
370 std::shared_ptr<PointCloud> cloud_origin = std::make_shared<PointCloud>();
371 cloud_origin->CopyFrom(*cloud);
373 for (
int i = 0; i < width; ++i) {
376 for (
int j = 0; j < height; ++j) {
379 int target_index = j * width + i;
380 int origin_index = j * width + col;
381 cloud->mutable_point(target_index)
382 ->CopyFrom(cloud_origin->point(origin_index));
void Order(std::shared_ptr< apollo::drivers::PointCloud > cloud)
LslidarCXV4Parser(const Config &config)
void decodePacket(const RawPacket_C32 *packet)
void GeneratePointcloud(const std::shared_ptr< apollo::drivers::lslidar::LslidarScan > &scan_msg, const std::shared_ptr< apollo::drivers::PointCloud > &out_msg)
bool checkPacketValidity(const RawPacket_C32 *packet)
Lslidar data conversion class
uint64_t current_packet_time
uint64_t previous_packet_time
These classes Unpack raw Lslidar LIDAR packets into several useful formats.
optional float bottom_left_y
optional uint32 vertical_angle
optional uint32 return_mode
optional float scan_end_angle
optional float top_right_x
optional float top_right_y
optional float distance_unit
optional float bottom_left_x
optional float scan_start_angle
uint16_t azimuth[SCANS_PER_PACKET]
double intensity[SCANS_PER_PACKET]
uint16_t firing_azimuth[BLOCKS_PER_PACKET]
double distance[SCANS_PER_PACKET]
RawBlock blocks[BLOCKS_PER_PACKET]
uint8_t data[BLOCK_DATA_SIZE]
combine rotation1 and rotation2 together to get 0-35999, divide by 100 to get degrees