@@ -269,9 +269,18 @@ void GoalPlannerModule::onTimer()
269
269
planner->setPlannerData (local_planner_data);
270
270
planner->setPreviousModuleOutput (previous_module_output);
271
271
auto pull_over_path = planner->plan (goal_candidate.goal_pose );
272
- if (pull_over_path) {
272
+ if (pull_over_path && pull_over_path-> getParkingPath (). points . size () >= 3 ) {
273
273
pull_over_path->goal_id = goal_candidate.id ;
274
274
pull_over_path->id = path_candidates.size ();
275
+
276
+ // calculate absolute maximum curvature of parking path(start pose to end pose) for path
277
+ // priority
278
+ const std::vector<double > curvatures =
279
+ autoware::motion_utils::calcCurvature (pull_over_path->getParkingPath ().points );
280
+ pull_over_path->max_curvature = std::abs (*std::max_element (
281
+ curvatures.begin (), curvatures.end (),
282
+ [](const double & a, const double & b) { return std::abs (a) < std::abs (b); }));
283
+
275
284
path_candidates.push_back (*pull_over_path);
276
285
// calculate closest pull over start pose for stop path
277
286
const double start_arc_length =
@@ -795,23 +804,37 @@ std::vector<PullOverPath> GoalPlannerModule::sortPullOverPathCandidatesByGoalPri
795
804
const auto debugPrintPathPriority =
796
805
[this ](
797
806
const std::vector<PullOverPath> & sorted_pull_over_path_candidates,
798
- const std::map<size_t , size_t > & goal_id_to_index,
799
- const std::optional<std:: map<size_t , double >> & path_id_to_margin_map_opt = std::nullopt ,
800
- const std::optional<std:: function<bool (const PullOverPath &)>> & isSoftMarginOpt =
801
- std::nullopt ) {
807
+ const std::map<size_t , size_t > & goal_id_to_index, const GoalCandidates & goal_candidates,
808
+ const std::map<size_t , double > & path_id_to_margin_map ,
809
+ const std::function<bool (const PullOverPath &)> & isSoftMargin,
810
+ const std::function< bool ( const PullOverPath &)> & isHighCurvature ) {
802
811
std::stringstream ss;
803
- ss << " \n ---------------------- path priority ----------------------\n " ;
804
- for (const auto & path : sorted_pull_over_path_candidates) {
805
- // clang-format off
806
- ss << " path_type: " << magic_enum::enum_name (path.type )
807
- << " , path_id: " << path.id
808
- << " , goal_id: " << path.goal_id
809
- << " , goal_priority:" << goal_id_to_index.at (path.goal_id );
810
- // clang-format on
811
- if (path_id_to_margin_map_opt && isSoftMarginOpt) {
812
- ss << " , margin: " << path_id_to_margin_map_opt->at (path.id )
813
- << ((*isSoftMarginOpt)(path) ? " (soft)" : " (hard)" );
812
+
813
+ // unsafe goal and it's priority are not visible as debug marker in rviz,
814
+ // so exclude unsafe goal from goal_priority
815
+ std::map<size_t , int > goal_id_and_priority;
816
+ {
817
+ int priority = 0 ;
818
+ for (const auto & goal_candidate : goal_candidates) {
819
+ goal_id_and_priority[goal_candidate.id ] = goal_candidate.is_safe ? priority++ : -1 ;
814
820
}
821
+ }
822
+
823
+ ss << " \n ---------------------- path priority ----------------------\n " ;
824
+ for (size_t i = 0 ; i < sorted_pull_over_path_candidates.size (); ++i) {
825
+ const auto & path = sorted_pull_over_path_candidates[i];
826
+
827
+ // goal_index is same to goal priority including unsafe goal
828
+ const int goal_index = static_cast <int >(goal_id_to_index.at (path.goal_id ));
829
+ const bool is_safe_goal = goal_candidates[goal_index].is_safe ;
830
+ const int goal_priority = goal_id_and_priority[path.goal_id ];
831
+
832
+ ss << " path_priority: " << i << " , path_type: " << magic_enum::enum_name (path.type )
833
+ << " , path_id: " << path.id << " , goal_id: " << path.goal_id
834
+ << " , goal_priority: " << (is_safe_goal ? std::to_string (goal_priority) : " unsafe" )
835
+ << " , margin: " << path_id_to_margin_map.at (path.id )
836
+ << (isSoftMargin (path) ? " (soft)" : " (hard)" ) << " , curvature: " << path.max_curvature
837
+ << (isHighCurvature (path) ? " (high)" : " (low)" );
815
838
ss << " \n " ;
816
839
}
817
840
ss << " -----------------------------------------------------------\n " ;
@@ -822,6 +845,7 @@ std::vector<PullOverPath> GoalPlannerModule::sortPullOverPathCandidatesByGoalPri
822
845
const auto & soft_margins = parameters_->object_recognition_collision_check_soft_margins ;
823
846
const auto & hard_margins = parameters_->object_recognition_collision_check_hard_margins ;
824
847
848
+ // (1) Sort pull_over_path_candidates based on the order in goal_candidates
825
849
// Create a map of goal_id to its index in goal_candidates
826
850
std::map<size_t , size_t > goal_id_to_index;
827
851
for (size_t i = 0 ; i < goal_candidates.size (); ++i) {
@@ -846,6 +870,7 @@ std::vector<PullOverPath> GoalPlannerModule::sortPullOverPathCandidatesByGoalPri
846
870
847
871
// if object recognition is enabled, sort by collision check margin
848
872
if (parameters_->use_object_recognition ) {
873
+ // (2) Sort by collision check margins
849
874
const std::vector<double > margins = std::invoke ([&]() {
850
875
std::vector<double > combined_margins = soft_margins;
851
876
combined_margins.insert (combined_margins.end (), hard_margins.begin (), hard_margins.end ());
@@ -892,42 +917,70 @@ std::vector<PullOverPath> GoalPlannerModule::sortPullOverPathCandidatesByGoalPri
892
917
return path_id_to_margin_map[a.id ] > path_id_to_margin_map[b.id ];
893
918
});
894
919
895
- // Sort pull_over_path_candidates based on the order in efficient_path_order
896
- if (parameters_->path_priority == " efficient_path" ) {
897
- const auto isSoftMargin = [&](const PullOverPath & path) -> bool {
898
- const double margin = path_id_to_margin_map[path.id ];
899
- return std::any_of (
900
- soft_margins.begin (), soft_margins.end (),
901
- [margin](const double soft_margin) { return std::abs (margin - soft_margin) < 0.01 ; });
902
- };
903
- const auto isSameHardMargin = [&](const PullOverPath & a, const PullOverPath & b) -> bool {
904
- return !isSoftMargin (a) && !isSoftMargin (b) &&
905
- std::abs (path_id_to_margin_map[a.id ] - path_id_to_margin_map[b.id ]) < 0.01 ;
906
- };
920
+ // (3) Sort by curvature
921
+ // If the curvature is less than the threshold, prioritize the path.
922
+ const auto isHighCurvature = [&](const PullOverPath & path) -> bool {
923
+ return path.max_curvature >= parameters_->high_curvature_threshold ;
924
+ };
907
925
926
+ const auto isSoftMargin = [&](const PullOverPath & path) -> bool {
927
+ const double margin = path_id_to_margin_map[path.id ];
928
+ return std::any_of (
929
+ soft_margins.begin (), soft_margins.end (),
930
+ [margin](const double soft_margin) { return std::abs (margin - soft_margin) < 0.01 ; });
931
+ };
932
+ const auto isSameHardMargin = [&](const PullOverPath & a, const PullOverPath & b) -> bool {
933
+ return !isSoftMargin (a) && !isSoftMargin (b) &&
934
+ std::abs (path_id_to_margin_map[a.id ] - path_id_to_margin_map[b.id ]) < 0.01 ;
935
+ };
936
+
937
+ // NOTE: this is just partition sort based on curvature threshold within each sub partitions
938
+ std::stable_sort (
939
+ sorted_pull_over_path_candidates.begin (), sorted_pull_over_path_candidates.end (),
940
+ [&](const PullOverPath & a, const PullOverPath & b) {
941
+ // if both are soft margin or both are same hard margin, prioritize the path with lower
942
+ // curvature.
943
+ if ((isSoftMargin (a) && isSoftMargin (b)) || isSameHardMargin (a, b)) {
944
+ return !isHighCurvature (a) && isHighCurvature (b);
945
+ }
946
+ // otherwise, keep the order based on the margin.
947
+ return false ;
948
+ });
949
+
950
+ // (4) Sort pull_over_path_candidates based on the order in efficient_path_order keeping the
951
+ // collision check margin and curvature priority.
952
+ if (parameters_->path_priority == " efficient_path" ) {
908
953
std::stable_sort (
909
954
sorted_pull_over_path_candidates.begin (), sorted_pull_over_path_candidates.end (),
910
955
[&](const auto & a, const auto & b) {
911
- // if both are soft margin or both are same hard margin, sort by planner priority
956
+ // if any of following conditions are met, sort by path type priority
957
+ // - both are soft margin
958
+ // - both are same hard margin
912
959
if ((isSoftMargin (a) && isSoftMargin (b)) || isSameHardMargin (a, b)) {
913
960
return comparePathTypePriority (a, b);
914
961
}
915
962
// otherwise, keep the order.
916
963
return false ;
917
964
});
918
965
919
- // debug print path priority: sorted by efficient_path_order and collision check margin
966
+ // debug print path priority sorted by
967
+ // - efficient_path_order
968
+ // - collision check margin
969
+ // - curvature
920
970
debugPrintPathPriority (
921
- sorted_pull_over_path_candidates, goal_id_to_index, path_id_to_margin_map, isSoftMargin);
971
+ sorted_pull_over_path_candidates, goal_id_to_index, goal_candidates, path_id_to_margin_map,
972
+ isSoftMargin, isHighCurvature);
922
973
}
923
974
} else {
924
- // Sort pull_over_path_candidates based on the order in efficient_path_order
975
+ /* *
976
+ * NOTE: use_object_recognition=false is not recommended. This option will be deprecated in the
977
+ * future. sort by curvature is not implemented yet.
978
+ * Sort pull_over_path_candidates based on the order in efficient_path_order
979
+ */
925
980
if (parameters_->path_priority == " efficient_path" ) {
926
981
std::stable_sort (
927
982
sorted_pull_over_path_candidates.begin (), sorted_pull_over_path_candidates.end (),
928
983
[&](const auto & a, const auto & b) { return comparePathTypePriority (a, b); });
929
- // debug print path priority: sorted by efficient_path_order and collision check margin
930
- debugPrintPathPriority (sorted_pull_over_path_candidates, goal_id_to_index);
931
984
}
932
985
}
933
986
0 commit comments