24#include <unordered_set>
26#include "modules/common_msgs/basic_msgs/pnc_point.pb.h"
27#include "modules/common_msgs/planning_msgs/decision.pb.h"
47using ObsTEdge = std::tuple<int, double, double, double, std::string>;
51 const double planning_time,
55 planning_time_ = planning_time;
56 planning_distance_ = planning_distance;
57 path_data_ = path_data;
60 path_decision_ = path_decision;
66 obs_id_to_st_boundary_.clear();
67 obs_id_to_decision_.clear();
68 candidate_clear_zones_.clear();
69 obs_id_to_alternative_st_boundary_.clear();
75 if (path_decision ==
nullptr) {
76 const std::string msg =
"path_decision is nullptr";
78 return Status(ErrorCode::PLANNING_ERROR, msg);
80 if (planning_time_ < 0.0) {
81 const std::string msg =
"Negative planning time.";
83 return Status(ErrorCode::PLANNING_ERROR, msg);
85 if (planning_distance_ < 0.0) {
86 const std::string msg =
"Negative planning distance.";
88 return Status(ErrorCode::PLANNING_ERROR, msg);
91 const std::string msg =
"Number of path points is too few.";
93 return Status(ErrorCode::PLANNING_ERROR, msg);
95 obs_id_to_st_boundary_.clear();
98 bool is_adc_low_road_right_beginning =
true;
100 double path_pt_s = 0.0;
102 std::tie(path_pt_s, path_pt_type, std::ignore) = path_pt_info;
105 if (is_adc_low_road_right_beginning) {
106 adc_low_road_right_segments_.emplace_back(path_pt_s, path_pt_s);
107 is_adc_low_road_right_beginning =
false;
109 adc_low_road_right_segments_.back().second = path_pt_s;
112 if (!is_adc_low_road_right_beginning) {
113 is_adc_low_road_right_beginning =
true;
120 std::unordered_set<std::string> non_ignore_obstacles;
121 std::tuple<std::string, STBoundary, Obstacle*> closest_stop_obstacle;
122 std::get<0>(closest_stop_obstacle) =
"NULL";
123 for (
const auto* obs_item_ptr : path_decision->
obstacles().
Items()) {
125 Obstacle* obs_ptr = path_decision->
Find(obs_item_ptr->Id());
126 if (obs_ptr ==
nullptr) {
127 const std::string msg =
"Null obstacle pointer.";
129 return Status(ErrorCode::PLANNING_ERROR, msg);
133 std::vector<STPoint> lower_points;
134 std::vector<STPoint> upper_points;
135 bool is_caution_obstacle =
false;
136 double obs_caution_end_t = 0.0;
137 if (!ComputeObstacleSTBoundary(*obs_ptr, &lower_points, &upper_points,
138 &is_caution_obstacle, &obs_caution_end_t)) {
144 boundary.set_id(obs_ptr->
Id());
145 if (is_caution_obstacle) {
146 boundary.set_obstacle_road_right_ending_t(obs_caution_end_t);
150 while (lower_points.size() > 2 &&
151 lower_points.back().t() > obs_caution_end_t) {
152 lower_points.pop_back();
154 while (upper_points.size() > 2 &&
155 upper_points.back().t() > obs_caution_end_t) {
156 upper_points.pop_back();
158 auto alternative_boundary =
160 alternative_boundary.set_id(obs_ptr->
Id());
161 obs_id_to_alternative_st_boundary_[obs_ptr->
Id()] = alternative_boundary;
162 ADEBUG <<
"Obstacle " << obs_ptr->
Id()
163 <<
" has an alternative st-boundary with "
164 << lower_points.size() + upper_points.size() <<
" points.";
167 if (obs_item_ptr->Id().find(
"KC") != std::string::npos) {
168 candidate_clear_zones_.push_back(
169 make_tuple(obs_ptr->
Id(), boundary, obs_ptr));
176 if (std::get<0>(closest_stop_obstacle) ==
"NULL" ||
177 std::get<1>(closest_stop_obstacle).bottom_left_point().s() >
178 boundary.bottom_left_point().s()) {
180 closest_stop_obstacle =
181 std::make_tuple(obs_ptr->
Id(), boundary, obs_ptr);
185 if (boundary.bottom_left_point().s() - adc_path_init_s_ <
192 obs_id_to_st_boundary_[obs_ptr->
Id()] = boundary;
194 non_ignore_obstacles.insert(obs_ptr->
Id());
195 ADEBUG <<
"Adding " << obs_ptr->
Id() <<
" into the ST-graph.";
205 if (std::get<0>(closest_stop_obstacle) !=
"NULL") {
206 std::string closest_stop_obs_id;
209 std::tie(closest_stop_obs_id, closest_stop_obs_boundary,
210 closest_stop_obs_ptr) = closest_stop_obstacle;
211 ADEBUG <<
"Closest obstacle ID = " << closest_stop_obs_id;
214 if (!closest_stop_obs_ptr->
IsVirtual()) {
215 for (
const auto& clear_zone : candidate_clear_zones_) {
216 const auto& clear_zone_boundary = std::get<1>(clear_zone);
217 if (closest_stop_obs_boundary.
min_s() >= clear_zone_boundary.min_s() &&
218 closest_stop_obs_boundary.
min_s() <= clear_zone_boundary.max_s()) {
219 std::tie(closest_stop_obs_id, closest_stop_obs_boundary,
220 closest_stop_obs_ptr) = clear_zone;
221 ADEBUG <<
"Clear zone " << closest_stop_obs_id <<
" is closer.";
226 obs_id_to_st_boundary_[closest_stop_obs_id] = closest_stop_obs_boundary;
228 non_ignore_obstacles.insert(closest_stop_obs_id);
229 ADEBUG <<
"Adding " << closest_stop_obs_ptr->
Id() <<
" into the ST-graph.";
230 ADEBUG <<
"min_s = " << closest_stop_obs_boundary.
min_s();
234 for (
const auto* obs_item_ptr : path_decision->
obstacles().
Items()) {
235 Obstacle* obs_ptr = path_decision->
Find(obs_item_ptr->Id());
236 if (non_ignore_obstacles.count(obs_ptr->
Id()) == 0) {
237 ObjectDecisionType ignore_decision;
238 ignore_decision.mutable_ignore();
251 for (
const auto& it : obs_id_to_st_boundary_) {
252 obs_t_edges_.emplace_back(
true, it.second.min_t(),
253 it.second.bottom_left_point().s(),
254 it.second.upper_left_point().s(), it.first);
255 obs_t_edges_.emplace_back(
false, it.second.max_t(),
256 it.second.bottom_right_point().s(),
257 it.second.upper_right_point().s(), it.first);
260 std::sort(obs_t_edges_.begin(), obs_t_edges_.end(),
261 [](
const ObsTEdge& lhs,
const ObsTEdge& rhs) {
262 if (std::get<1>(lhs) != std::get<1>(rhs)) {
263 return std::get<1>(lhs) < std::get<1>(rhs);
265 return std::get<0>(lhs) > std::get<0>(rhs);
272std::unordered_map<std::string, STBoundary>
273STObstaclesProcessor::GetAllSTBoundaries() {
274 return obs_id_to_st_boundary_;
277bool STObstaclesProcessor::GetLimitingSpeedInfo(
278 double t, std::pair<double, double>*
const limiting_speed_info) {
279 if (obs_id_to_decision_.empty()) {
285 double s_max = planning_distance_;
286 for (
auto it : obs_id_to_decision_) {
287 auto obs_id = it.first;
288 auto obs_decision = it.second;
289 auto obs_st_boundary = obs_id_to_st_boundary_[obs_id];
290 double obs_s_min = 0.0;
291 double obs_s_max = 0.0;
292 obs_st_boundary.GetBoundarySRange(t, &obs_s_max, &obs_s_min);
293 double obs_ds_lower = 0.0;
294 double obs_ds_upper = 0.0;
295 obs_st_boundary.GetBoundarySlopes(t, &obs_ds_upper, &obs_ds_lower);
296 if (obs_decision.has_yield() || obs_decision.has_stop()) {
297 if (obs_s_min <= s_max) {
299 limiting_speed_info->second = obs_ds_lower;
301 }
else if (it.second.has_overtake()) {
302 if (obs_s_max >= s_min) {
304 limiting_speed_info->first = obs_ds_upper;
308 return s_min <= s_max;
311bool STObstaclesProcessor::GetSBoundsFromDecisions(
312 double t, std::vector<std::pair<double, double>>*
const available_s_bounds,
313 std::vector<std::vector<std::pair<std::string, ObjectDecisionType>>>*
const
314 available_obs_decisions) {
316 available_s_bounds->clear();
317 available_obs_decisions->clear();
320 ADEBUG <<
"There are " << obs_t_edges_.size() <<
" t-edges.";
321 std::vector<ObsTEdge> new_t_edges;
322 while (obs_t_edges_idx_ <
static_cast<int>(obs_t_edges_.size()) &&
323 std::get<1>(obs_t_edges_[obs_t_edges_idx_]) <= t) {
324 if (std::get<0>(obs_t_edges_[obs_t_edges_idx_]) == 0 &&
325 std::get<1>(obs_t_edges_[obs_t_edges_idx_]) == t) {
328 ADEBUG <<
"Seeing a new t-edge at t = "
329 << std::get<1>(obs_t_edges_[obs_t_edges_idx_]);
330 new_t_edges.push_back(obs_t_edges_[obs_t_edges_idx_]);
335 for (
const auto& obs_t_edge : new_t_edges) {
336 if (std::get<0>(obs_t_edge) == 0) {
337 ADEBUG <<
"Obstacle id: " << std::get<4>(obs_t_edge)
338 <<
" is leaving st-graph.";
339 if (obs_id_to_decision_.count(std::get<4>(obs_t_edge)) != 0) {
340 obs_id_to_decision_.erase(std::get<4>(obs_t_edge));
347 std::vector<std::string> obs_id_to_remove;
348 for (
const auto& obs_id_to_decision_pair : obs_id_to_decision_) {
349 auto obs_id = obs_id_to_decision_pair.first;
350 auto obs_decision = obs_id_to_decision_pair.second;
351 auto obs_st_boundary = obs_id_to_st_boundary_[obs_id];
352 if (obs_decision.has_overtake() &&
354 obs_st_boundary.obstacle_road_right_ending_t() <=
356 obs_id_to_remove.push_back(obs_id_to_decision_pair.first);
359 for (
const auto& obs_id : obs_id_to_remove) {
360 obs_id_to_decision_.erase(obs_id);
362 if (obs_id_to_alternative_st_boundary_.count(obs_id) > 0) {
363 Obstacle* obs_ptr = path_decision_->Find(obs_id);
364 obs_id_to_st_boundary_[obs_id] =
365 obs_id_to_alternative_st_boundary_[obs_id];
366 obs_id_to_st_boundary_[obs_id].SetBoundaryType(
367 STBoundary::BoundaryType::OVERTAKE);
374 double s_max = planning_distance_;
375 for (
auto it : obs_id_to_decision_) {
376 auto obs_id = it.first;
377 auto obs_decision = it.second;
378 auto obs_st_boundary = obs_id_to_st_boundary_[obs_id];
379 double obs_s_min = 0.0;
380 double obs_s_max = 0.0;
381 obs_st_boundary.GetBoundarySRange(t, &obs_s_max, &obs_s_min);
382 if (obs_decision.has_yield() || obs_decision.has_stop()) {
383 s_max = std::fmin(s_max, obs_s_min);
384 }
else if (it.second.has_overtake()) {
385 s_min = std::fmax(s_min, obs_s_max);
391 ADEBUG <<
"S-boundary based on existing decisions = (" << s_min <<
", "
396 std::vector<ObsTEdge> ambiguous_t_edges;
397 for (
auto obs_t_edge : new_t_edges) {
398 ADEBUG <<
"For obstacle id: " << std::get<4>(obs_t_edge)
399 <<
", its s-range = [" << std::get<2>(obs_t_edge) <<
", "
400 << std::get<3>(obs_t_edge) <<
"]";
401 if (std::get<0>(obs_t_edge) == 1) {
402 if (std::get<2>(obs_t_edge) >= s_max) {
403 ADEBUG <<
" Apparently, it should be yielded.";
404 obs_id_to_decision_[std::get<4>(obs_t_edge)] =
405 DetermineObstacleDecision(std::get<2>(obs_t_edge),
406 std::get<3>(obs_t_edge), s_max);
407 obs_id_to_st_boundary_[std::get<4>(obs_t_edge)].SetBoundaryType(
408 STBoundary::BoundaryType::YIELD);
409 }
else if (std::get<3>(obs_t_edge) <= s_min) {
410 ADEBUG <<
" Apparently, it should be overtaken.";
411 obs_id_to_decision_[std::get<4>(obs_t_edge)] =
412 DetermineObstacleDecision(std::get<2>(obs_t_edge),
413 std::get<3>(obs_t_edge), s_min);
414 obs_id_to_st_boundary_[std::get<4>(obs_t_edge)].SetBoundaryType(
415 STBoundary::BoundaryType::OVERTAKE);
417 ADEBUG <<
" It should be further analyzed.";
418 ambiguous_t_edges.push_back(obs_t_edge);
423 auto s_gaps = FindSGaps(ambiguous_t_edges, s_min, s_max);
424 if (s_gaps.empty()) {
427 for (
auto s_gap : s_gaps) {
428 available_s_bounds->push_back(s_gap);
429 std::vector<std::pair<std::string, ObjectDecisionType>> obs_decisions;
430 for (
auto obs_t_edge : ambiguous_t_edges) {
431 std::string obs_id = std::get<4>(obs_t_edge);
432 double obs_s_min = std::get<2>(obs_t_edge);
433 double obs_s_max = std::get<3>(obs_t_edge);
434 obs_decisions.emplace_back(
436 DetermineObstacleDecision(obs_s_min, obs_s_max,
437 (s_gap.first + s_gap.second) / 2.0));
439 available_obs_decisions->push_back(obs_decisions);
445void STObstaclesProcessor::SetObstacleDecision(
446 const std::string& obs_id,
const ObjectDecisionType& obs_decision) {
447 obs_id_to_decision_[obs_id] = obs_decision;
448 ObjectStatus object_status;
449 object_status.mutable_motion_type()->mutable_dynamic();
450 if (obs_decision.has_yield() || obs_decision.has_stop()) {
451 obs_id_to_st_boundary_[obs_id].SetBoundaryType(
452 STBoundary::BoundaryType::YIELD);
453 object_status.mutable_decision_type()->mutable_yield();
454 }
else if (obs_decision.has_overtake()) {
455 obs_id_to_st_boundary_[obs_id].SetBoundaryType(
456 STBoundary::BoundaryType::OVERTAKE);
457 object_status.mutable_decision_type()->mutable_overtake();
459 history_->mutable_history_status()->SetObjectStatus(obs_id, object_status);
462void STObstaclesProcessor::SetObstacleDecision(
463 const std::vector<std::pair<std::string, ObjectDecisionType>>&
464 obstacle_decisions) {
465 for (
auto obs_decision : obstacle_decisions) {
466 SetObstacleDecision(obs_decision.first, obs_decision.second);
473bool STObstaclesProcessor::ComputeObstacleSTBoundary(
474 const Obstacle& obstacle, std::vector<STPoint>*
const lower_points,
475 std::vector<STPoint>*
const upper_points,
bool*
const is_caution_obstacle,
476 double*
const obs_caution_end_t) {
477 lower_points->clear();
478 upper_points->clear();
479 *is_caution_obstacle =
false;
480 const auto& adc_path_points = path_data_.discretized_path();
481 const auto& obs_trajectory = obstacle.
Trajectory();
483 if (obs_trajectory.trajectory_point().empty()) {
487 AWARN <<
"Non-static obstacle[" << obstacle.
Id()
488 <<
"] has NO prediction trajectory."
493 std::pair<double, double> overlapping_s;
494 if (GetOverlappingS(adc_path_points, obs_box, kADCSafetyLBuffer,
496 lower_points->emplace_back(overlapping_s.first, 0.0);
497 lower_points->emplace_back(overlapping_s.first, planning_time_);
498 upper_points->emplace_back(overlapping_s.second, 0.0);
499 upper_points->emplace_back(overlapping_s.second, planning_time_);
501 *is_caution_obstacle =
true;
502 *obs_caution_end_t = planning_time_;
507 bool is_obs_first_traj_pt =
true;
508 for (
const auto& obs_traj_pt : obs_trajectory.trajectory_point()) {
515 std::pair<double, double> overlapping_s;
516 if (GetOverlappingS(adc_path_points, obs_box, kADCSafetyLBuffer,
518 ADEBUG <<
"Obstacle instance is overlapping with ADC path.";
519 lower_points->emplace_back(overlapping_s.first,
520 obs_traj_pt.relative_time());
521 upper_points->emplace_back(overlapping_s.second,
522 obs_traj_pt.relative_time());
523 if (is_obs_first_traj_pt) {
524 if (IsSWithinADCLowRoadRightSegment(overlapping_s.first) ||
525 IsSWithinADCLowRoadRightSegment(overlapping_s.second)) {
526 *is_caution_obstacle =
true;
529 if ((*is_caution_obstacle)) {
530 if (IsSWithinADCLowRoadRightSegment(overlapping_s.first) ||
531 IsSWithinADCLowRoadRightSegment(overlapping_s.second)) {
532 *obs_caution_end_t = obs_traj_pt.relative_time();
536 is_obs_first_traj_pt =
false;
538 if (lower_points->size() == 1) {
539 lower_points->emplace_back(lower_points->front().s(),
540 lower_points->front().t() + 0.1);
541 upper_points->emplace_back(upper_points->front().s(),
542 upper_points->front().t() + 0.1);
546 return (!lower_points->empty() && !upper_points->empty());
549bool STObstaclesProcessor::GetOverlappingS(
550 const std::vector<PathPoint>& adc_path_points,
551 const Box2d& obstacle_instance,
const double adc_l_buffer,
552 std::pair<double, double>*
const overlapping_s) {
554 int pt_before_idx = GetSBoundingPathPointIndex(
555 adc_path_points, obstacle_instance, vehicle_param_.front_edge_to_center(),
556 true, 0,
static_cast<int>(adc_path_points.size()) - 2);
557 ADEBUG <<
"The index before is " << pt_before_idx;
558 int pt_after_idx = GetSBoundingPathPointIndex(
559 adc_path_points, obstacle_instance, vehicle_param_.back_edge_to_center(),
560 false, 0,
static_cast<int>(adc_path_points.size()) - 2);
561 ADEBUG <<
"The index after is " << pt_after_idx;
562 if (pt_before_idx ==
static_cast<int>(adc_path_points.size()) - 2) {
565 if (pt_after_idx == 0) {
569 if (pt_before_idx == -1) {
572 if (pt_after_idx == -1) {
573 pt_after_idx =
static_cast<int>(adc_path_points.size()) - 2;
575 if (pt_before_idx >= pt_after_idx) {
580 bool has_overlapping =
false;
581 for (
int i = pt_before_idx; i <= pt_after_idx; ++i) {
582 ADEBUG <<
"At ADC path index = " << i <<
" :";
583 if (IsADCOverlappingWithObstacle(adc_path_points[i], obstacle_instance,
585 overlapping_s->first = adc_path_points[std::max(i - 1, 0)].s();
586 has_overlapping =
true;
587 ADEBUG <<
"There is overlapping.";
591 if (!has_overlapping) {
594 for (
int i = pt_after_idx; i >= pt_before_idx; --i) {
595 ADEBUG <<
"At ADC path index = " << i <<
" :";
596 if (IsADCOverlappingWithObstacle(adc_path_points[i], obstacle_instance,
598 overlapping_s->second = adc_path_points[i + 1].s();
599 ADEBUG <<
"There is overlapping.";
606int STObstaclesProcessor::GetSBoundingPathPointIndex(
607 const std::vector<PathPoint>& adc_path_points,
608 const Box2d& obstacle_instance,
const double s_thresh,
const bool is_before,
609 const int start_idx,
const int end_idx) {
610 if (start_idx == end_idx) {
611 if (IsPathPointAwayFromObstacle(adc_path_points[start_idx],
612 adc_path_points[start_idx + 1],
613 obstacle_instance, s_thresh, is_before)) {
621 int mid_idx = (start_idx + end_idx - 1) / 2 + 1;
622 if (IsPathPointAwayFromObstacle(adc_path_points[mid_idx],
623 adc_path_points[mid_idx + 1],
624 obstacle_instance, s_thresh, is_before)) {
625 return GetSBoundingPathPointIndex(adc_path_points, obstacle_instance,
626 s_thresh, is_before, mid_idx, end_idx);
628 return GetSBoundingPathPointIndex(adc_path_points, obstacle_instance,
629 s_thresh, is_before, start_idx,
633 int mid_idx = (start_idx + end_idx) / 2;
634 if (IsPathPointAwayFromObstacle(adc_path_points[mid_idx],
635 adc_path_points[mid_idx + 1],
636 obstacle_instance, s_thresh, is_before)) {
637 return GetSBoundingPathPointIndex(adc_path_points, obstacle_instance,
638 s_thresh, is_before, start_idx,
641 return GetSBoundingPathPointIndex(adc_path_points, obstacle_instance,
642 s_thresh, is_before, mid_idx + 1,
648bool STObstaclesProcessor::IsPathPointAwayFromObstacle(
649 const PathPoint& path_point,
const PathPoint& direction_point,
650 const Box2d& obs_box,
const double s_thresh,
const bool is_before) {
651 Vec2d path_pt(path_point.x(), path_point.y());
652 Vec2d dir_pt(direction_point.x(), direction_point.y());
653 LineSegment2d path_dir_lineseg(path_pt, dir_pt);
654 LineSegment2d normal_line_seg(path_pt, path_dir_lineseg.rotate(M_PI_2));
656 auto corner_points = obs_box.GetAllCorners();
657 for (
const auto& corner_pt : corner_points) {
658 Vec2d normal_line_ft_pt;
659 normal_line_seg.GetPerpendicularFoot(corner_pt, &normal_line_ft_pt);
660 Vec2d path_dir_unit_vec = path_dir_lineseg.unit_direction();
661 Vec2d perpendicular_vec = corner_pt - normal_line_ft_pt;
662 double corner_pt_s_dist = path_dir_unit_vec.InnerProd(perpendicular_vec);
663 if (is_before && corner_pt_s_dist < s_thresh) {
666 if (!is_before && corner_pt_s_dist > -s_thresh) {
673bool STObstaclesProcessor::IsADCOverlappingWithObstacle(
674 const PathPoint& adc_path_point,
const Box2d& obs_box,
675 const double l_buffer)
const {
677 Vec2d ego_center_map_frame((vehicle_param_.front_edge_to_center() -
678 vehicle_param_.back_edge_to_center()) *
680 (vehicle_param_.left_edge_to_center() -
681 vehicle_param_.right_edge_to_center()) *
683 ego_center_map_frame.SelfRotate(adc_path_point.theta());
684 ego_center_map_frame.set_x(ego_center_map_frame.x() + adc_path_point.x());
685 ego_center_map_frame.set_y(ego_center_map_frame.y() + adc_path_point.y());
688 Box2d adc_box(ego_center_map_frame, adc_path_point.theta(),
689 vehicle_param_.length(), vehicle_param_.width() + l_buffer * 2);
691 ADEBUG <<
" ADC box is: " << adc_box.DebugString();
692 ADEBUG <<
" Obs box is: " << obs_box.DebugString();
695 return obs_box.HasOverlap(adc_box);
698std::vector<std::pair<double, double>> STObstaclesProcessor::FindSGaps(
699 const std::vector<ObsTEdge>& obstacle_t_edges,
double s_min,
double s_max) {
700 std::vector<std::pair<double, int>> obs_s_edges;
701 for (
auto obs_t_edge : obstacle_t_edges) {
702 obs_s_edges.emplace_back(std::get<2>(obs_t_edge), 1);
703 obs_s_edges.emplace_back(std::get<3>(obs_t_edge), 0);
706 obs_s_edges.emplace_back(s_min, 0);
707 obs_s_edges.emplace_back(s_max, 1);
710 obs_s_edges.begin(), obs_s_edges.end(),
711 [](
const std::pair<double, int>& lhs,
const std::pair<double, int>& rhs) {
712 if (lhs.first != rhs.first) {
713 return lhs.first < rhs.first;
715 return lhs.second > rhs.second;
719 std::vector<std::pair<double, double>> s_gaps;
721 double prev_open_s = 0.0;
722 for (
auto obs_s_edge : obs_s_edges) {
723 if (obs_s_edge.second == 1) {
725 if (num_st_obs == 1) {
726 s_gaps.emplace_back(prev_open_s, obs_s_edge.first);
730 if (num_st_obs == 0) {
731 prev_open_s = obs_s_edge.first;
739ObjectDecisionType STObstaclesProcessor::DetermineObstacleDecision(
740 const double obs_s_min,
const double obs_s_max,
const double s)
const {
741 ObjectDecisionType decision;
742 if (s <= obs_s_min) {
743 decision.mutable_yield()->set_distance_s(0.0);
744 }
else if (s >= obs_s_max) {
745 decision.mutable_overtake()->set_distance_s(0.0);
750bool STObstaclesProcessor::IsSWithinADCLowRoadRightSegment(
751 const double s)
const {
752 for (
const auto& seg : adc_low_road_right_segments_) {
753 if (s >= seg.first && s <= seg.second) {
A general class to denote the return status of an API call.
static Status OK()
generate a success status.
static const VehicleConfig & GetConfig()
Get the current vehicle configuration.
Rectangular (undirected) bounding box in 2-D.
std::string DebugString() const
Gets a human-readable description of the box
Implements a class of 2-dimensional vectors.
const std::vector< const T * > & Items() const
List all the items in the container.
This is the class that associates an Obstacle with its path properties.
const perception::PerceptionObstacle & Perception() const
void AddLongitudinalDecision(const std::string &decider_tag, const ObjectDecisionType &decision)
void AddLateralDecision(const std::string &decider_tag, const ObjectDecisionType &decision)
bool HasLongitudinalDecision() const
const prediction::Trajectory & Trajectory() const
const std::string & Id() const
common::math::Box2d GetBoundingBox(const common::TrajectoryPoint &point) const
bool HasLateralDecision() const
void set_path_st_boundary(const STBoundary &boundary)
const common::math::Box2d & PerceptionBoundingBox() const
const DiscretizedPath & discretized_path() const
const std::vector< std::tuple< double, PathPointType, double > > & path_point_decision_guide() const
PathDecision represents all obstacle decisions on one path.
const Obstacle * Find(const std::string &object_id) const
const IndexedList< std::string, Obstacle > & obstacles() const
static STBoundary CreateInstanceAccurate(const std::vector< STPoint > &lower_points, const std::vector< STPoint > &upper_points)
Wrapper of the constructor.
common::Status MapObstaclesToSTBoundaries(PathDecision *const path_decision)
void Init(const double planning_distance, const double planning_time, const PathData &path_data, PathDecision *const path_decision, History *const history)
Planning module main class.
Define the LineSegment2d class.
constexpr double kSIgnoreThreshold
constexpr double kOvertakenObsCautionTime
constexpr double kTIgnoreThreshold
optional VehicleParam vehicle_param
repeated apollo::common::TrajectoryPoint trajectory_point