Apollo 10.0
自动驾驶开放平台
apollo::prediction::MultiAgentEvaluator类 参考

#include <multi_agent_evaluator.h>

类 apollo::prediction::MultiAgentEvaluator 继承关系图:
apollo::prediction::MultiAgentEvaluator 的协作图:

Public 成员函数

 MultiAgentEvaluator ()
 Constructor
 
virtual ~MultiAgentEvaluator ()=default
 Destructor
 
void Clear ()
 Clear obstacle feature map
 
bool VectornetProcessObstaclePosition (ObstaclesContainer *obstacles_container, const ADCTrajectoryContainer *adc_trajectory_container, std::vector< int > &prediction_obs_ids, torch::Tensor *ptr_multi_obstacle_pos, torch::Tensor *ptr_multi_obstacle_pos_step, torch::Tensor *ptr_vector_mask, torch::Tensor *ptr_all_obs_data, torch::Tensor *ptr_all_obs_p_id, torch::Tensor *ptr_multi_obstacle_position)
 Process obstacle position to vector
 
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 Evaluate (Obstacle *obstacle, ObstaclesContainer *obstacles_container) override
 Override Evaluate
 
bool Evaluate (const ADCTrajectoryContainer *adc_trajectory_container, Obstacle *obstacle, ObstaclesContainer *obstacles_container) override
 Override Evaluate
 
bool ExtractObstaclesHistory (ObstaclesContainer *obstacles_container, std::vector< int > &prediction_obs_ids, std::vector< TrajectoryPoint > *trajectory_points, std::vector< std::vector< std::pair< double, double > > > *multi_obs_pos, std::vector< std::vector< double > > *multi_obs_position, std::vector< std::pair< double, double > > *all_obs_length, std::vector< std::vector< std::pair< double, double > > > *all_obs_pos_history, std::vector< std::pair< double, double > > *adc_traj_curr_pos, torch::Tensor *vector_mask)
 Extract all obstacles history
 
std::string GetName () override
 Get the name of evaluator.
 
- Public 成员函数 继承自 apollo::prediction::Evaluator
 Evaluator ()=default
 Constructor
 
virtual ~Evaluator ()=default
 Destructor
 
virtual bool Evaluate (Obstacle *obstacle, ObstaclesContainer *obstacles_container, std::vector< Obstacle * > dynamic_env)
 Evaluate an obstacle
 

额外继承的成员函数

- Protected 成员函数 继承自 apollo::prediction::Evaluator
std::pair< double, double > WorldCoordToObjCoord (std::pair< double, double > input_world_coord, std::pair< double, double > obj_world_coord, double obj_world_angle)
 
std::pair< double, double > WorldCoordToObjCoordNorth (std::pair< double, double > input_world_coord, std::pair< double, double > obj_world_coord, double obj_world_angle)
 
double WorldAngleToObjAngle (double input_world_angle, double obj_world_angle)
 
Eigen::MatrixXf VectorToMatrixXf (const std::vector< double > &nums, const int start_index, const int end_index)
 
Eigen::MatrixXf VectorToMatrixXf (const std::vector< double > &nums, const int start_index, const int end_index, const int output_num_row, const int output_num_col)
 
- Protected 属性 继承自 apollo::prediction::Evaluator
ObstacleConf::EvaluatorType evaluator_type_
 

详细描述

在文件 multi_agent_evaluator.h35 行定义.

构造及析构函数说明

◆ MultiAgentEvaluator()

apollo::prediction::MultiAgentEvaluator::MultiAgentEvaluator ( )

Constructor

在文件 multi_agent_evaluator.cc41 行定义.

41 : device_(Model::CPU) {
43 torch_default_output_tensor_ = torch::zeros({1, max_agent_num, 30, 2});
44 model_manager_ = ModelManager();
45 model_manager_.Init();
46 LoadModel();
47}
ObstacleConf::EvaluatorType evaluator_type_
Definition evaluator.h:156

◆ ~MultiAgentEvaluator()

virtual apollo::prediction::MultiAgentEvaluator::~MultiAgentEvaluator ( )
virtualdefault

Destructor

成员函数说明

◆ Clear()

void apollo::prediction::MultiAgentEvaluator::Clear ( )

Clear obstacle feature map

在文件 multi_agent_evaluator.cc49 行定义.

49{}

◆ Evaluate() [1/2]

bool apollo::prediction::MultiAgentEvaluator::Evaluate ( const ADCTrajectoryContainer adc_trajectory_container,
Obstacle obstacle,
ObstaclesContainer obstacles_container 
)
overridevirtual

Override Evaluate

参数
adc_trajectory_container
obstacle
obstacles_container

重载 apollo::prediction::Evaluator .

在文件 multi_agent_evaluator.cc313 行定义.

316 {
317 omp_set_num_threads(1);
318 Clear();
319
320 /* process the ids of obstacles to be evaluated */
321 auto start_time_pre = std::chrono::system_clock::now();
322
323 if (adc_trajectory_container == nullptr) {
324 AINFO << "Null adc traj container.";
325 with_planning_traj = false;
326 }
327
328 if (adc_trajectory_container->adc_trajectory().trajectory_point().size() < 1) {
329 AINFO << "Adc traj points are not enough.";
330 with_planning_traj = false;
331 }
332
333 std::vector<int> obs_ids =
334 obstacles_container->curr_frame_considered_obstacle_ids();
335 // add adc id
336 obs_ids.insert(obs_ids.begin(), -1);
337 std::vector<int> prediction_obs_ids;
338 for (int id : obs_ids) {
339 Obstacle* obstacle_ptr = obstacles_container->GetObstacle(id);
340 if (!obstacle_ptr) {
341 if (id == -1) {
342 AERROR << "Can not obtain adc info in multi agent evaluator.";
343 return false;
344 }
345 continue;
346 }
347 // do not care unknown obstacles to reduce the number of obstacles (< 50)
348 if (id != -1 && (obstacle_ptr->type() == perception::PerceptionObstacle::UNKNOWN ||
349 obstacle_ptr->type() == perception::PerceptionObstacle::UNKNOWN_MOVABLE ||
350 obstacle_ptr->type() == perception::PerceptionObstacle::UNKNOWN_UNMOVABLE)) {
351 continue;
352 }
353 // ignore the obj with histories less than 1s
354 if (id != -1 && obstacle_ptr->history_size() < 10) {
355 continue;
356 }
357 prediction_obs_ids.push_back(id);
358 }
359 obs_num = prediction_obs_ids.size();
360 if (obs_num <= 0) {
361 AERROR << "No obstacle to be evaluated in multi agent evaluator.";
362 return false;
363 } else if (obs_num > 50) {
364 AERROR << "Number of obstacles to be evaluated is too large: " << obs_num;
365 } else {
366 AINFO << "Number of objects to be evaluated: " << obs_num;
367 }
368 // planning traj, not to be evaulated
369 vector_obs_num = obs_num + 1;
370
371 auto end_time_pre = std::chrono::system_clock::now();
372 std::chrono::duration<double> diff_pre = end_time_pre - start_time_pre;
373 AINFO << "Evaluator prepare used time: " << diff_pre.count() * 1000 << " ms.";
374 /*************************************/
375
376 /* process the obstacle history pos into vector */
377 auto start_time_obs = std::chrono::system_clock::now();
378
379 torch::Tensor multi_obstacle_pos = torch::zeros({obs_num, 20, 2});
380 torch::Tensor multi_obstacle_pos_step = torch::zeros({obs_num, 20, 2});
381 torch::Tensor obs_position = torch::zeros({obs_num, 3});
382 torch::Tensor vector_mask = torch::zeros({450, 50});
383 torch::Tensor obstacle_data = torch::zeros({vector_obs_num, 50, 9});
384 torch::Tensor all_obs_p_id = torch::zeros({vector_obs_num, 2});
385
386 if (!VectornetProcessObstaclePosition(obstacles_container,
387 adc_trajectory_container,
388 prediction_obs_ids,
389 &multi_obstacle_pos,
390 &multi_obstacle_pos_step,
391 &vector_mask,
392 &obstacle_data,
393 &all_obs_p_id,
394 &obs_position)) {
395 AERROR << "Processing obstacle position fails.";
396 return false;
397 }
398
399 auto end_time_obs = std::chrono::system_clock::now();
400 std::chrono::duration<double> diff_obs = end_time_obs - start_time_obs;
401 AINFO << "Obstacle vectors used time: " << diff_obs.count() * 1000 << " ms.";
402 /*************************************/
403
404 /* Query the map data */
405 auto start_time_query = std::chrono::system_clock::now();
406
407 Obstacle* selected_obstacle = obstacles_container->GetObstacle(-1);
408 Feature* latest_feature_ptr = selected_obstacle->mutable_latest_feature();
409 CHECK_NOTNULL(latest_feature_ptr);
410
411 FeatureVector map_feature;
412 PidVector map_p_id;
413 const double pos_x = latest_feature_ptr->position().x();
414 const double pos_y = latest_feature_ptr->position().y();
415 common::PointENU center_point
417 const double heading = latest_feature_ptr->velocity_heading();
418
419 if (!vector_net_.query(center_point, heading, &map_feature, &map_p_id)) {
420 return false;
421 }
422
423 auto end_time_query = std::chrono::system_clock::now();
424 std::chrono::duration<double> diff_query = end_time_query - start_time_query;
425 AINFO << "map vector query used time: " << diff_query.count() * 1000 << " ms.";
426 /*************************************/
427
428 /* process map data & map p id & v_mask for map polyline */
429 auto start_time_map_vectorize = std::chrono::system_clock::now();
430
431 int map_polyline_num = map_feature.size();
432 int data_length =
433 ((vector_obs_num + map_polyline_num) < 450) ? (vector_obs_num + map_polyline_num) : 450;
434
435 // Process input tensor
436 torch::Tensor map_data = torch::zeros({map_polyline_num, 50, 9});
437 torch::Tensor all_map_p_id = torch::zeros({map_polyline_num, 2});
438
439 if (!VectornetProcessMapData(&map_feature,
440 &map_p_id,
441 vector_obs_num,
442 &map_data,
443 &all_map_p_id,
444 &vector_mask)) {
445 AERROR << "Processing map data fails.";
446 return false;
447 }
448
449 auto end_time_map_vectorize = std::chrono::system_clock::now();
450 std::chrono::duration<double> diff_map_vectorize =
451 end_time_map_vectorize - start_time_map_vectorize;
452 AINFO << "Map vectors used time: "
453 << diff_map_vectorize.count() * 1000 << " ms.";
454 /*************************************/
455
456 /* prepare input data for inference */
457 auto start_time_data_prep = std::chrono::system_clock::now();
458 // process p mask
459 torch::Tensor polyline_mask = torch::zeros({450});
460 if (data_length < 450) {
461 polyline_mask.index_put_(
462 {torch::indexing::Slice(data_length, torch::indexing::None)}, 1);
463 }
464
465 // Extend data & pid to specific demension
466 torch::Tensor data_tmp = torch::cat({obstacle_data, map_data}, 0);
467 torch::Tensor p_id_tmp = torch::cat({all_obs_p_id, all_map_p_id}, 0);
468 torch::Tensor vector_data;
469 torch::Tensor polyline_id;
470 if (data_length < 450) {
471 torch::Tensor data_zeros = torch::zeros({(450 - data_length), 50, 9});
472 torch::Tensor p_id_zeros = torch::zeros({(450 - data_length), 2});
473 vector_data = torch::cat({data_tmp, data_zeros}, 0);
474 polyline_id = torch::cat({p_id_tmp, p_id_zeros}, 0);
475 } else {
476 vector_data = data_tmp.index({torch::indexing::Slice(0, 450)});
477 polyline_id = p_id_tmp.index({torch::indexing::Slice(0, 450)});
478 }
479
480 if (obs_num < max_agent_num) {
481 torch::Tensor filling_zeros = torch::zeros({max_agent_num - obs_num, 20, 2});
482 multi_obstacle_pos = torch::cat({multi_obstacle_pos, filling_zeros}, 0);
483 multi_obstacle_pos_step = torch::cat({multi_obstacle_pos_step, filling_zeros}, 0);
484 torch::Tensor position_zeros = torch::zeros({max_agent_num - obs_num, 3});
485 obs_position = torch::cat({obs_position, position_zeros}, 0);
486 } else {
487 multi_obstacle_pos = multi_obstacle_pos.index({torch::indexing::Slice(0, max_agent_num)});
488 multi_obstacle_pos_step = multi_obstacle_pos_step.index({torch::indexing::Slice(0, max_agent_num)});
489 obs_position = obs_position.index({torch::indexing::Slice(0, max_agent_num)});
490 }
491
492 // Empty rand mask as placeholder
493 auto rand_mask = torch::zeros({450}).to(torch::kBool);
494 // Change mask type to bool
495 auto bool_vector_mask = vector_mask.to(torch::kBool);
496 auto bool_polyline_mask = polyline_mask.to(torch::kBool);
497
498 // Build input features for torch
499 std::vector<void*> input_buffers{
500 multi_obstacle_pos.unsqueeze(0).data_ptr<float>(),
501 multi_obstacle_pos_step.unsqueeze(0).data_ptr<float>(),
502 vector_data.unsqueeze(0).data_ptr<float>(),
503 bool_vector_mask.unsqueeze(0).data_ptr<bool>(),
504 bool_polyline_mask.unsqueeze(0).data_ptr<bool>(),
505 rand_mask.unsqueeze(0).data_ptr<bool>(),
506 polyline_id.unsqueeze(0).data_ptr<float>(),
507 obs_position.unsqueeze(0).data_ptr<float>()
508 };
509
510 std::vector<void*> output_buffers{
511 torch_default_output_tensor_.data_ptr<float>()};
512
513 auto end_time_data_prep = std::chrono::system_clock::now();
514 std::chrono::duration<double> diff_data_prep =
515 end_time_data_prep - start_time_data_prep;
516 AINFO << "vectornet input tensor preparation used time: "
517 << diff_data_prep.count() * 1000 << " ms.";
518 /*************************************/
519
520 /* Inference*/
521 auto start_time_inference = std::chrono::system_clock::now();
522
523 if (obstacle->IsPedestrian()) {
524 if (!model_manager_.SelectModel(
527 input_buffers, 8, &output_buffers, 1)) {
528 return false;
529 }
530 } else {
531 if (!model_manager_.SelectModel(
534 input_buffers, 8, &output_buffers, 1)) {
535 return false;
536 }
537 }
538 at::Tensor torch_output_tensor = torch::from_blob(
539 output_buffers[0], {1, max_agent_num, 30, 2});
540
541 auto end_time_inference = std::chrono::system_clock::now();
542 std::chrono::duration<double> diff_inference =
543 end_time_inference - start_time_inference;
544 AINFO << "vectornet inference used time: " << diff_inference.count() * 1000
545 << " ms.";
546 /*************************************/
547
548 /* post process to get the trajectory */
549 auto start_time_output_process = std::chrono::system_clock::now();
550
551 auto torch_output = torch_output_tensor.accessor<float, 4>();
552
553 // The first obstacle is the ego vehicle
554 // So the index starts from 1
555 int obj_id = 1;
556 for (int id : prediction_obs_ids) {
557 if (id == -1) {
558 continue;
559 }
560 Obstacle* obstacle_ptr = obstacles_container->GetObstacle(id);
561 if (obstacle_ptr->IsStill() || (obstacle_ptr->type() != obstacle->type())) {
562 obj_id++;
563 continue;
564 }
565
566 obstacle_ptr->SetEvaluatorType(evaluator_type_);
567 Feature* latest_feature_ptr = obstacle_ptr->mutable_latest_feature();
568 Trajectory* trajectory = latest_feature_ptr->add_predicted_trajectory();
569 trajectory->set_probability(1.0);
570 for (int i = 0; i < 30; ++i) {
571 double prev_x = latest_feature_ptr->position().x();
572 double prev_y = latest_feature_ptr->position().y();
573 if (i > 0) {
574 const auto& last_point = trajectory->trajectory_point(i - 1).path_point();
575 prev_x = last_point.x();
576 prev_y = last_point.y();
577 }
578 TrajectoryPoint* point = trajectory->add_trajectory_point();
579 double dx = static_cast<double>(torch_output[0][obj_id][i][0]);
580 double dy = static_cast<double>(torch_output[0][obj_id][i][1]);
581
582 double heading = latest_feature_ptr->velocity_heading();
583 Vec2d offset(dx, dy);
584 Vec2d rotated_offset = offset.rotate(heading - (M_PI / 2));
585 double point_x = latest_feature_ptr->position().x() + rotated_offset.x();
586 double point_y = latest_feature_ptr->position().y() + rotated_offset.y();
587 point->mutable_path_point()->set_x(point_x);
588 point->mutable_path_point()->set_y(point_y);
589
590 if (i < 10) { // use origin heading for the first second
591 point->mutable_path_point()->set_theta(
592 latest_feature_ptr->velocity_heading());
593 } else {
594 point->mutable_path_point()->set_theta(
595 std::atan2(trajectory->trajectory_point(i).path_point().y() -
596 trajectory->trajectory_point(i - 1).path_point().y(),
597 trajectory->trajectory_point(i).path_point().x() -
598 trajectory->trajectory_point(i - 1).path_point().x()));
599 }
600 point->set_relative_time(static_cast<double>(i) *
601 FLAGS_prediction_trajectory_time_resolution);
602 if (i == 0) {
603 point->set_v(latest_feature_ptr->speed());
604 } else {
605 double diff_x = point_x - prev_x;
606 double diff_y = point_y - prev_y;
607 point->set_v(std::hypot(diff_x, diff_y) /
608 FLAGS_prediction_trajectory_time_resolution);
609 }
610 }
611 obj_id++;
612 }
613
614 auto end_time_output_process = std::chrono::system_clock::now();
615 std::chrono::duration<double> diff_output_process =
616 end_time_output_process - start_time_output_process;
617 AINFO << "vectornet output process used time: "
618 << diff_output_process.count() * 1000 << " ms.";
619 /*************************************/
620
621 return true;
622}
static PointENU ToPointENU(const double x, const double y, const double z=0)
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 VectornetProcessObstaclePosition(ObstaclesContainer *obstacles_container, const ADCTrajectoryContainer *adc_trajectory_container, std::vector< int > &prediction_obs_ids, torch::Tensor *ptr_multi_obstacle_pos, torch::Tensor *ptr_multi_obstacle_pos_step, torch::Tensor *ptr_vector_mask, torch::Tensor *ptr_all_obs_data, torch::Tensor *ptr_all_obs_p_id, torch::Tensor *ptr_multi_obstacle_position)
Process obstacle position to vector
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
void Clear()
Clear obstacle feature map
bool query(const common::PointENU &center_point, const double obstacle_phi, FeatureVector *const feature_ptr, PidVector *const p_id_ptr)
#define AERROR
Definition log.h:44
#define AINFO
Definition log.h:42
std::vector< std::vector< double > > PidVector
Definition vector_net.h:34
std::vector< std::vector< std::vector< double > > > FeatureVector
Definition vector_net.h:33

◆ Evaluate() [2/2]

bool apollo::prediction::MultiAgentEvaluator::Evaluate ( Obstacle obstacle,
ObstaclesContainer obstacles_container 
)
overridevirtual

Override Evaluate

参数
obstacle
obstacles_container

实现了 apollo::prediction::Evaluator.

在文件 multi_agent_evaluator.cc305 行定义.

307 {
308 const ADCTrajectoryContainer* adc_trajectory_container;
309 Evaluate(adc_trajectory_container, obstacle, obstacles_container);
310 return true;
311}
bool Evaluate(Obstacle *obstacle, ObstaclesContainer *obstacles_container) override
Override Evaluate

◆ ExtractObstaclesHistory()

bool apollo::prediction::MultiAgentEvaluator::ExtractObstaclesHistory ( ObstaclesContainer obstacles_container,
std::vector< int > &  prediction_obs_ids,
std::vector< TrajectoryPoint > *  trajectory_points,
std::vector< std::vector< std::pair< double, double > > > *  multi_obs_pos,
std::vector< std::vector< double > > *  multi_obs_position,
std::vector< std::pair< double, double > > *  all_obs_length,
std::vector< std::vector< std::pair< double, double > > > *  all_obs_pos_history,
std::vector< std::pair< double, double > > *  adc_traj_curr_pos,
torch::Tensor *  vector_mask 
)

Extract all obstacles history

参数
obstacles_containerFeature container in a vector for receiving the obstacle history
prediction_obs_idsobstacle ids
trajectory_pointstrajectory points
multi_obs_posmulti obstacle hisotry pos
multi_obs_positionmulti obstacle position
all_obs_lengthalll obstacle length
all_obs_pos_historyall obstacle history pos
adc_traj_curr_posadc trajectory current pos
vector_maskvector mask

在文件 multi_agent_evaluator.cc624 行定义.

633 {
634
635 std::vector<double> adc_world_coord;
636 std::pair<double, double> adc_world_pos;
637
638 // v_mask
639 int cur_idx = 1;
640
641 // all the obstacles
642 for (int id : prediction_obs_ids) {
643 Obstacle* obstacle_ptr = obstacles_container->GetObstacle(id);
644 const Feature& obs_curr_feature = obstacle_ptr->latest_feature();
645
646 std::vector<double> ref_world_coord;
647 ref_world_coord.emplace_back(obs_curr_feature.position().x());
648 ref_world_coord.emplace_back(obs_curr_feature.position().y());
649 ref_world_coord.emplace_back(obs_curr_feature.velocity_heading());
650
651 if (id == -1) {
652 adc_world_coord = ref_world_coord;
653 adc_world_pos = std::make_pair(
654 adc_world_coord[0], adc_world_coord[1]);
655 }
656
657 // multi obs
658 std::pair<double, double> obs_position_pair = WorldCoordToObjCoordNorth(
659 std::make_pair(ref_world_coord[0],
660 ref_world_coord[1]),
661 adc_world_pos, adc_world_coord[2]);
662
663 std::vector<double> obs_position;
664 obs_position.emplace_back(obs_position_pair.first);
665 obs_position.emplace_back(obs_position_pair.second);
666 obs_position.emplace_back(ref_world_coord[2] - adc_world_coord[2]);
667
668 double obs_curr_heading = obs_curr_feature.velocity_heading();
669 std::pair<double, double> obs_curr_pos = std::make_pair(
670 obs_curr_feature.position().x(), obs_curr_feature.position().y());
671
672 std::vector<std::pair<double, double>> target_pos_history(20, {0.0, 0.0});
673 std::vector<std::pair<double, double>> obs_pos_history(20, {0.0, 0.0});
674 for (std::size_t i = 0; i < obstacle_ptr->history_size() && i < 20; ++i) {
675 const Feature& target_feature = obstacle_ptr->feature(i);
676 if (!target_feature.IsInitialized()) {
677 break;
678 }
679 target_pos_history[i] =
681 std::make_pair(target_feature.position().x(),
682 target_feature.position().y()),
683 obs_curr_pos, obs_curr_heading);
684 obs_pos_history[i] =
686 std::make_pair(target_feature.position().x(),
687 target_feature.position().y()),
688 adc_world_pos, adc_world_coord[2]);
689 }
690 multi_obstacle_pos->emplace_back(target_pos_history);
691 all_obs_pos_history->emplace_back(obs_pos_history);
692 all_obs_length->emplace_back(std::make_pair(
693 obs_curr_feature.length(), obs_curr_feature.width()));
694 multi_obstacle_position->emplace_back(obs_position);
695
696 size_t obs_his_size = obstacle_ptr->history_size();
697 obs_his_size = obs_his_size <= 20 ? obs_his_size : 20;
698 // if cur_dix >= 450, index_put_ discards it automatically.
699 if (obs_his_size > 1) {
700 vector_mask->index_put_({cur_idx,
701 torch::indexing::Slice(torch::indexing::None,
702 -(obs_his_size - 1))},
703 1);
704 } else {
705 vector_mask->index_put_({cur_idx,
706 torch::indexing::Slice(torch::indexing::None,
707 -1)},
708 1);
709 }
710 cur_idx++;
711 }
712
713 // adc trajectory
714 if (with_planning_traj) {
715 adc_traj_curr_pos->resize(30, {0.0, 0.0});
716 size_t adc_traj_points_num = trajectory_points->size();
717 for (size_t i = 0; i < 30; ++i) {
718 if (i > adc_traj_points_num -1) {
719 adc_traj_curr_pos->at(i) =
720 adc_traj_curr_pos->at(adc_traj_points_num - 1);
721 } else {
722 adc_traj_curr_pos->at(i) = WorldCoordToObjCoordNorth(
723 std::make_pair(trajectory_points->at(i).path_point().x(),
724 trajectory_points->at(i).path_point().y()),
725 adc_world_pos, adc_world_coord[2]);
726 }
727 }
728 }
729
730 return true;
731}
std::pair< double, double > WorldCoordToObjCoordNorth(std::pair< double, double > input_world_coord, std::pair< double, double > obj_world_coord, double obj_world_angle)
Definition evaluator.h:105

◆ GetName()

std::string apollo::prediction::MultiAgentEvaluator::GetName ( )
inlineoverridevirtual

Get the name of evaluator.

实现了 apollo::prediction::Evaluator.

在文件 multi_agent_evaluator.h135 行定义.

135{ return "MULTI_AGENT_EVALUATOR"; }

◆ VectornetProcessMapData()

bool apollo::prediction::MultiAgentEvaluator::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

参数
FeatureVectormap feature vector
PidVectormap p_id vector
intobstacle number
Tensormap data
Tensormap data p_id
Tensorvector mask

在文件 multi_agent_evaluator.cc260 行定义.

266 {
267 int map_polyline_num = map_feature->size();
268
269 for (int i = 0; i < map_polyline_num && other_obs_num + i < 450; ++i) {
270 size_t one_polyline_vector_size = map_feature->at(i).size();
271 if (one_polyline_vector_size < 50) {
272 ptr_vector_mask->index_put_({other_obs_num + i,
273 torch::indexing::Slice(
274 one_polyline_vector_size,
275 torch::indexing::None)},
276 1);
277 }
278 }
279
280 auto opts = torch::TensorOptions().dtype(torch::kDouble);
281
282 std::vector<double> all_map_p_id_temp(map_polyline_num * 2, 0.0);
283 std::vector<double> map_data_temp(map_polyline_num * 50 * 9, 0.0);
284 for (int i = 0; i < map_polyline_num && i + other_obs_num < 450; ++i) {
285 all_map_p_id_temp[i * 2 + 0] = map_p_id->at(i)[0];
286 all_map_p_id_temp[i * 2 + 1] = map_p_id->at(i)[1];
287
288 int one_polyline_vector_size = map_feature->at(i).size();
289 for (int j = 0; j < one_polyline_vector_size && j < 50; ++j) {
290 for (int k = 0; k < 9; ++k) {
291 map_data_temp[i * 50 * 9 + j * 9 + k] =
292 map_feature->at(i)[j][k];
293 }
294 }
295 }
296
297 *ptr_map_data = torch::from_blob(map_data_temp.data(),
298 {map_polyline_num, 50, 9}, opts).toType(at::kFloat);
299 *ptr_all_map_p_id = torch::from_blob(all_map_p_id_temp.data(),
300 {map_polyline_num, 2}, opts).toType(at::kFloat);
301
302 return true;
303}

◆ VectornetProcessObstaclePosition()

bool apollo::prediction::MultiAgentEvaluator::VectornetProcessObstaclePosition ( ObstaclesContainer obstacles_container,
const ADCTrajectoryContainer adc_trajectory_container,
std::vector< int > &  prediction_obs_ids,
torch::Tensor *  ptr_multi_obstacle_pos,
torch::Tensor *  ptr_multi_obstacle_pos_step,
torch::Tensor *  ptr_vector_mask,
torch::Tensor *  ptr_all_obs_data,
torch::Tensor *  ptr_all_obs_p_id,
torch::Tensor *  ptr_multi_obstacle_position 
)

Process obstacle position to vector

参数
obstacles_container
adc_trajectory_container
prediction_obs_ids
Tensorall obstacle hisotry pos
Tensorall obstacle hisotry pos step
Tensorvector mask
Tensorall obstacle data
Tensorall obstacle p_id
Tensorall obstacle position

在文件 multi_agent_evaluator.cc51 行定义.

60 {
61
62 std::vector<std::vector<std::pair<double, double>>> multi_obstacle_pos;
63 std::vector<std::vector<double>> multi_obstacle_position;
64 std::vector<std::vector<std::pair<double, double>>> all_obs_pos_history;
65 std::vector<std::pair<double, double>> all_obs_length;
66 std::vector<std::pair<double, double>> adc_traj_curr_pos(30, {0.0, 0.0});
67 std::vector<TrajectoryPoint> adc_traj_points;
68
69 // Process ADC trajectory & Extract features of ADC trajectory
70 if (with_planning_traj) {
71 const auto& adc_traj = adc_trajectory_container->adc_trajectory();
72 for (size_t i = 0; i < adc_traj.trajectory_point().size(); ++i) {
73 adc_traj_points.emplace_back(adc_traj.trajectory_point(i));
74 }
75 }
76
77 if (!ExtractObstaclesHistory(obstacles_container,
78 prediction_obs_ids,
79 &adc_traj_points,
80 &multi_obstacle_pos,
81 &multi_obstacle_position,
82 &all_obs_length,
83 &all_obs_pos_history,
84 &adc_traj_curr_pos,
85 ptr_vector_mask)) {
86 ADEBUG << "Failed to extract obstacle history";
87 return false;
88 }
89
90 // data convert for faster torch data convert
91 std::vector<double> multi_obs_pos_reverse(obs_num * 20 * 2, 0.0);
92 std::vector<double> multi_obs_pos_step(obs_num * 20 * 2, 0.0);
93 std::vector<double> all_obs_pos_temp(obs_num * 20 * 2, 0.0);
94 std::vector<double> all_obs_length_temp(obs_num * 2, 0.0);
95 std::vector<double> multi_obs_position_temp(obs_num * 3, 0.0);
96 std::vector<double> all_obs_p_id_temp(obs_num * 2, std::numeric_limits<float>::max());
97
98 for (int i = 0; i < obs_num; ++i) {
99 for (int j = 0; j < 20; ++j) {
100 multi_obs_pos_reverse[i * 20 * 2 + (19 - j) * 2 + 0] =
101 multi_obstacle_pos[i][j].first;
102 multi_obs_pos_reverse[i * 20 * 2 + (19 - j) * 2 + 1] =
103 multi_obstacle_pos[i][j].second;
104 if (j == 19 || (j > 0 && multi_obstacle_pos[i][j + 1].first == 0.0)) {
105 break;
106 }
107 multi_obs_pos_step[i * 20 * 2 + (19 - j) * 2 + 0] =
108 multi_obstacle_pos[i][j].first - multi_obstacle_pos[i][j + 1].first;
109 multi_obs_pos_step[i * 20 * 2 + (19 - j) * 2 + 1] =
110 multi_obstacle_pos[i][j].second - multi_obstacle_pos[i][j + 1].second;
111 }
112
113 for (int j = 0; j < 20; ++j) {
114 // Process obs pid
115 // p_id is the minimum values of the start coordinates
116 if (all_obs_p_id_temp[i * 2 + 0] > all_obs_pos_history[i][j].first) {
117 all_obs_p_id_temp[i * 2 + 0] = all_obs_pos_history[i][j].first;
118 }
119 if (all_obs_p_id_temp[i * 2 + 1] > all_obs_pos_history[i][j].second) {
120 all_obs_p_id_temp[i * 2 + 1] = all_obs_pos_history[i][j].second;
121 }
122 // Process obs pos history
123 all_obs_pos_temp[i * 20 * 2 + (19 - j) * 2 + 0] =
124 all_obs_pos_history[i][j].first;
125 all_obs_pos_temp[i * 20 * 2 + (19 - j) * 2 + 1] =
126 all_obs_pos_history[i][j].second;
127 }
128
129 // obs length
130 all_obs_length_temp[i * 2 + 0] = all_obs_length[i].first;
131 all_obs_length_temp[i * 2 + 1] = all_obs_length[i].second;
132
133 // obs position
134 multi_obs_position_temp[i * 3 + 0] = multi_obstacle_position[i][0];
135 multi_obs_position_temp[i * 3 + 1] = multi_obstacle_position[i][1];
136 multi_obs_position_temp[i * 3 + 2] = multi_obstacle_position[i][2];
137 }
138
139 torch::Tensor all_obs_pos_data = torch::zeros({obs_num, 20, 2});
140 torch::Tensor all_obs_p_id_data = torch::zeros({obs_num, 2});
141 torch::Tensor all_obs_length_data = torch::zeros({obs_num, 2});
142 auto opts = torch::TensorOptions().dtype(torch::kDouble);
143
144 *ptr_multi_obstacle_pos =
145 torch::from_blob(multi_obs_pos_reverse.data(), {obs_num, 20, 2}, opts).toType(at::kFloat);
146 *ptr_multi_obstacle_pos_step =
147 torch::from_blob(multi_obs_pos_step.data(), {obs_num, 20, 2}, opts).toType(at::kFloat);
148 *ptr_multi_obstacle_position =
149 torch::from_blob(multi_obs_position_temp.data(), {obs_num, 3}, opts).toType(at::kFloat);
150 all_obs_pos_data =
151 torch::from_blob(all_obs_pos_temp.data(), {obs_num, 20, 2}, opts).toType(at::kFloat);
152 all_obs_p_id_data =
153 torch::from_blob(all_obs_p_id_temp.data(), {obs_num, 2}, opts).toType(at::kFloat);
154 all_obs_length_data =
155 torch::from_blob(all_obs_length_temp.data(), {obs_num, 2}, opts).toType(at::kFloat);
156
157 // Extend obs data to specific dimension
158 all_obs_pos_data = torch::cat(
159 {all_obs_pos_data.index(
160 {torch::indexing::Slice(),
161 torch::indexing::Slice(torch::indexing::None, -1),
162 torch::indexing::Slice()}),
163 all_obs_pos_data.index({torch::indexing::Slice(),
164 torch::indexing::Slice(1, torch::indexing::None),
165 torch::indexing::Slice()})},
166 2);
167
168 // Add obs attribute
169 torch::Tensor obs_attr_agent =
170 torch::tensor({11.0, 4.0}).unsqueeze(0).unsqueeze(0).repeat(
171 {1, 19, 1});
172 torch::Tensor obs_attr_other =
173 torch::tensor({10.0, 4.0}).unsqueeze(0).unsqueeze(0).repeat(
174 {(obs_num - 1), 19, 1});
175 torch::Tensor obs_attr = torch::cat({obs_attr_agent, obs_attr_other}, 0);
176 // ADD obs id
177 // add 401 to avoid same id as in map_info
178 torch::Tensor obs_id =
179 torch::arange(401,
180 obs_num + 401).unsqueeze(1).repeat({1, 19}).unsqueeze(2);
181 // Process obs data
182 all_obs_length_data = all_obs_length_data.unsqueeze(1).repeat({1, 19, 1});
183 torch::Tensor obs_data_with_len =
184 torch::cat({all_obs_pos_data, all_obs_length_data}, 2);
185
186 torch::Tensor obs_data_with_attr =
187 torch::cat({obs_data_with_len, obs_attr}, 2);
188
189 torch::Tensor obs_data_with_id = torch::cat({obs_data_with_attr, obs_id}, 2);
190 obs_data_with_id =
191 torch::cat({torch::zeros({obs_num, (50 - 19), 9}), obs_data_with_id}, 1);
192
193 // adc trajectory
194 if (with_planning_traj) {
195 std::vector<double> adc_traj_p_id{std::numeric_limits<float>::max(),
196 std::numeric_limits<float>::max()};
197 for (int j = 0; j < 30; ++j) {
198 if (adc_traj_p_id[0] > adc_traj_curr_pos[j].first) {
199 adc_traj_p_id[0] = adc_traj_curr_pos[j].first;
200 }
201 if (adc_traj_p_id[1] > adc_traj_curr_pos[j].second) {
202 adc_traj_p_id[1] = adc_traj_curr_pos[j].second;
203 }
204 }
205 torch::Tensor planning_p_id = torch::zeros({1, 2});
206 planning_p_id.index_put_({0},
207 torch::from_blob(adc_traj_p_id.data(), {2}, opts));
208 torch::Tensor planning_data = torch::zeros({30, 2});
209 for (int j = 0; j < 30; ++j) {
210 // Process obs pos history
211 planning_data.index_put_(
212 {j, 0},
213 adc_traj_curr_pos[j].first);
214 planning_data.index_put_(
215 {j, 1},
216 adc_traj_curr_pos[j].second);
217 }
218 planning_data = torch::cat(
219 {planning_data.index(
220 {torch::indexing::Slice(torch::indexing::None, -1),
221 torch::indexing::Slice()}),
222 planning_data.index(
223 {torch::indexing::Slice(1, torch::indexing::None),
224 torch::indexing::Slice()})},
225 1);
226 planning_data = planning_data.unsqueeze(0);
227
228 // Add obs attribute
229 torch::Tensor attr_planning =
230 torch::tensor({0.0, 0.0, 12.0, 4.0}).unsqueeze(0).unsqueeze(0).repeat(
231 {1, 29, 1});
232 planning_data =
233 torch::cat({planning_data, attr_planning}, 2);
234 torch::Tensor planning_id =
235 torch::tensor({400}).unsqueeze(1).repeat({1, 29}).unsqueeze(2);
236 planning_data = torch::cat({planning_data, planning_id}, 2);
237 planning_data =
238 torch::cat({torch::zeros({1, (50 - 29), 9}), planning_data}, 1);
239 ptr_vector_mask->index_put_({0,
240 torch::indexing::Slice(torch::indexing::None,-29)},
241 1);
242
243 // planning data + obj data
244 *ptr_all_obs_data = torch::cat({planning_data, obs_data_with_id}, 0);
245 *ptr_all_obs_p_id = torch::cat({planning_p_id, all_obs_p_id_data}, 0);
246 return true;
247 }
248
249 // planning data + obj data
250 torch::Tensor planning_data = torch::zeros({1, 50, 9});
251 torch::Tensor planning_p_id = torch::zeros({1, 2});
252 ptr_vector_mask->index_put_({0,
253 torch::indexing::Slice(torch::indexing::None,-29)},
254 1);
255 *ptr_all_obs_data = torch::cat({planning_data, obs_data_with_id}, 0);
256 *ptr_all_obs_p_id = torch::cat({planning_p_id, all_obs_p_id_data}, 0);
257 return true;
258}
bool ExtractObstaclesHistory(ObstaclesContainer *obstacles_container, std::vector< int > &prediction_obs_ids, std::vector< TrajectoryPoint > *trajectory_points, std::vector< std::vector< std::pair< double, double > > > *multi_obs_pos, std::vector< std::vector< double > > *multi_obs_position, std::vector< std::pair< double, double > > *all_obs_length, std::vector< std::vector< std::pair< double, double > > > *all_obs_pos_history, std::vector< std::pair< double, double > > *adc_traj_curr_pos, torch::Tensor *vector_mask)
Extract all obstacles history
#define ADEBUG
Definition log.h:41

该类的文档由以下文件生成: