obstacles_prioritizer.cc 17.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/******************************************************************************
 * Copyright 2019 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

#include "modules/prediction/scenario/prioritization/obstacles_prioritizer.h"

#include <algorithm>
20
#include <limits>
21
#include <memory>
22
#include <queue>
23
#include <string>
24 25 26
#include <unordered_map>
#include <unordered_set>
#include <utility>
27 28 29

#include "modules/prediction/common/prediction_gflags.h"
#include "modules/prediction/common/prediction_map.h"
30
#include "modules/prediction/container/adc_trajectory/adc_trajectory_container.h"
31
#include "modules/prediction/container/container_manager.h"
32
#include "modules/prediction/container/obstacles/obstacle_clusters.h"
33 34 35 36 37
#include "modules/prediction/container/pose/pose_container.h"

namespace apollo {
namespace prediction {

38
using apollo::perception::PerceptionObstacle;
39 40
using common::adapter::AdapterConfig;
using common::math::Box2d;
41
using common::math::Vec2d;
K
kechxu 已提交
42
using hdmap::LaneInfo;
43
using hdmap::OverlapInfo;
44
using ConstLaneInfoPtr = std::shared_ptr<const LaneInfo>;
45

46 47
namespace {

48 49
bool IsLaneSequenceInReferenceLine(
    const LaneSequence& lane_sequence,
50 51 52 53 54 55 56 57 58 59 60
    const ADCTrajectoryContainer* ego_trajectory_container) {
  for (const auto& lane_segment : lane_sequence.lane_segment()) {
    std::string lane_id = lane_segment.lane_id();
    if (ego_trajectory_container->IsLaneIdInReferenceLine(lane_id)) {
      return true;
    }
  }
  return false;
}

int NearestFrontObstacleIdOnLaneSequence(const LaneSequence& lane_sequence) {
61 62
  int nearest_front_obstacle_id = std::numeric_limits<int>::min();
  double smallest_relative_s = std::numeric_limits<double>::max();
63 64 65 66 67 68 69 70 71 72 73 74 75
  for (const auto& nearby_obs : lane_sequence.nearby_obstacle()) {
    if (nearby_obs.s() < 0.0) {
      continue;
    }
    if (nearby_obs.s() < smallest_relative_s) {
      smallest_relative_s = nearby_obs.s();
      nearest_front_obstacle_id = nearby_obs.id();
    }
  }
  return nearest_front_obstacle_id;
}

int NearestBackwardObstacleIdOnLaneSequence(const LaneSequence& lane_sequence) {
76 77
  int nearest_backward_obstacle_id = std::numeric_limits<int>::min();
  double smallest_relative_s = std::numeric_limits<double>::max();
78 79 80 81 82 83 84 85 86 87 88 89 90 91
  for (const auto& nearby_obs : lane_sequence.nearby_obstacle()) {
    if (nearby_obs.s() > 0.0) {
      continue;
    }
    if (-nearby_obs.s() < smallest_relative_s) {
      smallest_relative_s = -nearby_obs.s();
      nearest_backward_obstacle_id = nearby_obs.id();
    }
  }
  return nearest_backward_obstacle_id;
}

}  // namespace

92 93 94 95
void ObstaclesPrioritizer::PrioritizeObstacles(
    const EnvironmentFeatures& environment_features,
    const std::shared_ptr<ScenarioFeatures> scenario_features) {
  AssignIgnoreLevel(environment_features, scenario_features);
K
kechxu 已提交
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
  AssignCautionLevel(scenario_features);
}

void ObstaclesPrioritizer::AssignCautionLevel(
    const std::shared_ptr<ScenarioFeatures> scenario_features) {
  switch (scenario_features->scenario().type()) {
    case Scenario::JUNCTION: {
      AssignCautionLevelInJunction(scenario_features);
      break;
    }
    case Scenario::CRUISE: {
      AssignCautionLevelInCruise(scenario_features);
      break;
    }
    default: {
      AssignCautionLevelInCruise(scenario_features);
      break;
    }
  }
115 116 117 118 119
}

void ObstaclesPrioritizer::AssignIgnoreLevel(
    const EnvironmentFeatures& environment_features,
    const std::shared_ptr<ScenarioFeatures> ptr_scenario_features) {
120 121 122
  auto obstacles_container =
      ContainerManager::Instance()->GetContainer<ObstaclesContainer>(
          AdapterConfig::PERCEPTION_OBSTACLES);
123 124 125 126 127 128

  if (obstacles_container == nullptr) {
    AERROR << "Obstacles container pointer is a null pointer.";
    return;
  }

129 130 131
  auto pose_container =
      ContainerManager::Instance()->GetContainer<PoseContainer>(
          AdapterConfig::LOCALIZATION);
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
  if (pose_container == nullptr) {
    AERROR << "Pose container pointer is a null pointer.";
    return;
  }

  const PerceptionObstacle* pose_obstacle_ptr =
      pose_container->ToPerceptionObstacle();
  if (pose_obstacle_ptr == nullptr) {
    AERROR << "Pose obstacle pointer is a null pointer.";
    return;
  }

  double pose_theta = pose_obstacle_ptr->theta();
  double pose_x = pose_obstacle_ptr->position().x();
  double pose_y = pose_obstacle_ptr->position().y();

148 149
  ADEBUG << "Get pose (" << pose_x << ", " << pose_y << ", " << pose_theta
         << ")";
150 151 152 153

  // Build rectangular scan_area
  Box2d scan_box({pose_x + FLAGS_scan_length / 2.0 * std::cos(pose_theta),
                  pose_y + FLAGS_scan_length / 2.0 * std::sin(pose_theta)},
154
                 pose_theta, FLAGS_scan_length, FLAGS_scan_width);
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173

  const auto& obstacle_ids =
      obstacles_container->curr_frame_predictable_obstacle_ids();

  for (const int& obstacle_id : obstacle_ids) {
    Obstacle* obstacle_ptr = obstacles_container->GetObstacle(obstacle_id);
    if (obstacle_ptr->history_size() == 0) {
      AERROR << "Obstacle [" << obstacle_ptr->id() << "] has no feature.";
      continue;
    }
    Feature* latest_feature_ptr = obstacle_ptr->mutable_latest_feature();
    double obstacle_x = latest_feature_ptr->position().x();
    double obstacle_y = latest_feature_ptr->position().y();
    Vec2d ego_to_obstacle_vec(obstacle_x - pose_x, obstacle_y - pose_y);
    Vec2d ego_vec = Vec2d::CreateUnitVec2d(pose_theta);
    double s = ego_to_obstacle_vec.InnerProd(ego_vec);

    double pedestrian_like_nearby_lane_radius =
        FLAGS_pedestrian_nearby_lane_search_radius;
174 175
    bool is_near_lane = PredictionMap::HasNearbyLane(
        obstacle_x, obstacle_y, pedestrian_like_nearby_lane_radius);
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193

    // Decide if we need consider this obstacle
    bool is_in_scan_area = scan_box.IsPointIn({obstacle_x, obstacle_y});
    bool is_on_lane = obstacle_ptr->IsOnLane();
    bool is_pedestrian_like_in_front_near_lanes =
        s > FLAGS_back_dist_ignore_ped &&
        (latest_feature_ptr->type() == PerceptionObstacle::PEDESTRIAN ||
         latest_feature_ptr->type() == PerceptionObstacle::BICYCLE ||
         latest_feature_ptr->type() == PerceptionObstacle::UNKNOWN ||
         latest_feature_ptr->type() == PerceptionObstacle::UNKNOWN_MOVABLE) &&
        is_near_lane;
    bool is_near_junction = obstacle_ptr->IsNearJunction();

    bool need_consider = is_in_scan_area || is_on_lane || is_near_junction ||
                         is_pedestrian_like_in_front_near_lanes;

    if (!need_consider) {
      latest_feature_ptr->mutable_priority()->set_priority(
194
          ObstaclePriority::IGNORE);
195 196
    } else {
      latest_feature_ptr->mutable_priority()->set_priority(
197
          ObstaclePriority::NORMAL);
198 199 200 201
    }
  }
}

K
kechxu 已提交
202 203 204 205
void ObstaclesPrioritizer::AssignCautionLevelInCruise(
    const std::shared_ptr<ScenarioFeatures> scenario_features) {
  // TODO(kechxu) integrate change lane when ready to check change lane
  AssignCautionLevelCruiseKeepLane();
206
  AssignCautionLevelByEgoReferenceLine();
K
kechxu 已提交
207 208
}

209 210
void ObstaclesPrioritizer::AssignCautionLevelCruiseKeepLane() {
  ObstaclesContainer* obstacles_container =
211 212
      ContainerManager::Instance()->GetContainer<ObstaclesContainer>(
          AdapterConfig::PERCEPTION_OBSTACLES);
213 214 215 216
  if (obstacles_container == nullptr) {
    AERROR << "Null obstacles container found";
    return;
  }
217 218 219 220 221 222
  Obstacle* ego_vehicle =
      obstacles_container->GetObstacle(FLAGS_ego_vehicle_id);
  if (ego_vehicle == nullptr) {
    AERROR << "Ego vehicle not found";
    return;
  }
223
  if (ego_vehicle->history_size() < 2) {
224 225 226
    AERROR << "Ego vehicle has no history";
    return;
  }
227
  const Feature& ego_latest_feature = ego_vehicle->feature(1);
228 229 230 231 232
  for (const LaneSequence& lane_sequence :
       ego_latest_feature.lane().lane_graph().lane_sequence()) {
    int nearest_front_obstacle_id =
        NearestFrontObstacleIdOnLaneSequence(lane_sequence);
    if (nearest_front_obstacle_id < 0) {
233 234
      continue;
    }
235 236
    Obstacle* obstacle_ptr =
        obstacles_container->GetObstacle(nearest_front_obstacle_id);
237 238 239
    if (obstacle_ptr == nullptr) {
      AERROR << "Obstacle [" << nearest_front_obstacle_id << "] Not found";
      continue;
240
    }
241
    obstacle_ptr->SetCaution();
242 243 244
  }
}

245
void ObstaclesPrioritizer::AssignCautionLevelCruiseChangeLane() {
246
  ObstaclesContainer* obstacles_container =
247 248
      ContainerManager::Instance()->GetContainer<ObstaclesContainer>(
          AdapterConfig::PERCEPTION_OBSTACLES);
249 250 251 252
  if (obstacles_container == nullptr) {
    AERROR << "Null obstacles container found";
    return;
  }
253 254 255
  ADCTrajectoryContainer* ego_trajectory_container =
      ContainerManager::Instance()->GetContainer<ADCTrajectoryContainer>(
          AdapterConfig::PLANNING_TRAJECTORY);
256 257 258 259 260 261 262 263 264 265 266 267 268
  Obstacle* ego_vehicle =
      obstacles_container->GetObstacle(FLAGS_ego_vehicle_id);
  if (ego_vehicle == nullptr) {
    AERROR << "Ego vehicle not found";
    return;
  }
  if (ego_vehicle->history_size() == 0) {
    AERROR << "Ego vehicle has no history";
    return;
  }
  const Feature& ego_latest_feature = ego_vehicle->latest_feature();
  for (const LaneSequence& lane_sequence :
       ego_latest_feature.lane().lane_graph().lane_sequence()) {
269 270 271 272
    if (lane_sequence.vehicle_on_lane()) {
      int nearest_front_obstacle_id =
          NearestFrontObstacleIdOnLaneSequence(lane_sequence);
      if (nearest_front_obstacle_id < 0) {
273 274
        continue;
      }
275 276
      Obstacle* obstacle_ptr =
          obstacles_container->GetObstacle(nearest_front_obstacle_id);
277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300
      if (obstacle_ptr == nullptr) {
        AERROR << "Obstacle [" << nearest_front_obstacle_id << "] Not found";
        continue;
      }
      obstacle_ptr->SetCaution();
    } else if (IsLaneSequenceInReferenceLine(lane_sequence,
                                             ego_trajectory_container)) {
      int nearest_front_obstacle_id =
          NearestFrontObstacleIdOnLaneSequence(lane_sequence);
      int nearest_backward_obstacle_id =
          NearestBackwardObstacleIdOnLaneSequence(lane_sequence);
      if (nearest_front_obstacle_id >= 0) {
        Obstacle* front_obstacle_ptr =
            obstacles_container->GetObstacle(nearest_front_obstacle_id);
        if (front_obstacle_ptr != nullptr) {
          front_obstacle_ptr->SetCaution();
        }
      }
      if (nearest_backward_obstacle_id >= 0) {
        Obstacle* backward_obstacle_ptr =
            obstacles_container->GetObstacle(nearest_backward_obstacle_id);
        if (backward_obstacle_ptr != nullptr) {
          backward_obstacle_ptr->SetCaution();
        }
301 302 303 304 305
      }
    }
  }
}

306 307 308 309 310 311 312 313
void ObstaclesPrioritizer::AssignCautionLevelInJunction(
    const std::shared_ptr<ScenarioFeatures> scenario_features) {
  if (scenario_features->scenario().type() != Scenario::JUNCTION) {
    ADEBUG << "Not in Junction Scenario";
    return;
  }
  std::string junction_id = scenario_features->scenario().junction_id();
  ObstaclesContainer* obstacles_container =
314 315
      ContainerManager::Instance()->GetContainer<ObstaclesContainer>(
          AdapterConfig::PERCEPTION_OBSTACLES);
316 317 318 319
  if (obstacles_container == nullptr) {
    AERROR << "Null obstacles container found";
    return;
  }
320 321 322 323 324 325 326 327 328 329 330 331 332 333
  Obstacle* ego_vehicle =
      obstacles_container->GetObstacle(FLAGS_ego_vehicle_id);
  if (ego_vehicle == nullptr) {
    AERROR << "Ego vehicle not found";
    return;
  }
  for (const int id :
       obstacles_container->curr_frame_predictable_obstacle_ids()) {
    Obstacle* obstacle_ptr = obstacles_container->GetObstacle(id);
    if (obstacle_ptr != nullptr && obstacle_ptr->IsInJunction(junction_id)) {
      obstacle_ptr->SetCaution();
      ADEBUG << "SetCaution for obstacle [" << obstacle_ptr->id() << "]";
    }
  }
334
  AssignCautionLevelByEgoReferenceLine();
335 336
}

337 338 339 340
void ObstaclesPrioritizer::AssignCautionLevelByEgoReferenceLine() {
  ADCTrajectoryContainer* adc_trajectory_container =
      ContainerManager::Instance()->GetContainer<ADCTrajectoryContainer>(
          AdapterConfig::PLANNING_TRAJECTORY);
341 342 343 344
  if (adc_trajectory_container == nullptr) {
    AERROR << "adc_trajectory_container is nullptr";
    return;
  }
345 346 347 348 349 350
  const std::vector<std::string>& lane_ids =
      adc_trajectory_container->GetADCLaneIDSequence();
  if (lane_ids.empty()) {
    return;
  }

351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367
  auto pose_container =
      ContainerManager::Instance()->GetContainer<PoseContainer>(
          AdapterConfig::LOCALIZATION);
  if (pose_container == nullptr) {
    AERROR << "Pose container pointer is a null pointer.";
    return;
  }
  const PerceptionObstacle* pose_obstacle_ptr =
      pose_container->ToPerceptionObstacle();
  if (pose_obstacle_ptr == nullptr) {
    AERROR << "Pose obstacle pointer is a null pointer.";
    return;
  }
  double pose_x = pose_obstacle_ptr->position().x();
  double pose_y = pose_obstacle_ptr->position().y();
  double ego_vehicle_s = std::numeric_limits<double>::max();
  double ego_vehicle_l = std::numeric_limits<double>::max();
368
  double accumulated_s = 0.0;
369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387
  // first loop of lane_ids to findout ego_vehicle_s
  for (const std::string& lane_id : lane_ids) {
    std::shared_ptr<const LaneInfo> lane_info_ptr =
        PredictionMap::LaneById(lane_id);
    if (lane_info_ptr == nullptr) {
      AERROR << "Null lane info pointer found.";
      continue;
    }
    double s, l;
    PredictionMap::GetProjection({pose_x, pose_y}, lane_info_ptr, &s, &l);
    if (l < ego_vehicle_l) {
      ego_vehicle_s = accumulated_s + s;
      ego_vehicle_l = l;
    }
    accumulated_s += lane_info_ptr->total_length();
  }

  // then loop of lane_ids to AssignCaution
  accumulated_s = 0.0;
388 389 390 391 392 393 394 395 396 397
  for (const std::string& lane_id : lane_ids) {
    std::shared_ptr<const LaneInfo> lane_info_ptr =
        PredictionMap::LaneById(lane_id);
    if (lane_info_ptr == nullptr) {
      AERROR << "Null lane info pointer found.";
      continue;
    }
    accumulated_s += lane_info_ptr->total_length();
    AssignCautionByMerge(lane_info_ptr);
    AssignCautionByOverlap(lane_info_ptr);
398
    if (accumulated_s > FLAGS_caution_search_distance_ahead + ego_vehicle_s) {
399 400 401 402 403 404 405
      break;
    }
  }
}

void ObstaclesPrioritizer::AssignCautionByMerge(
    std::shared_ptr<const LaneInfo> lane_info_ptr) {
406
  SetCautionBackward(lane_info_ptr,
A
Aaron Xiao 已提交
407
                     FLAGS_caution_search_distance_backward_for_merge);
408 409 410 411
}

void ObstaclesPrioritizer::AssignCautionByOverlap(
    std::shared_ptr<const LaneInfo> lane_info_ptr) {
412 413 414 415
  std::string lane_id = lane_info_ptr->id().id();
  const std::vector<std::shared_ptr<const OverlapInfo>> cross_lanes_ =
      lane_info_ptr->cross_lanes();
  for (const auto overlap_ptr : cross_lanes_) {
A
Aaron Xiao 已提交
416 417
    for (const auto& object : overlap_ptr->overlap().object()) {
      const auto& object_id = object.id().id();
418 419 420 421 422
      if (object_id == lane_info_ptr->id().id()) {
        continue;
      } else {
        std::shared_ptr<const LaneInfo> overlap_lane_ptr =
            PredictionMap::LaneById(object_id);
423
        SetCautionBackward(overlap_lane_ptr,
A
Aaron Xiao 已提交
424
                           FLAGS_caution_search_distance_backward_for_overlap);
425 426 427
      }
    }
  }
428 429 430 431
}

void ObstaclesPrioritizer::SetCautionBackward(
    std::shared_ptr<const LaneInfo> start_lane_info_ptr,
432
    const double max_distance) {
433 434 435 436 437
  ObstaclesContainer* obstacles_container =
      ContainerManager::Instance()->GetContainer<ObstaclesContainer>(
          AdapterConfig::PERCEPTION_OBSTACLES);
  std::unordered_map<std::string, std::vector<LaneObstacle>> lane_obstacles =
      ObstacleClusters::GetLaneObstacles();
438 439 440
  std::queue<std::pair<ConstLaneInfoPtr, double>> lane_info_queue;
  lane_info_queue.emplace(start_lane_info_ptr,
                          start_lane_info_ptr->total_length());
441 442
  while (!lane_info_queue.empty()) {
    ConstLaneInfoPtr curr_lane = lane_info_queue.front().first;
443
    double cumu_distance = lane_info_queue.front().second;
444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467
    lane_info_queue.pop();
    const std::string& lane_id = curr_lane->id().id();
    std::unordered_set<std::string> visited_lanes;
    if (visited_lanes.find(lane_id) == visited_lanes.end() &&
        lane_obstacles.find(lane_id) != lane_obstacles.end() &&
        !lane_obstacles[lane_id].empty()) {
      visited_lanes.insert(lane_id);
      // find the obstacle with largest lane_s on the lane
      int obstacle_id = lane_obstacles[lane_id].front().obstacle_id();
      double obstacle_s = lane_obstacles[lane_id].front().lane_s();
      for (const LaneObstacle& lane_obstacle : lane_obstacles[lane_id]) {
        if (lane_obstacle.lane_s() > obstacle_s) {
          obstacle_id = lane_obstacle.obstacle_id();
          obstacle_s = lane_obstacle.lane_s();
        }
      }
      Obstacle* obstacle_ptr = obstacles_container->GetObstacle(obstacle_id);
      if (obstacle_ptr == nullptr) {
        AERROR << "Obstacle [" << obstacle_id << "] Not found";
        continue;
      }
      obstacle_ptr->SetCaution();
      continue;
    }
468
    if (cumu_distance > max_distance) {
469 470 471 472
      continue;
    }
    for (const auto& pre_lane_id : curr_lane->lane().predecessor_id()) {
      ConstLaneInfoPtr pre_lane_ptr = PredictionMap::LaneById(pre_lane_id.id());
473 474
      lane_info_queue.emplace(pre_lane_ptr,
                              cumu_distance + pre_lane_ptr->total_length());
475 476
    }
  }
477 478
}

479 480
}  // namespace prediction
}  // namespace apollo