Apollo 10.0
自动驾驶开放平台
laneline_calibrator.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 "absl/strings/str_cat.h"
19
20namespace apollo {
21namespace perception {
22namespace camera {
23
25 LocalCalibratorInitOptions local_options;
26 local_options.cx = options.cx;
27 local_options.cy = options.cy;
28 local_options.focal_x = options.focal_x;
29 local_options.focal_y = options.focal_y;
30 image_width_ = local_options.image_width = options.image_width;
31 image_height_ = local_options.image_height = options.image_height;
32 calibrator_.Init(local_options);
33 return true;
34}
35
37 float *pitch_angle) {
38 if (pitch_angle == nullptr) {
39 AERROR << "pitch_angle is not available";
40 return false;
41 }
42 EgoLane ego_lane;
43 if (!LoadEgoLaneline(*options.lane_objects, &ego_lane)) {
44 AINFO << "Failed to get the ego lane.";
45 return false;
46 }
47
48 double cam_ori[4] = {0};
49 cam_ori[3] = 1.0;
50
51 // Camera to world pose
52 Eigen::Affine3d c2w = *options.camera2world_pose;
53
54 double p2w[12] = {
55 c2w(0, 0), c2w(0, 1), c2w(0, 2), c2w(0, 3), c2w(1, 0), c2w(1, 1),
56 c2w(1, 2), c2w(1, 3), c2w(2, 0), c2w(2, 1), c2w(2, 2), c2w(2, 3),
57 };
58
59 ADEBUG << "c2w transform this frame:\n"
60 << p2w[0] << ", " << p2w[1] << ", " << p2w[2] << ", " << p2w[3] << "\n"
61 << p2w[4] << ", " << p2w[5] << ", " << p2w[6] << ", " << p2w[7] << "\n"
62 << p2w[8] << ", " << p2w[9] << ", " << p2w[10] << ", " << p2w[11];
63
64 algorithm::IMultAx3x4(p2w, cam_ori, cam_coord_cur_);
65 time_diff_ = kTimeDiffDefault;
66 yaw_rate_ = kYawRateDefault;
67 velocity_ = kVelocityDefault;
68
69 timestamp_cur_ = *options.timestamp;
70 if (!is_first_frame_) {
71 time_diff_ = fabsf(static_cast<float>(timestamp_cur_ - timestamp_pre_));
72 ADEBUG << timestamp_cur_ << " " << timestamp_pre_ << std::endl;
73 camera::GetYawVelocityInfo(time_diff_, cam_coord_cur_, cam_coord_pre_,
74 cam_coord_pre_pre_, &yaw_rate_, &velocity_);
75 std::string timediff_yawrate_velocity_text =
76 absl::StrCat("time_diff_: ", std::to_string(time_diff_).substr(0, 4),
77 " | yaw_rate_: ", std::to_string(yaw_rate_).substr(0, 4),
78 " | velocity_: ", std::to_string(velocity_).substr(0, 4));
79 ADEBUG << timediff_yawrate_velocity_text << std::endl;
80 }
81
82 bool updated =
83 calibrator_.Process(ego_lane, velocity_, yaw_rate_, time_diff_);
84 if (updated) {
85 *pitch_angle = calibrator_.get_pitch_estimation();
86 float vanishing_row = calibrator_.get_vanishing_row();
87 AINFO << "#updated pitch angle: " << *pitch_angle;
88 AINFO << "#vanishing row: " << vanishing_row;
89 }
90
91 if (!is_first_frame_) {
92 memcpy(cam_coord_pre_pre_, cam_coord_pre_, sizeof(double) * 3);
93 }
94 is_first_frame_ = false;
95 memcpy(cam_coord_pre_, cam_coord_cur_, sizeof(double) * 3);
96 timestamp_pre_ = timestamp_cur_;
97 return updated;
98}
99
100bool LaneLineCalibrator::LoadEgoLaneline(
101 const std::vector<base::LaneLine> &lane_objects, EgoLane *ego_lane) {
102 if (ego_lane == nullptr) {
103 AERROR << "ego_lane is not available";
104 return false;
105 }
106
107 bool found_ego_left = false;
108 bool found_ego_right = false;
109 // Using points from model fitting
110 for (size_t i = 0; i < lane_objects.size(); ++i) {
111 if (lane_objects[i].pos_type == base::LaneLinePositionType::EGO_LEFT) {
112 int num_points =
113 static_cast<int>(lane_objects[i].curve_image_point_set.size());
114 ego_lane->left_line.lane_point.resize(num_points);
115 const auto &curve = lane_objects[i].curve_image_coord;
116 float y_curve = 0.0f;
117 float x_curve = 0.0f;
118 float x_raw = 0.0f;
119 for (int j = 0; j < num_points; ++j) {
120 y_curve = lane_objects[i].curve_image_point_set[j].y;
121 x_curve = curve.a * algorithm::ICub(y_curve) +
122 curve.b * algorithm::ISqr(y_curve) + curve.c * y_curve +
123 curve.d;
124 x_raw = lane_objects[i].curve_image_point_set[j].x;
125 ego_lane->left_line.lane_point[j](1) = y_curve;
126 ego_lane->left_line.lane_point[j](0) = (x_curve + x_raw) / 2;
127 }
128 found_ego_left = true;
129 }
130 if (lane_objects[i].pos_type == base::LaneLinePositionType::EGO_RIGHT) {
131 int num_points =
132 static_cast<int>(lane_objects[i].curve_image_point_set.size());
133 ego_lane->right_line.lane_point.resize(num_points);
134 const auto &curve = lane_objects[i].curve_image_coord;
135 float y_curve = 0.0f;
136 float x_curve = 0.0f;
137 float x_raw = 0.0f;
138 for (int j = 0; j < num_points; ++j) {
139 y_curve = lane_objects[i].curve_image_point_set[j].y;
140 x_curve = curve.a * algorithm::ICub(y_curve) +
141 curve.b * algorithm::ISqr(y_curve) + curve.c * y_curve +
142 curve.d;
143 x_raw = lane_objects[i].curve_image_point_set[j].x;
144 ego_lane->right_line.lane_point[j](1) = y_curve;
145 ego_lane->right_line.lane_point[j](0) = (x_curve + x_raw) / 2;
146 }
147 found_ego_right = true;
148 }
149 if (found_ego_left && found_ego_right) {
150 return true;
151 }
152 }
153 return false;
154}
155
156// Register plugin.
158
159} // namespace camera
160} // namespace perception
161} // namespace apollo
#define REGISTER_CALIBRATOR(name)
bool Process(const EgoLane &lane, const float &velocity, const float &yaw_rate, const float &time_diff)
void Init(const LocalCalibratorInitOptions &options, const CalibratorParams *params=nullptr)
bool Init(const CalibratorInitOptions &options=CalibratorInitOptions()) override
bool Calibrate(const CalibratorOptions &options, float *pitch_angle) override
#define ADEBUG
Definition log.h:41
#define AERROR
Definition log.h:44
#define AINFO
Definition log.h:42
void IMultAx3x4(const T A[12], const T x[4], T Ax[3])
Definition i_blas.h:4380
@ EGO_LEFT
left lane marking of the ego lane
@ EGO_RIGHT
right lane marking of the ego lane
void GetYawVelocityInfo(const float &time_diff, const double cam_coord_cur[3], const double cam_coord_pre[3], const double cam_coord_pre_pre[3], float *yaw_rate, float *velocity)
class register implement
Definition arena_queue.h:37
std::shared_ptr< std::vector< base::LaneLine > > lane_objects
std::shared_ptr< Eigen::Affine3d > camera2world_pose
apollo::common::EigenVector< Eigen::Vector2f > lane_point