170 {
171 omp_set_num_threads(1);
172
174
176 CHECK_NOTNULL(obstacle_ptr);
177 int id = obstacle_ptr->id();
178 if (!obstacle_ptr->latest_feature().IsInitialized()) {
179 AERROR <<
"Obstacle [" <<
id <<
"] has no latest feature.";
180 return false;
181 }
182 Feature* latest_feature_ptr = obstacle_ptr->mutable_latest_feature();
183 CHECK_NOTNULL(latest_feature_ptr);
184
185 if (adc_trajectory_container == nullptr) {
186 AERROR <<
"Null adc trajectory container";
187 return false;
188 }
189
190 int obs_num =
191 obstacles_container->curr_frame_considered_obstacle_ids().size();
192
193 auto start_time_obs = std::chrono::system_clock::now();
194
195 torch::Tensor target_obstacle_pos = torch::zeros({20, 2});
196 torch::Tensor target_obstacle_pos_step = torch::zeros({20, 2});
197 torch::Tensor vector_mask = torch::zeros({450, 50});
198 torch::Tensor all_obstacle_pos = torch::zeros({obs_num, 20, 2});
199 torch::Tensor all_obs_p_id = torch::zeros({obs_num, 2});
200 torch::Tensor obs_length_tmp = torch::zeros({obs_num, 2});
201
203 obstacles_container,
204 &target_obstacle_pos,
205 &target_obstacle_pos_step,
206 &vector_mask,
207 &all_obstacle_pos,
208 &all_obs_p_id,
209 &obs_length_tmp)) {
210 AERROR <<
"Obstacle [" <<
id <<
"] processing obstacle position fails.";
211 return false;
212 }
213
214 auto end_time_obs = std::chrono::system_clock::now();
215 std::chrono::duration<double> diff_obs = end_time_obs - start_time_obs;
216 ADEBUG <<
"obstacle vectors used time: " << diff_obs.count() * 1000 <<
" ms.";
217
218
219
222 double pos_x = latest_feature_ptr->position().x();
223 double pos_y = latest_feature_ptr->position().y();
224 common::PointENU center_point;
225 center_point.set_x(pos_x);
226 center_point.set_y(pos_y);
227 double heading = latest_feature_ptr->velocity_heading();
228
229 auto start_time_query = std::chrono::system_clock::now();
230
231 if (!vector_net_.
query(center_point, heading, &map_feature, &map_p_id)) {
232 return false;
233 }
234
235 auto end_time_query = std::chrono::system_clock::now();
236 std::chrono::duration<double> diff_query = end_time_query - start_time_query;
237 ADEBUG <<
"vectors query used time: " << diff_query.count() * 1000 <<
" ms.";
238
239
240 int map_polyline_num = map_feature.size();
241 int data_length =
242 ((obs_num + map_polyline_num) < 450) ? (obs_num + map_polyline_num) : 450;
243
244
245 auto start_time_data_prep = std::chrono::system_clock::now();
246 int map_polyline_num_valid =
247 ((obs_num + map_polyline_num) < 450) ? map_polyline_num : (450 - obs_num);
248 map_polyline_num_valid =
249 map_polyline_num_valid > 0 ? map_polyline_num_valid : 0;
250 torch::Tensor map_data = torch::zeros({map_polyline_num_valid, 50, 9});
251 torch::Tensor all_map_p_id = torch::zeros({map_polyline_num_valid, 2});
252
254 &map_p_id,
255 obs_num,
256 &map_data,
257 &all_map_p_id,
258 &vector_mask)) {
259 AERROR <<
"Obstacle [" <<
id <<
"] processing map data fails.";
260 return false;
261 }
262
263
264 torch::Tensor polyline_mask = torch::zeros({450});
265 if (data_length < 450) {
266 polyline_mask.index_put_(
267 {torch::indexing::Slice(data_length, torch::indexing::None)}, 1);
268 }
269
270
271 torch::Tensor obs_pos_data = torch::cat(
272 {all_obstacle_pos.index(
273 {torch::indexing::Slice(),
274 torch::indexing::Slice(torch::indexing::None, -1),
275 torch::indexing::Slice()}),
276 all_obstacle_pos.index({torch::indexing::Slice(),
277 torch::indexing::Slice(1, torch::indexing::None),
278 torch::indexing::Slice()})},
279 2);
280
281 torch::Tensor obs_length = obs_length_tmp.unsqueeze(1).repeat({1, 19, 1});
282
283 torch::Tensor obs_attr_agent =
284 torch::tensor({11.0, 4.0}).unsqueeze(0).unsqueeze(0).repeat({1, 19, 1});
285 torch::Tensor obs_attr_other =
286 torch::tensor({10.0, 4.0}).unsqueeze(0).unsqueeze(0).repeat(
287 {(obs_num - 1), 19, 1});
288 torch::Tensor obs_attr = torch::cat({obs_attr_agent, obs_attr_other}, 0);
289
290
291 torch::Tensor obs_id =
292 torch::arange(500, obs_num + 500).unsqueeze(1).repeat(
293 {1, 19}).unsqueeze(2);
294
295 torch::Tensor obs_data_with_len = torch::cat({obs_pos_data, obs_length}, 2);
296 torch::Tensor obs_data_with_attr =
297 torch::cat({obs_data_with_len, obs_attr}, 2);
298 torch::Tensor obs_data_with_id = torch::cat({obs_data_with_attr, obs_id}, 2);
299 torch::Tensor obs_data_final =
300 torch::cat({torch::zeros({obs_num, (50 - 19), 9}), obs_data_with_id}, 1);
301
302
303 torch::Tensor data_tmp = torch::cat({obs_data_final, map_data}, 0);
304 torch::Tensor p_id_tmp = torch::cat({all_obs_p_id, all_map_p_id}, 0);
305 torch::Tensor vector_data;
306 torch::Tensor polyline_id;
307 if (data_length < 450) {
308 torch::Tensor data_zeros = torch::zeros({(450 - data_length), 50, 9});
309 torch::Tensor p_id_zeros = torch::zeros({(450 - data_length), 2});
310 vector_data = torch::cat({data_tmp, data_zeros}, 0);
311 polyline_id = torch::cat({p_id_tmp, p_id_zeros}, 0);
312 } else {
313 vector_data = data_tmp;
314 polyline_id = p_id_tmp;
315 }
316
317
318 auto rand_mask = torch::zeros({450}).toType(at::kBool);
319
320 auto bool_vector_mask = vector_mask.toType(at::kBool);
321 auto bool_polyline_mask = polyline_mask.toType(at::kBool);
322
323
324 std::vector<std::pair<double, double>> adc_traj_curr_pos(30, {0.0, 0.0});
325 torch::Tensor adc_trajectory = torch::zeros({1, 30, 6});
326 const auto& adc_traj = adc_trajectory_container->adc_trajectory();
327 size_t adc_traj_points_num = adc_traj.trajectory_point().size();
328 if (adc_traj_points_num < 1) {
329 AERROR <<
"adc_traj points num is " << adc_traj_points_num
330 << " adc traj points are not enough";
331 return false;
332 }
333 std::vector<TrajectoryPoint> adc_traj_points;
334
335
336 double time_interval = obstacle_ptr->latest_feature().timestamp() -
337 adc_traj.header().timestamp_sec();
338 for (size_t i = 0; i < adc_traj_points_num - 1; ++i) {
339 double delta_time = time_interval -
340 adc_traj.trajectory_point(0).relative_time();
341 adc_traj_points.emplace_back(
343 adc_traj.trajectory_point(i),
344 adc_traj.trajectory_point(i + 1), delta_time));
345 }
347 obstacle_ptr, &adc_traj_curr_pos)) {
348 AERROR <<
"Failed to extract adc trajectory";
349 return false;
350 }
351 size_t traj_points_num = adc_traj_points.size();
352 for (size_t j = 0; j < 30; ++j) {
353 if (j > traj_points_num - 1) {
354 adc_trajectory[0][j][0] =
355 adc_traj_curr_pos[traj_points_num - 1].first;
356 adc_trajectory[0][j][1] =
357 adc_traj_curr_pos[traj_points_num - 1].second;
358 adc_trajectory[0][j][2] =
359 adc_traj_points[traj_points_num - 1].path_point().theta();
360 adc_trajectory[0][j][3] =
361 adc_traj_points[traj_points_num - 1].v();
362 adc_trajectory[0][j][4] =
363 adc_traj_points[traj_points_num - 1].a();
364 adc_trajectory[0][j][5] =
365 adc_traj_points[traj_points_num - 1].path_point().kappa();
366 } else {
367 adc_trajectory[0][j][0] =
368 adc_traj_curr_pos[j].first;
369 adc_trajectory[0][j][1] =
370 adc_traj_curr_pos[j].second;
371 adc_trajectory[0][j][2] =
372 adc_traj_points[j].path_point().theta();
373 adc_trajectory[0][j][3] =
374 adc_traj_points[j].v();
375 adc_trajectory[0][j][4] =
376 adc_traj_points[j].a();
377 adc_trajectory[0][j][5] =
378 adc_traj_points[j].path_point().kappa();
379 }
380 }
381
382
383 std::vector<torch::jit::IValue> torch_inputs;
384 auto X_value = c10::ivalue::Tuple::create(
385 {std::move(target_obstacle_pos.unsqueeze(0).to(device_)),
386 std::move(target_obstacle_pos_step.unsqueeze(0).to(device_)),
387 std::move(vector_data.unsqueeze(0).to(device_)),
388 std::move(bool_vector_mask.unsqueeze(0).to(device_)),
389 std::move(bool_polyline_mask.unsqueeze(0).to(device_)),
390 std::move(rand_mask.unsqueeze(0).to(device_)),
391 std::move(polyline_id.unsqueeze(0).to(device_))});
392 torch_inputs.push_back(c10::ivalue::Tuple::create(
393 {X_value, std::move(adc_trajectory.to(device_))}));
394
395 auto end_time_data_prep = std::chrono::system_clock::now();
396 std::chrono::duration<double> diff_data_prep =
397 end_time_data_prep - start_time_data_prep;
398 ADEBUG <<
"vectornet input tensor prepration used time: "
399 << diff_data_prep.count() * 1000 << " ms.";
400
401
402 auto start_time_inference = std::chrono::system_clock::now();
403 at::Tensor torch_output_tensor = torch_default_output_tensor_;
404 torch_output_tensor =
405 torch_vehicle_model_.forward(torch_inputs).toTensor().to(torch::kCPU);
406
407 auto end_time_inference = std::chrono::system_clock::now();
408 std::chrono::duration<double> diff_inference =
409 end_time_inference - start_time_inference;
410 ADEBUG <<
"vectornet-interaction inference used time: "
411 << diff_inference.count() * 1000
412 << " ms.";
413
414
415 auto torch_output = torch_output_tensor.accessor<float, 3>();
416 Trajectory* trajectory = latest_feature_ptr->add_predicted_trajectory();
417 trajectory->set_probability(1.0);
418
419 for (int i = 0; i < 30; ++i) {
420 double prev_x = pos_x;
421 double prev_y = pos_y;
422 if (i > 0) {
423 const auto& last_point = trajectory->trajectory_point(i - 1).path_point();
424 prev_x = last_point.x();
425 prev_y = last_point.y();
426 }
427 TrajectoryPoint* point = trajectory->add_trajectory_point();
428 double dx = static_cast<double>(torch_output[0][i][0]);
429 double dy = static_cast<double>(torch_output[0][i][1]);
430
431 double heading = latest_feature_ptr->velocity_heading();
432 Vec2d offset(dx, dy);
433 Vec2d rotated_offset = offset.rotate(heading - (M_PI / 2));
434 double point_x = pos_x + rotated_offset.x();
435 double point_y = pos_y + rotated_offset.y();
436 point->mutable_path_point()->set_x(point_x);
437 point->mutable_path_point()->set_y(point_y);
438
439 if (i < 10) {
440 point->mutable_path_point()->set_theta(
441 latest_feature_ptr->velocity_heading());
442 } else {
443 point->mutable_path_point()->set_theta(
444 std::atan2(trajectory->trajectory_point(i).path_point().y() -
445 trajectory->trajectory_point(i - 1).path_point().y(),
446 trajectory->trajectory_point(i).path_point().x() -
447 trajectory->trajectory_point(i - 1).path_point().x()));
448 }
449 point->set_relative_time(static_cast<double>(i) *
450 FLAGS_prediction_trajectory_time_resolution);
451 if (i == 0) {
452 point->set_v(latest_feature_ptr->speed());
453 } else {
454 double diff_x = point_x - prev_x;
455 double diff_y = point_y - prev_y;
456 point->set_v(std::hypot(diff_x, diff_y) /
457 FLAGS_prediction_trajectory_time_resolution);
458 }
459 }
460
461 return true;
462}
bool VectornetProcessMapData(FeatureVector *map_feature, PidVector *map_p_id, const int obs_num, torch::Tensor *ptr_map_data, torch::Tensor *ptr_all_map_p_id, torch::Tensor *ptr_vector_mask)
Process map data to vector
bool VectornetProcessObstaclePosition(Obstacle *obstacle_ptr, ObstaclesContainer *obstacles_container, torch::Tensor *ptr_target_obs_pos, torch::Tensor *ptr_target_obs_pos_step, torch::Tensor *ptr_vector_mask, torch::Tensor *ptr_all_obstacle_pos, torch::Tensor *ptr_all_obs_p_id, torch::Tensor *ptr_obs_length)
Process obstacle position to vector
void Clear()
Clear obstacle feature map
bool ExtractADCTrajectory(std::vector< TrajectoryPoint > *trajectory_points, Obstacle *obstacle_ptr, std::vector< std::pair< double, double > > *acd_traj_curr_pos)
Extract adc trajectory and convert world coord to obstacle coord
bool query(const common::PointENU ¢er_point, const double obstacle_phi, FeatureVector *const feature_ptr, PidVector *const p_id_ptr)
SLPoint InterpolateUsingLinearApproximation(const SLPoint &p0, const SLPoint &p1, const double w)
std::vector< std::vector< double > > PidVector
std::vector< std::vector< std::vector< double > > > FeatureVector