26#include "modules/common_msgs/planning_msgs/decision.pb.h"
42 const std::shared_ptr<DependencyInjector> &injector) {
47 return Task::LoadConfig<PathDeciderConfig>(&config_);
53 return Process(reference_line_info, reference_line_info->
path_data(),
61 if (FLAGS_enable_skip_path_tasks && reference_line_info->
path_reusable()) {
64 PrintCurves debug_info;
67 const auto &vehicle_box =
68 common::VehicleConfigHelper::Instance()->GetBoundingBox(path[0]);
69 debug_info.AddPoint(
"start_point_box", vehicle_box.GetAllCorners());
72 for (
const auto &path_pt : path) {
73 debug_info.AddPoint(
"output_path", path_pt.x(), path_pt.y());
75 debug_info.PrintToLog();
76 std::string blocking_obstacle_id;
77 auto *mutable_path_decider_status =
injector_->planning_context()
78 ->mutable_planning_status()
79 ->mutable_path_decider();
82 int front_static_obstacle_cycle_counter =
83 mutable_path_decider_status->front_static_obstacle_cycle_counter();
84 mutable_path_decider_status->set_front_static_obstacle_cycle_counter(
85 std::max(front_static_obstacle_cycle_counter, 0));
86 mutable_path_decider_status->set_front_static_obstacle_cycle_counter(
87 std::min(front_static_obstacle_cycle_counter + 1, 10));
88 mutable_path_decider_status->set_front_static_obstacle_id(
91 int front_static_obstacle_cycle_counter =
92 mutable_path_decider_status->front_static_obstacle_cycle_counter();
93 mutable_path_decider_status->set_front_static_obstacle_cycle_counter(
94 std::min(front_static_obstacle_cycle_counter, 0));
95 mutable_path_decider_status->set_front_static_obstacle_cycle_counter(
96 std::max(front_static_obstacle_cycle_counter - 1, -10));
97 if (mutable_path_decider_status->front_static_obstacle_cycle_counter() <
100 mutable_path_decider_status->set_front_static_obstacle_id(
id);
103 if (!MakeObjectDecision(path_data, blocking_obstacle_id, path_decision)) {
104 const std::string msg =
"Failed to make decision based on tunnel";
106 return Status(ErrorCode::PLANNING_ERROR, msg);
111bool PathDecider::MakeObjectDecision(
const PathData &path_data,
112 const std::string &blocking_obstacle_id,
113 PathDecision *
const path_decision) {
114 if (!MakeStaticObstacleDecision(path_data, blocking_obstacle_id,
116 AERROR <<
"Failed to make decisions for static obstacles";
120 IgnoreBackwardObstacle(path_decision);
129bool PathDecider::MakeStaticObstacleDecision(
130 const PathData &path_data,
const std::string &blocking_obstacle_id,
131 PathDecision *
const path_decision) {
134 const auto &frenet_path = path_data.frenet_frame_path();
135 if (frenet_path.empty()) {
136 AERROR <<
"Path is empty.";
139 const double half_width =
141 const double lateral_radius = half_width + FLAGS_lateral_ignore_buffer;
144 for (
const auto *obstacle : path_decision->obstacles().Items()) {
145 const std::string &obstacle_id = obstacle->Id();
146 const std::string obstacle_type_name =
147 PerceptionObstacle_Type_Name(obstacle->Perception().type());
148 ADEBUG <<
"obstacle_id[<< " << obstacle_id <<
"] type["
149 << obstacle_type_name <<
"]";
151 if (!obstacle->IsStatic() || obstacle->IsVirtual()) {
155 if (obstacle->HasLongitudinalDecision() &&
156 obstacle->LongitudinalDecision().has_ignore() &&
157 obstacle->HasLateralDecision() &&
158 obstacle->LateralDecision().has_ignore()) {
161 if (obstacle->HasLongitudinalDecision() &&
162 obstacle->LongitudinalDecision().has_stop()) {
167 if (obstacle->Id() == blocking_obstacle_id &&
171 .is_in_path_lane_borrow_scenario()) {
173 ADEBUG <<
"Blocking obstacle = " << blocking_obstacle_id;
174 ObjectDecisionType object_decision;
175 *object_decision.mutable_stop() = GenerateObjectStopDecision(*obstacle);
176 path_decision->AddLongitudinalDecision(
"PathDecider/blocking_obstacle",
177 obstacle->Id(), object_decision);
181 if (obstacle->reference_line_st_boundary().boundary_type() ==
187 ObjectDecisionType object_decision;
188 object_decision.mutable_ignore();
189 const auto &sl_boundary = obstacle->PerceptionSLBoundary();
190 if (sl_boundary.end_s() < frenet_path.front().s() ||
191 sl_boundary.start_s() > frenet_path.back().s()) {
192 path_decision->AddLongitudinalDecision(
"PathDecider/not-in-s",
193 obstacle->Id(), object_decision);
194 path_decision->AddLateralDecision(
"PathDecider/not-in-s", obstacle->Id(),
199 const auto frenet_point = frenet_path.GetNearestPoint(sl_boundary);
200 const double curr_l = frenet_point.l();
203 if (curr_l - lateral_radius > sl_boundary.end_l() ||
204 curr_l + lateral_radius < sl_boundary.start_l()) {
206 path_decision->AddLateralDecision(
"PathDecider/not-in-l", obstacle->Id(),
208 }
else if (sl_boundary.end_l() >= curr_l - min_nudge_l &&
209 sl_boundary.start_l() <= curr_l + min_nudge_l) {
211 AINFO <<
"skip_overlap_stop_check";
214 *object_decision.mutable_stop() = GenerateObjectStopDecision(*obstacle);
216 if (path_decision->MergeWithMainStop(
217 object_decision.stop(), obstacle->Id(),
220 path_decision->AddLongitudinalDecision(
221 "PathDecider/nearest-stop", obstacle->Id(), object_decision);
223 ObjectDecisionType object_decision;
224 object_decision.mutable_ignore();
225 path_decision->AddLongitudinalDecision(
226 "PathDecider/not-nearest-stop", obstacle->Id(), object_decision);
228 AINFO <<
"Add stop decision for static obs " << obstacle->Id()
229 <<
"start l" << sl_boundary.start_l() <<
"end l"
230 << sl_boundary.end_l() <<
"curr_l" << curr_l <<
"min_nudge_l"
235 if (sl_boundary.end_l() < curr_l - min_nudge_l) {
238 ObjectNudge *object_nudge_ptr = object_decision.mutable_nudge();
239 object_nudge_ptr->set_type(ObjectNudge::LEFT_NUDGE);
241 path_decision->AddLateralDecision(
"PathDecider/left-nudge",
242 obstacle->Id(), object_decision);
243 }
else if (sl_boundary.start_l() > curr_l + min_nudge_l) {
246 ObjectNudge *object_nudge_ptr = object_decision.mutable_nudge();
247 object_nudge_ptr->set_type(ObjectNudge::RIGHT_NUDGE);
249 path_decision->AddLateralDecision(
"PathDecider/right-nudge",
250 obstacle->Id(), object_decision);
258ObjectStop PathDecider::GenerateObjectStopDecision(
259 const Obstacle &obstacle)
const {
260 ObjectStop object_stop;
262 double stop_distance = obstacle.MinRadiusStopDistance(
264 object_stop.set_reason_code(StopReasonCode::STOP_REASON_OBSTACLE);
265 object_stop.set_distance_s(-stop_distance);
267 const double stop_ref_s =
268 obstacle.PerceptionSLBoundary().start_s() - stop_distance;
269 const auto stop_ref_point =
271 object_stop.mutable_stop_point()->
set_x(stop_ref_point.x());
272 object_stop.mutable_stop_point()->set_y(stop_ref_point.y());
273 object_stop.set_stop_heading(stop_ref_point.heading());
277bool PathDecider::IgnoreBackwardObstacle(PathDecision *
const path_decision) {
279 for (
const auto *obstacle : path_decision->obstacles().Items()) {
280 if (obstacle->IsStatic() || obstacle->IsVirtual()) {
283 if (obstacle->Obstacle::PerceptionSLBoundary().end_s() < adc_start_s) {
284 ObjectDecisionType object_decision;
285 object_decision.mutable_ignore();
286 path_decision->AddLongitudinalDecision(
287 "PathDecider/ignore-backward-obstacle", obstacle->Id(),
A general class to denote the return status of an API call.
static Status OK()
generate a success status.
@Brief This is a helper class that can load vehicle configurations.
static const VehicleConfig & GetConfig()
Get the current vehicle configuration.
void set_x(const double x)
Setter for x component
Frame holds all data for one planning cycle.
const std::string & Id() const
const DiscretizedPath & discretized_path() const
bool Init(const std::string &config_dir, const std::string &name, const std::shared_ptr< DependencyInjector > &injector) override
apollo::common::Status Execute(Frame *frame, ReferenceLineInfo *reference_line_info) override
PathDecision represents all obstacle decisions on one path.
ReferenceLineInfo holds all data for one reference line.
bool path_reusable() const
PathDecision * path_decision()
Obstacle * GetBlockingObstacle() const
const ReferenceLine & reference_line() const
const PathData & path_data() const
const SLBoundary & AdcSlBoundary() const
ReferencePoint GetReferencePoint(const double s) const
std::shared_ptr< DependencyInjector > injector_
ReferenceLineInfo * reference_line_info_
virtual bool Init(const std::string &config_dir, const std::string &name, const std::shared_ptr< DependencyInjector > &injector)
virtual common::Status Execute(Frame *frame, ReferenceLineInfo *reference_line_info)
Planning module main class.
optional VehicleParam vehicle_param
optional bool ignore_backward_obstacle
optional bool skip_overlap_stop_check
optional double static_obstacle_buffer