Skip to content

Commit e56519f

Browse files
committed
feat(goal_planner): consider lane changing previous module path
Signed-off-by: Mamoru Sobue <[email protected]>
1 parent b4f2f95 commit e56519f

File tree

10 files changed

+145
-33
lines changed

10 files changed

+145
-33
lines changed

planning/behavior_path_planner/autoware_behavior_path_goal_planner_module/include/autoware/behavior_path_goal_planner_module/decision_state.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ class PathDecisionStateController
5555
const autoware_perception_msgs::msg::PredictedObjects & dynamic_target_objects,
5656
const std::shared_ptr<const PlannerData> planner_data,
5757
const std::shared_ptr<OccupancyGridBasedCollisionDetector> occupancy_grid_map,
58-
const bool is_current_safe, const GoalPlannerParameters & parameters,
59-
const GoalSearcher & goal_searcher,
58+
const bool is_current_safe, const bool lane_change_status_changed,
59+
const GoalPlannerParameters & parameters, const GoalSearcher & goal_searcher,
6060
std::vector<autoware_utils::Polygon2d> & ego_polygons_expanded);
6161

6262
PathDecisionState get_current_state() const { return current_state_; }
@@ -75,8 +75,8 @@ class PathDecisionStateController
7575
const PredictedObjects & dynamic_target_objects,
7676
const std::shared_ptr<const PlannerData> planner_data,
7777
const std::shared_ptr<OccupancyGridBasedCollisionDetector> occupancy_grid_map,
78-
const bool is_current_safe, const GoalPlannerParameters & parameters,
79-
const GoalSearcher & goal_searcher,
78+
const bool is_current_safe, const bool lane_change_status_changed,
79+
const GoalPlannerParameters & parameters, const GoalSearcher & goal_searcher,
8080
std::vector<autoware_utils::Polygon2d> & ego_polygons_expanded) const;
8181
};
8282

planning/behavior_path_planner/autoware_behavior_path_goal_planner_module/include/autoware/behavior_path_goal_planner_module/goal_planner_module.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,11 @@ class GoalPlannerModule : public SceneModuleInterface
302302
const bool left_side_parking_;
303303

304304
bool trigger_thread_on_approach_{false};
305+
306+
// signal path generator and state manager to regenerate path candidates and remain NOT_DECIDED
307+
std::optional<bool> prev_lane_change_status_{};
308+
bool lane_change_status_changed_{false};
309+
305310
// pre-generate lane parking paths in a separate thread
306311
rclcpp::TimerBase::SharedPtr lane_parking_timer_;
307312
rclcpp::CallbackGroup::SharedPtr lane_parking_timer_cb_group_;

planning/behavior_path_planner/autoware_behavior_path_goal_planner_module/include/autoware/behavior_path_goal_planner_module/pull_over_planner/pull_over_planner_base.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ struct PullOverPath
9191

9292
std::vector<Pose> debug_poses{};
9393

94+
std::optional<PathWithLaneId> debug_processed_prev_module_path;
95+
9496
private:
9597
PullOverPath(
9698
const PullOverPlannerType & type, const size_t id, const Pose & start_pose,

planning/behavior_path_planner/autoware_behavior_path_goal_planner_module/include/autoware/behavior_path_goal_planner_module/thread_data.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class LaneParkingRequest
4545
const PlannerData & planner_data, const ModuleStatus & current_status,
4646
const BehaviorModuleOutput & upstream_module_output,
4747
const std::optional<PullOverPath> & pull_over_path, const PathDecisionState & prev_data,
48-
const bool trigger_thread_on_approach);
48+
const bool trigger_thread_on_approach, const bool lane_change_status_changed);
4949

5050
const autoware_utils::LinearRing2d vehicle_footprint_;
5151
const GoalCandidates goal_candidates_;
@@ -60,6 +60,7 @@ class LaneParkingRequest
6060
const std::optional<PullOverPath> & get_pull_over_path() const { return pull_over_path_; }
6161
const PathDecisionState & get_prev_data() const { return prev_data_; }
6262
bool trigger_thread_on_approach() const { return trigger_thread_on_approach_; }
63+
bool lane_change_status_changed() const { return lane_change_status_changed_; }
6364

6465
private:
6566
std::shared_ptr<PlannerData> planner_data_;
@@ -68,6 +69,7 @@ class LaneParkingRequest
6869
std::optional<PullOverPath> pull_over_path_; //<! pull over path selected by main thread
6970
PathDecisionState prev_data_;
7071
bool trigger_thread_on_approach_{false};
72+
bool lane_change_status_changed_{false};
7173
};
7274

7375
struct LaneParkingResponse

planning/behavior_path_planner/autoware_behavior_path_goal_planner_module/include/autoware/behavior_path_goal_planner_module/util.hpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,23 @@ bool hasDeviatedFromPath(
252252
*/
253253
bool has_stopline_except_terminal(const PathWithLaneId & path);
254254

255+
/**
256+
* @brief find the lanelet that has changed "laterally" from previous lanelet on the routing graph
257+
* @return the lanelet that changed "laterally" if the path is lane changing, otherwise nullopt
258+
*/
259+
std::optional<lanelet::ConstLanelet> find_lane_change_completed_lanelet(
260+
const PathWithLaneId & path, const lanelet::LaneletMapConstPtr lanelet_map,
261+
const lanelet::routing::RoutingGraphConstPtr routing_graph);
262+
263+
/**
264+
* @brief generate lanelets with which pull over path is alinged
265+
* @note if lane changing path is detected, this returns lanelets aligned with later part of the
266+
* lane changing path
267+
*/
268+
lanelet::ConstLanelets get_reference_lanelets_for_pullover(
269+
const PathWithLaneId & path, const std::shared_ptr<const PlannerData> & planner_data,
270+
const double backward_length, const double forward_length);
271+
255272
} // namespace autoware::behavior_path_planner::goal_planner_utils
256273

257274
#endif // AUTOWARE__BEHAVIOR_PATH_GOAL_PLANNER_MODULE__UTIL_HPP_

planning/behavior_path_planner/autoware_behavior_path_goal_planner_module/src/decision_state.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,14 @@ void PathDecisionStateController::transit_state(
3131
const PredictedObjects & dynamic_target_objects,
3232
const std::shared_ptr<const PlannerData> planner_data,
3333
const std::shared_ptr<OccupancyGridBasedCollisionDetector> occupancy_grid_map,
34-
const bool is_current_safe, const GoalPlannerParameters & parameters,
35-
const GoalSearcher & goal_searcher,
34+
const bool is_current_safe, const bool lane_change_status_changed,
35+
const GoalPlannerParameters & parameters, const GoalSearcher & goal_searcher,
3636
std::vector<autoware_utils::Polygon2d> & ego_polygons_expanded)
3737
{
3838
const auto next_state = get_next_state(
3939
pull_over_path_opt, upstream_module_has_stopline, now, static_target_objects,
40-
dynamic_target_objects, planner_data, occupancy_grid_map, is_current_safe, parameters,
41-
goal_searcher, ego_polygons_expanded);
40+
dynamic_target_objects, planner_data, occupancy_grid_map, is_current_safe,
41+
lane_change_status_changed, parameters, goal_searcher, ego_polygons_expanded);
4242
current_state_ = next_state;
4343
}
4444

@@ -48,8 +48,8 @@ PathDecisionState PathDecisionStateController::get_next_state(
4848
const PredictedObjects & dynamic_target_objects,
4949
const std::shared_ptr<const PlannerData> planner_data,
5050
const std::shared_ptr<OccupancyGridBasedCollisionDetector> occupancy_grid_map,
51-
const bool is_current_safe, const GoalPlannerParameters & parameters,
52-
const GoalSearcher & goal_searcher,
51+
const bool is_current_safe, const bool lane_change_status_changed,
52+
const GoalPlannerParameters & parameters, const GoalSearcher & goal_searcher,
5353
std::vector<autoware_utils::Polygon2d> & ego_polygons_expanded) const
5454
{
5555
auto next_state = current_state_;
@@ -74,6 +74,12 @@ PathDecisionState PathDecisionStateController::get_next_state(
7474
return next_state;
7575
}
7676

77+
// if lane change is triggered, reference path for pull over must be reset accordingly
78+
if (lane_change_status_changed) {
79+
next_state.state = PathDecisionState::DecisionKind::NOT_DECIDED;
80+
return next_state;
81+
}
82+
7783
// while upstream module path has stopline, goal_planner remains NOT_DECIDED
7884
if (upstream_module_has_stopline) {
7985
next_state.state = PathDecisionState::DecisionKind::NOT_DECIDED;

planning/behavior_path_planner/autoware_behavior_path_goal_planner_module/src/goal_planner_module.cpp

Lines changed: 50 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ void LaneParkingPlanner::onTimer()
269269
const auto & prev_data = local_request.get_prev_data();
270270
const auto trigger_thread_on_approach = local_request.trigger_thread_on_approach();
271271
const auto use_bus_stop_area = local_request.use_bus_stop_area_;
272+
const auto lane_change_status_changed = local_request.lane_change_status_changed();
272273

273274
if (!trigger_thread_on_approach) {
274275
return;
@@ -317,6 +318,10 @@ void LaneParkingPlanner::onTimer()
317318
RCLCPP_DEBUG(getLogger(), "has deviated from last previous module path");
318319
return true;
319320
}
321+
if (lane_change_status_changed) {
322+
RCLCPP_INFO(getLogger(), "[LaneParkingPlanner]: lane_change_status changed, so replan");
323+
return true;
324+
}
320325
const bool upstream_module_has_stopline_except_terminal =
321326
goal_planner_utils::has_stopline_except_terminal(upstream_module_output.path);
322327
if (upstream_module_has_stopline_except_terminal) {
@@ -613,6 +618,12 @@ std::pair<LaneParkingResponse, FreespaceParkingResponse> GoalPlannerModule::sync
613618
vehicle_footprint_, goal_candidates_, getPreviousModuleOutput(),
614619
use_bus_stop_area_ && goal_searcher.bus_stop_area_available());
615620
}
621+
const auto lane_change_status =
622+
goal_planner_utils::find_lane_change_completed_lanelet(
623+
getPreviousModuleOutput().path, planner_data_->route_handler->getLaneletMapPtr(),
624+
planner_data_->route_handler->getRoutingGraphPtr())
625+
.has_value();
626+
616627
// NOTE: for the above reasons, PlannerManager/behavior_path_planner_node ensure that
617628
// planner_data_ is not nullptr, so it is OK to copy as value
618629
// By copying PlannerData as value, the internal shared member variables are also copied
@@ -622,7 +633,8 @@ std::pair<LaneParkingResponse, FreespaceParkingResponse> GoalPlannerModule::sync
622633
// count is affected
623634
lane_parking_request_.value().update(
624635
*planner_data_, getCurrentStatus(), getPreviousModuleOutput(), pull_over_path,
625-
path_decision_controller_.get_current_state(), trigger_thread_on_approach_);
636+
path_decision_controller_.get_current_state(), trigger_thread_on_approach_,
637+
lane_change_status);
626638
// NOTE: RouteHandler holds several shared pointers in it, so just copying PlannerData as
627639
// value does not adds the reference counts of RouteHandler.lanelet_map_ptr_ and others. Since
628640
// behavior_path_planner::run() updates
@@ -685,28 +697,41 @@ void GoalPlannerModule::updateData()
685697
goal_candidates_ = generateGoalCandidates(goal_searcher_.value(), use_bus_stop_area_);
686698
}
687699

700+
const auto lane_change_status =
701+
goal_planner_utils::find_lane_change_completed_lanelet(
702+
getPreviousModuleOutput().path, planner_data_->route_handler->getLaneletMapPtr(),
703+
planner_data_->route_handler->getRoutingGraphPtr())
704+
.has_value();
705+
lane_change_status_changed_ =
706+
prev_lane_change_status_ && prev_lane_change_status_.value() != lane_change_status;
707+
prev_lane_change_status_ = lane_change_status;
708+
688709
const lanelet::ConstLanelets current_lanes =
689710
utils::getCurrentLanesFromPath(getPreviousModuleOutput().reference_path, planner_data_);
690711

691-
if (
692-
!trigger_thread_on_approach_ &&
693-
utils::isAllowedGoalModification(planner_data_->route_handler) &&
694-
goal_planner_utils::is_goal_reachable_on_path(
695-
current_lanes, *(planner_data_->route_handler), left_side_parking_)) {
696-
const double self_to_goal_arc_length = utils::getSignedDistance(
697-
planner_data_->self_odometry->pose.pose, planner_data_->route_handler->getOriginalGoalPose(),
698-
current_lanes);
699-
if (self_to_goal_arc_length < parameters_.pull_over_prepare_length) {
700-
trigger_thread_on_approach_ = true;
712+
if (getCurrentStatus() == ModuleStatus::IDLE) {
713+
if (
714+
!trigger_thread_on_approach_ &&
715+
utils::isAllowedGoalModification(planner_data_->route_handler) &&
716+
goal_planner_utils::is_goal_reachable_on_path(
717+
current_lanes, *(planner_data_->route_handler), left_side_parking_)) {
718+
const double self_to_goal_arc_length = utils::getSignedDistance(
719+
planner_data_->self_odometry->pose.pose,
720+
planner_data_->route_handler->getOriginalGoalPose(), current_lanes);
721+
if (self_to_goal_arc_length < parameters_.pull_over_prepare_length) {
722+
trigger_thread_on_approach_ = true;
723+
[[maybe_unused]] const auto send_only_request = syncWithThreads();
724+
RCLCPP_INFO(
725+
getLogger(), "start preparing goal candidates once for goal ahead of %f meter",
726+
self_to_goal_arc_length);
727+
return;
728+
}
729+
}
730+
if (lane_change_status_changed_) {
701731
[[maybe_unused]] const auto send_only_request = syncWithThreads();
702-
RCLCPP_INFO(
703-
getLogger(), "start preparing goal candidates once for goal ahead of %f meter",
704-
self_to_goal_arc_length);
732+
RCLCPP_INFO(getLogger(), "restart preparing goal candidates since lane_change is detected");
705733
return;
706734
}
707-
}
708-
709-
if (getCurrentStatus() == ModuleStatus::IDLE) {
710735
return;
711736
}
712737

@@ -737,10 +762,12 @@ void GoalPlannerModule::updateData()
737762

738763
const bool upstream_module_has_stopline_except_terminal =
739764
goal_planner_utils::has_stopline_except_terminal(getPreviousModuleOutput().path);
765+
740766
path_decision_controller_.transit_state(
741767
pull_over_path_recv, upstream_module_has_stopline_except_terminal, clock_->now(),
742768
static_target_objects, dynamic_target_objects, planner_data_, occupancy_grid_map_,
743-
is_current_safe, parameters_, goal_searcher, debug_data_.ego_polygons_expanded);
769+
is_current_safe, lane_change_status_changed_, parameters_, goal_searcher,
770+
debug_data_.ego_polygons_expanded);
744771
const auto new_decision_state = path_decision_controller_.get_current_state();
745772

746773
auto [lane_parking_response, freespace_parking_response] = syncWithThreads();
@@ -2561,6 +2588,11 @@ void GoalPlannerModule::setDebugData(const PullOverContextData & context_data)
25612588
createPathMarkerArray(pull_over_path.full_path(), "full_path", 0, 0.0, 0.5, 0.9));
25622589
add_debug_marker(
25632590
createPathMarkerArray(pull_over_path.getCurrentPath(), "current_path", 0, 0.9, 0.5, 0.0));
2591+
if (pull_over_path.debug_processed_prev_module_path) {
2592+
add_debug_marker(createPathMarkerArray(
2593+
pull_over_path.debug_processed_prev_module_path.value(), "processed_prev_module_path", 0,
2594+
0.9, 0.5, 0.9));
2595+
}
25642596

25652597
// visualize each partial path
25662598
for (size_t i = 0; i < pull_over_path.partial_paths().size(); ++i) {

planning/behavior_path_planner/autoware_behavior_path_goal_planner_module/src/pull_over_planner/shift_pull_over.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,8 @@ std::optional<PullOverPath> ShiftPullOver::plan(
5454
const int shift_sampling_num = parameters_.shift_sampling_num;
5555
const double jerk_resolution = std::abs(max_jerk - min_jerk) / shift_sampling_num;
5656

57-
const auto road_lanes = utils::getExtendedCurrentLanesFromPath(
58-
upstream_module_output.path, planner_data, backward_search_length, forward_search_length,
59-
/*forward_only_in_route*/ false);
57+
const auto road_lanes = goal_planner_utils::get_reference_lanelets_for_pullover(
58+
upstream_module_output.path, planner_data, backward_search_length, forward_search_length);
6059

6160
const auto pull_over_lanes = goal_planner_utils::getPullOverLanes(
6261
*route_handler, left_side_parking_, backward_search_length, forward_search_length);
@@ -286,6 +285,7 @@ std::optional<PullOverPath> ShiftPullOver::generatePullOverPath(
286285
return {};
287286
}
288287

288+
pull_over_path.debug_processed_prev_module_path = processed_prev_module_path;
289289
return pull_over_path;
290290
}
291291

planning/behavior_path_planner/autoware_behavior_path_goal_planner_module/src/thread_data.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ void LaneParkingRequest::update(
2323
const PlannerData & planner_data, const ModuleStatus & current_status,
2424
const BehaviorModuleOutput & upstream_module_output,
2525
const std::optional<PullOverPath> & pull_over_path, const PathDecisionState & prev_data,
26-
const bool trigger_thread_on_approach)
26+
const bool trigger_thread_on_approach, const bool lane_change_status_changed)
2727
{
2828
planner_data_ = std::make_shared<PlannerData>(planner_data);
2929
planner_data_->route_handler = std::make_shared<RouteHandler>(*(planner_data.route_handler));
@@ -32,6 +32,7 @@ void LaneParkingRequest::update(
3232
pull_over_path_ = pull_over_path;
3333
prev_data_ = prev_data;
3434
trigger_thread_on_approach_ = trigger_thread_on_approach;
35+
lane_change_status_changed_ = lane_change_status_changed;
3536
}
3637

3738
void FreespaceParkingRequest::initializeOccupancyGridMap(

planning/behavior_path_planner/autoware_behavior_path_goal_planner_module/src/util.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1076,4 +1076,51 @@ bool has_stopline_except_terminal(const PathWithLaneId & path)
10761076
path.points.size();
10771077
}
10781078

1079+
std::optional<lanelet::ConstLanelet> find_lane_change_completed_lanelet(
1080+
const PathWithLaneId & path, const lanelet::LaneletMapConstPtr lanelet_map,
1081+
const lanelet::routing::RoutingGraphConstPtr routing_graph)
1082+
{
1083+
std::vector<lanelet::Id> path_lane_ids;
1084+
for (const auto & point : path.points) {
1085+
const auto & lane_ids = point.lane_ids;
1086+
for (const auto & lane_id : lane_ids) {
1087+
if (std::find(path_lane_ids.begin(), path_lane_ids.end(), lane_id) == path_lane_ids.end()) {
1088+
path_lane_ids.push_back(lane_id);
1089+
}
1090+
}
1091+
}
1092+
1093+
if (path_lane_ids.size() < 2) {
1094+
return std::nullopt;
1095+
}
1096+
for (unsigned i = 0, j = 1; i < path_lane_ids.size() && j < path_lane_ids.size(); i++, j++) {
1097+
const auto & lane1 = lanelet_map->laneletLayer.get(path_lane_ids.at(i));
1098+
const auto & lane2 = lanelet_map->laneletLayer.get(path_lane_ids.at(j));
1099+
const auto & followings = routing_graph->following(lane1);
1100+
if (std::any_of(followings.begin(), followings.end(), [&](const auto & lane) {
1101+
return lane.id() == lane2.id();
1102+
})) {
1103+
continue;
1104+
}
1105+
return lane2;
1106+
}
1107+
return std::nullopt;
1108+
}
1109+
1110+
lanelet::ConstLanelets get_reference_lanelets_for_pullover(
1111+
const PathWithLaneId & path, const std::shared_ptr<const PlannerData> & planner_data,
1112+
const double backward_length, const double forward_length)
1113+
{
1114+
const auto & routing_graph = planner_data->route_handler->getRoutingGraphPtr();
1115+
const auto & lanelet_map = planner_data->route_handler->getLaneletMapPtr();
1116+
const auto lane_change_complete_lane =
1117+
find_lane_change_completed_lanelet(path, lanelet_map, routing_graph);
1118+
if (!lane_change_complete_lane) {
1119+
return utils::getExtendedCurrentLanesFromPath(
1120+
path, planner_data, backward_length, forward_length,
1121+
/*forward_only_in_route*/ false);
1122+
}
1123+
return planner_data->route_handler->getLaneletSequence(
1124+
*lane_change_complete_lane, backward_length, forward_length);
1125+
}
10791126
} // namespace autoware::behavior_path_planner::goal_planner_utils

0 commit comments

Comments
 (0)