35 const std::shared_ptr<DependencyInjector>& injector) {
40 return Task::LoadConfig<ReusePathConfig>(&config_);
49 if (!IsPathReusable(frame, reference_line_info)) {
50 path_reusable_ =
false;
53 path_reusable_ =
true;
54 if (!TrimHistoryPath(frame, reference_line_info)) {
55 path_reusable_ =
false;
64bool ReusePath::IsPathReusable(
Frame* frame,
65 ReferenceLineInfo*
const reference_line_info) {
67 auto* lane_change_status =
injector_->planning_context()
68 ->mutable_planning_status()
69 ->mutable_change_lane();
70 ADEBUG <<
"lane change status: " << lane_change_status->ShortDebugString();
71 if (!reference_line_info->IsChangeLanePath() &&
73 ADEBUG <<
"skipping reusing path: not in lane_change";
76 if (reference_line_info->IsChangeLanePath() &&
85 bool speed_optimization_successful =
false;
86 const auto& history_frame =
injector_->frame_history()->Latest();
88 const auto history_trajectory_type =
89 history_frame->reference_line_info().front().trajectory_type();
90 speed_optimization_successful =
92 if (history_frame->current_frame_planned_path().empty()) {
97 if (!frame->current_frame_planned_trajectory().is_replan() &&
98 speed_optimization_successful && IsCollisionFree(reference_line_info)) {
103 ADEBUG <<
"stop reuse path";
108 auto* mutable_path_decider_status =
injector_->planning_context()
109 ->mutable_planning_status()
110 ->mutable_path_decider();
111 static constexpr int kWaitCycle = -2;
113 const int front_static_obstacle_cycle_counter =
114 mutable_path_decider_status->front_static_obstacle_cycle_counter();
115 const bool ignore_blocking_obstacle =
116 IsIgnoredBlockingObstacle(reference_line_info);
117 ADEBUG <<
"counter[" << front_static_obstacle_cycle_counter
118 <<
"] IsIgnoredBlockingObstacle[" << ignore_blocking_obstacle <<
"]";
123 if ((front_static_obstacle_cycle_counter <= kWaitCycle ||
124 ignore_blocking_obstacle) &&
125 speed_optimization_successful && IsCollisionFree(reference_line_info)) {
127 ADEBUG <<
"reuse path: front_blocking_obstacle ignorable";
131 return path_reusable_;
134bool ReusePath::IsIgnoredBlockingObstacle(
135 ReferenceLineInfo*
const reference_line_info) {
136 const ReferenceLine& reference_line = reference_line_info->reference_line();
137 static constexpr double kSDistBuffer = 30.0;
138 static constexpr int kTimeBuffer = 3;
140 double adc_speed =
injector_->vehicle_state()->linear_velocity();
141 double final_s_buffer = std::max(kSDistBuffer, kTimeBuffer * adc_speed);
143 common::SLPoint adc_position_sl;
144 GetADCSLPoint(reference_line, &adc_position_sl);
146 double blocking_obstacle_start_s;
147 if (GetBlockingObstacleS(reference_line_info, &blocking_obstacle_start_s) &&
149 (blocking_obstacle_start_s - adc_position_sl.s() > final_s_buffer)) {
150 ADEBUG <<
"blocking obstacle distance: "
151 << blocking_obstacle_start_s - adc_position_sl.s();
158bool ReusePath::GetBlockingObstacleS(
159 ReferenceLineInfo*
const reference_line_info,
double* blocking_obstacle_s) {
160 auto* mutable_path_decider_status =
injector_->planning_context()
161 ->mutable_planning_status()
162 ->mutable_path_decider();
164 const std::string& blocking_obstacle_ID =
165 mutable_path_decider_status->front_static_obstacle_id();
166 const IndexedList<std::string, Obstacle>& indexed_obstacles =
167 reference_line_info->path_decision()->obstacles();
168 const auto* blocking_obstacle = indexed_obstacles.Find(blocking_obstacle_ID);
170 if (blocking_obstacle ==
nullptr) {
174 const auto& obstacle_sl = blocking_obstacle->PerceptionSLBoundary();
175 *blocking_obstacle_s = obstacle_sl.start_s();
176 ADEBUG <<
"blocking obstacle distance: " << obstacle_sl.start_s();
180void ReusePath::GetADCSLPoint(
const ReferenceLine& reference_line,
181 common::SLPoint* adc_position_sl) {
182 common::math::Vec2d adc_position = {
injector_->vehicle_state()->x(),
184 reference_line.XYToSL(adc_position, adc_position_sl);
187bool ReusePath::IsCollisionFree(ReferenceLineInfo*
const reference_line_info) {
188 const ReferenceLine& reference_line = reference_line_info->reference_line();
190 const double kSBuffer = 0.5;
192 common::SLPoint adc_position_sl;
193 GetADCSLPoint(reference_line, &adc_position_sl);
196 std::vector<Polygon2d> obstacle_polygons;
198 reference_line_info->path_decision()->obstacles().Items()) {
200 if (!obstacle->IsStatic() || obstacle->IsVirtual()) {
201 if (!obstacle->IsStatic()) {
202 ADEBUG <<
"SPOT a dynamic obstacle";
204 if (obstacle->IsVirtual()) {
205 ADEBUG <<
"SPOT a virtual obstacle";
210 const auto& obstacle_sl = obstacle->PerceptionSLBoundary();
212 if ((obstacle_sl.end_s() < adc_position_sl.s() - kSBuffer) ||
214 (obstacle_sl.end_s() - obstacle_sl.start_s()) *
215 (obstacle_sl.end_l() - obstacle_sl.start_l()) <
219 obstacle_polygons.push_back(
220 Polygon2d({Vec2d(obstacle_sl.start_s(), obstacle_sl.start_l()),
221 Vec2d(obstacle_sl.start_s(), obstacle_sl.end_l()),
222 Vec2d(obstacle_sl.end_s(), obstacle_sl.end_l()),
223 Vec2d(obstacle_sl.end_s(), obstacle_sl.start_l())}));
226 if (obstacle_polygons.empty()) {
230 const auto& history_frame =
injector_->frame_history()->Latest();
231 if (!history_frame) {
234 const DiscretizedPath& history_path =
235 history_frame->current_frame_planned_path();
236 if (history_path.empty()) {
237 AINFO <<
"No history path skip reuse";
241 common::SLPoint path_end_position_sl;
242 common::math::Vec2d path_end_position = {history_path.back().x(),
243 history_path.back().y()};
244 reference_line.XYToSL(path_end_position, &path_end_position_sl);
245 const double min_distance_to_end =
246 FLAGS_path_bounds_decider_resolution * FLAGS_num_extra_tail_bound_point;
247 for (
size_t i = 0; i < history_path.size(); ++i) {
248 common::SLPoint path_position_sl;
249 common::math::Vec2d path_position = {history_path[i].x(),
250 history_path[i].y()};
251 reference_line.XYToSL(path_position, &path_position_sl);
252 if (path_end_position_sl.s() - path_position_sl.s() <=
253 min_distance_to_end) {
256 if (path_position_sl.s() < adc_position_sl.s() - kSBuffer) {
259 const auto& vehicle_box =
260 common::VehicleConfigHelper::Instance()->GetBoundingBox(
262 std::vector<Vec2d> ABCDpoints = vehicle_box.GetAllCorners();
263 for (
const auto& corner_point : ABCDpoints) {
265 common::SLPoint curr_point_sl;
266 if (!reference_line.XYToSL(corner_point, &curr_point_sl)) {
267 AERROR <<
"Failed to get the projection from point onto "
271 auto curr_point = Vec2d(curr_point_sl.s(), curr_point_sl.l());
273 for (
const auto& obstacle_polygon : obstacle_polygons) {
274 if (obstacle_polygon.IsPointIn(curr_point)) {
276 ADEBUG <<
"s distance to end point:" << path_end_position_sl.s();
277 ADEBUG <<
"s distance to end point:" << path_position_sl.s();
279 <<
", history_path[i].x(): " << std::setprecision(9)
280 << history_path[i].x() <<
", history_path[i].y()"
281 << std::setprecision(9) << history_path[i].y();
282 ADEBUG <<
"collision:" << curr_point.x() <<
", " << curr_point.y();
284 reference_line.SLToXY(curr_point_sl, &xy_point);
285 ADEBUG <<
"collision:" << xy_point.x() <<
", " << xy_point.y();
296bool ReusePath::NotShortPath(
const DiscretizedPath& current_path) {
301bool ReusePath::TrimHistoryPath(
Frame* frame,
302 ReferenceLineInfo*
const reference_line_info) {
303 const ReferenceLine& reference_line = reference_line_info->reference_line();
304 const auto& history_frame =
injector_->frame_history()->Latest();
305 if (!history_frame) {
306 ADEBUG <<
"no history frame";
310 const common::TrajectoryPoint history_planning_start_point =
311 history_frame->PlanningStartPoint();
312 common::PathPoint history_init_path_point =
313 history_planning_start_point.path_point();
314 ADEBUG <<
"history_init_path_point x:[" << std::setprecision(9)
315 << history_init_path_point.x() <<
"], y["
316 << history_init_path_point.y() <<
"], s: ["
317 << history_init_path_point.s() <<
"]";
319 const common::TrajectoryPoint planning_start_point =
320 frame->PlanningStartPoint();
321 common::PathPoint init_path_point = planning_start_point.path_point();
322 ADEBUG <<
"init_path_point x:[" << std::setprecision(9) << init_path_point.x()
323 <<
"], y[" << init_path_point.y() <<
"], s: [" << init_path_point.s()
326 const DiscretizedPath& history_path =
327 history_frame->current_frame_planned_path();
328 DiscretizedPath trimmed_path;
329 common::SLPoint adc_position_sl;
330 GetADCSLPoint(reference_line, &adc_position_sl);
331 ADEBUG <<
"adc_position_sl.s(): " << adc_position_sl.s();
332 ADEBUG <<
"history_path.size(): " << history_path.size();
333 size_t path_start_index = 0;
335 for (
size_t i = 0; i < history_path.size(); ++i) {
337 if (history_path[i].s() > 0) {
338 path_start_index = i;
342 ADEBUG <<
"!!!path_start_index[" << path_start_index <<
"]";
345 common::SLPoint init_path_position_sl;
346 reference_line.XYToSL(init_path_point, &init_path_position_sl);
347 bool inserted_init_point =
false;
349 for (
size_t i = path_start_index; i < history_path.size(); ++i) {
350 common::SLPoint path_position_sl;
351 common::math::Vec2d path_position = {history_path[i].x(),
352 history_path[i].y()};
354 reference_line.XYToSL(path_position, &path_position_sl);
356 double updated_s = path_position_sl.s() - init_path_position_sl.s();
358 if (updated_s > 0 && !inserted_init_point) {
359 trimmed_path.emplace_back(init_path_point);
360 trimmed_path.back().set_s(0);
361 inserted_init_point =
true;
364 trimmed_path.emplace_back(history_path[i]);
374 trimmed_path.back().set_s(updated_s);
377 ADEBUG <<
"trimmed_path[0]: " << trimmed_path.front().s();
378 ADEBUG <<
"[END] trimmed_path.size(): " << trimmed_path.size();
380 if (!NotShortPath(trimmed_path)) {
381 ADEBUG <<
"short path: " << trimmed_path.size();
386 auto path_data = reference_line_info->mutable_path_data();
387 ADEBUG <<
"previous path_data size: " << history_path.size();
388 path_data->SetReferenceLine(&reference_line);
389 ADEBUG <<
"previous path_data size: " << path_data->discretized_path().size();
390 path_data->SetDiscretizedPath(DiscretizedPath(std::move(trimmed_path)));
391 ADEBUG <<
"not short path: " << trimmed_path.size();
392 ADEBUG <<
"current path size: "
393 << reference_line_info->path_data().discretized_path().size();
394 RecordDebugInfo(*path_data, path_data->path_label(), reference_line_info);
A general class to denote the return status of an API call.
static Status OK()
generate a success status.
The class of polygon in 2-D.
Implements a class of 2-dimensional vectors.
Frame holds all data for one planning cycle.
void RecordDebugInfo(const PathBound &path_boundaries, const std::string &debug_name, ReferenceLineInfo *const reference_line_info)
add path_boundary debug info for PnC monitor
ReferenceLineInfo holds all data for one reference line.
const PathData & path_data() const
void set_path_reusable(const bool path_reusable)
bool Init(const std::string &config_dir, const std::string &name, const std::shared_ptr< DependencyInjector > &injector) override
std::shared_ptr< DependencyInjector > injector_
virtual bool Init(const std::string &config_dir, const std::string &name, const std::shared_ptr< DependencyInjector > &injector)
Planning module main class.
constexpr double kMinObstacleArea
optional uint32 short_path_threshold
optional bool enable_reuse_path_in_lane_follow