Apollo 10.0
自动驾驶开放平台
lslidarCH128_parser.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2017 The Apollo Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *****************************************************************************/
16
18
19namespace apollo {
20namespace drivers {
21namespace lslidar {
22namespace parser {
23
25 LslidarParser(config), previous_packet_stamp_(0), gps_base_usec_(0) {
26 last_packet_time = 0;
27}
28
30 const std::shared_ptr<LslidarScan> &scan_msg,
31 const std::shared_ptr<PointCloud> &out_msg) {
32 // allocate a point cloud with same time and frame ID as raw data
33 out_msg->mutable_header()->set_timestamp_sec(
34 scan_msg->basetime() / 1000000000.0);
35 out_msg->mutable_header()->set_module_name(
36 scan_msg->header().module_name());
37 out_msg->mutable_header()->set_frame_id(scan_msg->header().frame_id());
38 out_msg->set_height(1);
39 out_msg->set_measurement_time(scan_msg->basetime() / 1000000000.0);
40 out_msg->mutable_header()->set_sequence_num(
41 scan_msg->header().sequence_num());
42 gps_base_usec_ = scan_msg->basetime();
43
44 const unsigned char *difop_ptr
45 = (const unsigned char *)scan_msg->difop_pkts(0).data().c_str();
46
47 two_bytes angle_1, angle_2, angle_3, angle_4;
48 angle_1.bytes[0] = difop_ptr[87];
49 angle_1.bytes[1] = difop_ptr[86];
50 prism_angle128[0] = angle_1.uint * 0.01;
51
52 angle_2.bytes[0] = difop_ptr[89];
53 angle_2.bytes[1] = difop_ptr[88];
54 prism_angle128[1] = angle_2.uint * 0.01;
55
56 angle_3.bytes[0] = difop_ptr[91];
57 angle_3.bytes[1] = difop_ptr[90];
58 prism_angle128[2] = angle_3.uint * 0.01;
59
60 angle_4.bytes[0] = difop_ptr[93];
61 angle_4.bytes[1] = difop_ptr[92];
62 prism_angle128[3] = angle_4.uint * 0.01;
63
64 packets_size = scan_msg->firing_pkts_size();
65
66 for (size_t i = 0; i < packets_size; ++i) {
67 Unpack(static_cast<int>(i),
68 scan_msg->firing_pkts(static_cast<int>(i)),
69 out_msg);
70 last_time_stamp_ = out_msg->measurement_time();
71 ADEBUG << "stamp: " << std::fixed << last_time_stamp_;
72 }
73
74 if (out_msg->point().empty()) {
75 // we discard this pointcloud if empty
76 AERROR << "All points is NAN!Please check lslidar:" << config_.model();
77 }
78 // set default width
79 out_msg->set_width(out_msg->point_size());
80}
81
86void LslidarCH128Parser::Unpack(
87 int num,
88 const LslidarPacket &pkt,
89 std::shared_ptr<PointCloud> pc) {
90 float x, y, z;
91 uint64_t packet_end_time;
92 double z_sin_altitude = 0.0;
93 double z_cos_altitude = 0.0;
94 double cos_azimuth_half = 0.0;
95 const RawPacket *raw = (const RawPacket *)pkt.data().c_str();
96 time_last = 0;
97
98 packet_end_time = pkt.stamp();
99
100 for (int i = 0; i < 128; i++) {
101 if (abs(prism_angle128[0]) < 1e-6 && abs(prism_angle128[1]) < 1e-6
102 && abs(prism_angle128[2]) < 1e-6 && abs(prism_angle128[3]) < 1e-6) {
103 sinTheta_2[i] = sin_scan_mirror_altitude_ch128[i % 4];
104 } else {
105 sinTheta_2[i] = std::sin(prism_angle128[i % 4] * M_PI / 180);
106 }
107 }
108 for (int point_idx1 = 0; point_idx1 < POINTS_PER_PACKET; point_idx1++) {
109 firings[point_idx1].vertical_line
110 = raw->points[point_idx1].vertical_line;
111 two_bytes point_amuzith;
112 point_amuzith.bytes[0] = raw->points[point_idx1].azimuth_2;
113 point_amuzith.bytes[1] = raw->points[point_idx1].azimuth_1;
114 firings[point_idx1].azimuth
115 = static_cast<double>(point_amuzith.uint * 0.01 * DEG_TO_RAD);
116 four_bytes point_distance;
117 point_distance.bytes[0] = raw->points[point_idx1].distance_3;
118 point_distance.bytes[1] = raw->points[point_idx1].distance_2;
119 point_distance.bytes[2] = raw->points[point_idx1].distance_1;
120 point_distance.bytes[3] = 0;
121 firings[point_idx1].distance = static_cast<double>(point_distance.uint)
122 * DISTANCE_RESOLUTION2;
123 firings[point_idx1].intensity = raw->points[point_idx1].intensity;
124 }
125
126 for (int point_idx = 0; point_idx < POINTS_PER_PACKET; point_idx++) {
127 LaserCorrection &corrections
129 .laser_corrections_[firings[point_idx].vertical_line];
130
131 if (config_.calibration())
132 firings[point_idx].distance
133 = firings[point_idx].distance + corrections.dist_correction;
134
135 if (firings[point_idx].distance > config_.max_range()
136 || firings[point_idx].distance < config_.min_range())
137 continue;
138
139 if (firings[point_idx].vertical_line / 4 % 2 == 0) {
140 cos_azimuth_half
141 = sin((firings[point_idx].azimuth - 15 * DEG_TO_RAD) * 0.5);
142 } else {
143 cos_azimuth_half
144 = cos((firings[point_idx].azimuth + 15 * DEG_TO_RAD) * 0.5);
145 }
146
147 z_sin_altitude = sin_scan_laser_altitude_ch128
148 [firings[point_idx].vertical_line / 4]
149 + 2 * cos_azimuth_half
150 * sinTheta_2[firings[point_idx].vertical_line];
151 z_cos_altitude = sqrt(1 - z_sin_altitude * z_sin_altitude);
152 x = firings[point_idx].distance * z_cos_altitude
153 * cos(firings[point_idx].azimuth);
154 y = firings[point_idx].distance * z_cos_altitude
155 * sin(firings[point_idx].azimuth);
156 z = firings[point_idx].distance * z_sin_altitude;
157
158 // Compute the time of the point
159 uint64_t point_time = packet_end_time
160 - 1562.5 * ((POINTS_PER_PACKET - point_idx) / 7 - 1);
161 if (time_last < point_time && time_last > 0) {
162 point_time = time_last + 1562.5;
163 }
164 time_last = point_time;
165
166 PointXYZIT *point = pc->add_point();
167 point->set_timestamp(point_time);
168 point->set_intensity(firings[point_idx].intensity);
169
170 if (config_.calibration()) {
172 firings[point_idx].vertical_line,
173 CH128,
174 firings[point_idx].distance,
175 &corrections,
176 firings[point_idx].azimuth,
177 point);
178 } else {
179 if ((y >= config_.bottom_left_x() && y <= config_.top_right_x())
180 && (-x >= config_.bottom_left_y()
181 && -x <= config_.top_right_y())) {
182 point->set_x(nan);
183 point->set_y(nan);
184 point->set_z(nan);
185 point->set_timestamp(point_time);
186 point->set_intensity(0);
187 } else {
188 point->set_x(y);
189 point->set_y(-x);
190 point->set_z(z);
191 }
192 }
193 }
194}
195
196void LslidarCH128Parser::Order(std::shared_ptr<PointCloud> cloud) {}
197
198} // namespace parser
199} // namespace lslidar
200} // namespace drivers
201} // namespace apollo
std::map< int, LaserCorrection > laser_corrections_
Definition calibration.h:72
void Order(std::shared_ptr< PointCloud > cloud)
void GeneratePointcloud(const std::shared_ptr< LslidarScan > &scan_msg, const std::shared_ptr< PointCloud > &out_msg)
void ComputeCoords2(int Laser_ring, int Type, const float &raw_distance, LaserCorrection *corrections, const double rotation, PointXYZIT *point)
#define ADEBUG
Definition log.h:41
#define AERROR
Definition log.h:44
These classes Unpack raw Lslidar LIDAR packets into several useful formats.
#define DEG_TO_RAD
#define CH128
float cos(Angle16 a)
Definition angle.cc:42
float sin(Angle16 a)
Definition angle.cc:25
class register implement
Definition arena_queue.h:37
used for unpacking the first two data bytes in a block