Apollo 10.0
自动驾驶开放平台
lslidarCH64w_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 point_time_diff = 1 / (60.0 * 1000 * 32); // s
27 for (int i = 0; i < 4; ++i) {
28 prism_angle64[i] = i * 0.35;
29 }
30 for (int j = 0; j < 128; ++j) {
31 if (j / 4 % 2 == 0) {
32 theat1_s[j] = sin((-25 + floor(j / 8) * 2.5) * M_PI / 180);
33 theat2_s[j] = sin(prism_angle64[j % 4] * M_PI / 180);
34 theat1_c[j] = cos((-25 + floor(j / 8) * 2.5) * M_PI / 180);
35 theat2_c[j] = cos(prism_angle64[j % 4] * M_PI / 180);
36 } else {
37 theat1_s[j] = sin((-24 + floor(j / 8) * 2.5) * M_PI / 180);
38 theat2_s[j] = sin(prism_angle64[j % 4] * M_PI / 180);
39 theat1_c[j] = cos((-24 + floor(j / 8) * 2.5) * M_PI / 180);
40 theat2_c[j] = cos(prism_angle64[j % 4] * M_PI / 180);
41 }
42 }
43}
44
46 const std::shared_ptr<LslidarScan>& scan_msg,
47 const std::shared_ptr<PointCloud>& out_msg) {
48 // allocate a point cloud with same time and frame ID as raw data
49 out_msg->mutable_header()->set_timestamp_sec(
50 scan_msg->basetime() / 1000000000.0);
51 out_msg->mutable_header()->set_module_name(
52 scan_msg->header().module_name());
53 out_msg->mutable_header()->set_frame_id(scan_msg->header().frame_id());
54 out_msg->set_height(1);
55 out_msg->set_measurement_time(scan_msg->basetime() / 1000000000.0);
56 out_msg->mutable_header()->set_sequence_num(
57 scan_msg->header().sequence_num());
58 gps_base_usec_ = scan_msg->basetime();
59
60 packets_size = scan_msg->firing_pkts_size();
61 AINFO << "packets_size :" << packets_size;
62 for (size_t i = 0; i < packets_size; ++i) {
63 Unpack(static_cast<int>(i),
64 scan_msg->firing_pkts(static_cast<int>(i)),
65 out_msg);
66 last_time_stamp_ = out_msg->measurement_time();
67 ADEBUG << "stamp: " << std::fixed << last_time_stamp_;
68 }
69 if (out_msg->point().empty()) {
70 // we discard this pointcloud if empty
71 AERROR << "All points is NAN!Please check lslidar:" << config_.model();
72 }
73
74 // set default width
75 out_msg->set_width(out_msg->point_size());
76}
77
82void LslidarCH64wParser::Unpack(
83 int num,
84 const LslidarPacket& pkt,
85 std::shared_ptr<PointCloud> pc) {
86 float x, y, z;
87 uint64_t point_time;
88 uint64_t packet_end_time;
89 time_last = 0;
90 const RawPacket* raw = (const RawPacket*)pkt.data().c_str();
91 double cos_xita;
92 // 垂直角度
93 double sin_theat;
94 double cos_theat;
95 double _R_;
96 // 水平角度
97 double cos_H_xita;
98 double sin_H_xita;
99 double cos_xita_F;
100 double sin_xita_F;
101
102 packet_end_time = pkt.stamp();
103
104 current_packet_time = packet_end_time;
105
106 for (size_t point_idx = 0; point_idx < POINTS_PER_PACKET; point_idx++) {
107 firings[point_idx].vertical_line = raw->points[point_idx].vertical_line;
108 two_bytes point_amuzith;
109 point_amuzith.bytes[0] = raw->points[point_idx].azimuth_2;
110 point_amuzith.bytes[1] = raw->points[point_idx].azimuth_1;
111 firings[point_idx].azimuth
112 = static_cast<double>(point_amuzith.uint) * 0.01 * DEG_TO_RAD;
113 four_bytes point_distance;
114 point_distance.bytes[0] = raw->points[point_idx].distance_3;
115 point_distance.bytes[1] = raw->points[point_idx].distance_2;
116 point_distance.bytes[2] = raw->points[point_idx].distance_1;
117 point_distance.bytes[3] = 0;
118 firings[point_idx].distance = static_cast<double>(point_distance.uint)
119 * DISTANCE_RESOLUTION2;
120 firings[point_idx].intensity = raw->points[point_idx].intensity;
121 }
122
123 for (size_t point_idx = 0; point_idx < POINTS_PER_PACKET; point_idx++) {
124 LaserCorrection& corrections
126 .laser_corrections_[firings[point_idx].vertical_line];
127
128 if (config_.calibration())
129 firings[point_idx].distance
130 = firings[point_idx].distance + corrections.dist_correction;
131
132 if (firings[point_idx].distance > config_.max_range()
133 || firings[point_idx].distance < config_.min_range())
134 continue;
135
136 int line_num = firings[point_idx].vertical_line;
137 if (line_num / 4 % 2 == 0) {
138 cos_xita
139 = cos((firings[point_idx].azimuth * RAD_TO_DEG / 2.0 + 22.5)
140 * M_PI / 180);
141 } else {
142 cos_xita = cos(
143 (-firings[point_idx].azimuth * RAD_TO_DEG / 2.0 + 112.5)
144 * M_PI / 180);
145 }
146
147 _R_ = theat2_c[line_num] * theat1_c[line_num] * cos_xita
148 - theat2_s[line_num] * theat1_s[line_num];
149 sin_theat = theat1_s[line_num] + 2 * _R_ * theat2_s[line_num];
150 cos_theat = sqrt(1 - pow(sin_theat, 2));
151 cos_H_xita
152 = (2 * _R_ * theat2_c[line_num] * cos_xita - theat1_c[line_num])
153 / cos_theat;
154 sin_H_xita = sqrt(1 - pow(cos_H_xita, 2));
155
156 if (line_num / 4 % 2 == 0) {
157 cos_xita_F = (cos_H_xita + sin_H_xita) * sqrt(0.5);
158 sin_xita_F = sqrt(1 - pow(cos_xita_F, 2));
159 } else {
160 cos_xita_F = (cos_H_xita + sin_H_xita) * (-sqrt(0.5));
161 sin_xita_F = sqrt(1 - pow(cos_xita_F, 2));
162 }
163
164 x = firings[point_idx].distance * cos_theat * cos_xita_F;
165 y = firings[point_idx].distance * cos_theat * sin_xita_F;
166 z = firings[point_idx].distance * sin_theat;
167
168 if ((y >= config_.bottom_left_x() && y <= config_.top_right_x())
169 && (-x >= config_.bottom_left_y() && -x <= config_.top_right_y()))
170 return;
171 // modify
172 if (previous_packet_time > 1e-6) {
173 point_time = current_packet_time
174 - (POINTS_PER_PACKET - point_idx - 1)
176 / (POINTS_PER_PACKET);
177 } else { // fist packet
178 point_time = current_packet_time;
179 }
180
181 PointXYZIT* point = pc->add_point();
182 point->set_timestamp(point_time);
183 point->set_intensity(firings[point_idx].intensity);
184
185 if (config_.calibration()) {
187 firings[point_idx].vertical_line,
188 CH64w,
189 firings[point_idx].distance,
190 &corrections,
191 firings[point_idx].azimuth,
192 point);
193
194 } else {
195 if ((y >= config_.bottom_left_x() && y <= config_.top_right_x())
196 && (-x >= config_.bottom_left_y()
197 && -x <= config_.top_right_y())) {
198 point->set_x(nan);
199 point->set_y(nan);
200 point->set_z(nan);
201 point->set_timestamp(point_time);
202 point->set_intensity(0);
203 } else {
204 point->set_x(y);
205 point->set_y(-x);
206 point->set_z(z);
207 }
208 }
209 }
211}
212
213void LslidarCH64wParser::Order(std::shared_ptr<PointCloud> cloud) {}
214
215} // namespace parser
216} // namespace lslidar
217} // namespace drivers
218} // 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< apollo::drivers::PointCloud > &out_msg)
Set up for data processing.
void Order(std::shared_ptr< apollo::drivers::PointCloud > cloud)
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 RAD_TO_DEG
#define CH64w
class register implement
Definition arena_queue.h:37
used for unpacking the first two data bytes in a block