46 {
47 omp_set_num_threads(1);
48
50
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
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
80 std::vector<std::pair<double, double>> pos_history(20, {0.0, 0.0});
82 ADEBUG <<
"Obstacle [" <<
id <<
"] failed to extract obstacle history";
83 return false;
84 }
85
86
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
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
111 std::vector<double> pred_traj;
112
113 auto start_time = std::chrono::system_clock::now();
114 if (obstacle_ptr->IsPedestrian()) {
118 input_buffers, 3, &output_buffers, 1)) {
119 return false;
120 }
121 } else {
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
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) {
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}
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
bool ExtractObstacleHistory(Obstacle *obstacle_ptr, std::vector< std::pair< double, double > > *pos_history)
Extract obstacle history
void Clear()
Clear obstacle feature map
bool GetMapById(const int obstacle_id, cv::Mat *feature_map)