Apollo 10.0
自动驾驶开放平台
calibration.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
31
32#include <cmath>
33#include <fstream>
34#include <iostream>
35#include <limits>
36#include <string>
37#include <utility>
38
39#include "yaml-cpp/yaml.h"
40
41namespace YAML {
42
43// The >> operator disappeared in yaml-cpp 0.5, so this function is
44// added to provide support for code written under the yaml-cpp 0.3 API.
45template <typename T>
46void operator>>(const YAML::Node& node, T& i) {
47 i = node.as<T>();
48}
49} // namespace YAML
50
51namespace apollo {
52namespace drivers {
53namespace velodyne {
54
55const char* NUM_LASERS = "num_lasers";
56const char* LASERS = "lasers";
57const char* LASER_ID = "laser_id";
58const char* ROT_CORRECTION = "rot_correction";
59const char* VERT_CORRECTION = "vert_correction";
60const char* DIST_CORRECTION = "dist_correction";
61const char* TWO_PT_CORRECTION_AVAILABLE = "two_pt_correction_available";
62const char* DIST_CORRECTION_X = "dist_correction_x";
63const char* DIST_CORRECTION_Y = "dist_correction_y";
64const char* VERT_OFFSET_CORRECTION = "vert_offset_correction";
65const char* HORIZ_OFFSET_CORRECTION = "horiz_offset_correction";
66const char* MAX_INTENSITY = "max_intensity";
67const char* MIN_INTENSITY = "min_intensity";
68const char* FOCAL_DISTANCE = "focal_distance";
69const char* FOCAL_SLOPE = "focal_slope";
70
71void operator>>(const YAML::Node& node,
72 std::pair<int, LaserCorrection>& correction) {
73 node[LASER_ID] >> correction.first;
74 node[ROT_CORRECTION] >> correction.second.rot_correction;
75 node[VERT_CORRECTION] >> correction.second.vert_correction;
76 node[DIST_CORRECTION] >> correction.second.dist_correction;
77 node[DIST_CORRECTION_X] >> correction.second.dist_correction_x;
78 node[DIST_CORRECTION_Y] >> correction.second.dist_correction_y;
79 node[VERT_OFFSET_CORRECTION] >> correction.second.vert_offset_correction;
80 if (node[HORIZ_OFFSET_CORRECTION]) {
81 node[HORIZ_OFFSET_CORRECTION] >> correction.second.horiz_offset_correction;
82 } else {
83 correction.second.horiz_offset_correction = 0.0;
84 }
85
86 if (node[MAX_INTENSITY]) {
87 node[MAX_INTENSITY] >> correction.second.max_intensity;
88 } else {
89 correction.second.max_intensity = 255;
90 }
91
92 if (node[MIN_INTENSITY]) {
93 node[MIN_INTENSITY] >> correction.second.min_intensity;
94 } else {
95 correction.second.min_intensity = 0;
96 }
97
98 node[FOCAL_DISTANCE] >> correction.second.focal_distance;
99 node[FOCAL_SLOPE] >> correction.second.focal_slope;
100
101 // Calculate cached values
102 correction.second.cos_rot_correction = cosf(correction.second.rot_correction);
103 correction.second.sin_rot_correction = sinf(correction.second.rot_correction);
104 correction.second.cos_vert_correction =
105 cosf(correction.second.vert_correction);
106 correction.second.sin_vert_correction =
107 sinf(correction.second.vert_correction);
108 correction.second.focal_offset =
109 256.0f * static_cast<float>(std::pow(
110 1 - correction.second.focal_distance / 13100.0f, 2));
111 correction.second.laser_ring = 0; // clear initially (set later)
112}
113
114void operator>>(const YAML::Node& node, Calibration& calibration) {
115 int num_lasers = 0;
116 node[NUM_LASERS] >> num_lasers;
117 const YAML::Node& lasers = node[LASERS];
118 calibration.laser_corrections_.clear();
119 calibration.num_lasers_ = num_lasers;
120
121 if (static_cast<int>(lasers.size()) != num_lasers) {
122 std::cerr << "num_lasers didn't match";
123 return;
124 }
125
126 for (int i = 0; i < num_lasers; i++) {
127 std::pair<int, LaserCorrection> correction;
128 lasers[i] >> correction;
129 calibration.laser_corrections_.insert(correction);
130 }
131
132 // For each laser ring, find the next-smallest vertical angle.
133 //
134 // This implementation is simple, but not efficient. That is OK,
135 // since it only runs while starting up.
136 double next_angle = -std::numeric_limits<double>::infinity();
137
138 for (int ring = 0; ring < num_lasers; ++ring) {
139 // find minimum remaining vertical offset correction
140 double min_seen = std::numeric_limits<double>::infinity();
141 int next_index = num_lasers;
142
143 for (int j = 0; j < num_lasers; ++j) {
144 double angle = calibration.laser_corrections_[j].vert_correction;
145
146 if (next_angle < angle && angle < min_seen) {
147 min_seen = angle;
148 next_index = j;
149 }
150 }
151
152 if (next_index < num_lasers) { // anything found in this ring?
153 // store this ring number with its corresponding laser number
154 calibration.laser_corrections_[next_index].laser_ring = ring;
155 next_angle = min_seen;
156 }
157 }
158}
159
160YAML::Emitter& operator<<(YAML::Emitter& out,
161 const std::pair<int, LaserCorrection>& correction) {
162 out << YAML::BeginMap;
163 out << YAML::Key << LASER_ID << YAML::Value << correction.first;
164 out << YAML::Key << ROT_CORRECTION << YAML::Value
165 << correction.second.rot_correction;
166 out << YAML::Key << VERT_CORRECTION << YAML::Value
167 << correction.second.vert_correction;
168 out << YAML::Key << DIST_CORRECTION << YAML::Value
169 << correction.second.dist_correction;
170 out << YAML::Key << DIST_CORRECTION_X << YAML::Value
171 << correction.second.dist_correction_x;
172 out << YAML::Key << DIST_CORRECTION_Y << YAML::Value
173 << correction.second.dist_correction_y;
174 out << YAML::Key << VERT_OFFSET_CORRECTION << YAML::Value
175 << correction.second.vert_offset_correction;
176 out << YAML::Key << HORIZ_OFFSET_CORRECTION << YAML::Value
177 << correction.second.horiz_offset_correction;
178 out << YAML::Key << MAX_INTENSITY << YAML::Value
179 << correction.second.max_intensity;
180 out << YAML::Key << MIN_INTENSITY << YAML::Value
181 << correction.second.min_intensity;
182 out << YAML::Key << FOCAL_DISTANCE << YAML::Value
183 << correction.second.focal_distance;
184 out << YAML::Key << FOCAL_SLOPE << YAML::Value
185 << correction.second.focal_slope;
186 out << YAML::EndMap;
187 return out;
188}
189
190YAML::Emitter& operator<<(YAML::Emitter& out, const Calibration& calibration) {
191 out << YAML::BeginMap;
192 out << YAML::Key << NUM_LASERS << YAML::Value
193 << calibration.laser_corrections_.size();
194 out << YAML::Key << LASERS << YAML::Value << YAML::BeginSeq;
195
196 for (std::map<int, LaserCorrection>::const_iterator it =
197 calibration.laser_corrections_.begin();
198 it != calibration.laser_corrections_.end(); ++it) {
199 out << *it;
200 }
201
202 out << YAML::EndSeq;
203 out << YAML::EndMap;
204 return out;
205}
206
207void Calibration::read(const std::string& calibration_file) {
208 std::ifstream fin(calibration_file.c_str());
209
210 if (!fin.is_open()) {
211 initialized_ = false;
212 return;
213 }
214
215 initialized_ = true;
216
217 try {
218 YAML::Node doc;
219 fin.close();
220 doc = YAML::LoadFile(calibration_file);
221 doc >> *this;
222 } catch (YAML::Exception& e) {
223 std::cerr << "YAML Exception: " << e.what() << std::endl;
224 initialized_ = false;
225 }
226
227 fin.close();
228}
229
230void Calibration::write(const std::string& calibration_file) {
231 std::ofstream fout(calibration_file.c_str());
232 YAML::Emitter out;
233 out << *this;
234 fout << out.c_str();
235 fout.close();
236}
237
238} // namespace velodyne
239} // namespace drivers
240} // namespace apollo
Calibration class storing entire configuration for the Velodyne
Definition calibration.h:68
void write(const std::string &calibration_file)
void read(const std::string &calibration_file)
std::map< int, LaserCorrection > laser_corrections_
Definition calibration.h:70
void operator>>(const YAML::Node &node, T &i)
YAML::Emitter & operator<<(YAML::Emitter &out, const std::pair< int, LaserCorrection > &correction)
const char * DIST_CORRECTION_X
const char * VERT_OFFSET_CORRECTION
const char * TWO_PT_CORRECTION_AVAILABLE
const char * HORIZ_OFFSET_CORRECTION
const char * DIST_CORRECTION_Y
void operator>>(const YAML::Node &node, std::pair< int, LaserCorrection > &correction)
class register implement
Definition arena_queue.h:37