Apollo 10.0
自动驾驶开放平台
semantic_lstm_evaluator.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2019 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
19#include <omp.h>
20
21#include "Eigen/Dense"
22#include "cyber/common/file.h"
27
28namespace apollo {
29namespace prediction {
30
33
35 : semantic_map_(semantic_map) {
37 torch_default_output_tensor_ = torch::zeros({1, 30, 2});
38 model_manager_ = ModelManager();
39 model_manager_.Init();
40 LoadModel();
41}
42
44
46 ObstaclesContainer* obstacles_container) {
47 omp_set_num_threads(1);
48
49 obstacle_ptr->SetEvaluatorType(evaluator_type_);
50
51 Clear();
52 CHECK_NOTNULL(obstacle_ptr);
53 int id = obstacle_ptr->id();
54 if (!obstacle_ptr->latest_feature().IsInitialized()) {
55 AERROR << "Obstacle [" << id << "] has no latest feature.";
56 return false;
57 }
58 Feature* latest_feature_ptr = obstacle_ptr->mutable_latest_feature();
59 CHECK_NOTNULL(latest_feature_ptr);
60
61 if (!FLAGS_enable_semantic_map) {
62 ADEBUG << "Not enable semantic map, exit semantic_lstm_evaluator.";
63 return false;
64 }
65 cv::Mat feature_map;
66 if (!semantic_map_->GetMapById(id, &feature_map)) {
67 return false;
68 }
69 // Process the feature_map
70 cv::cvtColor(feature_map, feature_map, cv::COLOR_BGR2RGB);
71 cv::Mat img_float;
72 feature_map.convertTo(img_float, CV_32F, 1.0 / 255);
73 torch::Tensor img_tensor = torch::from_blob(img_float.data, {1, 224, 224, 3});
74 img_tensor = img_tensor.permute({0, 3, 1, 2});
75 img_tensor[0][0] = img_tensor[0][0].sub(0.485).div(0.229);
76 img_tensor[0][1] = img_tensor[0][1].sub(0.456).div(0.224);
77 img_tensor[0][2] = img_tensor[0][2].sub(0.406).div(0.225);
78
79 // Extract features of pos_history
80 std::vector<std::pair<double, double>> pos_history(20, {0.0, 0.0});
81 if (!ExtractObstacleHistory(obstacle_ptr, &pos_history)) {
82 ADEBUG << "Obstacle [" << id << "] failed to extract obstacle history";
83 return false;
84 }
85 // Process obstacle_history
86 // TODO(Hongyi): move magic numbers to parameters and gflags
87 torch::Tensor obstacle_pos = torch::zeros({1, 20, 2});
88 torch::Tensor obstacle_pos_step = torch::zeros({1, 20, 2});
89 for (int i = 0; i < 20; ++i) {
90 obstacle_pos[0][19 - i][0] = pos_history[i].first;
91 obstacle_pos[0][19 - i][1] = pos_history[i].second;
92 if (i == 19 || (i > 0 && pos_history[i].first == 0.0)) {
93 break;
94 }
95 obstacle_pos_step[0][19 - i][0] =
96 pos_history[i].first - pos_history[i + 1].first;
97 obstacle_pos_step[0][19 - i][1] =
98 pos_history[i].second - pos_history[i + 1].second;
99 }
100
101 // Build input features for torch
102 std::vector<void*> input_buffers{
103 img_tensor.data_ptr<float>(),
104 obstacle_pos.data_ptr<float>(),
105 obstacle_pos_step.data_ptr<float>()
106 };
107 std::vector<void*> output_buffers{
108 torch_default_output_tensor_.data_ptr<float>()};
109
110 // Compute pred_traj
111 std::vector<double> pred_traj;
112
113 auto start_time = std::chrono::system_clock::now();
114 if (obstacle_ptr->IsPedestrian()) {
115 if (!model_manager_.SelectModel(
118 input_buffers, 3, &output_buffers, 1)) {
119 return false;
120 }
121 } else {
122 if (!model_manager_.SelectModel(
125 input_buffers, 3, &output_buffers, 1)) {
126 return false;
127 }
128 }
129 at::Tensor torch_output_tensor = torch::from_blob(
130 output_buffers[0], {1, 30, 2});
131
132 auto end_time = std::chrono::system_clock::now();
133 std::chrono::duration<double> diff = end_time - start_time;
134 ADEBUG << "Semantic_LSTM_evaluator used time: " << diff.count() * 1000
135 << " ms.";
136 auto torch_output = torch_output_tensor.accessor<float, 3>();
137
138 // Get the trajectory
139 double pos_x = latest_feature_ptr->position().x();
140 double pos_y = latest_feature_ptr->position().y();
141 Trajectory* trajectory = latest_feature_ptr->add_predicted_trajectory();
142 trajectory->set_probability(1.0);
143
144 for (int i = 0; i < 30; ++i) {
145 double prev_x = pos_x;
146 double prev_y = pos_y;
147 if (i > 0) {
148 const auto& last_point = trajectory->trajectory_point(i - 1).path_point();
149 prev_x = last_point.x();
150 prev_y = last_point.y();
151 }
152 TrajectoryPoint* point = trajectory->add_trajectory_point();
153 double dx = static_cast<double>(torch_output[0][i][0]);
154 double dy = static_cast<double>(torch_output[0][i][1]);
155
156 double heading = latest_feature_ptr->velocity_heading();
157 Vec2d offset(dx, dy);
158 Vec2d rotated_offset = offset.rotate(heading);
159 double point_x = pos_x + rotated_offset.x();
160 double point_y = pos_y + rotated_offset.y();
161 point->mutable_path_point()->set_x(point_x);
162 point->mutable_path_point()->set_y(point_y);
163
164 if (torch_output_tensor.sizes()[2] == 5) {
165 double sigma_xr = std::abs(static_cast<double>(torch_output[0][i][2]));
166 double sigma_yr = std::abs(static_cast<double>(torch_output[0][i][3]));
167 double corr_r = static_cast<double>(torch_output[0][i][4]);
168 Eigen::Matrix2d cov_matrix_r;
169 cov_matrix_r(0, 0) = sigma_xr * sigma_xr;
170 cov_matrix_r(0, 1) = corr_r * sigma_xr * sigma_yr;
171 cov_matrix_r(1, 0) = corr_r * sigma_xr * sigma_yr;
172 cov_matrix_r(1, 1) = sigma_yr * sigma_yr;
173
174 Eigen::Matrix2d rotation_matrix;
175 rotation_matrix(0, 0) = std::cos(heading);
176 rotation_matrix(0, 1) = -std::sin(heading);
177 rotation_matrix(1, 0) = std::sin(heading);
178 rotation_matrix(1, 1) = std::cos(heading);
179
180 Eigen::Matrix2d cov_matrix;
181 cov_matrix =
182 rotation_matrix * cov_matrix_r * (rotation_matrix.transpose());
183 double sigma_x = std::sqrt(std::abs(cov_matrix(0, 0)));
184 double sigma_y = std::sqrt(std::abs(cov_matrix(1, 1)));
185 double corr = cov_matrix(0, 1) / (sigma_x + FLAGS_double_precision) /
186 (sigma_y + FLAGS_double_precision);
187
188 point->mutable_gaussian_info()->set_sigma_x(sigma_x);
189 point->mutable_gaussian_info()->set_sigma_y(sigma_y);
190 point->mutable_gaussian_info()->set_correlation(corr);
191
192 if (i > 0) {
193 Eigen::EigenSolver<Eigen::Matrix2d> eigen_solver(cov_matrix);
194 const auto& eigen_values = eigen_solver.eigenvalues();
195 const auto& eigen_vectors = eigen_solver.eigenvectors();
196 point->mutable_gaussian_info()->set_ellipse_a(
197 std::sqrt(std::abs(eigen_values(0).real())));
198 point->mutable_gaussian_info()->set_ellipse_b(
199 std::sqrt(std::abs(eigen_values(1).real())));
200 double cos_theta_a = eigen_vectors(0, 0).real();
201 double sin_theta_a = eigen_vectors(1, 0).real();
202 point->mutable_gaussian_info()->set_theta_a(
203 std::atan2(sin_theta_a, cos_theta_a));
204 }
205 }
206
207 if (i < 10) { // use origin heading for the first second
208 point->mutable_path_point()->set_theta(
209 latest_feature_ptr->velocity_heading());
210 } else {
211 point->mutable_path_point()->set_theta(
212 std::atan2(trajectory->trajectory_point(i).path_point().y() -
213 trajectory->trajectory_point(i - 1).path_point().y(),
214 trajectory->trajectory_point(i).path_point().x() -
215 trajectory->trajectory_point(i - 1).path_point().x()));
216 }
217 point->set_relative_time(static_cast<double>(i) *
218 FLAGS_prediction_trajectory_time_resolution);
219 if (i == 0) {
220 point->set_v(latest_feature_ptr->speed());
221 } else {
222 double diff_x = point_x - prev_x;
223 double diff_y = point_y - prev_y;
224 point->set_v(std::hypot(diff_x, diff_y) /
225 FLAGS_prediction_trajectory_time_resolution);
226 }
227 }
228
229 return true;
230}
231
233 Obstacle* obstacle_ptr,
234 std::vector<std::pair<double, double>>* pos_history) {
235 pos_history->resize(20, {0.0, 0.0});
236 const Feature& obs_curr_feature = obstacle_ptr->latest_feature();
237 double obs_curr_heading = obs_curr_feature.velocity_heading();
238 std::pair<double, double> obs_curr_pos = std::make_pair(
239 obs_curr_feature.position().x(), obs_curr_feature.position().y());
240 for (std::size_t i = 0; i < obstacle_ptr->history_size() && i < 20; ++i) {
241 const Feature& feature = obstacle_ptr->feature(i);
242 if (!feature.IsInitialized()) {
243 break;
244 }
245 pos_history->at(i) = WorldCoordToObjCoord(
246 std::make_pair(feature.position().x(), feature.position().y()),
247 obs_curr_pos, obs_curr_heading);
248 }
249 return true;
250}
251
252void SemanticLSTMEvaluator::LoadModel() {
253 if (FLAGS_use_cuda &&
254 torch::cuda::is_available()) {
255 ADEBUG << "CUDA is available";
256 device_ = Model::GPU;
257 } else {
258 device_ = Model::CPU;
259 }
260 auto vehicle_model_ptr = model_manager_.SelectModel(
263
264 auto pedestrian_model_ptr = model_manager_.SelectModel(
267
268 ACHECK(vehicle_model_ptr->Init());
269 ACHECK(pedestrian_model_ptr->Init());
270}
271
272} // namespace prediction
273} // namespace apollo
Implements a class of 2-dimensional vectors.
Definition vec2d.h:42
double y() const
Getter for y component
Definition vec2d.h:57
Vec2d rotate(const double angle) const
rotate the vector by angle.
Definition vec2d.cc:65
double x() const
Getter for x component
Definition vec2d.h:54
std::pair< double, double > WorldCoordToObjCoord(std::pair< double, double > input_world_coord, std::pair< double, double > obj_world_coord, double obj_world_angle)
Definition evaluator.h:94
ObstacleConf::EvaluatorType evaluator_type_
Definition evaluator.h:156
std::shared_ptr< ModelBase > SelectModel(const Model::Backend &backend, const ObstacleConf::EvaluatorType &evaluator_type, const apollo::perception::PerceptionObstacle::Type &obstacle_type)
select the best model
Prediction obstacle.
Definition obstacle.h:52
Feature * mutable_latest_feature()
Get a pointer to the latest feature.
Definition obstacle.cc:88
int id() const
Get the obstacle's ID.
Definition obstacle.cc:60
size_t history_size() const
Get the number of historical features.
Definition obstacle.cc:93
const Feature & feature(const size_t i) const
Get the ith feature from latest to earliest.
Definition obstacle.cc:67
void SetEvaluatorType(const ObstacleConf::EvaluatorType &evaluator_type)
Definition obstacle.cc:1484
const Feature & latest_feature() const
Get the latest feature.
Definition obstacle.cc:78
bool ExtractObstacleHistory(Obstacle *obstacle_ptr, std::vector< std::pair< double, double > > *pos_history)
Extract obstacle history
bool Evaluate(Obstacle *obstacle_ptr, ObstaclesContainer *obstacles_container) override
Override Evaluate
bool GetMapById(const int obstacle_id, cv::Mat *feature_map)
#define ACHECK(cond)
Definition log.h:80
#define ADEBUG
Definition log.h:41
#define AERROR
Definition log.h:44
class register implement
Definition arena_queue.h:37
optional double velocity_heading
Definition feature.proto:93
optional apollo::common::Point3D position
Definition feature.proto:88
repeated apollo::common::TrajectoryPoint trajectory_point
Definition feature.proto:78