26#include "modules/common_msgs/basic_msgs/pnc_point.pb.h"
46 std::vector<Obstacle*> dummy_dynamic_env;
47 Evaluate(obstacle_ptr, obstacles_container, dummy_dynamic_env);
53 std::vector<Obstacle*> dynamic_env) {
55 omp_set_num_threads(1);
56 CHECK_NOTNULL(obstacle_ptr);
60 int id = obstacle_ptr->
id();
62 AERROR <<
"Obstacle [" <<
id <<
"] has no latest feature.";
66 CHECK_NOTNULL(latest_feature_ptr);
67 if (!latest_feature_ptr->has_lane() ||
68 !latest_feature_ptr->
lane().has_lane_graph_ordered()) {
69 AERROR <<
"Obstacle [" <<
id <<
"] has no lane graph.";
73 latest_feature_ptr->mutable_lane()->mutable_lane_graph_ordered();
74 CHECK_NOTNULL(lane_graph_ptr);
76 AERROR <<
"Obstacle [" <<
id <<
"] has no lane sequences.";
79 ADEBUG <<
"There are " << lane_graph_ptr->lane_sequence_size()
80 <<
" lane sequences to scan.";
85 std::vector<double> feature_values;
87 std::vector<std::string> string_feature_values;
90 std::vector<double> labels = {0.0};
91 if (FLAGS_prediction_offline_mode ==
93 std::string learning_data_tag =
"vehicle_cruise";
94 if (latest_feature_ptr->has_junction_feature()) {
95 learning_data_tag =
"vehicle_junction";
98 string_feature_values,
99 learning_data_tag,
nullptr);
100 ADEBUG <<
"Save extracted features for learning locally.";
104 feature_values.push_back(
static_cast<double>(MAX_NUM_LANE));
106 std::vector<torch::jit::IValue> torch_inputs;
107 torch::Tensor torch_input =
108 torch::zeros({1,
static_cast<int>(feature_values.size())});
109 for (
size_t i = 0; i < feature_values.size(); ++i) {
110 torch_input[0][i] =
static_cast<float>(feature_values[i]);
112 torch_inputs.push_back(std::move(torch_input));
113 ModelInference(torch_inputs, torch_lane_scanning_model_, latest_feature_ptr);
119 std::vector<std::string>*
const string_feature_values) {
121 string_feature_values->push_back(
"|");
122 for (
int i = lane_sequence.adc_lane_segment_idx();
123 i < static_cast<int>(lane_sequence.lane_segment_size()); ++i) {
124 string_feature_values->push_back(lane_sequence.lane_segment(i).lane_id());
132 std::vector<double>* feature_values) {
134 CHECK_NOTNULL(obstacle_ptr);
135 int id = obstacle_ptr->
id();
136 CHECK_NOTNULL(lane_graph_ptr);
139 std::vector<double> obstacle_feature_values;
140 if (!ExtractObstacleFeatures(obstacle_ptr, &obstacle_feature_values)) {
141 ADEBUG <<
"Failed to extract obstacle features for obs_id = " << id;
143 if (obstacle_feature_values.size() != OBSTACLE_FEATURE_SIZE) {
144 ADEBUG <<
"Obstacle [" <<
id <<
"] has fewer than "
145 <<
"expected obstacle feature_values "
146 << obstacle_feature_values.size() <<
".";
149 ADEBUG <<
"Obstacle feature size = " << obstacle_feature_values.size();
150 feature_values->insert(feature_values->end(), obstacle_feature_values.begin(),
151 obstacle_feature_values.end());
154 std::vector<double> static_feature_values;
155 std::vector<int> lane_sequence_idx_to_remove;
156 if (!ExtractStaticEnvFeatures(obstacle_ptr, lane_graph_ptr,
157 &static_feature_values,
158 &lane_sequence_idx_to_remove)) {
159 AERROR <<
"Failed to extract static environmental features around obs_id = "
162 if (static_feature_values.size() %
163 (SINGLE_LANE_FEATURE_SIZE *
164 (LANE_POINTS_SIZE + BACKWARD_LANE_POINTS_SIZE)) !=
166 AERROR <<
"Obstacle [" <<
id <<
"] has incorrect static env feature size: "
167 << static_feature_values.size() <<
".";
170 feature_values->insert(feature_values->end(), static_feature_values.begin(),
171 static_feature_values.end());
176bool LaneScanningEvaluator::ExtractObstacleFeatures(
177 const Obstacle* obstacle_ptr, std::vector<double>* feature_values) {
179 CHECK_NOTNULL(obstacle_ptr);
180 feature_values->clear();
181 FLAGS_cruise_historical_frame_length = 20;
182 int max_num_poly_pt = 20;
183 std::vector<double> has_history(FLAGS_cruise_historical_frame_length, 1.0);
184 std::vector<std::pair<double, double>> pos_history(
185 FLAGS_cruise_historical_frame_length, std::make_pair(0.0, 0.0));
186 std::vector<std::pair<double, double>> vel_history(
187 FLAGS_cruise_historical_frame_length, std::make_pair(0.0, 0.0));
188 std::vector<std::pair<double, double>> acc_history(
189 FLAGS_cruise_historical_frame_length, std::make_pair(0.0, 0.0));
190 std::vector<double> vel_heading_history(FLAGS_cruise_historical_frame_length,
192 std::vector<double> vel_heading_changing_rate_history(
193 FLAGS_cruise_historical_frame_length, 0.0);
194 std::vector<std::vector<std::pair<double, double>>> polygon_points_history(
195 FLAGS_cruise_historical_frame_length,
196 std::vector<std::pair<double, double>>(max_num_poly_pt,
197 std::make_pair(0.0, 0.0)));
202 std::pair<double, double> obs_curr_pos = std::make_pair(
204 double prev_timestamp = obs_curr_feature.
timestamp();
208 <<
" history timestamps.";
209 for (std::size_t i = 0; i < std::min(obstacle_ptr->
history_size(),
210 FLAGS_cruise_historical_frame_length);
213 if (!feature.IsInitialized()) {
214 has_history[i] = 0.0;
217 if (i != 0 && has_history[i - 1] == 0.0) {
218 has_history[i] = 0.0;
222 if (feature.has_position()) {
226 has_history[i] = 0.0;
229 if (feature.has_velocity()) {
232 obs_curr_pos, obs_curr_heading);
234 obs_curr_pos, obs_curr_heading);
235 vel_history[i] = std::make_pair(vel_end.first - vel_begin.first,
236 vel_end.second - vel_begin.second);
238 has_history[i] = 0.0;
241 if (feature.has_acceleration()) {
245 obs_curr_pos, obs_curr_heading);
247 obs_curr_pos, obs_curr_heading);
248 acc_history[i] = std::make_pair(acc_end.first - acc_begin.first,
249 acc_end.second - acc_begin.second);
251 has_history[i] = 0.0;
254 if (feature.has_velocity_heading()) {
257 vel_heading_changing_rate_history[i] =
258 (vel_heading_history[i] - vel_heading_history[i - 1]) /
259 (feature.
timestamp() - prev_timestamp + FLAGS_double_precision);
263 has_history[i] = 0.0;
266 for (
int j = 0; j < feature.polygon_point_size(); ++j) {
267 if (j >= max_num_poly_pt) {
270 polygon_points_history[i][j].first = feature.
polygon_point(j).
x();
271 polygon_points_history[i][j].second = feature.
polygon_point(j).
y();
276 i < FLAGS_cruise_historical_frame_length; ++i) {
277 has_history[i] = 0.0;
281 for (std::size_t i = 0; i < FLAGS_cruise_historical_frame_length; i++) {
282 feature_values->push_back(has_history[i]);
283 feature_values->push_back(pos_history[i].first);
284 feature_values->push_back(pos_history[i].second);
285 feature_values->push_back(vel_history[i].first);
286 feature_values->push_back(vel_history[i].second);
287 feature_values->push_back(acc_history[i].first);
288 feature_values->push_back(acc_history[i].second);
289 feature_values->push_back(vel_heading_history[i]);
290 feature_values->push_back(vel_heading_changing_rate_history[i]);
291 for (
int j = 0; j < max_num_poly_pt; ++j) {
292 feature_values->push_back(polygon_points_history[i][j].first);
293 feature_values->push_back(polygon_points_history[i][j].second);
300bool LaneScanningEvaluator::ExtractStaticEnvFeatures(
301 const Obstacle* obstacle_ptr,
const LaneGraph* lane_graph_ptr,
302 std::vector<double>* feature_values,
303 std::vector<int>* lane_sequence_idx_to_remove) {
305 CHECK_NOTNULL(lane_graph_ptr);
306 feature_values->clear();
309 const Feature& obs_curr_feature = obstacle_ptr->latest_feature();
311 std::pair<double, double> obs_curr_pos = std::make_pair(
312 obs_curr_feature.position().x(), obs_curr_feature.position().y());
316 for (
int i = 0; i < lane_graph_ptr->lane_sequence_size(); ++i) {
319 const LaneSequence& lane_sequence = lane_graph_ptr->lane_sequence(i);
323 std::vector<double> backward_feature_values;
324 for (
int j = lane_sequence.adc_lane_segment_idx(); j >= 0; --j) {
325 if (count >= SINGLE_LANE_FEATURE_SIZE * BACKWARD_LANE_POINTS_SIZE) {
328 const LaneSegment& lane_segment = lane_sequence.lane_segment(j);
329 int k_starting_idx = lane_segment.lane_point_size() - 1;
330 if (j == lane_sequence.adc_lane_segment_idx()) {
331 k_starting_idx = std::min(lane_segment.adc_lane_point_idx(),
332 lane_segment.lane_point_size() - 1);
334 for (
int k = k_starting_idx; k >= 0; --k) {
335 if (count >= SINGLE_LANE_FEATURE_SIZE * BACKWARD_LANE_POINTS_SIZE) {
338 const LanePoint& lane_point = lane_segment.lane_point(k);
339 std::pair<double, double> relative_s_l =
341 lane_point.position().y()),
342 obs_curr_pos, obs_curr_heading);
343 double relative_ang =
346 backward_feature_values.push_back(lane_point.kappa());
347 backward_feature_values.push_back(relative_ang);
348 backward_feature_values.push_back(relative_s_l.first);
349 backward_feature_values.push_back(relative_s_l.second);
355 while (count >= SINGLE_LANE_FEATURE_SIZE * 2 &&
356 count < SINGLE_LANE_FEATURE_SIZE * BACKWARD_LANE_POINTS_SIZE) {
357 std::size_t s = backward_feature_values.size();
358 double relative_l_new =
359 2 * backward_feature_values[s - 1] - backward_feature_values[s - 5];
360 double relative_s_new =
361 2 * backward_feature_values[s - 2] - backward_feature_values[s - 6];
362 double relative_ang_new = backward_feature_values[s - 3];
364 backward_feature_values.push_back(0.0);
365 backward_feature_values.push_back(relative_ang_new);
366 backward_feature_values.push_back(relative_s_new);
367 backward_feature_values.push_back(relative_l_new);
372 for (
int j =
static_cast<int>(backward_feature_values.size()) - 1; j >= 0;
374 feature_values->push_back(backward_feature_values[j]);
379 for (
int j = lane_sequence.adc_lane_segment_idx();
380 j < lane_sequence.lane_segment_size(); ++j) {
381 if (count >= SINGLE_LANE_FEATURE_SIZE * LANE_POINTS_SIZE) {
384 const LaneSegment& lane_segment = lane_sequence.lane_segment(j);
385 int k_starting_idx = 0;
386 if (j == lane_sequence.adc_lane_segment_idx()) {
387 k_starting_idx = std::min(lane_segment.adc_lane_point_idx(),
388 lane_segment.lane_point_size() - 1);
390 for (
int k = k_starting_idx; k < lane_segment.lane_point_size(); ++k) {
391 if (count >= SINGLE_LANE_FEATURE_SIZE * LANE_POINTS_SIZE) {
394 const LanePoint& lane_point = lane_segment.lane_point(k);
395 std::pair<double, double> relative_s_l =
397 lane_point.position().y()),
398 obs_curr_pos, obs_curr_heading);
399 double relative_ang =
402 feature_values->push_back(relative_s_l.second);
403 feature_values->push_back(relative_s_l.first);
404 feature_values->push_back(relative_ang);
405 feature_values->push_back(lane_point.kappa());
410 while (count >= SINGLE_LANE_FEATURE_SIZE * 2 &&
411 count < SINGLE_LANE_FEATURE_SIZE * LANE_POINTS_SIZE) {
412 std::size_t s = feature_values->size();
413 double relative_l_new = 2 * feature_values->operator[](s - 4) -
414 feature_values->operator[](s - 8);
415 double relative_s_new = 2 * feature_values->operator[](s - 3) -
416 feature_values->operator[](s - 7);
417 double relative_ang_new = feature_values->operator[](s - 2);
419 feature_values->push_back(relative_l_new);
420 feature_values->push_back(relative_s_new);
421 feature_values->push_back(relative_ang_new);
422 feature_values->push_back(0.0);
427 if (FLAGS_prediction_offline_mode ==
433 size_t max_feature_size =
434 LANE_POINTS_SIZE * SINGLE_LANE_FEATURE_SIZE * MAX_NUM_LANE;
435 while (feature_values->size() < max_feature_size) {
436 feature_values->push_back(0.0);
442void LaneScanningEvaluator::LoadModel() {
443 if (FLAGS_use_cuda && torch::cuda::is_available()) {
444 ADEBUG <<
"CUDA is available";
445 device_ = torch::Device(torch::kCUDA);
447 torch::set_num_threads(1);
448 torch_lane_scanning_model_ =
449 torch::jit::load(FLAGS_torch_vehicle_lane_scanning_file, device_);
452void LaneScanningEvaluator::ModelInference(
453 const std::vector<torch::jit::IValue>& torch_inputs,
454 torch::jit::script::Module torch_model, Feature* feature_ptr) {
455 auto torch_output_tensor = torch_model.forward(torch_inputs).toTensor();
456 auto torch_output = torch_output_tensor.accessor<float, 3>();
457 for (
size_t i = 0; i < SHORT_TERM_TRAJECTORY_SIZE; ++i) {
458 TrajectoryPoint point;
459 double dx =
static_cast<double>(torch_output[0][0][i]);
461 static_cast<double>(torch_output[0][0][i + SHORT_TERM_TRAJECTORY_SIZE]);
462 Vec2d offset(dx, dy);
463 Vec2d rotated_offset = offset.rotate(feature_ptr->velocity_heading());
464 double point_x = feature_ptr->position().x() + rotated_offset.x();
465 double point_y = feature_ptr->position().y() + rotated_offset.y();
466 point.mutable_path_point()->set_x(point_x);
467 point.mutable_path_point()->set_y(point_y);
468 point.set_relative_time(
static_cast<double>(i) *
469 FLAGS_prediction_trajectory_time_resolution);
470 feature_ptr->add_short_term_predicted_trajectory_points()->CopyFrom(point);
Implements a class of 2-dimensional vectors.
double WorldAngleToObjAngle(double input_world_angle, double obj_world_angle)
std::pair< double, double > WorldCoordToObjCoord(std::pair< double, double > input_world_coord, std::pair< double, double > obj_world_coord, double obj_world_angle)
ObstacleConf::EvaluatorType evaluator_type_
static void InsertDataForLearning(const Feature &feature, const std::vector< double > &feature_values, const std::string &category, const LaneSequence *lane_sequence_ptr)
Insert a data_for_learning
LaneScanningEvaluator()
Constructor
bool Evaluate(Obstacle *obstacle_ptr, ObstaclesContainer *obstacles_container) override
Override Evaluate
bool ExtractFeatures(const Obstacle *obstacle_ptr, const LaneGraph *lane_graph_ptr, std::vector< double > *feature_values)
Extract features for learning model's input
bool ExtractStringFeatures(const LaneGraph &lane_graph, std::vector< std::string > *const string_feature_values)
Feature * mutable_latest_feature()
Get a pointer to the latest feature.
int id() const
Get the obstacle's ID.
size_t history_size() const
Get the number of historical features.
const Feature & feature(const size_t i) const
Get the ith feature from latest to earliest.
void SetEvaluatorType(const ObstacleConf::EvaluatorType &evaluator_type)
const Feature & latest_feature() const
Get the latest feature.
static const int kDumpDataForLearning
Use container manager to manage all containers
Holds all global constants for the prediction module.
optional double timestamp
optional apollo::common::Point3D velocity
optional double velocity_heading
optional apollo::common::Point3D position
repeated apollo::common::Point3D polygon_point
optional apollo::common::Point3D acceleration
repeated LaneSequence lane_sequence
@ LANE_SCANNING_EVALUATOR