39using apollo::common::util::FindOrDie;
44const double kStBoundaryDeltaS = 0.2;
45const double kStBoundarySparseDeltaS = 1.0;
46const double kStBoundaryDeltaT = 0.05;
49const std::unordered_map<ObjectDecisionType::ObjectTagCase, int,
50 Obstacle::ObjectTagCaseHash>
51 Obstacle::s_longitudinal_decision_safety_sorter_ = {
52 {ObjectDecisionType::kIgnore, 0},
53 {ObjectDecisionType::kOvertake, 100},
54 {ObjectDecisionType::kFollow, 300},
55 {ObjectDecisionType::kYield, 400},
56 {ObjectDecisionType::kStop, 500}};
58const std::unordered_map<ObjectDecisionType::ObjectTagCase, int,
59 Obstacle::ObjectTagCaseHash>
60 Obstacle::s_lateral_decision_safety_sorter_ = {
61 {ObjectDecisionType::kIgnore, 0}, {ObjectDecisionType::kNudge, 100}};
68 perception_id_(perception_obstacle.id()),
69 perception_obstacle_(perception_obstacle),
70 perception_bounding_box_({perception_obstacle_.
position().
x(),
72 perception_obstacle_.theta(),
73 perception_obstacle_.length(),
74 perception_obstacle_.width()) {
76 std::vector<common::math::Vec2d> polygon_points;
77 if (FLAGS_use_navigation_mode ||
78 perception_obstacle.polygon_point_size() <= 2) {
79 perception_bounding_box_.GetAllCorners(&polygon_points);
81 ACHECK(perception_obstacle.polygon_point_size() > 2)
82 <<
"object " <<
id <<
"has less than 3 polygon points";
83 for (
const auto& point : perception_obstacle.polygon_point()) {
84 polygon_points.emplace_back(point.x(), point.y());
88 &perception_polygon_))
89 <<
"object[" <<
id <<
"] polygon is not a valid convex hull.\n"
90 << perception_obstacle.DebugString();
93 is_virtual_ = (perception_obstacle.id() < 0);
94 speed_ = std::hypot(perception_obstacle.velocity().x(),
95 perception_obstacle.velocity().y());
102 const bool is_static)
103 :
Obstacle(id, perception_obstacle, obstacle_priority, is_static) {
104 trajectory_ = trajectory;
105 auto& trajectory_points = *trajectory_.mutable_trajectory_point();
106 double cumulative_s = 0.0;
107 if (trajectory_points.size() > 0) {
108 trajectory_points[0].mutable_path_point()->set_s(0.0);
110 for (
int i = 1; i < trajectory_points.size(); ++i) {
111 const auto& prev = trajectory_points[i - 1];
112 const auto& cur = trajectory_points[i];
113 if (prev.relative_time() >= cur.relative_time()) {
114 AERROR <<
"prediction time is not increasing."
115 <<
"current point: " << cur.ShortDebugString()
116 <<
"previous point: " << prev.ShortDebugString();
120 trajectory_points[i].mutable_path_point()->set_s(cumulative_s);
125 const double relative_time)
const {
127 if (points.size() < 2) {
129 point.mutable_path_point()->set_x(perception_obstacle_.
position().
x());
130 point.mutable_path_point()->set_y(perception_obstacle_.
position().
y());
131 point.mutable_path_point()->set_z(perception_obstacle_.
position().
z());
132 point.mutable_path_point()->set_theta(perception_obstacle_.
theta());
133 point.mutable_path_point()->set_s(0.0);
134 point.mutable_path_point()->set_kappa(0.0);
135 point.mutable_path_point()->set_dkappa(0.0);
136 point.mutable_path_point()->set_ddkappa(0.0);
139 point.set_relative_time(0.0);
147 std::lower_bound(points.begin(), points.end(), relative_time, comp);
149 if (it_lower == points.begin()) {
150 return *points.begin();
151 }
else if (it_lower == points.end()) {
152 return *points.rbegin();
155 *(it_lower - 1), *it_lower, relative_time);
163 perception_obstacle_.
length(),
164 perception_obstacle_.
width());
168 if (obstacle.
length() <= 0.0) {
169 AERROR <<
"invalid obstacle length:" << obstacle.
length();
172 if (obstacle.
width() <= 0.0) {
173 AERROR <<
"invalid obstacle width:" << obstacle.
width();
176 if (obstacle.
height() <= 0.0) {
177 AERROR <<
"invalid obstacle height:" << obstacle.
height();
180 if (obstacle.has_velocity()) {
181 if (std::isnan(obstacle.
velocity().
x()) ||
183 AERROR <<
"invalid obstacle velocity:"
184 << obstacle.
velocity().DebugString();
189 if (std::isnan(pt.x()) || std::isnan(pt.y())) {
190 AERROR <<
"invalid obstacle polygon point:" << pt.DebugString();
199 std::list<std::unique_ptr<Obstacle>> obstacles;
202 AERROR <<
"Invalid perception obstacle: "
203 << prediction_obstacle.perception_obstacle().DebugString();
206 const auto perception_id =
207 std::to_string(prediction_obstacle.perception_obstacle().id());
208 if (prediction_obstacle.trajectory().empty()) {
209 obstacles.emplace_back(
210 new Obstacle(perception_id, prediction_obstacle.perception_obstacle(),
211 prediction_obstacle.priority().priority(),
212 prediction_obstacle.is_static()));
216 int trajectory_index = 0;
217 for (
const auto& trajectory : prediction_obstacle.trajectory()) {
218 bool is_valid_trajectory =
true;
219 for (
const auto& point : trajectory.trajectory_point()) {
221 AERROR <<
"obj:" << perception_id
222 <<
" TrajectoryPoint: " << trajectory.ShortDebugString()
224 is_valid_trajectory =
false;
228 if (!is_valid_trajectory) {
232 const std::string obstacle_id =
233 absl::StrCat(perception_id,
"_", trajectory_index);
234 obstacles.emplace_back(
235 new Obstacle(obstacle_id, prediction_obstacle.perception_obstacle(),
236 trajectory, prediction_obstacle.priority().priority(),
237 prediction_obstacle.is_static()));
249 size_t negative_id = std::hash<std::string>{}(id);
251 negative_id |= (0x1 << 31);
252 perception_obstacle.set_id(
static_cast<int32_t
>(negative_id));
253 perception_obstacle.mutable_position()->set_x(obstacle_box.
center().
x());
254 perception_obstacle.mutable_position()->set_y(obstacle_box.
center().
y());
255 perception_obstacle.set_theta(obstacle_box.
heading());
256 perception_obstacle.mutable_velocity()->set_x(0);
257 perception_obstacle.mutable_velocity()->set_y(0);
258 perception_obstacle.set_length(obstacle_box.
length());
259 perception_obstacle.set_width(obstacle_box.
width());
260 perception_obstacle.set_height(FLAGS_virtual_stop_wall_height);
261 perception_obstacle.set_type(
263 perception_obstacle.set_tracking_time(1.0);
265 std::vector<common::math::Vec2d> corner_points;
267 for (
const auto& corner_point : corner_points) {
268 auto* point = perception_obstacle.add_polygon_point();
269 point->set_x(corner_point.x());
270 point->set_y(corner_point.y());
274 obstacle->is_virtual_ =
true;
275 return std::unique_ptr<Obstacle>(obstacle);
279 return !((!point.has_path_point()) || std::isnan(point.
path_point().
x()) ||
290 sl_boundary_ = sl_boundary;
295 if (min_radius_stop_distance_ > 0) {
296 return min_radius_stop_distance_;
298 static constexpr double stop_distance_buffer = 0.5;
300 double lateral_diff =
301 vehicle_param.
width() / 2.0 + std::max(std::fabs(sl_boundary_.
start_l()),
302 std::fabs(sl_boundary_.
end_l()));
303 const double kEpison = 1e-5;
304 lateral_diff = std::min(lateral_diff, min_turn_radius - kEpison);
305 double stop_distance =
306 std::sqrt(std::fabs(min_turn_radius * min_turn_radius -
307 (min_turn_radius - lateral_diff) *
308 (min_turn_radius - lateral_diff))) +
309 stop_distance_buffer;
311 stop_distance = std::min(stop_distance, FLAGS_max_stop_distance_obstacle);
312 stop_distance = std::max(stop_distance, FLAGS_min_stop_distance_obstacle);
313 return stop_distance;
317 const double adc_start_s) {
318 const auto& adc_param =
319 VehicleConfigHelper::Instance()->GetConfig().vehicle_param();
320 const double half_adc_width = adc_param.width() / 2;
322 std::vector<std::pair<STPoint, STPoint>> point_pairs;
323 double start_s = sl_boundary_.
start_s();
324 double end_s = sl_boundary_.
end_s();
325 if (end_s - start_s < kStBoundaryDeltaS) {
326 end_s = start_s + kStBoundaryDeltaS;
328 if (!reference_line.
IsBlockRoad(perception_bounding_box_, half_adc_width)) {
331 point_pairs.emplace_back(
STPoint(start_s - adc_start_s, 0.0),
332 STPoint(end_s - adc_start_s, 0.0));
333 point_pairs.emplace_back(
STPoint(start_s - adc_start_s, FLAGS_st_max_t),
334 STPoint(end_s - adc_start_s, FLAGS_st_max_t));
335 reference_line_st_boundary_ =
STBoundary(point_pairs);
337 if (BuildTrajectoryStBoundary(reference_line, adc_start_s,
338 &reference_line_st_boundary_)) {
339 ADEBUG <<
"Found st_boundary for obstacle " << id_;
340 ADEBUG <<
"st_boundary: min_t = " << reference_line_st_boundary_.
min_t()
341 <<
", max_t = " << reference_line_st_boundary_.
max_t()
342 <<
", min_s = " << reference_line_st_boundary_.
min_s()
343 <<
", max_s = " << reference_line_st_boundary_.
max_s();
345 ADEBUG <<
"No st_boundary for obstacle " << id_;
350bool Obstacle::BuildTrajectoryStBoundary(
const ReferenceLine& reference_line,
351 const double adc_start_s,
353 if (!IsValidObstacle(perception_obstacle_)) {
354 AERROR <<
"Fail to build trajectory st boundary because object is not "
355 "valid. PerceptionObstacle: "
356 << perception_obstacle_.DebugString();
359 const double object_width = perception_obstacle_.
width();
360 const double object_length = perception_obstacle_.
length();
362 if (trajectory_points.empty()) {
363 AWARN <<
"object " << id_ <<
" has no trajectory points";
366 const auto& adc_param =
367 VehicleConfigHelper::Instance()->GetConfig().vehicle_param();
368 const double adc_length = adc_param.length();
369 const double adc_half_length = adc_length / 2.0;
370 const double adc_width = adc_param.width();
371 common::math::Box2d min_box({0, 0}, 1.0, 1.0, 1.0);
372 common::math::Box2d max_box({0, 0}, 1.0, 1.0, 1.0);
373 std::vector<std::pair<STPoint, STPoint>> polygon_points;
375 SLBoundary last_sl_boundary;
378 for (
int i = 1; i < trajectory_points.size(); ++i) {
379 ADEBUG <<
"last_sl_boundary: " << last_sl_boundary.ShortDebugString();
381 const auto& first_traj_point = trajectory_points[i - 1];
382 const auto& second_traj_point = trajectory_points[i];
383 const auto& first_point = first_traj_point.path_point();
384 const auto& second_point = second_traj_point.path_point();
386 double object_moving_box_length =
389 common::math::Vec2d center((first_point.x() + second_point.x()) / 2.0,
390 (first_point.y() + second_point.y()) / 2.0);
391 common::math::Box2d object_moving_box(
392 center, first_point.theta(), object_moving_box_length, object_width);
393 SLBoundary object_boundary;
397 const double distance_xy =
399 trajectory_points[i].path_point());
400 if (last_sl_boundary.start_l() > distance_xy ||
401 last_sl_boundary.end_l() < -distance_xy) {
406 (last_sl_boundary.start_s() + last_sl_boundary.end_s()) / 2.0;
407 const double start_s = std::fmax(0.0, mid_s - 2.0 * distance_xy);
408 const double end_s = (i == 1) ? reference_line.
Length()
409 : std::fmin(reference_line.
Length(),
410 mid_s + 2.0 * distance_xy);
413 end_s, &object_boundary)) {
414 AERROR <<
"failed to calculate boundary";
419 last_sl_boundary = object_boundary;
423 static constexpr double kSkipLDistanceFactor = 0.4;
424 const double skip_l_distance =
425 (object_boundary.end_s() - object_boundary.start_s()) *
426 kSkipLDistanceFactor +
430 (std::fmin(object_boundary.start_l(), object_boundary.end_l()) >
432 std::fmax(object_boundary.start_l(), object_boundary.end_l()) <
441 static constexpr double kSparseMappingS = 20.0;
442 const double st_boundary_delta_s =
443 (std::fabs(object_boundary.start_s() - adc_start_s) > kSparseMappingS)
444 ? kStBoundarySparseDeltaS
446 const double object_s_diff =
447 object_boundary.end_s() - object_boundary.start_s();
448 if (object_s_diff < st_boundary_delta_s) {
451 const double delta_t =
452 second_traj_point.relative_time() - first_traj_point.relative_time();
453 double low_s = std::max(object_boundary.start_s() - adc_half_length, 0.0);
454 bool has_low =
false;
456 std::min(object_boundary.end_s() + adc_half_length, FLAGS_st_max_s);
457 bool has_high =
false;
458 while (low_s + st_boundary_delta_s < high_s && !(has_low && has_high)) {
461 has_low = object_moving_box.HasOverlap(
462 {low_ref, low_ref.heading(), adc_length,
463 adc_width + FLAGS_nonstatic_obstacle_nudge_l_buffer});
464 low_s += st_boundary_delta_s;
468 has_high = object_moving_box.HasOverlap(
469 {high_ref, high_ref.heading(), adc_length,
470 adc_width + FLAGS_nonstatic_obstacle_nudge_l_buffer});
471 high_s -= st_boundary_delta_s;
474 if (has_low && has_high) {
475 low_s -= st_boundary_delta_s;
476 high_s += st_boundary_delta_s;
478 (first_traj_point.relative_time() +
479 std::fabs((low_s - object_boundary.start_s()) / object_s_diff) *
481 polygon_points.emplace_back(
482 std::make_pair(STPoint{low_s - adc_start_s, low_t},
483 STPoint{high_s - adc_start_s, low_t}));
485 (first_traj_point.relative_time() +
486 std::fabs((high_s - object_boundary.start_s()) / object_s_diff) *
488 if (high_t - low_t > 0.05) {
489 polygon_points.emplace_back(
490 std::make_pair(STPoint{low_s - adc_start_s, high_t},
491 STPoint{high_s - adc_start_s, high_t}));
495 if (!polygon_points.empty()) {
496 std::sort(polygon_points.begin(), polygon_points.end(),
497 [](
const std::pair<STPoint, STPoint>& a,
498 const std::pair<STPoint, STPoint>& b) {
499 return a.first.t() < b.first.t();
501 auto last = std::unique(polygon_points.begin(), polygon_points.end(),
502 [](
const std::pair<STPoint, STPoint>& a,
503 const std::pair<STPoint, STPoint>& b) {
504 return std::fabs(a.first.t() - b.first.t()) <
507 polygon_points.erase(last, polygon_points.end());
508 if (polygon_points.size() > 2) {
509 *st_boundary = STBoundary(polygon_points);
518 return reference_line_st_boundary_;
522 return path_st_boundary_;
526 return decider_tags_;
534 return decision.has_ignore() || decision.has_nudge();
538 return decision.has_ignore() || decision.has_stop() || decision.has_yield() ||
539 decision.has_follow() || decision.has_overtake();
542ObjectDecisionType Obstacle::MergeLongitudinalDecision(
543 const ObjectDecisionType& lhs,
const ObjectDecisionType& rhs) {
544 if (lhs.object_tag_case() == ObjectDecisionType::OBJECT_TAG_NOT_SET) {
547 if (rhs.object_tag_case() == ObjectDecisionType::OBJECT_TAG_NOT_SET) {
551 FindOrDie(s_longitudinal_decision_safety_sorter_, lhs.object_tag_case());
553 FindOrDie(s_longitudinal_decision_safety_sorter_, rhs.object_tag_case());
554 if (lhs_val < rhs_val) {
556 }
else if (lhs_val > rhs_val) {
559 if (lhs.has_ignore()) {
561 }
else if (lhs.has_stop()) {
562 return lhs.stop().distance_s() < rhs.stop().distance_s() ? lhs : rhs;
563 }
else if (lhs.has_yield()) {
564 return lhs.yield().distance_s() < rhs.yield().distance_s() ? lhs : rhs;
565 }
else if (lhs.has_follow()) {
566 return lhs.follow().distance_s() < rhs.follow().distance_s() ? lhs : rhs;
567 }
else if (lhs.has_overtake()) {
568 return lhs.overtake().distance_s() > rhs.overtake().distance_s() ? lhs
571 DCHECK(
false) <<
"Unknown decision";
578 return longitudinal_decision_;
582 return lateral_decision_;
590 return longitudinal_decision_.has_ignore();
594 return lateral_decision_.has_ignore();
597ObjectDecisionType Obstacle::MergeLateralDecision(
598 const ObjectDecisionType& lhs,
const ObjectDecisionType& rhs) {
599 if (lhs.object_tag_case() == ObjectDecisionType::OBJECT_TAG_NOT_SET) {
602 if (rhs.object_tag_case() == ObjectDecisionType::OBJECT_TAG_NOT_SET) {
606 FindOrDie(s_lateral_decision_safety_sorter_, lhs.object_tag_case());
608 FindOrDie(s_lateral_decision_safety_sorter_, rhs.object_tag_case());
609 if (lhs_val < rhs_val) {
611 }
else if (lhs_val > rhs_val) {
614 if (lhs.has_ignore()) {
616 }
else if (lhs.has_nudge()) {
617 DCHECK(lhs.nudge().type() == rhs.nudge().type())
618 <<
"could not merge left nudge and right nudge";
619 return std::fabs(lhs.nudge().distance_l()) >
620 std::fabs(rhs.nudge().distance_l())
625 DCHECK(
false) <<
"Does not have rule to merge decision: "
626 << lhs.ShortDebugString()
627 <<
" and decision: " << rhs.ShortDebugString();
632 return lateral_decision_.object_tag_case() !=
633 ObjectDecisionType::OBJECT_TAG_NOT_SET;
637 return longitudinal_decision_.object_tag_case() !=
638 ObjectDecisionType::OBJECT_TAG_NOT_SET;
647 const ObjectDecisionType& decision) {
649 <<
"Decision: " << decision.ShortDebugString()
650 <<
" is not a longitudinal decision";
651 longitudinal_decision_ =
652 MergeLongitudinalDecision(longitudinal_decision_, decision);
653 ADEBUG << decider_tag <<
" added obstacle " <<
Id()
654 <<
" longitudinal decision: " << decision.ShortDebugString()
655 <<
". The merged decision is: "
656 << longitudinal_decision_.ShortDebugString();
657 decisions_.push_back(decision);
658 decider_tags_.push_back(decider_tag);
662 const ObjectDecisionType& decision) {
664 <<
"Decision: " << decision.ShortDebugString()
665 <<
" is not a lateral decision";
666 lateral_decision_ = MergeLateralDecision(lateral_decision_, decision);
667 ADEBUG << decider_tag <<
" added obstacle " <<
Id()
668 <<
" a lateral decision: " << decision.ShortDebugString()
669 <<
". The merged decision is: "
670 << lateral_decision_.ShortDebugString();
671 decisions_.push_back(decision);
672 decider_tags_.push_back(decider_tag);
676 std::stringstream ss;
677 ss <<
"Obstacle id: " << id_;
678 for (
size_t i = 0; i < decisions_.size(); ++i) {
679 ss <<
" decision: " << decisions_[i].DebugString() <<
", made by "
682 if (lateral_decision_.object_tag_case() !=
683 ObjectDecisionType::OBJECT_TAG_NOT_SET) {
684 ss <<
"lateral decision: " << lateral_decision_.ShortDebugString();
686 if (longitudinal_decision_.object_tag_case() !=
687 ObjectDecisionType::OBJECT_TAG_NOT_SET) {
688 ss <<
"longitudinal decision: "
689 << longitudinal_decision_.ShortDebugString();
699 path_st_boundary_ = boundary;
700 path_st_boundary_initialized_ =
true;
710 lateral_decision_.Clear();
711 longitudinal_decision_.Clear();
712 decider_tags_.clear();
716 reference_line_st_boundary_ = boundary;
728bool Obstacle::IsValidObstacle(
730 const double object_width = perception_obstacle.
width();
731 const double object_length = perception_obstacle.
length();
733 const double kMinObjectDimension = 1.0e-6;
734 return !std::isnan(object_width) && !std::isnan(object_length) &&
735 object_width > kMinObjectDimension &&
736 object_length > kMinObjectDimension;
741 is_lane_blocking_ =
false;
744 DCHECK(sl_boundary_.has_start_s());
745 DCHECK(sl_boundary_.has_end_s());
746 DCHECK(sl_boundary_.has_start_l());
747 DCHECK(sl_boundary_.has_end_l());
749 if (sl_boundary_.
start_l() * sl_boundary_.
end_l() < 0.0) {
750 is_lane_blocking_ =
true;
754 const double driving_width = reference_line.
GetDrivingWidth(sl_boundary_);
757 if (reference_line.
IsOnLane(sl_boundary_) &&
759 vehicle_param.width() + FLAGS_static_obstacle_nudge_l_buffer) {
760 is_lane_blocking_ =
true;
764 is_lane_blocking_ =
false;
768 is_lane_change_blocking_ = is_distance_clear;
775 double delta_heading =
777 double cos_delta_heading = cos(delta_heading);
778 double sin_delta_heading = sin(delta_heading);
779 std::vector<common::math::Vec2d> polygon_point;
780 polygon_point.reserve(perception_polygon_.
points().size());
782 for (
auto& iter : perception_polygon_.
points()) {
783 double relative_x = iter.x() - perception_obstacle_.
position().
x();
784 double relative_y = iter.y() - perception_obstacle_.
position().
y();
785 double x = relative_x * cos_delta_heading - relative_y * sin_delta_heading +
787 double y = relative_x * sin_delta_heading + relative_y * cos_delta_heading +
789 polygon_point.emplace_back(x, y);
793 return trajectory_point_polygon;
797 if (perception_polygon_.
points().size() < 1) {
802 for (
const auto& p : perception_polygon_.
points()) {
803 print_curve.
AddPoint(id_ +
"_ObsPolygon", p.x(), p.y());
805 print_curve.
AddPoint(id_ +
"_ObsPolygon", perception_polygon_.
points()[0].x(),
806 perception_polygon_.
points()[0].y());
@Brief This is a helper class that can load vehicle configurations.
static double MinSafeTurnRadius()
Get the safe turning radius when the vehicle is turning with maximum steering angle.
static const VehicleConfig & GetConfig()
Get the current vehicle configuration.
Rectangular (undirected) bounding box in 2-D.
void GetAllCorners(std::vector< Vec2d > *const corners) const
Getter of the corners of the box
double width() const
Getter of the width
const Vec2d & center() const
Getter of the center of the box
double length() const
Getter of the length
double heading() const
Getter of the heading
The class of polygon in 2-D.
static bool ComputeConvexHull(const std::vector< Vec2d > &points, Polygon2d *const polygon, bool check_area=true)
Compute the convex hull of a group of points.
const std::vector< Vec2d > & points() const
Get the vertices of the polygon.
double y() const
Getter for y component
double x() const
Getter for x component
This is the class that associates an Obstacle with its path properties.
static bool IsLongitudinalDecision(const ObjectDecisionType &decision)
check if an ObjectDecisionType is a longitudinal decision.
std::string DebugString() const
const std::vector< std::string > & decider_tags() const
const STBoundary & path_st_boundary() const
const STBoundary & reference_line_st_boundary() const
static bool IsLateralDecision(const ObjectDecisionType &decision)
check if an ObjectDecisionType is a lateral decision.
void SetReferenceLineStBoundaryType(const STBoundary::BoundaryType type)
bool IsLongitudinalIgnore() const
const std::vector< ObjectDecisionType > & decisions() const
void AddLongitudinalDecision(const std::string &decider_tag, const ObjectDecisionType &decision)
const ObjectDecisionType & LateralDecision() const
return the merged lateral decision Lateral decision is one of {Nudge, Ignore}
common::TrajectoryPoint GetPointAtTime(const double time) const
static bool IsValidTrajectoryPoint(const common::TrajectoryPoint &point)
double MinRadiusStopDistance(const common::VehicleParam &vehicle_param) const
Calculate stop distance with the obstacle using the ADC's minimum turning radius
void EraseReferenceLineStBoundary()
void PrintPolygonCurve() const
void SetReferenceLineStBoundary(const STBoundary &boundary)
void AddLateralDecision(const std::string &decider_tag, const ObjectDecisionType &decision)
void CheckLaneBlocking(const ReferenceLine &reference_line)
bool HasLongitudinalDecision() const
const ObjectDecisionType & LongitudinalDecision() const
return the merged longitudinal decision Longitudinal decision is one of {Stop, Yield,...
void SetLaneChangeBlocking(const bool is_distance_clear)
const std::string & Id() const
bool IsCautionLevelObstacle() const
common::math::Box2d GetBoundingBox(const common::TrajectoryPoint &point) const
void SetStBoundaryType(const STBoundary::BoundaryType type)
bool IsLateralIgnore() const
bool HasLateralDecision() const
static std::unique_ptr< Obstacle > CreateStaticVirtualObstacles(const std::string &id, const common::math::Box2d &obstacle_box)
static bool IsValidPerceptionObstacle(const perception::PerceptionObstacle &obstacle)
bool HasNonIgnoreDecision() const
void BuildReferenceLineStBoundary(const ReferenceLine &reference_line, const double adc_start_s)
void set_path_st_boundary(const STBoundary &boundary)
const SLBoundary & PerceptionSLBoundary() const
static std::list< std::unique_ptr< Obstacle > > CreateObstacles(const prediction::PredictionObstacles &predictions)
This is a helper function that can create obstacles from prediction data.
void SetPerceptionSlBoundary(const SLBoundary &sl_boundary)
common::math::Polygon2d GetObstacleTrajectoryPolygon(const common::TrajectoryPoint &point) const
bool IsIgnore() const
Check if this object can be safely ignored.
void AddPoint(std::string key, double x, double y)
add point to curve key
bool GetApproximateSLBoundary(const common::math::Box2d &box, const double start_s, const double end_s, SLBoundary *const sl_boundary) const
bool IsOnLane(const common::SLPoint &sl_point) const
: check if a box/point is on lane along reference line
ReferencePoint GetReferencePoint(const double s) const
double GetDrivingWidth(const SLBoundary &sl_boundary) const
bool IsBlockRoad(const common::math::Box2d &box2d, double gap) const
Check if a box is blocking the road surface.
void SetBoundaryType(const BoundaryType &boundary_type)
Planning module main class.
Linear interpolation functions.
SLPoint InterpolateUsingLinearApproximation(const SLPoint &p0, const SLPoint &p1, const double w)
double DistanceXY(const U &u, const V &v)
calculate the distance beteween Point u and Point v, which are all have member function x() and y() i...
optional double relative_time
optional PathPoint path_point
optional VehicleParam vehicle_param
optional double front_edge_to_center
repeated apollo::common::Point3D polygon_point
optional apollo::common::Point3D velocity
optional apollo::common::Point3D position
repeated PredictionObstacle prediction_obstacle
repeated apollo::common::TrajectoryPoint trajectory_point