obstacles_prioritizer.cc 20.1 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 23 24
#include <queue>
#include <unordered_map>
#include <utility>
25 26 27

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

namespace apollo {
namespace prediction {

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

44 45
namespace {

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

int NearestFrontObstacleIdOnLaneSequence(const LaneSequence& lane_sequence) {
59 60
  int nearest_front_obstacle_id = std::numeric_limits<int>::min();
  double smallest_relative_s = std::numeric_limits<double>::max();
61
  for (const auto& nearby_obs : lane_sequence.nearby_obstacle()) {
62 63
    if (nearby_obs.s() < 0.0 ||
        nearby_obs.s() > FLAGS_caution_search_distance_ahead) {
64 65 66 67 68 69 70 71 72 73 74
      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) {
75 76
  int nearest_backward_obstacle_id = std::numeric_limits<int>::min();
  double smallest_relative_s = std::numeric_limits<double>::max();
77
  for (const auto& nearby_obs : lane_sequence.nearby_obstacle()) {
78 79
    if (nearby_obs.s() > 0.0 ||
        nearby_obs.s() < -FLAGS_caution_search_distance_backward) {
80 81 82 83 84 85 86 87 88 89 90 91
      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
ObstaclesPrioritizer::ObstaclesPrioritizer() {}

94
void ObstaclesPrioritizer::PrioritizeObstacles() {
95
  ego_back_lane_id_set_.clear();
96 97
  AssignIgnoreLevel();
  AssignCautionLevel();
K
kechxu 已提交
98 99
}

100
void ObstaclesPrioritizer::AssignIgnoreLevel() {
101 102 103
  auto obstacles_container =
      ContainerManager::Instance()->GetContainer<ObstaclesContainer>(
          AdapterConfig::PERCEPTION_OBSTACLES);
104 105 106 107 108
  if (obstacles_container == nullptr) {
    AERROR << "Obstacles container pointer is a null pointer.";
    return;
  }

109 110 111 112
  Obstacle* ego_obstacle_ptr =
      obstacles_container->GetObstacle(FLAGS_ego_vehicle_id);
  if (ego_obstacle_ptr == nullptr) {
    AERROR << "Ego obstacle nullptr found";
113 114 115
    return;
  }

116 117 118 119 120
  const Feature& ego_feature = ego_obstacle_ptr->latest_feature();
  double ego_theta = ego_feature.theta();
  double ego_x = ego_feature.position().x();
  double ego_y = ego_feature.position().y();
  ADEBUG << "Get pose (" << ego_x << ", " << ego_y << ", " << ego_theta
121
         << ")";
122 123

  // Build rectangular scan_area
124 125 126
  Box2d scan_box({ego_x + FLAGS_scan_length / 2.0 * std::cos(ego_theta),
                  ego_y + FLAGS_scan_length / 2.0 * std::sin(ego_theta)},
                 ego_theta, FLAGS_scan_length, FLAGS_scan_width);
127 128

  const auto& obstacle_ids =
129
      obstacles_container->curr_frame_movable_obstacle_ids();
130
  for (const int obstacle_id : obstacle_ids) {
131
    Obstacle* obstacle_ptr = obstacles_container->GetObstacle(obstacle_id);
132 133 134 135
    if (obstacle_ptr == nullptr) {
      AERROR << "Null obstacle pointer found.";
      continue;
    }
136 137 138 139 140 141 142
    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();
143 144
    Vec2d ego_to_obstacle_vec(obstacle_x - ego_x, obstacle_y - ego_y);
    Vec2d ego_vec = Vec2d::CreateUnitVec2d(ego_theta);
145 146 147 148
    double s = ego_to_obstacle_vec.InnerProd(ego_vec);

    double pedestrian_like_nearby_lane_radius =
        FLAGS_pedestrian_nearby_lane_search_radius;
149 150
    bool is_near_lane = PredictionMap::HasNearbyLane(
        obstacle_x, obstacle_y, pedestrian_like_nearby_lane_radius);
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168

    // 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(
169
          ObstaclePriority::IGNORE);
170 171
    } else {
      latest_feature_ptr->mutable_priority()->set_priority(
172
          ObstaclePriority::NORMAL);
173 174
    }
  }
175
  obstacles_container->SetConsideredObstacleIds();
176 177
}

178
void ObstaclesPrioritizer::AssignCautionLevel() {
179
  // AssignCautionLevelInJunction();
K
kechxu 已提交
180
  AssignCautionLevelCruiseKeepLane();
181
  AssignCautionLevelCruiseChangeLane();
182
  AssignCautionLevelByEgoReferenceLine();
K
kechxu 已提交
183 184
}

185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
void ObstaclesPrioritizer::AssignCautionLevelInJunction() {
  auto obstacles_container =
      ContainerManager::Instance()->GetContainer<ObstaclesContainer>(
          AdapterConfig::PERCEPTION_OBSTACLES);
  if (obstacles_container == nullptr) {
    AERROR << "Obstacles container pointer is a null pointer.";
    return;
  }

  // TODO(Hongyi): get current junction_id from Storytelling
  std::string curr_junction_id;
  const auto& obstacle_ids =
      obstacles_container->curr_frame_movable_obstacle_ids();
  for (const int obstacle_id : obstacle_ids) {
    Obstacle* obstacle_ptr = obstacles_container->GetObstacle(obstacle_id);
    if (obstacle_ptr == nullptr) {
      AERROR << "Null obstacle pointer found.";
      continue;
    }
    if (obstacle_ptr->IsInJunction(curr_junction_id)) {
      obstacle_ptr->SetCaution();
    }
  }
}

210 211
void ObstaclesPrioritizer::AssignCautionLevelCruiseKeepLane() {
  ObstaclesContainer* obstacles_container =
212 213
      ContainerManager::Instance()->GetContainer<ObstaclesContainer>(
          AdapterConfig::PERCEPTION_OBSTACLES);
214 215 216 217
  if (obstacles_container == nullptr) {
    AERROR << "Null obstacles container found";
    return;
  }
218 219 220 221 222 223
  Obstacle* ego_vehicle =
      obstacles_container->GetObstacle(FLAGS_ego_vehicle_id);
  if (ego_vehicle == nullptr) {
    AERROR << "Ego vehicle not found";
    return;
  }
F
fengzongbao 已提交
224
  if (ego_vehicle->history_size() == 0) {
225 226 227
    AERROR << "Ego vehicle has no history";
    return;
  }
228
  const Feature& ego_latest_feature = ego_vehicle->latest_feature();
229 230 231 232 233
  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) {
234 235
      continue;
    }
236 237
    Obstacle* obstacle_ptr =
        obstacles_container->GetObstacle(nearest_front_obstacle_id);
238 239 240
    if (obstacle_ptr == nullptr) {
      AERROR << "Obstacle [" << nearest_front_obstacle_id << "] Not found";
      continue;
241
    }
242
    obstacle_ptr->SetCaution();
243 244 245
  }
}

246
void ObstaclesPrioritizer::AssignCautionLevelCruiseChangeLane() {
247
  ObstaclesContainer* obstacles_container =
248 249
      ContainerManager::Instance()->GetContainer<ObstaclesContainer>(
          AdapterConfig::PERCEPTION_OBSTACLES);
250 251 252 253
  if (obstacles_container == nullptr) {
    AERROR << "Null obstacles container found";
    return;
  }
254 255 256
  ADCTrajectoryContainer* ego_trajectory_container =
      ContainerManager::Instance()->GetContainer<ADCTrajectoryContainer>(
          AdapterConfig::PLANNING_TRAJECTORY);
257 258 259 260 261 262 263 264 265 266 267 268 269
  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()) {
270 271 272 273
    if (lane_sequence.vehicle_on_lane()) {
      int nearest_front_obstacle_id =
          NearestFrontObstacleIdOnLaneSequence(lane_sequence);
      if (nearest_front_obstacle_id < 0) {
274 275
        continue;
      }
276 277
      Obstacle* obstacle_ptr =
          obstacles_container->GetObstacle(nearest_front_obstacle_id);
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301
      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();
        }
302 303 304 305 306
      }
    }
  }
}

307
void ObstaclesPrioritizer::AssignCautionLevelByEgoReferenceLine() {
308 309 310 311 312 313 314
  ObstaclesContainer* obstacles_container =
      ContainerManager::Instance()->GetContainer<ObstaclesContainer>(
          AdapterConfig::PERCEPTION_OBSTACLES);
  if (obstacles_container == nullptr) {
    AERROR << "Null obstacles container found";
    return;
  }
315

316 317 318
  ADCTrajectoryContainer* adc_trajectory_container =
      ContainerManager::Instance()->GetContainer<ADCTrajectoryContainer>(
          AdapterConfig::PLANNING_TRAJECTORY);
319 320 321 322
  if (adc_trajectory_container == nullptr) {
    AERROR << "adc_trajectory_container is nullptr";
    return;
  }
323
  const std::vector<std::string>& lane_ids =
324
      adc_trajectory_container->GetADCTargetLaneIDSequence();
325 326 327 328
  if (lane_ids.empty()) {
    return;
  }

329 330 331 332
  Obstacle* ego_obstacle_ptr =
      obstacles_container->GetObstacle(FLAGS_ego_vehicle_id);
  if (ego_obstacle_ptr == nullptr) {
    AERROR << "Ego obstacle nullptr found";
333 334
    return;
  }
335 336 337 338

  const Feature& ego_feature = ego_obstacle_ptr->latest_feature();
  double ego_x = ego_feature.position().x();
  double ego_y = ego_feature.position().y();
339 340
  double ego_vehicle_s = std::numeric_limits<double>::max();
  double ego_vehicle_l = std::numeric_limits<double>::max();
341
  double accumulated_s = 0.0;
342
  // first loop for lane_ids to findout ego_vehicle_s
343 344 345 346 347 348 349
  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;
    }
350 351
    double s = 0.0;
    double l = 0.0;
352
    if (PredictionMap::GetProjection({ego_x, ego_y}, lane_info_ptr, &s, &l)) {
353
      if (std::fabs(l) < std::fabs(ego_vehicle_l)) {
354 355
        ego_vehicle_s = accumulated_s + s;
        ego_vehicle_l = l;
356 357
        ego_lane_id_ = lane_id;
        ego_lane_s_ = s;
358
      }
359 360 361 362
    }
    accumulated_s += lane_info_ptr->total_length();
  }

363
  // insert ego_back_lane_id
364
  accumulated_s = 0.0;
365
  for (const std::string& lane_id : lane_ids) {
366
    if (lane_id == ego_lane_id_) {
367 368
      break;
    }
369
    ego_back_lane_id_set_.insert(lane_id);
370 371
  }

372 373 374
  std::unordered_set<std::string> visited_lanes(lane_ids.begin(),
                                                lane_ids.end());

375 376 377 378 379
  // then loop through lane_ids to AssignCaution for obstacle vehicles
  for (const std::string& lane_id : lane_ids) {
    if (ego_back_lane_id_set_.find(lane_id) != ego_back_lane_id_set_.end()) {
      continue;
    }
380 381 382 383 384 385 386
    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();
387 388
    if (lane_id != ego_lane_id_) {
      AssignCautionByMerge(lane_info_ptr, &visited_lanes);
389
    }
390
    AssignCautionByOverlap(lane_info_ptr, &visited_lanes);
391
    if (accumulated_s > FLAGS_caution_search_distance_ahead + ego_vehicle_s) {
392 393 394
      break;
    }
  }
395 396 397

  // finally loop through all pedestrian to AssignCaution
  for (const int obstacle_id :
398
       obstacles_container->curr_frame_movable_obstacle_ids()) {
399
    Obstacle* obstacle_ptr = obstacles_container->GetObstacle(obstacle_id);
400 401 402 403
    if (obstacle_ptr == nullptr) {
      AERROR << "Null obstacle pointer found.";
      continue;
    }
404 405 406 407 408 409 410 411 412 413 414
    if (obstacle_ptr->history_size() == 0) {
      AERROR << "Obstacle [" << obstacle_ptr->id() << "] has no feature.";
      continue;
    }
    Feature* latest_feature_ptr = obstacle_ptr->mutable_latest_feature();
    if (latest_feature_ptr->type() != PerceptionObstacle::PEDESTRIAN) {
      continue;
    }
    double start_x = latest_feature_ptr->position().x();
    double start_y = latest_feature_ptr->position().y();
    double end_x = start_x + FLAGS_caution_pedestrian_approach_time *
A
Aaron Xiao 已提交
415
                                 latest_feature_ptr->raw_velocity().x();
416
    double end_y = start_y + FLAGS_caution_pedestrian_approach_time *
A
Aaron Xiao 已提交
417
                                 latest_feature_ptr->raw_velocity().y();
418 419 420 421 422 423
    std::vector<std::string> nearby_lane_ids = PredictionMap::NearbyLaneIds(
        {start_x, start_y}, FLAGS_pedestrian_nearby_lane_search_radius);
    if (nearby_lane_ids.empty()) {
      continue;
    }
    for (const std::string& lane_id : nearby_lane_ids) {
424
      if (!adc_trajectory_container->IsLaneIdInTargetReferenceLine(lane_id)) {
425 426 427
        continue;
      }
      std::shared_ptr<const LaneInfo> lane_info_ptr =
A
Aaron Xiao 已提交
428
          PredictionMap::LaneById(lane_id);
429 430 431 432 433 434 435 436
      if (lane_info_ptr == nullptr) {
        AERROR << "Null lane info pointer found.";
        continue;
      }
      double start_s = 0.0;
      double start_l = 0.0;
      double end_s = 0.0;
      double end_l = 0.0;
A
Aaron Xiao 已提交
437 438 439 440
      if (PredictionMap::GetProjection({start_x, start_y}, lane_info_ptr,
                                       &start_s, &start_l) &&
          PredictionMap::GetProjection({end_x, end_y}, lane_info_ptr, &end_s,
                                       &end_l)) {
441 442
        if (std::fabs(start_l) < FLAGS_pedestrian_nearby_lane_search_radius ||
            std::fabs(end_l) < FLAGS_pedestrian_nearby_lane_search_radius ||
443 444 445 446 447 448
            start_l * end_l < 0.0) {
          obstacle_ptr->SetCaution();
        }
      }
    }
  }
449 450 451
}

void ObstaclesPrioritizer::AssignCautionByMerge(
452 453
    std::shared_ptr<const LaneInfo> lane_info_ptr,
    std::unordered_set<std::string>* const visited_lanes) {
454
  SetCautionBackward(lane_info_ptr,
A
Aaron Xiao 已提交
455 456
                     FLAGS_caution_search_distance_backward_for_merge,
                     visited_lanes);
457 458 459
}

void ObstaclesPrioritizer::AssignCautionByOverlap(
460 461
    std::shared_ptr<const LaneInfo> lane_info_ptr,
    std::unordered_set<std::string>* const visited_lanes) {
462
  std::string lane_id = lane_info_ptr->id().id();
463
  const std::vector<std::shared_ptr<const OverlapInfo>> cross_lanes =
464
      lane_info_ptr->cross_lanes();
465
  for (const auto overlap_ptr : cross_lanes) {
466 467
    bool consider_overlap = true;
    for (const auto& object : overlap_ptr->overlap().object()) {
X
Xiangquan Xiao 已提交
468
      if (object.id().id() == lane_info_ptr->id().id() &&
469 470 471 472 473 474 475 476 477
          object.lane_overlap_info().end_s() < ego_lane_s_) {
        consider_overlap = false;
      }
    }

    if (!consider_overlap) {
      continue;
    }

A
Aaron Xiao 已提交
478 479
    for (const auto& object : overlap_ptr->overlap().object()) {
      const auto& object_id = object.id().id();
480 481 482
      if (object_id == lane_info_ptr->id().id()) {
        continue;
      }
483 484 485 486 487 488 489 490 491
      std::shared_ptr<const LaneInfo> overlap_lane_ptr =
          PredictionMap::LaneById(object_id);
      // ahead_s is the length in front of the overlap
      double ahead_s = overlap_lane_ptr->total_length() -
                       object.lane_overlap_info().start_s();
      SetCautionBackward(
          overlap_lane_ptr,
          ahead_s + FLAGS_caution_search_distance_backward_for_overlap,
          visited_lanes);
492 493
    }
  }
494 495 496 497
}

void ObstaclesPrioritizer::SetCautionBackward(
    std::shared_ptr<const LaneInfo> start_lane_info_ptr,
498 499
    const double max_distance,
    std::unordered_set<std::string>* const visited_lanes) {
500 501 502 503 504
  std::string start_lane_id = start_lane_info_ptr->id().id();
  if (ego_back_lane_id_set_.find(start_lane_id) !=
      ego_back_lane_id_set_.end()) {
    return;
  }
505 506 507 508 509
  ObstaclesContainer* obstacles_container =
      ContainerManager::Instance()->GetContainer<ObstaclesContainer>(
          AdapterConfig::PERCEPTION_OBSTACLES);
  std::unordered_map<std::string, std::vector<LaneObstacle>> lane_obstacles =
      ObstacleClusters::GetLaneObstacles();
510 511 512
  std::queue<std::pair<ConstLaneInfoPtr, double>> lane_info_queue;
  lane_info_queue.emplace(start_lane_info_ptr,
                          start_lane_info_ptr->total_length());
513 514
  while (!lane_info_queue.empty()) {
    ConstLaneInfoPtr curr_lane = lane_info_queue.front().first;
515
    double cumu_distance = lane_info_queue.front().second;
516 517
    lane_info_queue.pop();
    const std::string& lane_id = curr_lane->id().id();
518
    if (visited_lanes->find(lane_id) == visited_lanes->end() &&
519 520
        lane_obstacles.find(lane_id) != lane_obstacles.end() &&
        !lane_obstacles[lane_id].empty()) {
521
      visited_lanes->insert(lane_id);
522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538
      // 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;
    }
539
    if (cumu_distance > max_distance) {
540 541 542
      continue;
    }
    for (const auto& pre_lane_id : curr_lane->lane().predecessor_id()) {
543 544 545 546
      if (ego_back_lane_id_set_.find(pre_lane_id.id()) !=
          ego_back_lane_id_set_.end()) {
        continue;
      }
547
      ConstLaneInfoPtr pre_lane_ptr = PredictionMap::LaneById(pre_lane_id.id());
548 549
      lane_info_queue.emplace(pre_lane_ptr,
                              cumu_distance + pre_lane_ptr->total_length());
550 551
    }
  }
552 553
}

554 555
}  // namespace prediction
}  // namespace apollo