Apollo 10.0
自动驾驶开放平台
online_calibration_service.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2018 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 *****************************************************************************/
17
18#include <utility>
19
23
24namespace apollo {
25namespace perception {
26namespace camera {
27
29 const CalibrationServiceInitOptions &options) {
30 master_sensor_name_ = options.calibrator_working_sensor_name;
31 sensor_name_ = options.calibrator_working_sensor_name;
32 // Init k_matrix
33 auto &name_intrinsic_map = options.name_intrinsic_map;
34 ACHECK(name_intrinsic_map.find(master_sensor_name_) !=
35 name_intrinsic_map.end());
36 CameraStatus camera_status;
37 name_camera_status_map_.clear();
38 for (auto iter = name_intrinsic_map.begin(); iter != name_intrinsic_map.end();
39 ++iter) {
40 camera_status.k_matrix[0] = static_cast<double>(iter->second(0, 0));
41 camera_status.k_matrix[4] = static_cast<double>(iter->second(1, 1));
42 camera_status.k_matrix[2] = static_cast<double>(iter->second(0, 2));
43 camera_status.k_matrix[5] = static_cast<double>(iter->second(1, 2));
44 camera_status.k_matrix[8] = 1.0;
45 name_camera_status_map_.insert(
46 std::pair<std::string, CameraStatus>(iter->first, camera_status));
47 }
48 // Only init calibrator on master_sensor
49 CalibratorInitOptions calibrator_init_options;
50 calibrator_init_options.image_width = options.image_width;
51 calibrator_init_options.image_height = options.image_height;
52 calibrator_init_options.focal_x = static_cast<float>(
53 name_camera_status_map_[master_sensor_name_].k_matrix[0]);
54 calibrator_init_options.focal_y = static_cast<float>(
55 name_camera_status_map_[master_sensor_name_].k_matrix[4]);
56 calibrator_init_options.cx = static_cast<float>(
57 name_camera_status_map_[master_sensor_name_].k_matrix[2]);
58 calibrator_init_options.cy = static_cast<float>(
59 name_camera_status_map_[master_sensor_name_].k_matrix[5]);
60 calibrator_.reset(
61 BaseCalibratorRegisterer::GetInstanceByName(options.calibrator_method));
62 ACHECK(calibrator_ != nullptr);
63 ACHECK(calibrator_->Init(calibrator_init_options))
64 << "Failed to init " << options.calibrator_method;
65 return true;
66}
67
69 is_service_ready_ = HasSetIntrinsics() && HasSetGroundPlane();
70 return is_service_ready_;
71}
72
74 double *depth) const {
75 if (!is_service_ready_) {
76 return false;
77 }
78 ACHECK(depth != nullptr);
79 double pixel[2] = {static_cast<double>(x), static_cast<double>(y)};
80 double point[3] = {0};
81
82 auto iter = name_camera_status_map_.find(sensor_name_);
84 pixel, &(iter->second.k_matrix[0]), &(iter->second.ground_plane[0]),
85 point);
86 if (!success) {
87 *depth = 0.0;
88 return false;
89 }
90
91 *depth = point[2];
92 return true;
93}
94
96 int x, int y, Eigen::Vector3d *point3d) const {
97 if (!is_service_ready_) {
98 return false;
99 }
100 ACHECK(point3d != nullptr);
101 double pixel[2] = {static_cast<double>(x), static_cast<double>(y)};
102 double point[3] = {0};
103 auto iter = name_camera_status_map_.find(sensor_name_);
105 pixel, &(iter->second.k_matrix[0]), &(iter->second.ground_plane[0]),
106 point);
107 if (!success) {
108 (*point3d)(0) = (*point3d)(1) = (*point3d)(2) = 0.0;
109 return false;
110 }
111
112 (*point3d)(0) = point[0];
113 (*point3d)(1) = point[1];
114 (*point3d)(2) = point[2];
115 return true;
116}
117
119 Eigen::Vector4d *plane_param) const {
120 if (plane_param == nullptr) {
121 AERROR << "plane_param is nullptr";
122 return false;
123 }
124 if (!is_service_ready_) {
125 (*plane_param)(0) = (*plane_param)(1) = (*plane_param)(2) =
126 (*plane_param)(3) = 0.0;
127 return false;
128 }
129 auto iter = name_camera_status_map_.find(sensor_name_);
130 (*plane_param)(0) = iter->second.ground_plane[0];
131 (*plane_param)(1) = iter->second.ground_plane[1];
132 (*plane_param)(2) = iter->second.ground_plane[2];
133 (*plane_param)(3) = iter->second.ground_plane[3];
134 return true;
135}
136
138 float *height, float *pitch) const {
139 if (height == nullptr) {
140 AERROR << "height is nullptr";
141 return false;
142 }
143 if (pitch == nullptr) {
144 AERROR << "pitch is nullptr";
145 return false;
146 }
147 if (!is_service_ready_) {
148 *height = *pitch = 0.0;
149 return false;
150 }
151 auto iter = name_camera_status_map_.find(sensor_name_);
152 *height = iter->second.camera_ground_height;
153 *pitch = iter->second.pitch_angle;
154 return true;
155}
156
158 if (frame == nullptr) {
159 AERROR << "frame is nullptr";
160 return;
161 }
162 sensor_name_ = frame->data_provider->sensor_name();
163 if (sensor_name_ == master_sensor_name_) {
164 CalibratorOptions calibrator_options;
165 // todo(daohu527) need complete
166 // calibrator_options.lane_objects =
167 // std::make_shared<std::vector<base::LaneLine>>(frame->lane_objects);
168 calibrator_options.camera2world_pose.reset(
169 new Eigen::Affine3d(frame->camera2world_pose));
170 calibrator_options.timestamp = &(frame->timestamp);
171 float pitch_angle = 0.f;
172 bool updated = calibrator_->Calibrate(calibrator_options, &pitch_angle);
173 // rebuild the service when updated
174 if (updated) {
175 name_camera_status_map_[master_sensor_name_].pitch_angle = pitch_angle;
176 for (auto iter = name_camera_status_map_.begin();
177 iter != name_camera_status_map_.end(); iter++) {
178 // update pitch angle
179 iter->second.pitch_angle =
180 iter->second.pitch_angle_diff +
181 name_camera_status_map_[master_sensor_name_].pitch_angle;
182 // update ground plane param
183 iter->second.ground_plane[1] = cos(iter->second.pitch_angle);
184 iter->second.ground_plane[2] = -sin(iter->second.pitch_angle);
185 }
186 }
187 }
188 auto iter = name_camera_status_map_.find(sensor_name_);
189 AINFO << "camera_ground_height: " << iter->second.camera_ground_height
190 << " meter.";
191 AINFO << "pitch_angle: " << iter->second.pitch_angle * 180.0 / M_PI
192 << " degree.";
193 // ACHECK(BuildIndex());
194 is_service_ready_ = true;
195}
196
198 if (frame == nullptr) {
199 AERROR << "frame is nullptr";
200 return;
201 }
202 sensor_name_ = frame->data_provider->sensor_name();
203 if (sensor_name_ == master_sensor_name_) {
204 CalibratorOptions calibrator_options;
205
206 calibrator_options.lane_objects =
207 std::make_shared<std::vector<base::LaneLine>>(frame->lane_objects);
208 calibrator_options.camera2world_pose.reset(
209 new Eigen::Affine3d(frame->camera2world_pose));
210 calibrator_options.timestamp = &(frame->timestamp);
211 float pitch_angle = 0.f;
212 bool updated = calibrator_->Calibrate(calibrator_options, &pitch_angle);
213 // rebuild the service when updated
214 if (updated) {
215 name_camera_status_map_[master_sensor_name_].pitch_angle = pitch_angle;
216 for (auto iter = name_camera_status_map_.begin();
217 iter != name_camera_status_map_.end(); iter++) {
218 // update pitch angle
219 iter->second.pitch_angle =
220 iter->second.pitch_angle_diff +
221 name_camera_status_map_[master_sensor_name_].pitch_angle;
222 // update ground plane param
223 iter->second.ground_plane[1] = cos(iter->second.pitch_angle);
224 iter->second.ground_plane[2] = -sin(iter->second.pitch_angle);
225 }
226 }
227 }
228 auto iter = name_camera_status_map_.find(sensor_name_);
229 AINFO << "camera_ground_height: " << iter->second.camera_ground_height
230 << " meter.";
231 AINFO << "pitch_angle: " << iter->second.pitch_angle * 180.0 / M_PI
232 << " degree.";
233 // ACHECK(BuildIndex());
234 is_service_ready_ = true;
235}
236
238 const std::map<std::string, float> &name_camera_ground_height_map,
239 const std::map<std::string, float> &name_camera_pitch_angle_diff_map,
240 const float &pitch_angle_master_sensor) {
241 name_camera_status_map_[master_sensor_name_].pitch_angle =
242 pitch_angle_master_sensor;
243 for (auto iter = name_camera_status_map_.begin();
244 iter != name_camera_status_map_.end(); ++iter) {
245 // get iters
246 auto iter_ground_height = name_camera_ground_height_map.find(iter->first);
247 auto iter_pitch_angle_diff =
248 name_camera_pitch_angle_diff_map.find(iter->first);
249 ACHECK(iter_ground_height != name_camera_ground_height_map.end());
250 ACHECK(iter_pitch_angle_diff != name_camera_pitch_angle_diff_map.end());
251 // set camera status
252 name_camera_status_map_[iter->first].camera_ground_height =
253 iter_ground_height->second;
254 name_camera_status_map_[iter->first].pitch_angle_diff =
255 iter_pitch_angle_diff->second;
256 name_camera_status_map_[iter->first].pitch_angle =
257 pitch_angle_master_sensor + iter_pitch_angle_diff->second;
258 name_camera_status_map_[iter->first].ground_plane[1] =
259 cos(name_camera_status_map_[iter->first].pitch_angle);
260 name_camera_status_map_[iter->first].ground_plane[2] =
261 -sin(name_camera_status_map_[iter->first].pitch_angle);
262 name_camera_status_map_[iter->first].ground_plane[3] =
263 -name_camera_status_map_[iter->first].camera_ground_height;
264 }
265}
266
268
269} // namespace camera
270} // namespace perception
271} // namespace apollo
#define REGISTER_CALIBRATION_SERVICE(name)
bool QueryGroundPlaneInCameraFrame(Eigen::Vector4d *plane_param) const override
void SetCameraHeightAndPitch(const std::map< std::string, float > &name_camera_ground_height_map, const std::map< std::string, float > &name_camera_pitch_angle_diff_map, const float &pitch_angle_master_sensor) override
bool QueryCameraToGroundHeightAndPitchAngle(float *height, float *pitch) const override
bool QueryDepthOnGroundPlane(int x, int y, double *depth) const override
bool Init(const CalibrationServiceInitOptions &options=CalibrationServiceInitOptions()) override
bool QueryPoint3dOnGroundPlane(int x, int y, Eigen::Vector3d *point3d) const override
#define ACHECK(cond)
Definition log.h:80
#define AERROR
Definition log.h:44
#define AINFO
Definition log.h:42
bool IBackprojectPlaneIntersectionCanonical(const T *x, const T *K, const T *pi, T *X)
Definition i_util.h:197
class register implement
Definition arena_queue.h:37
apollo::common::EigenMap< std::string, Eigen::Matrix3f > name_intrinsic_map
std::shared_ptr< std::vector< base::LaneLine > > lane_objects
std::shared_ptr< Eigen::Affine3d > camera2world_pose
std::vector< base::LaneLine > lane_objects
std::vector< std::shared_ptr< DataProvider > > data_provider
std::shared_ptr< camera::DataProvider > data_provider