Apollo 10.0
自动驾驶开放平台
evaluator_manager.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2017 The Apollo Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *****************************************************************************/
16
18
19#include <algorithm>
20
41
42namespace apollo {
43namespace prediction {
44
46using IdObstacleListMap = std::unordered_map<int, std::list<Obstacle*>>;
47
48namespace {
49
50bool IsTrainable(const Feature& feature) {
51 if (feature.id() == FLAGS_ego_vehicle_id) {
52 return false;
53 }
54 if (feature.priority().priority() == ObstaclePriority::IGNORE ||
55 feature.is_still() || feature.type() != PerceptionObstacle::VEHICLE) {
56 return false;
57 }
58 return true;
59}
60
61void GroupObstaclesByObstacleIds(ObstaclesContainer* const obstacles_container,
62 IdObstacleListMap* const id_obstacle_map) {
63 int caution_thread_idx = 0;
64 for (int obstacle_id :
65 obstacles_container->curr_frame_considered_obstacle_ids()) {
66 Obstacle* obstacle_ptr = obstacles_container->GetObstacle(obstacle_id);
67 if (obstacle_ptr == nullptr) {
68 AERROR << "Null obstacle [" << obstacle_id << "] found";
69 continue;
70 }
71 if (obstacle_ptr->IsStill()) {
72 ADEBUG << "Ignore still obstacle [" << obstacle_id << "]";
73 continue;
74 }
75 const Feature& feature = obstacle_ptr->latest_feature();
76 if (feature.priority().priority() == ObstaclePriority::IGNORE) {
77 ADEBUG << "Skip ignored obstacle [" << obstacle_id << "]";
78 continue;
79 } else if (feature.priority().priority() == ObstaclePriority::CAUTION) {
80 caution_thread_idx = caution_thread_idx % FLAGS_max_caution_thread_num;
81 (*id_obstacle_map)[caution_thread_idx].push_back(obstacle_ptr);
82 ADEBUG << "Cautioned obstacle [" << obstacle_id << "] for thread"
83 << caution_thread_idx;
84 ++caution_thread_idx;
85 } else {
86 int normal_thread_num =
87 FLAGS_max_thread_num - FLAGS_max_caution_thread_num;
88 int id_mod =
89 obstacle_id % normal_thread_num + FLAGS_max_caution_thread_num;
90 (*id_obstacle_map)[id_mod].push_back(obstacle_ptr);
91 ADEBUG << "Normal obstacle [" << obstacle_id << "] for thread" << id_mod;
92 }
93 }
94}
95
96} // namespace
97
99
100void EvaluatorManager::RegisterEvaluators() {
101 RegisterEvaluator(ObstacleConf::MLP_EVALUATOR);
102 RegisterEvaluator(ObstacleConf::COST_EVALUATOR);
103 RegisterEvaluator(ObstacleConf::CRUISE_MLP_EVALUATOR);
104 RegisterEvaluator(ObstacleConf::JUNCTION_MLP_EVALUATOR);
106 RegisterEvaluator(ObstacleConf::LANE_SCANNING_EVALUATOR);
108 RegisterEvaluator(ObstacleConf::JUNCTION_MAP_EVALUATOR);
109 if (!FLAGS_enable_multi_agent_pedestrian_evaluator) {
110 RegisterEvaluator(ObstacleConf::SEMANTIC_LSTM_EVALUATOR);
111 }
112 if (!FLAGS_enable_multi_agent_vehicle_evaluator) {
114 RegisterEvaluator(ObstacleConf::VECTORNET_EVALUATOR);
115 }
116 if (FLAGS_enable_multi_agent_pedestrian_evaluator ||
117 FLAGS_enable_multi_agent_vehicle_evaluator) {
118 RegisterEvaluator(ObstacleConf::MULTI_AGENT_EVALUATOR);
119 }
120}
121
123 if (FLAGS_enable_semantic_map) {
124 semantic_map_.reset(new SemanticMap());
125 semantic_map_->Init();
126 AINFO << "Init SemanticMap instance.";
127 } else {
128 AINFO << "SemanticMap is not enabled.";
129 }
130
131 RegisterEvaluators();
132
133 for (const auto& obstacle_conf : config.obstacle_conf()) {
134 if (!obstacle_conf.has_obstacle_type()) {
135 AERROR << "Obstacle config [" << obstacle_conf.ShortDebugString()
136 << "] has not defined obstacle type.";
137 continue;
138 }
139
140 if (!obstacle_conf.has_evaluator_type()) {
141 ADEBUG << "Obstacle config [" << obstacle_conf.ShortDebugString()
142 << "] has not defined evaluator type.";
143 continue;
144 }
145
146 if (obstacle_conf.has_obstacle_status()) {
147 switch (obstacle_conf.obstacle_type()) {
149 if (obstacle_conf.obstacle_status() == ObstacleConf::ON_LANE) {
150 if (obstacle_conf.priority_type() == ObstaclePriority::CAUTION) {
151 vehicle_on_lane_caution_evaluator_ =
152 obstacle_conf.evaluator_type();
153 } else {
154 vehicle_on_lane_evaluator_ = obstacle_conf.evaluator_type();
155 }
156 }
157 if (obstacle_conf.obstacle_status() == ObstacleConf::IN_JUNCTION) {
158 if (obstacle_conf.priority_type() == ObstaclePriority::CAUTION) {
159 vehicle_in_junction_caution_evaluator_ =
160 obstacle_conf.evaluator_type();
161 } else {
162 vehicle_in_junction_evaluator_ = obstacle_conf.evaluator_type();
163 }
164 }
165 break;
166 }
168 if (obstacle_conf.obstacle_status() == ObstacleConf::ON_LANE) {
169 cyclist_on_lane_evaluator_ = obstacle_conf.evaluator_type();
170 }
171 break;
172 }
174 if (FLAGS_prediction_offline_mode ==
176 obstacle_conf.priority_type() == ObstaclePriority::CAUTION) {
177 pedestrian_evaluator_ = obstacle_conf.evaluator_type();
178 break;
179 }
180 }
182 if (obstacle_conf.obstacle_status() == ObstacleConf::ON_LANE) {
183 default_on_lane_evaluator_ = obstacle_conf.evaluator_type();
184 }
185 break;
186 }
187 default: {
188 break;
189 }
190 }
191 } else if (obstacle_conf.has_interactive_tag()) {
192 interaction_evaluator_ = obstacle_conf.evaluator_type();
193 }
194 }
195
196 AINFO << "Defined vehicle on lane obstacle evaluator ["
197 << vehicle_on_lane_evaluator_ << "]";
198 AINFO << "Defined cyclist on lane obstacle evaluator ["
199 << cyclist_on_lane_evaluator_ << "]";
200 AINFO << "Defined default on lane obstacle evaluator ["
201 << default_on_lane_evaluator_ << "]";
202}
203
205 const ObstacleConf::EvaluatorType& type) {
206 auto it = evaluators_.find(type);
207 return it != evaluators_.end() ? it->second.get() : nullptr;
208}
209
211 const ADCTrajectoryContainer* adc_trajectory_container,
212 ObstaclesContainer* obstacles_container) {
213 if (FLAGS_enable_semantic_map ||
214 FLAGS_prediction_offline_mode == PredictionConstants::kDumpFrameEnv) {
215 size_t max_num_frame = 10;
216 if (FLAGS_prediction_offline_mode == PredictionConstants::kDumpFrameEnv) {
217 max_num_frame = 20;
218 }
219 BuildObstacleIdHistoryMap(obstacles_container, max_num_frame);
220 DumpCurrentFrameEnv(obstacles_container);
221 if (FLAGS_prediction_offline_mode == PredictionConstants::kDumpFrameEnv) {
222 return;
223 }
224 semantic_map_->RunCurrFrame(obstacle_id_history_map_);
225 }
226
227 std::vector<Obstacle*> dynamic_env;
228
229 if (FLAGS_enable_multi_agent_pedestrian_evaluator ||
230 FLAGS_enable_multi_agent_vehicle_evaluator) {
231 auto start_time_multi = std::chrono::system_clock::now();
232 EvaluateMultiObstacle(adc_trajectory_container, obstacles_container);
233 auto end_time_multi = std::chrono::system_clock::now();
234 std::chrono::duration<double> time_cost_multi =
235 end_time_multi - start_time_multi;
236 AINFO << "multi agents evaluator used time: "
237 << time_cost_multi.count() * 1000 << " ms.";
238 }
239
240 if (FLAGS_enable_multi_thread) {
241 IdObstacleListMap id_obstacle_map;
242 GroupObstaclesByObstacleIds(obstacles_container, &id_obstacle_map);
244 id_obstacle_map.begin(), id_obstacle_map.end(),
245 [&](IdObstacleListMap::iterator::value_type& obstacles_iter) {
246 for (auto obstacle_ptr : obstacles_iter.second) {
247 EvaluateObstacle(adc_trajectory_container, obstacle_ptr,
248 obstacles_container, dynamic_env);
249 }
250 });
251 } else {
252 for (int id : obstacles_container->curr_frame_considered_obstacle_ids()) {
253 Obstacle* obstacle = obstacles_container->GetObstacle(id);
254
255 if (obstacle == nullptr) {
256 continue;
257 }
258 if (obstacle->IsStill()) {
259 ADEBUG << "Ignore still obstacle [" << id << "] in evaluator_manager";
260 continue;
261 }
262
263 EvaluateObstacle(adc_trajectory_container, obstacle,
264 obstacles_container, dynamic_env);
265 }
266 }
267}
268
269void EvaluatorManager::EvaluateObstacle(
270 const ADCTrajectoryContainer* adc_trajectory_container,
271 Obstacle* obstacle,
272 ObstaclesContainer* obstacles_container,
273 std::vector<Obstacle*> dynamic_env) {
274 Evaluator* evaluator = nullptr;
275 // Select different evaluators depending on the obstacle's type.
276 switch (obstacle->type()) {
277 case PerceptionObstacle::VEHICLE: {
278 if (FLAGS_enable_multi_agent_vehicle_evaluator) {
279 AINFO << "The vehicles are evaluated by multi agent evaluator!";
280 break;
281 }
282 if (obstacle->IsCaution() && !obstacle->IsSlow()) {
283 if (obstacle->IsInteractiveObstacle()) {
284 evaluator = GetEvaluator(interaction_evaluator_);
285 } else if (obstacle->IsNearJunction()) {
286 evaluator = GetEvaluator(vehicle_in_junction_caution_evaluator_);
287 } else if (obstacle->IsOnLane()) {
288 evaluator = GetEvaluator(vehicle_on_lane_caution_evaluator_);
289 } else {
290 evaluator = GetEvaluator(vehicle_default_caution_evaluator_);
291 }
292 CHECK_NOTNULL(evaluator);
293 AINFO << "Caution Obstacle: " << obstacle->id() << " used " << evaluator->GetName();
294 // Evaluate and break if success
295 if (evaluator->GetName() == "JOINTLY_PREDICTION_PLANNING_EVALUATOR") {
296 if (evaluator->Evaluate(adc_trajectory_container,
297 obstacle, obstacles_container)) {
298 break;
299 } else {
300 AERROR << "Obstacle: " << obstacle->id()
301 << " interaction evaluator failed,"
302 << " downgrade to normal level!";
303 }
304 } else {
305 if (evaluator->Evaluate(obstacle, obstacles_container)) {
306 break;
307 } else {
308 AERROR << "Obstacle: " << obstacle->id()
309 << " caution evaluator failed, downgrade to normal level!";
310 }
311 }
312 }
313
314 // if obstacle is not caution or caution_evaluator run failed
315 if (obstacle->HasJunctionFeatureWithExits() &&
316 !obstacle->IsCloseToJunctionExit()) {
317 evaluator = GetEvaluator(vehicle_in_junction_evaluator_);
318 } else if (obstacle->IsOnLane()) {
319 evaluator = GetEvaluator(vehicle_on_lane_evaluator_);
320 } else {
321 AINFO << "Obstacle: " << obstacle->id()
322 << " is neither on lane, nor in junction. Skip evaluating.";
323 break;
324 }
325 AINFO << "Normal Obstacle: " << obstacle->id() << " used " << evaluator->GetName();
326 CHECK_NOTNULL(evaluator);
327 if (evaluator->GetName() == "LANE_SCANNING_EVALUATOR") {
328 evaluator->Evaluate(obstacle, obstacles_container, dynamic_env);
329 } else {
330 evaluator->Evaluate(obstacle, obstacles_container);
331 }
332 break;
333 }
334 case PerceptionObstacle::BICYCLE: {
335 if (obstacle->IsOnLane()) {
336 evaluator = GetEvaluator(cyclist_on_lane_evaluator_);
337 CHECK_NOTNULL(evaluator);
338 evaluator->Evaluate(obstacle, obstacles_container);
339 }
340 break;
341 }
342 case PerceptionObstacle::PEDESTRIAN: {
343 if (FLAGS_prediction_offline_mode ==
344 PredictionConstants::kDumpDataForLearning ||
345 (!FLAGS_enable_multi_agent_pedestrian_evaluator &&
346 obstacle->latest_feature().priority().priority() ==
347 ObstaclePriority::CAUTION)) {
348 evaluator = GetEvaluator(pedestrian_evaluator_);
349 CHECK_NOTNULL(evaluator);
350 auto start_time_inference = std::chrono::system_clock::now();
351 evaluator->Evaluate(obstacle, obstacles_container);
352 auto end_time_inference = std::chrono::system_clock::now();
353 std::chrono::duration<double> time_cost_lstm =
354 end_time_inference - start_time_inference;
355 AINFO << "semantic lstm evaluator used time: "
356 << time_cost_lstm.count() * 1000 << " ms.";
357 break;
358 }
359 }
360 default: {
361 if (obstacle->IsOnLane()) {
362 evaluator = GetEvaluator(default_on_lane_evaluator_);
363 CHECK_NOTNULL(evaluator);
364 evaluator->Evaluate(obstacle, obstacles_container);
365 }
366 break;
367 }
368 }
369}
370
371void EvaluatorManager::EvaluateMultiObstacle(
372 const ADCTrajectoryContainer* adc_trajectory_container,
373 ObstaclesContainer* obstacles_container) {
374 Evaluator* evaluator = nullptr;
375 evaluator = GetEvaluator(multi_agent_evaluator_);
376 CHECK_NOTNULL(evaluator);
377 std::vector<int> obs_ids = obstacles_container->curr_frame_considered_obstacle_ids();
378
379 // 1. Evaluate the pedestrain
380 if (FLAGS_enable_multi_agent_pedestrian_evaluator) {
381 for (int id : obs_ids) {
382 Obstacle* obstacle = obstacles_container->GetObstacle(id);
383 // whether the pedestrian exsit in the conside obstacle list
385 !obstacle->IsStill()) {
386 evaluator->Evaluate(adc_trajectory_container,
387 obstacle, obstacles_container);
388 AINFO << "Succeed to run multi agent pedestrian evaluator!";
389 break;
390 }
391 }
392 }
393
394 // 2. Evaluate the vechicle
395 if (FLAGS_enable_multi_agent_vehicle_evaluator) {
396 for (int id : obs_ids) {
397 Obstacle* obstacle = obstacles_container->GetObstacle(id);
398 // whether the vehicle exsit in the conside obstacle list
400 !obstacle->IsStill()) {
401 evaluator->Evaluate(adc_trajectory_container,
402 obstacle, obstacles_container);
403 AINFO << "Succeed to run multi agent vehicle evaluator!";
404 break;
405 }
406 }
407 }
408}
409
410void EvaluatorManager::EvaluateObstacle(
411 Obstacle* obstacle, ObstaclesContainer* obstacles_container) {
412 std::vector<Obstacle*> dummy_dynamic_env;
413 ADCTrajectoryContainer* adc_trajectory_container = nullptr;
414 EvaluateObstacle(adc_trajectory_container, obstacle,
415 obstacles_container, dummy_dynamic_env);
416}
417
418void EvaluatorManager::BuildObstacleIdHistoryMap(
419 ObstaclesContainer* obstacles_container, size_t max_num_frame) {
420 obstacle_id_history_map_.clear();
421 std::vector<int> obstacle_ids =
422 obstacles_container->curr_frame_movable_obstacle_ids();
423 obstacle_ids.push_back(FLAGS_ego_vehicle_id);
424 for (int id : obstacle_ids) {
425 Obstacle* obstacle = obstacles_container->GetObstacle(id);
426 if (obstacle == nullptr || obstacle->history_size() == 0) {
427 continue;
428 }
429 size_t num_frames = std::min(max_num_frame, obstacle->history_size());
430 for (size_t i = 0; i < num_frames; ++i) {
431 const Feature& obstacle_feature = obstacle->feature(i);
432 Feature feature;
433 feature.set_id(obstacle_feature.id());
434 feature.set_timestamp(obstacle_feature.timestamp());
435 feature.set_type(obstacle_feature.type());
436 feature.mutable_position()->CopyFrom(obstacle_feature.position());
437 feature.set_theta(obstacle_feature.velocity_heading());
438 feature.mutable_interactive_tag()->CopyFrom(
439 obstacle_feature.interactive_tag());
440 feature.mutable_priority()->CopyFrom(obstacle_feature.priority());
441
442 if (obstacle_feature.id() != FLAGS_ego_vehicle_id) {
443 feature.mutable_polygon_point()->CopyFrom(
444 obstacle_feature.polygon_point());
445 feature.set_length(obstacle_feature.length());
446 feature.set_width(obstacle_feature.width());
447 } else {
448 const auto& vehicle_config =
449 common::VehicleConfigHelper::Instance()->GetConfig();
450 feature.set_length(vehicle_config.vehicle_param().length());
451 feature.set_width(vehicle_config.vehicle_param().width());
452 }
453 obstacle_id_history_map_[id].add_feature()->CopyFrom(feature);
454 }
455 obstacle_id_history_map_[id].set_is_trainable(
456 IsTrainable(obstacle->latest_feature()));
457 }
458}
459
460void EvaluatorManager::DumpCurrentFrameEnv(
461 ObstaclesContainer* obstacles_container) {
462 FrameEnv curr_frame_env;
463 curr_frame_env.set_timestamp(obstacles_container->timestamp());
464 for (const auto obstacle_id_history_pair : obstacle_id_history_map_) {
465 int id = obstacle_id_history_pair.first;
466 if (id != FLAGS_ego_vehicle_id) {
467 curr_frame_env.add_obstacles_history()->CopyFrom(
468 obstacle_id_history_pair.second);
469 } else {
470 curr_frame_env.mutable_ego_history()->CopyFrom(
471 obstacle_id_history_pair.second);
472 }
473 }
474 FeatureOutput::InsertFrameEnv(curr_frame_env);
475}
476
477std::unique_ptr<Evaluator> EvaluatorManager::CreateEvaluator(
478 const ObstacleConf::EvaluatorType& type) {
479 std::unique_ptr<Evaluator> evaluator_ptr(nullptr);
480 switch (type) {
481 case ObstacleConf::MLP_EVALUATOR: {
482 evaluator_ptr.reset(new MLPEvaluator());
483 break;
484 }
485 case ObstacleConf::CRUISE_MLP_EVALUATOR: {
486 evaluator_ptr.reset(new CruiseMLPEvaluator());
487 break;
488 }
489 case ObstacleConf::JUNCTION_MLP_EVALUATOR: {
490 evaluator_ptr.reset(new JunctionMLPEvaluator());
491 break;
492 }
493 case ObstacleConf::COST_EVALUATOR: {
494 evaluator_ptr.reset(new CostEvaluator());
495 break;
496 }
497 case ObstacleConf::CYCLIST_KEEP_LANE_EVALUATOR: {
498 evaluator_ptr.reset(new CyclistKeepLaneEvaluator());
499 break;
500 }
501 case ObstacleConf::LANE_SCANNING_EVALUATOR: {
502 evaluator_ptr.reset(new LaneScanningEvaluator());
503 break;
504 }
505 case ObstacleConf::LANE_AGGREGATING_EVALUATOR: {
506 evaluator_ptr.reset(new LaneAggregatingEvaluator());
507 break;
508 }
509 case ObstacleConf::JUNCTION_MAP_EVALUATOR: {
510 evaluator_ptr.reset(new JunctionMapEvaluator(semantic_map_.get()));
511 break;
512 }
513 case ObstacleConf::SEMANTIC_LSTM_EVALUATOR: {
514 evaluator_ptr.reset(new SemanticLSTMEvaluator(semantic_map_.get()));
515 break;
516 }
517 case ObstacleConf::JOINTLY_PREDICTION_PLANNING_EVALUATOR: {
518 evaluator_ptr.reset(new JointlyPredictionPlanningEvaluator());
519 break;
520 }
521 case ObstacleConf::VECTORNET_EVALUATOR: {
522 evaluator_ptr.reset(new VectornetEvaluator());
523 break;
524 }
525 case ObstacleConf::MULTI_AGENT_EVALUATOR: {
526 evaluator_ptr.reset(new MultiAgentEvaluator());
527 break;
528 }
529 default: {
530 break;
531 }
532 }
533 return evaluator_ptr;
534}
535
536void EvaluatorManager::RegisterEvaluator(
537 const ObstacleConf::EvaluatorType& type) {
538 evaluators_[type] = CreateEvaluator(type);
539 AINFO << "Evaluator [" << type << "] is registered.";
540}
541
542} // namespace prediction
543} // namespace apollo
Evaluator * GetEvaluator(const ObstacleConf::EvaluatorType &type)
Get evaluator
void EvaluateMultiObstacle(const ADCTrajectoryContainer *adc_trajectory_container, ObstaclesContainer *obstacles_container)
void Run(const ADCTrajectoryContainer *adc_trajectory_container, ObstaclesContainer *obstacles_container)
Run evaluators
void Init(const PredictionConf &config)
Initializer
virtual bool Evaluate(Obstacle *obstacle, ObstaclesContainer *obstacles_container)=0
Evaluate an obstacle
virtual std::string GetName()=0
Get the name of evaluator
Prediction obstacle.
Definition obstacle.h:52
bool HasJunctionFeatureWithExits() const
Check if the obstacle has junction feature.
Definition obstacle.cc:622
bool IsNearJunction()
Check if the obstacle is near a junction.
Definition obstacle.cc:130
perception::PerceptionObstacle::Type type() const
Get the type of perception obstacle's type.
Definition obstacle.cc:54
bool IsCloseToJunctionExit() const
Check if the obstacle is close to a junction exit.
Definition obstacle.cc:274
bool IsStill()
Check if the obstacle is still.
Definition obstacle.cc:95
int id() const
Get the obstacle's ID.
Definition obstacle.cc:60
size_t history_size() const
Get the number of historical features.
Definition obstacle.cc:93
const Feature & feature(const size_t i) const
Get the ith feature from latest to earliest.
Definition obstacle.cc:67
bool IsInteractiveObstacle() const
Definition obstacle.cc:1475
bool IsOnLane() const
Check if the obstacle is on any lane.
Definition obstacle.cc:107
bool IsSlow()
Check if the obstacle is slow.
Definition obstacle.cc:102
const Feature & latest_feature() const
Get the latest feature.
Definition obstacle.cc:78
const std::vector< int > & curr_frame_movable_obstacle_ids()
Get movable obstacle IDs in the current frame
const std::vector< int > & curr_frame_considered_obstacle_ids()
Get non-ignore obstacle IDs in the current frame
Obstacle * GetObstacle(const int id)
Get obstacle pointer
static void ForEach(InputIter begin, InputIter end, F f)
Use container manager to manage all containers
Define the cyclist keep lane predictor class
Define the lane aggregating evaluator class
#define ADEBUG
Definition log.h:41
#define AERROR
Definition log.h:44
#define AINFO
Definition log.h:42
bool IsTrainable(const Feature &feature)
std::unordered_map< int, std::list< Obstacle * > > IdObstacleListMap
class register implement
Definition arena_queue.h:37
Obstacles container
Use evaluator manager to manage all evaluators
Holds all global constants for the prediction module.
optional apollo::perception::PerceptionObstacle::Type type
optional ObstaclePriority priority