Apollo 10.0
自动驾驶开放平台
lslidarCH128X1_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
28 const std::shared_ptr<LslidarScan>& scan_msg,
29 const std::shared_ptr<PointCloud>& out_msg) {
30 // allocate a point cloud with same time and frame ID as raw data
31 out_msg->mutable_header()->set_timestamp_sec(
32 scan_msg->basetime() / 1000000000.0);
33 out_msg->mutable_header()->set_module_name(
34 scan_msg->header().module_name());
35 out_msg->mutable_header()->set_frame_id(scan_msg->header().frame_id());
36 out_msg->set_height(1);
37 out_msg->set_measurement_time(scan_msg->basetime() / 1000000000.0);
38 out_msg->mutable_header()->set_sequence_num(
39 scan_msg->header().sequence_num());
40 gps_base_usec_ = scan_msg->basetime();
41
42 const unsigned char* difop_ptr
43 = (const unsigned char*)scan_msg->difop_pkts(0).data().c_str();
44
45 two_bytes angle_1, angle_2, angle_3, angle_4;
46 angle_1.bytes[0] = difop_ptr[243];
47 angle_1.bytes[1] = difop_ptr[242];
48 prism_angle[0] = angle_1.uint * 0.01;
49
50 angle_2.bytes[0] = difop_ptr[245];
51 angle_2.bytes[1] = difop_ptr[244];
52 prism_angle[1] = angle_2.uint * 0.01;
53
54 angle_3.bytes[0] = difop_ptr[247];
55 angle_3.bytes[1] = difop_ptr[246];
56 prism_angle[2] = angle_3.uint * 0.01;
57
58 angle_4.bytes[0] = difop_ptr[249];
59 angle_4.bytes[1] = difop_ptr[248];
60 prism_angle[3] = angle_4.uint * 0.01;
61
62 packets_size = scan_msg->firing_pkts_size();
63
64 for (size_t i = 0; i < packets_size; ++i) {
65 Unpack(static_cast<int>(i),
66 scan_msg->firing_pkts(static_cast<int>(i)),
67 out_msg);
68 last_time_stamp_ = out_msg->measurement_time();
69 ADEBUG << "stamp: " << std::fixed << last_time_stamp_;
70 }
71
72 AINFO << "packets_size :" << packets_size;
73 if (out_msg->point().empty()) {
74 // we discard this pointcloud if empty
75 AERROR << "All points is NAN!Please check lslidar:" << config_.model();
76 }
77
78 // set default width
79 out_msg->set_width(out_msg->point_size());
80}
81
86void LslidarCH128X1Parser::Unpack(
87 int num,
88 const LslidarPacket& pkt,
89 std::shared_ptr<PointCloud> pc) {
90 float x, y, z;
91 uint64_t point_time;
92 uint64_t packet_end_time;
93 double z_sin_altitude = 0.0;
94 double z_cos_altitude = 0.0;
95 double sinTheta_1[128] = {0};
96 double cosTheta_1[128] = {0};
97 double sinTheta_2[128] = {0};
98 double cosTheta_2[128] = {0};
99
100 for (int i = 0; i < 128; i++) {
101 sinTheta_1[i] = sin(big_angle[i / 4] * M_PI / 180);
102 cosTheta_1[i] = cos(big_angle[i / 4] * M_PI / 180);
103
104 if (abs(prism_angle[0]) < 1e-6 && abs(prism_angle[1]) < 1e-6
105 && abs(prism_angle[2]) < 1e-6 && abs(prism_angle[3]) < 1e-6) {
106 sinTheta_2[i] = sin((i % 4) * (-0.17) * M_PI / 180);
107 cosTheta_2[i] = cos((i % 4) * (-0.17) * M_PI / 180);
108 } else {
109 sinTheta_2[i] = sin(prism_angle[i % 4] * M_PI / 180);
110 cosTheta_2[i] = cos(prism_angle[i % 4] * M_PI / 180);
111 }
112 }
113
114 const RawPacket* raw = (const RawPacket*)pkt.data().c_str();
115
116 packet_end_time = pkt.stamp();
117 current_packet_time = packet_end_time;
118
119 for (size_t point_idx = 0; point_idx < POINTS_PER_PACKET; point_idx++) {
120 firings[point_idx].vertical_line = raw->points[point_idx].vertical_line;
121 two_bytes point_amuzith;
122 point_amuzith.bytes[0] = raw->points[point_idx].azimuth_2;
123 point_amuzith.bytes[1] = raw->points[point_idx].azimuth_1;
124 firings[point_idx].azimuth
125 = static_cast<double>(point_amuzith.uint) * 0.01 * DEG_TO_RAD;
126 four_bytes point_distance;
127 point_distance.bytes[0] = raw->points[point_idx].distance_3;
128 point_distance.bytes[1] = raw->points[point_idx].distance_2;
129 point_distance.bytes[2] = raw->points[point_idx].distance_1;
130 point_distance.bytes[3] = 0;
131 firings[point_idx].distance = static_cast<double>(point_distance.uint)
132 * DISTANCE_RESOLUTION2;
133 firings[point_idx].intensity = raw->points[point_idx].intensity;
134 }
135
136 for (size_t point_idx = 0; point_idx < POINTS_PER_PACKET; point_idx++) {
137 LaserCorrection& corrections
139 .laser_corrections_[firings[point_idx].vertical_line];
140
141 if (config_.calibration())
142 firings[point_idx].distance
143 = firings[point_idx].distance + corrections.dist_correction;
144
145 if (firings[point_idx].distance > config_.max_range()
146 || firings[point_idx].distance < config_.min_range())
147 continue;
148
149 double _R_ = cosTheta_2[firings[point_idx].vertical_line]
150 * cosTheta_1[firings[point_idx].vertical_line]
151 * cos(firings[point_idx].azimuth / 2.0)
152 - sinTheta_2[firings[point_idx].vertical_line]
153 * sinTheta_1[firings[point_idx].vertical_line];
154
155 z_sin_altitude = sinTheta_1[firings[point_idx].vertical_line]
156 + 2 * _R_ * sinTheta_2[firings[point_idx].vertical_line];
157
158 z_cos_altitude = sqrt(1 - pow(z_sin_altitude, 2));
159 x = firings[point_idx].distance * z_cos_altitude
160 * cos(firings[point_idx].azimuth);
161 y = firings[point_idx].distance * z_cos_altitude
162 * sin(firings[point_idx].azimuth);
163 z = firings[point_idx].distance * z_sin_altitude;
164
165 if ((y >= config_.bottom_left_x() && y <= config_.top_right_x())
166 && (-x >= config_.bottom_left_y() && -x <= config_.top_right_y()))
167 return;
168
169 // Compute the time of the point
170 // modify
171 if (previous_packet_time > 1e-6) {
172 point_time = current_packet_time
173 - (POINTS_PER_PACKET - point_idx - 1)
175 / (POINTS_PER_PACKET);
176 } else { // fist packet
177 point_time = current_packet_time;
178 }
179
180 PointXYZIT* point = pc->add_point();
181 point->set_timestamp(point_time);
182 point->set_intensity(firings[point_idx].intensity);
183
184 if (config_.calibration()) {
186 firings[point_idx].vertical_line,
187 CH128X1,
188 firings[point_idx].distance,
189 &corrections,
190 firings[point_idx].azimuth,
191 point);
192
193 } else {
194 if ((y >= config_.bottom_left_x() && y <= config_.top_right_x())
195 && (-x >= config_.bottom_left_y()
196 && -x <= config_.top_right_y())) {
197 point->set_x(nan);
198 point->set_y(nan);
199 point->set_z(nan);
200 point->set_timestamp(point_time);
201 point->set_intensity(0);
202 } else {
203 point->set_x(y);
204 point->set_y(-x);
205 point->set_z(z);
206 }
207 }
208 }
210}
211
212void LslidarCH128X1Parser::Order(std::shared_ptr<PointCloud> cloud) {}
213
214} // namespace parser
215} // namespace lslidar
216} // namespace drivers
217} // namespace apollo
std::map< int, LaserCorrection > laser_corrections_
Definition calibration.h:72
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
#define AINFO
Definition log.h:42
These classes Unpack raw Lslidar LIDAR packets into several useful formats.
#define DEG_TO_RAD
#define CH128X1
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