54 std::vector<int>& prediction_obs_ids,
55 torch::Tensor* ptr_multi_obstacle_pos,
56 torch::Tensor* ptr_multi_obstacle_pos_step,
57 torch::Tensor* ptr_vector_mask,
58 torch::Tensor* ptr_all_obs_data,
59 torch::Tensor* ptr_all_obs_p_id,
60 torch::Tensor* ptr_multi_obstacle_position) {
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;
70 if (with_planning_traj) {
72 for (
size_t i = 0; i < adc_traj.trajectory_point().size(); ++i) {
73 adc_traj_points.emplace_back(adc_traj.trajectory_point(i));
81 &multi_obstacle_position,
86 ADEBUG <<
"Failed to extract obstacle history";
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());
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)) {
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;
113 for (
int j = 0; j < 20; ++j) {
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;
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;
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;
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;
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];
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);
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);
151 torch::from_blob(all_obs_pos_temp.data(), {obs_num, 20, 2}, opts).toType(at::kFloat);
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);
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()})},
169 torch::Tensor obs_attr_agent =
170 torch::tensor({11.0, 4.0}).unsqueeze(0).unsqueeze(0).repeat(
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);
178 torch::Tensor obs_id =
180 obs_num + 401).unsqueeze(1).repeat({1, 19}).unsqueeze(2);
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);
186 torch::Tensor obs_data_with_attr =
187 torch::cat({obs_data_with_len, obs_attr}, 2);
189 torch::Tensor obs_data_with_id = torch::cat({obs_data_with_attr, obs_id}, 2);
191 torch::cat({torch::zeros({obs_num, (50 - 19), 9}), obs_data_with_id}, 1);
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;
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;
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) {
211 planning_data.index_put_(
213 adc_traj_curr_pos[j].first);
214 planning_data.index_put_(
216 adc_traj_curr_pos[j].second);
218 planning_data = torch::cat(
219 {planning_data.index(
220 {torch::indexing::Slice(torch::indexing::None, -1),
221 torch::indexing::Slice()}),
223 {torch::indexing::Slice(1, torch::indexing::None),
224 torch::indexing::Slice()})},
226 planning_data = planning_data.unsqueeze(0);
229 torch::Tensor attr_planning =
230 torch::tensor({0.0, 0.0, 12.0, 4.0}).unsqueeze(0).unsqueeze(0).repeat(
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);
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)},
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);
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)},
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);
313bool MultiAgentEvaluator::Evaluate(
317 omp_set_num_threads(1);
321 auto start_time_pre = std::chrono::system_clock::now();
323 if (adc_trajectory_container ==
nullptr) {
324 AINFO <<
"Null adc traj container.";
325 with_planning_traj =
false;
329 AINFO <<
"Adc traj points are not enough.";
330 with_planning_traj =
false;
333 std::vector<int> obs_ids =
336 obs_ids.insert(obs_ids.begin(), -1);
337 std::vector<int> prediction_obs_ids;
338 for (
int id : obs_ids) {
342 AERROR <<
"Can not obtain adc info in multi agent evaluator.";
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)) {
357 prediction_obs_ids.push_back(
id);
359 obs_num = prediction_obs_ids.size();
361 AERROR <<
"No obstacle to be evaluated in multi agent evaluator.";
363 }
else if (obs_num > 50) {
364 AERROR <<
"Number of obstacles to be evaluated is too large: " << obs_num;
366 AINFO <<
"Number of objects to be evaluated: " << obs_num;
369 vector_obs_num = obs_num + 1;
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.";
377 auto start_time_obs = std::chrono::system_clock::now();
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});
386 if (!VectornetProcessObstaclePosition(obstacles_container,
387 adc_trajectory_container,
390 &multi_obstacle_pos_step,
395 AERROR <<
"Processing obstacle position fails.";
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.";
405 auto start_time_query = std::chrono::system_clock::now();
409 CHECK_NOTNULL(latest_feature_ptr);
413 const double pos_x = latest_feature_ptr->
position().
x();
414 const double pos_y = latest_feature_ptr->
position().
y();
416 = common::util::PointFactory::ToPointENU(pos_x, pos_y);;
419 if (!vector_net_.query(center_point, heading, &map_feature, &map_p_id)) {
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.";
429 auto start_time_map_vectorize = std::chrono::system_clock::now();
431 int map_polyline_num = map_feature.size();
433 ((vector_obs_num + map_polyline_num) < 450) ? (vector_obs_num + map_polyline_num) : 450;
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});
439 if (!VectornetProcessMapData(&map_feature,
445 AERROR <<
"Processing map data fails.";
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.";
457 auto start_time_data_prep = std::chrono::system_clock::now();
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);
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);
476 vector_data = data_tmp.index({torch::indexing::Slice(0, 450)});
477 polyline_id = p_id_tmp.index({torch::indexing::Slice(0, 450)});
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);
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)});
493 auto rand_mask = torch::zeros({450}).to(torch::kBool);
495 auto bool_vector_mask = vector_mask.to(torch::kBool);
496 auto bool_polyline_mask = polyline_mask.to(torch::kBool);
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>()
510 std::vector<void*> output_buffers{
511 torch_default_output_tensor_.data_ptr<
float>()};
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.";
521 auto start_time_inference = std::chrono::system_clock::now();
524 if (!model_manager_.SelectModel(
525 device_, ObstacleConf::MULTI_AGENT_EVALUATOR,
527 input_buffers, 8, &output_buffers, 1)) {
531 if (!model_manager_.SelectModel(
532 device_, ObstacleConf::MULTI_AGENT_EVALUATOR,
534 input_buffers, 8, &output_buffers, 1)) {
538 at::Tensor torch_output_tensor = torch::from_blob(
539 output_buffers[0], {1, max_agent_num, 30, 2});
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
549 auto start_time_output_process = std::chrono::system_clock::now();
551 auto torch_output = torch_output_tensor.accessor<float, 4>();
556 for (
int id : prediction_obs_ids) {
561 if (obstacle_ptr->
IsStill() || (obstacle_ptr->
type() != obstacle->
type())) {
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();
575 prev_x = last_point.
x();
576 prev_y = last_point.y();
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]);
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);
591 point->mutable_path_point()->set_theta(
594 point->mutable_path_point()->set_theta(
600 point->set_relative_time(
static_cast<double>(i) *
601 FLAGS_prediction_trajectory_time_resolution);
603 point->set_v(latest_feature_ptr->
speed());
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);
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.";
624bool MultiAgentEvaluator::ExtractObstaclesHistory(
626 std::vector<int>& prediction_obs_ids,
627 std::vector<TrajectoryPoint>* trajectory_points,
628 std::vector<std::vector<std::pair<double, double>>>* multi_obstacle_pos,
629 std::vector<std::vector<double>>* multi_obstacle_position,
630 std::vector<std::pair<double, double>>* all_obs_length,
631 std::vector<std::vector<std::pair<double, double>>>* all_obs_pos_history,
632 std::vector<std::pair<double, double>>* adc_traj_curr_pos,
633 torch::Tensor* vector_mask) {
635 std::vector<double> adc_world_coord;
636 std::pair<double, double> adc_world_pos;
642 for (
int id : prediction_obs_ids) {
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());
652 adc_world_coord = ref_world_coord;
653 adc_world_pos = std::make_pair(
654 adc_world_coord[0], adc_world_coord[1]);
658 std::pair<double, double> obs_position_pair = WorldCoordToObjCoordNorth(
659 std::make_pair(ref_world_coord[0],
661 adc_world_pos, adc_world_coord[2]);
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]);
669 std::pair<double, double> obs_curr_pos = std::make_pair(
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) {
676 if (!target_feature.IsInitialized()) {
679 target_pos_history[i] =
680 WorldCoordToObjCoordNorth(
681 std::make_pair(target_feature.
position().
x(),
683 obs_curr_pos, obs_curr_heading);
685 WorldCoordToObjCoordNorth(
686 std::make_pair(target_feature.
position().
x(),
688 adc_world_pos, adc_world_coord[2]);
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);
697 obs_his_size = obs_his_size <= 20 ? obs_his_size : 20;
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))},
705 vector_mask->index_put_({cur_idx,
706 torch::indexing::Slice(torch::indexing::None,
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);
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]);