for (constauto& obs_traj_pt : obs_trajectory.trajectory_point()) { // TODO(jiacheng): Currently, if the obstacle overlaps with ADC at // disjoint segments (happens very rarely), we merge them into one. // In the future, this could be considered in greater details rather // than being approximated. const Box2d& obs_box = obstacle.GetBoundingBox(obs_traj_pt); ADEBUG << obs_box.DebugString(); std::pair<double, double> overlapping_s; if (GetOverlappingS(adc_path_points, obs_box, kADCSafetyLBuffer, &overlapping_s)) { ADEBUG << "Obstacle instance is overlapping with ADC path."; lower_points->emplace_back(overlapping_s.first, obs_traj_pt.relative_time()); upper_points->emplace_back(overlapping_s.second, obs_traj_pt.relative_time()); if (is_obs_first_traj_pt) { if (IsSWithinADCLowRoadRightSegment(overlapping_s.first) || IsSWithinADCLowRoadRightSegment(overlapping_s.second)) { *is_caution_obstacle = true; } } if ((*is_caution_obstacle)) { if (IsSWithinADCLowRoadRightSegment(overlapping_s.first) || IsSWithinADCLowRoadRightSegment(overlapping_s.second)) { *obs_caution_end_t = obs_traj_pt.relative_time(); } } } is_obs_first_traj_pt = false; }
// Process all other obstacles than Keep-Clear zone. if (obs_ptr->Trajectory().trajectory_point().empty()) { // Obstacle is static. if (std::get<0>(closest_stop_obstacle) == "NULL" || std::get<1>(closest_stop_obstacle).bottom_left_point().s() > boundary.bottom_left_point().s()) { // If this static obstacle is closer for ADC to stop, record it. closest_stop_obstacle = std::make_tuple(obs_ptr->Id(), boundary, obs_ptr); } } else { // Obstacle is dynamic. if (boundary.bottom_left_point().s() - adc_path_init_s_ < kSIgnoreThreshold && boundary.bottom_left_point().t() > kTIgnoreThreshold) { // Ignore obstacles that are behind. // TODO(jiacheng): don't ignore if ADC is in dangerous segments. continue; } obs_id_to_st_boundary_[obs_ptr->Id()] = boundary; obs_ptr->set_path_st_boundary(boundary); non_ignore_obstacles.insert(obs_ptr->Id()); ADEBUG << "Adding " << obs_ptr->Id() << " into the ST-graph."; }
// For static obstacles, only retain the closest one (also considers // Keep-Clear zone here). // Note: We only need to check the overlapping between the closest obstacle // and all the Keep-Clear zones. Because if there is another obstacle // overlapping with a Keep-Clear zone, which results in an even closer // stop fence, then that very Keep-Clear zone must also overlap with // the closest obstacle. (Proof omitted here) if (std::get<0>(closest_stop_obstacle) != "NULL") { std::string closest_stop_obs_id; STBoundary closest_stop_obs_boundary; Obstacle* closest_stop_obs_ptr; std::tie(closest_stop_obs_id, closest_stop_obs_boundary, closest_stop_obs_ptr) = closest_stop_obstacle; ADEBUG << "Closest obstacle ID = " << closest_stop_obs_id; // Go through all Keep-Clear zones, and see if there is an even closer // stop fence due to them. if (!closest_stop_obs_ptr->IsVirtual()) { for (constauto& clear_zone : candidate_clear_zones_) { constauto& clear_zone_boundary = std::get<1>(clear_zone); if (closest_stop_obs_boundary.min_s() >= clear_zone_boundary.min_s() && closest_stop_obs_boundary.min_s() <= clear_zone_boundary.max_s()) { std::tie(closest_stop_obs_id, closest_stop_obs_boundary, closest_stop_obs_ptr) = clear_zone; ADEBUG << "Clear zone " << closest_stop_obs_id << " is closer."; break; } } } obs_id_to_st_boundary_[closest_stop_obs_id] = closest_stop_obs_boundary; closest_stop_obs_ptr->set_path_st_boundary(closest_stop_obs_boundary); non_ignore_obstacles.insert(closest_stop_obs_id); ADEBUG << "Adding " << closest_stop_obs_ptr->Id() << " into the ST-graph."; ADEBUG << "min_s = " << closest_stop_obs_boundary.min_s(); }
// Get Boundary due to driving limits auto driving_limits_bound = st_driving_limits_.GetVehicleDynamicsLimits(t); s_lower = std::fmax(s_lower, driving_limits_bound.first); s_upper = std::fmin(s_upper, driving_limits_bound.second); ADEBUG << "Bounds for s due to driving limits are " << "s_upper = " << s_upper << ", s_lower = " << s_lower;
if (!available_choices.empty()) { ADEBUG << "One decision needs to be made among " << available_choices.size() << " choices."; double guide_line_s = st_guide_line_.GetGuideSFromT(t); st_guide_line->emplace_back(t, guide_line_s); RankDecisions(guide_line_s, driving_limits_bound, &available_choices); // Select the top decision. auto top_choice_s_range = available_choices.front().first; bool is_limited_by_upper_obs = false; bool is_limited_by_lower_obs = false; if (s_lower < std::get<1>(top_choice_s_range)) { s_lower = std::get<1>(top_choice_s_range); is_limited_by_lower_obs = true; } if (s_upper > std::get<2>(top_choice_s_range)) { s_upper = std::get<2>(top_choice_s_range); is_limited_by_upper_obs = true; }
// Set decision for obstacles without decisions. auto top_choice_decision = available_choices.front().second; st_obstacles_processor_.SetObstacleDecision(top_choice_decision);