48 torch::Tensor* ptr_target_obs_pos,
49 torch::Tensor* ptr_target_obs_pos_step,
50 torch::Tensor* ptr_vector_mask,
51 torch::Tensor* ptr_obstacle_data,
52 torch::Tensor* ptr_all_obs_p_id) {
54 std::vector<std::pair<double, double>> target_pos_history(20, {0.0, 0.0});
55 std::vector<std::pair<double, double>> all_obs_length;
56 std::vector<std::vector<std::pair<double, double>>> all_obs_pos_history;
59 &target_pos_history, &all_obs_length,
60 &all_obs_pos_history, ptr_vector_mask)) {
61 ADEBUG <<
"Obstacle [" << obstacle_ptr->
id()
62 <<
"] failed to extract obstacle history";
66 for (
int j = 0; j < 20; ++j) {
67 ptr_target_obs_pos->index_put_({19 - j, 0}, target_pos_history[j].first);
68 ptr_target_obs_pos->index_put_({19 - j, 1}, target_pos_history[j].second);
69 if (j == 19 || (j > 0 && target_pos_history[j + 1].first == 0.0)) {
72 ptr_target_obs_pos_step->index_put_(
74 target_pos_history[j].first - target_pos_history[j + 1].first);
75 ptr_target_obs_pos_step->index_put_(
77 target_pos_history[j].second - target_pos_history[j + 1].second);
82 torch::Tensor all_obstacle_pos = torch::zeros({obs_num, 20, 2});
83 torch::Tensor obs_length_data = torch::zeros({obs_num, 2});
84 auto opts = torch::TensorOptions().dtype(torch::kDouble);
86 for (
int i = 0; i < obs_num; ++i) {
87 std::vector<double> obs_p_id{std::numeric_limits<float>::max(),
88 std::numeric_limits<float>::max()};
89 for (
int j = 0; j < 20; ++j) {
91 if (obs_p_id[0] > all_obs_pos_history[i][j].first) {
92 obs_p_id[0] = all_obs_pos_history[i][j].first;
94 if (obs_p_id[1] > all_obs_pos_history[i][j].second) {
95 obs_p_id[1] = all_obs_pos_history[i][j].second;
98 all_obstacle_pos.index_put_(
100 all_obs_pos_history[i][j].first);
101 all_obstacle_pos.index_put_(
103 all_obs_pos_history[i][j].second);
106 ptr_all_obs_p_id->index_put_({i},
107 torch::from_blob(obs_p_id.data(), {2}, opts));
108 obs_length_data.index_put_({i, 0}, all_obs_length[i].first);
109 obs_length_data.index_put_({i, 1}, all_obs_length[i].second);
113 torch::Tensor obs_pos_data = torch::cat(
114 {all_obstacle_pos.index(
115 {torch::indexing::Slice(),
116 torch::indexing::Slice(torch::indexing::None, -1),
117 torch::indexing::Slice()}),
118 all_obstacle_pos.index({torch::indexing::Slice(),
119 torch::indexing::Slice(1, torch::indexing::None),
120 torch::indexing::Slice()})},
124 torch::Tensor obs_attr_agent =
125 torch::tensor({11.0, 4.0}).unsqueeze(0).unsqueeze(0).repeat({1, 19, 1});
126 torch::Tensor obs_attr_other =
127 torch::tensor({10.0, 4.0}).unsqueeze(0).unsqueeze(0).repeat(
128 {(obs_num - 1), 19, 1});
129 torch::Tensor obs_attr = torch::cat({obs_attr_agent, obs_attr_other}, 0);
132 torch::Tensor obs_id =
134 obs_num + 500).unsqueeze(1).repeat({1, 19}).unsqueeze(2);
136 obs_length_data = obs_length_data.unsqueeze(1).repeat({1, 19, 1});
137 torch::Tensor obs_data_with_len =
138 torch::cat({obs_pos_data, obs_length_data}, 2);
140 torch::Tensor obs_data_with_attr =
141 torch::cat({obs_data_with_len, obs_attr}, 2);
143 torch::Tensor obs_data_with_id = torch::cat({obs_data_with_attr, obs_id}, 2);
145 torch::cat({torch::zeros({obs_num, (50 - 19), 9}), obs_data_with_id}, 1);
150bool VectornetEvaluator::VectornetProcessMapData(
154 torch::Tensor* ptr_map_data,
155 torch::Tensor* ptr_all_map_p_id,
156 torch::Tensor* ptr_vector_mask) {
157 int map_polyline_num = map_feature->size();
159 for (
int i = 0; i < map_polyline_num && obs_num + i < 450; ++i) {
160 size_t one_polyline_vector_size = map_feature->at(i).size();
161 if (one_polyline_vector_size < 50) {
162 ptr_vector_mask->index_put_({obs_num + i,
163 torch::indexing::Slice(
164 one_polyline_vector_size,
165 torch::indexing::None)},
170 auto opts = torch::TensorOptions().dtype(torch::kDouble);
172 for (
int i = 0; i < map_polyline_num && i + obs_num < 450; ++i) {
173 ptr_all_map_p_id->index_put_({i}, torch::from_blob(map_p_id->at(i).data(),
177 int one_polyline_vector_size = map_feature->at(i).size();
178 for (
int j = 0; j < one_polyline_vector_size && j < 50; ++j) {
179 ptr_map_data->index_put_({i, j},
180 torch::from_blob(map_feature->at(i)[j].data(),
185 *ptr_map_data = ptr_map_data->toType(at::kFloat);
186 *ptr_all_map_p_id = ptr_all_map_p_id->toType(at::kFloat);
191bool VectornetEvaluator::Evaluate(
Obstacle* obstacle_ptr,
193 omp_set_num_threads(1);
198 CHECK_NOTNULL(obstacle_ptr);
199 int id = obstacle_ptr->
id();
201 AERROR <<
"Obstacle [" <<
id <<
"] has no latest feature.";
208 auto start_time_obs = std::chrono::system_clock::now();
210 torch::Tensor target_obstacle_pos = torch::zeros({20, 2});
211 torch::Tensor target_obstacle_pos_step = torch::zeros({20, 2});
212 torch::Tensor vector_mask = torch::zeros({450, 50});
213 torch::Tensor obstacle_data = torch::zeros({obs_num, 20, 2});
214 torch::Tensor all_obs_p_id = torch::zeros({obs_num, 2});
217 if (!VectornetProcessObstaclePosition(obstacle_ptr,
219 &target_obstacle_pos,
220 &target_obstacle_pos_step,
224 AERROR <<
"Obstacle [" <<
id <<
"] processing obstacle position fails.";
228 auto end_time_obs = std::chrono::system_clock::now();
229 std::chrono::duration<double> diff_obs = end_time_obs - start_time_obs;
230 AINFO <<
"obstacle vectors used time: " << diff_obs.count() * 1000 <<
" ms.";
233 CHECK_NOTNULL(latest_feature_ptr);
238 const double pos_x = latest_feature_ptr->
position().
x();
239 const double pos_y = latest_feature_ptr->
position().
y();
244 auto start_time_query = std::chrono::system_clock::now();
246 if (!vector_net_.query(center_point, heading, &map_feature, &map_p_id)) {
250 auto end_time_query = std::chrono::system_clock::now();
251 std::chrono::duration<double> diff_query = end_time_query - start_time_query;
252 AINFO <<
"vectors query used time: " << diff_query.count() * 1000 <<
" ms.";
255 int map_polyline_num = map_feature.size();
257 ((obs_num + map_polyline_num) < 450) ? (obs_num + map_polyline_num) : 450;
260 auto start_time_data_prep = std::chrono::system_clock::now();
261 torch::Tensor map_data = torch::zeros({map_polyline_num, 50, 9});
262 torch::Tensor all_map_p_id = torch::zeros({map_polyline_num, 2});
264 if (!VectornetProcessMapData(&map_feature,
270 AERROR <<
"Obstacle [" <<
id <<
"] processing map data fails.";
275 torch::Tensor polyline_mask = torch::zeros({450});
276 if (data_length < 450) {
277 polyline_mask.index_put_(
278 {torch::indexing::Slice(data_length, torch::indexing::None)}, 1);
283 torch::Tensor data_tmp = torch::cat({obstacle_data, map_data}, 0);
284 torch::Tensor p_id_tmp = torch::cat({all_obs_p_id, all_map_p_id}, 0);
285 torch::Tensor vector_data;
286 torch::Tensor polyline_id;
287 if (data_length < 450) {
288 torch::Tensor data_zeros = torch::zeros({(450 - data_length), 50, 9});
289 torch::Tensor p_id_zeros = torch::zeros({(450 - data_length), 2});
290 vector_data = torch::cat({data_tmp, data_zeros}, 0);
291 polyline_id = torch::cat({p_id_tmp, p_id_zeros}, 0);
293 vector_data = data_tmp.index({torch::indexing::Slice(0, 450)});
294 polyline_id = p_id_tmp.index({torch::indexing::Slice(0, 450)});
298 auto rand_mask = torch::zeros({450}).toType(at::kBool);
300 auto bool_vector_mask = vector_mask.toType(at::kBool);
301 auto bool_polyline_mask = polyline_mask.toType(at::kBool);
303 std::vector<torch::jit::IValue> torch_inputs;
305 torch_inputs.push_back(c10::ivalue::Tuple::create(
306 {std::move(target_obstacle_pos.unsqueeze(0).to(device_)),
307 std::move(target_obstacle_pos_step.unsqueeze(0).to(device_)),
308 std::move(vector_data.unsqueeze(0).to(device_)),
309 std::move(bool_vector_mask.unsqueeze(0).to(device_)),
310 std::move(bool_polyline_mask.unsqueeze(0).to(device_)),
311 std::move(rand_mask.unsqueeze(0).to(device_)),
312 std::move(polyline_id.unsqueeze(0).to(device_))}));
314 auto end_time_data_prep = std::chrono::system_clock::now();
315 std::chrono::duration<double> diff_data_prep =
316 end_time_data_prep - start_time_data_prep;
317 AINFO <<
"vectornet input tensor preparation used time: "
318 << diff_data_prep.count() * 1000 <<
" ms.";
320 auto start_time_inference = std::chrono::system_clock::now();
322 at::Tensor torch_output_tensor = torch_default_output_tensor_;
323 torch_output_tensor =
324 torch_vehicle_model_.forward(torch_inputs).toTensor().to(torch::kCPU);
326 auto end_time_inference = std::chrono::system_clock::now();
327 std::chrono::duration<double> diff_inference =
328 end_time_inference - start_time_inference;
329 AINFO <<
"vectornet inference used time: " << diff_inference.count() * 1000
333 auto start_time_output_process = std::chrono::system_clock::now();
335 auto torch_output = torch_output_tensor.accessor<float, 3>();
336 Trajectory* trajectory = latest_feature_ptr->add_predicted_trajectory();
337 trajectory->set_probability(1.0);
339 for (
int i = 0; i < 30; ++i) {
340 double prev_x = pos_x;
341 double prev_y = pos_y;
343 const auto& last_point = trajectory->trajectory_point(i - 1).path_point();
344 prev_x = last_point.x();
345 prev_y = last_point.y();
348 double dx =
static_cast<double>(torch_output[0][i][0]);
349 double dy =
static_cast<double>(torch_output[0][i][1]);
352 Vec2d offset(dx, dy);
353 Vec2d rotated_offset = offset.
rotate(heading - (M_PI / 2));
354 double point_x = pos_x + rotated_offset.
x();
355 double point_y = pos_y + rotated_offset.
y();
356 point->mutable_path_point()->set_x(point_x);
357 point->mutable_path_point()->set_y(point_y);
360 point->mutable_path_point()->set_theta(
363 point->mutable_path_point()->set_theta(
364 std::atan2(trajectory->trajectory_point(i).path_point().y() -
365 trajectory->trajectory_point(i - 1).path_point().y(),
366 trajectory->trajectory_point(i).path_point().x() -
367 trajectory->trajectory_point(i - 1).path_point().x()));
369 point->set_relative_time(
static_cast<double>(i) *
370 FLAGS_prediction_trajectory_time_resolution);
372 point->set_v(latest_feature_ptr->
speed());
374 double diff_x = point_x - prev_x;
375 double diff_y = point_y - prev_y;
376 point->set_v(std::hypot(diff_x, diff_y) /
377 FLAGS_prediction_trajectory_time_resolution);
381 auto end_time_output_process = std::chrono::system_clock::now();
382 std::chrono::duration<double> diff_output_process =
383 end_time_output_process - start_time_output_process;
384 AINFO <<
"vectornet output process used time: "
385 << diff_output_process.count() * 1000 <<
" ms.";
389bool VectornetEvaluator::ExtractObstaclesHistory(
391 std::vector<std::pair<double, double>>* target_pos_history,
392 std::vector<std::pair<double, double>>* all_obs_length,
393 std::vector<std::vector<std::pair<double, double>>>* all_obs_pos_history,
394 torch::Tensor* vector_mask) {
397 std::pair<double, double> obs_curr_pos = std::make_pair(
400 for (std::size_t i = 0; i < obstacle_ptr->
history_size() && i < 20; ++i) {
402 if (!target_feature.IsInitialized()) {
405 target_pos_history->at(i) =
406 WorldCoordToObjCoordNorth(
407 std::make_pair(target_feature.
position().
x(),
409 obs_curr_pos, obs_curr_heading);
411 all_obs_length->emplace_back(
412 std::make_pair(obs_curr_feature.
length(), obs_curr_feature.
width()));
413 all_obs_pos_history->emplace_back(*target_pos_history);
416 std::vector<std::pair<double, double>> pos_history(20, {0.0, 0.0});
422 int target_id = obstacle_ptr->
id();
423 if (
id == target_id) {
427 all_obs_length->emplace_back(std::make_pair(
428 other_obs_curr_feature.
length(), other_obs_curr_feature.
width()));
431 obs_his_size = obs_his_size <= 20 ? obs_his_size : 20;
432 int cur_idx = all_obs_pos_history->size();
434 if (obs_his_size > 1) {
435 vector_mask->index_put_({cur_idx,
436 torch::indexing::Slice(torch::indexing::None,
437 -(obs_his_size - 1))},
440 vector_mask->index_put_({cur_idx,
441 torch::indexing::Slice(torch::indexing::None,
446 for (
size_t i = 0; i < obs_his_size; ++i) {
448 if (!feature.IsInitialized()) {
451 pos_history[i] = WorldCoordToObjCoordNorth(
453 obs_curr_pos, obs_curr_heading);
455 all_obs_pos_history->emplace_back(pos_history);