Apollo 10.0
自动驾驶开放平台
velodyne_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
17#include "cyber/cyber.h"
18
21
22namespace apollo {
23namespace drivers {
24namespace velodyne {
25
26uint64_t VelodyneParser::GetGpsStamp(double current_packet_stamp,
27 double *previous_packet_stamp,
28 uint64_t *gps_base_usec) {
29 if (current_packet_stamp < *previous_packet_stamp) {
30 // plus 3600 when large jump back, discard little jump back for wrong time
31 // in lidar
32 if (std::abs(*previous_packet_stamp - current_packet_stamp) > 3599000000) {
33 *gps_base_usec += static_cast<uint64_t>(3600 * 1e6);
34 AINFO << "Base time plus 3600s. Model: " << config_.model() << std::fixed
35 << ". current:" << current_packet_stamp
36 << ", last time:" << *previous_packet_stamp;
37 } else {
38 AWARN << "Current stamp:" << std::fixed << current_packet_stamp
39 << " less than previous stamp:" << *previous_packet_stamp
40 << ". GPS time stamp maybe incorrect!";
41 }
42 } else if (*previous_packet_stamp != 0 &&
43 current_packet_stamp - *previous_packet_stamp > 100000) { // 100ms
44 AERROR << "Current stamp:" << std::fixed << current_packet_stamp
45 << " ahead previous stamp:" << *previous_packet_stamp
46 << " over 100ms. GPS time stamp incorrect!";
47 }
48
49 *previous_packet_stamp = current_packet_stamp;
50 uint64_t gps_stamp =
51 *gps_base_usec + static_cast<uint64_t>(current_packet_stamp);
52
53 gps_stamp = gps_stamp * 1000;
54 return gps_stamp;
55}
56
58 PointXYZIT nan_point;
59 nan_point.set_timestamp(timestamp);
60 nan_point.set_x(nan);
61 nan_point.set_y(nan);
62 nan_point.set_z(nan);
63 nan_point.set_intensity(0);
64 return nan_point;
65}
66
68 : last_time_stamp_(0), config_(config), mode_(STRONGEST) {}
69
70void VelodyneParser::init_angle_params(double view_direction,
71 double view_width) {
72 // converting angle parameters into the velodyne reference (rad)
73 double tmp_min_angle = view_direction + view_width / 2;
74 double tmp_max_angle = view_direction - view_width / 2;
75
76 // computing positive modulo to keep theses angles into [0;2*M_PI]
77 tmp_min_angle = fmod(fmod(tmp_min_angle, 2 * M_PI) + 2 * M_PI, 2 * M_PI);
78 tmp_max_angle = fmod(fmod(tmp_max_angle, 2 * M_PI) + 2 * M_PI, 2 * M_PI);
79
80 // converting into the hardware velodyne ref (negative yaml and degrees)
81 // adding 0.5 performs a centered double to int conversion
82 config_.set_min_angle(100 * (2 * M_PI - tmp_min_angle) * 180 / M_PI + 0.5);
83 config_.set_max_angle(100 * (2 * M_PI - tmp_max_angle) * 180 / M_PI + 0.5);
85 // avoid returning empty cloud if min_angle = max_angle
86 config_.set_min_angle(0);
87 config_.set_max_angle(36000);
88 }
89}
90
95
97 AFATAL << "Unable to open calibration file: "
99 }
100 }
101
102 // setup angle parameters.
105 ROTATION_RESOLUTION);
106}
107
108bool VelodyneParser::is_scan_valid(int rotation, float range) {
109 // check range first
110 if (range < config_.min_range() || range > config_.max_range()) {
111 return false;
112 }
113 // condition added to avoid calculating points which are not
114 // in the interesting defined area (min_angle < area < max_angle)
115 // not used now
116 // if ((config_.min_angle > config_.max_angle && (rotation <=
117 // config_.max_angle || rotation >= config_.min_angle))
118 // || (config_.min_angle < config_.max_angle && rotation >=
119 // config_.min_angle
120 // && rotation <= config_.max_angle)) {
121 // return true;
122 // }
123 return true;
124}
125
126void VelodyneParser::ComputeCoords(const float &raw_distance,
127 const LaserCorrection &corrections,
128 const uint16_t rotation, PointXYZIT *point) {
129 // ROS_ASSERT_MSG(rotation < 36000, "rotation must between 0 and 35999");
130 assert(rotation <= 36000);
131 double x = 0.0;
132 double y = 0.0;
133 double z = 0.0;
134
135 double distance = raw_distance + corrections.dist_correction;
136
137 // cos(a-b) = cos(a)*cos(b) + sin(a)*sin(b)
138 // sin(a-b) = sin(a)*cos(b) - cos(a)*sin(b)
139 double cos_rot_angle =
140 cos_rot_table_[rotation] * corrections.cos_rot_correction +
141 sin_rot_table_[rotation] * corrections.sin_rot_correction;
142 double sin_rot_angle =
143 sin_rot_table_[rotation] * corrections.cos_rot_correction -
144 cos_rot_table_[rotation] * corrections.sin_rot_correction;
145
146 // double vert_offset = corrections.vert_offset_correction;
147
148 // Compute the distance in the xy plane (w/o accounting for rotation)
149 double xy_distance = distance * corrections.cos_vert_correction;
150
151 // Calculate temporal X, use absolute value.
152 double xx = fabs(xy_distance * sin_rot_angle -
153 corrections.horiz_offset_correction * cos_rot_angle);
154 // Calculate temporal Y, use absolute value
155 double yy = fabs(xy_distance * cos_rot_angle +
156 corrections.horiz_offset_correction * sin_rot_angle);
157
158 // Get 2points calibration values,Linear interpolation to get distance
159 // correction for X and Y, that means distance correction use
160 // different value at different distance
161 double distance_corr_x = 0;
162 double distance_corr_y = 0;
163
164 if (need_two_pt_correction_ && raw_distance <= 2500) {
165 distance_corr_x =
166 (corrections.dist_correction - corrections.dist_correction_x) *
167 (xx - 2.4) / 22.64 +
168 corrections.dist_correction_x; // 22.64 = 25.04 - 2.4
169 distance_corr_y =
170 (corrections.dist_correction - corrections.dist_correction_y) *
171 (yy - 1.93) / 23.11 +
172 corrections.dist_correction_y; // 23.11 = 25.04 - 1.93
173 } else {
174 distance_corr_x = distance_corr_y = corrections.dist_correction;
175 }
176
177 double distance_x = raw_distance + distance_corr_x;
178
179 xy_distance = distance_x * corrections.cos_vert_correction;
180 // xy_distance = distance_x * cos_vert_correction - vert_offset *
181 // sin_vert_correction;
182
183 x = xy_distance * sin_rot_angle -
184 corrections.horiz_offset_correction * cos_rot_angle;
185
186 double distance_y = raw_distance + distance_corr_y;
187 xy_distance = distance_y * corrections.cos_vert_correction;
188 // xy_distance = distance_y * cos_vert_correction - vert_offset *
189 // sin_vert_correction;
190 y = xy_distance * cos_rot_angle +
191 corrections.horiz_offset_correction * sin_rot_angle;
192
193 z = distance * corrections.sin_vert_correction +
194 corrections.vert_offset_correction;
195 // z = distance * sin_vert_correction + vert_offset * cos_vert_correction;
196
198 point->set_x(static_cast<float>(y));
199 point->set_y(static_cast<float>(-x));
200 point->set_z(static_cast<float>(z));
201}
202
204 Config config = source_config;
205 if (config.model() == VLP16) {
206 config.set_calibration_online(false);
207 return new Velodyne16Parser(config);
208 } else if (config.model() == HDL32E || config.model() == VLP32C) {
209 config.set_calibration_online(false);
210 return new Velodyne32Parser(config);
211 } else if (config.model() == HDL64E_S3S || config.model() == HDL64E_S3D ||
212 config.model() == HDL64E_S2) {
213 return new Velodyne64Parser(config);
214 } else if (config.model() == VLS128) {
215 return new Velodyne128Parser(config);
216 } else {
217 AERROR << "invalid model, must be 64E_S2|64E_S3S"
218 << "|64E_S3D_STRONGEST|64E_S3D_LAST|64E_S3D_DUAL|HDL32E|VLP16";
219 return nullptr;
220 }
221}
222
223} // namespace velodyne
224} // namespace drivers
225} // namespace apollo
void read(const std::string &calibration_file)
static VelodyneParser * CreateParser(Config config)
virtual void setup()
Set up for on-line operation.
bool is_scan_valid(int rotation, float distance)
uint64_t GetGpsStamp(double current_stamp, double *previous_stamp, uint64_t *gps_base_usec)
PointXYZIT get_nan_point(uint64_t timestamp)
void init_angle_params(double view_direction, double view_width)
void ComputeCoords(const float &raw_distance, const LaserCorrection &corrections, const uint16_t rotation, PointXYZIT *point)
Compute coords with the data in block
#define AERROR
Definition log.h:44
#define AFATAL
Definition log.h:45
#define AINFO
Definition log.h:42
#define AWARN
Definition log.h:43
void init_sin_cos_rot_table(float *sin_rot_table, float *cos_rot_table, uint16_t rotation, float rotation_resolution)
Definition util.cc:23
class register implement
Definition arena_queue.h:37
correction values for a single laser
Definition calibration.h:43
float sin_rot_correction
cached sine of rot_correction
Definition calibration.h:60
float cos_rot_correction
cached values calculated when the calibration file is read
Definition calibration.h:59
float cos_vert_correction
cached cosine of vert_correction
Definition calibration.h:61
float sin_vert_correction
cached sine of vert_correction
Definition calibration.h:62
Velodyne HDL-64E 3D LIDAR data accessors