Skip to content

Commit abbf6fa

Browse files
committed
fix(goal_planner): use precise distance to objects for sorting candidate paths
Signed-off-by: kosuke55 <kosuke.tnp@gmail.com>
1 parent 1bebec9 commit abbf6fa

File tree

4 files changed

+103
-20
lines changed

4 files changed

+103
-20
lines changed

planning/behavior_path_planner/autoware_behavior_path_goal_planner_module/src/goal_planner_module.cpp

+22-3
Original file line numberDiff line numberDiff line change
@@ -1085,9 +1085,28 @@ void sortPullOverPaths(
10851085
const auto & target_objects = static_target_objects;
10861086
for (const size_t i : sorted_path_indices) {
10871087
const auto & path = pull_over_path_candidates[i];
1088-
const double distance = utils::path_safety_checker::calculateRoughDistanceToObjects(
1089-
path.parking_path(), target_objects, planner_data->parameters, false, "max");
1090-
auto it = std::lower_bound(
1088+
1089+
// check collision roughly with {min_distance, max_distance} between ego footprint and objects
1090+
// footprint
1091+
const std::pair<bool, bool> has_collision_rough =
1092+
utils::path_safety_checker::checkObjectsCollisionRough(
1093+
path.parking_path(), target_objects, soft_margins.front(), hard_margins.back(),
1094+
planner_data->parameters, false);
1095+
// min_distance > soft_margin.front() means no collision with any margin
1096+
if (!has_collision_rough.first) {
1097+
path_id_to_rough_margin_map[path.id()] = soft_margins.front();
1098+
continue;
1099+
}
1100+
// max_distance < hard_margin.front() means collision with any margin
1101+
if (has_collision_rough.second) {
1102+
path_id_to_rough_margin_map[path.id()] = 0.0;
1103+
continue;
1104+
}
1105+
// calculate the precise distance to object footprint from the path footprint
1106+
const double distance = utils::path_safety_checker::calculate_distance_to_objects_from_path(
1107+
path.parking_path(), target_objects, planner_data->parameters, true);
1108+
1109+
const auto it = std::lower_bound(
10911110
margins_with_zero.begin(), margins_with_zero.end(), distance, std::greater<double>());
10921111
if (it == margins_with_zero.end()) {
10931112
path_id_to_rough_margin_map[path.id()] = margins_with_zero.back();

planning/behavior_path_planner/autoware_behavior_path_planner_common/include/autoware/behavior_path_planner_common/utils/path_safety_checker/safety_check.hpp

+10-3
Original file line numberDiff line numberDiff line change
@@ -255,15 +255,17 @@ double calc_obstacle_max_length(const Shape & shape);
255255
* @brief Calculate collision roughly by comparing minimum/maximum distance with margin.
256256
* @param path The path of the ego vehicle.
257257
* @param objects The predicted objects.
258-
* @param margin Distance margin to judge collision.
258+
* @param min_margin_threshold threshold for collision check when the minimum distance between ego
259+
* @param max_margin_threshold threshold for collision check when the maximum distance between ego
259260
* @param parameters The common parameters used in behavior path planner.
260261
* @param use_offset_ego_point If true, the closest point to the object is calculated by
261262
* interpolating the path points.
262263
* @return Collision (rough) between minimum distance and maximum distance
263264
*/
264265
std::pair<bool, bool> checkObjectsCollisionRough(
265-
const PathWithLaneId & path, const PredictedObjects & objects, const double margin,
266-
const BehaviorPathPlannerParameters & parameters, const bool use_offset_ego_point);
266+
const PathWithLaneId & path, const PredictedObjects & objects, const double min_margin_threshold,
267+
const double max_margin_threshold, const BehaviorPathPlannerParameters & parameters,
268+
const bool use_offset_ego_point);
267269

268270
/**
269271
* @brief Calculate the rough distance between the ego vehicle and the objects.
@@ -281,6 +283,11 @@ double calculateRoughDistanceToObjects(
281283
const PathWithLaneId & path, const PredictedObjects & objects,
282284
const BehaviorPathPlannerParameters & parameters, const bool use_offset_ego_point,
283285
const std::string & distance_type);
286+
287+
double calculate_distance_to_objects_from_path(
288+
const PathWithLaneId & path, const PredictedObjects & objects,
289+
const BehaviorPathPlannerParameters & parameters, const bool use_offset_ego_pose);
290+
284291
// debug
285292
CollisionCheckDebugPair createObjectDebug(const ExtendedPredictedObject & obj);
286293
void updateCollisionCheckDebugMap(

planning/behavior_path_planner/autoware_behavior_path_planner_common/src/utils/path_safety_checker/safety_check.cpp

+42-4
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ namespace autoware::behavior_path_planner::utils::path_safety_checker
4141
namespace bg = boost::geometry;
4242

4343
using autoware::motion_utils::calcLongitudinalOffsetPoint;
44+
using autoware::motion_utils::calcLongitudinalOffsetPose;
4445
using autoware::motion_utils::calcLongitudinalOffsetToSegment;
4546
using autoware::motion_utils::findNearestIndex;
4647
using autoware::motion_utils::findNearestSegmentIndex;
@@ -774,8 +775,9 @@ double calc_obstacle_max_length(const Shape & shape)
774775
}
775776

776777
std::pair<bool, bool> checkObjectsCollisionRough(
777-
const PathWithLaneId & path, const PredictedObjects & objects, const double margin,
778-
const BehaviorPathPlannerParameters & parameters, const bool use_offset_ego_point)
778+
const PathWithLaneId & path, const PredictedObjects & objects, const double min_margin_threshold,
779+
const double max_margin_threshold, const BehaviorPathPlannerParameters & parameters,
780+
const bool use_offset_ego_point)
779781
{
780782
const auto & points = path.points;
781783

@@ -815,10 +817,10 @@ std::pair<bool, bool> checkObjectsCollisionRough(
815817
const double min_distance = distance - object_max_length - ego_max_length;
816818
const double max_distance = distance - object_min_length - ego_min_length;
817819

818-
if (min_distance < margin) {
820+
if (min_distance < min_margin_threshold) {
819821
has_collision.first = true;
820822
}
821-
if (max_distance < margin) {
823+
if (max_distance < max_margin_threshold) {
822824
has_collision.second = true;
823825
}
824826
}
@@ -877,6 +879,42 @@ double calculateRoughDistanceToObjects(
877879
return min_distance;
878880
}
879881

882+
double calculate_distance_to_objects_from_path(
883+
const PathWithLaneId & path, const PredictedObjects & objects,
884+
const BehaviorPathPlannerParameters & parameters, const bool use_offset_ego_pose)
885+
886+
{
887+
if (objects.objects.empty()) return 0.0;
888+
889+
const auto & p = parameters;
890+
double min_distance = std::numeric_limits<double>::max();
891+
for (const auto & object : objects.objects) {
892+
const auto & object_point = object.kinematics.initial_pose_with_covariance.pose.position;
893+
894+
const auto ego_pose = std::invoke([&]() -> Pose {
895+
if (use_offset_ego_pose) {
896+
const size_t nearest_segment_idx = findNearestSegmentIndex(path.points, object_point);
897+
const double offset_length =
898+
calcLongitudinalOffsetToSegment(path.points, nearest_segment_idx, object_point);
899+
const auto ego_pose_opt =
900+
calcLongitudinalOffsetPose(path.points, nearest_segment_idx, offset_length);
901+
if (ego_pose_opt.has_value()) return ego_pose_opt.value();
902+
}
903+
const auto ego_nearest_idx = findNearestIndex(path.points, object_point);
904+
return path.points.at(ego_nearest_idx).point.pose;
905+
});
906+
907+
const auto ego_footprint =
908+
autoware_utils::to_footprint(ego_pose, p.base_link2front, p.base_link2rear, p.vehicle_width);
909+
910+
const double distance =
911+
boost::geometry::distance(ego_footprint, autoware_utils::to_polygon2d(object));
912+
min_distance = std::min(min_distance, distance);
913+
}
914+
915+
return min_distance;
916+
}
917+
880918
autoware_internal_planning_msgs::msg::SafetyFactorArray to_safety_factor_array(
881919
const CollisionCheckDebugMap & debug_map)
882920
{

planning/behavior_path_planner/autoware_behavior_path_planner_common/test/test_safety_check.cpp

+29-10
Original file line numberDiff line numberDiff line change
@@ -676,47 +676,66 @@ TEST(BehaviorPathPlanningSafetyUtilsTest, checkObjectsCollisionRough)
676676

677677
auto path = generateTrajectory<PathWithLaneId>(10, 1.0);
678678
autoware_perception_msgs::msg::PredictedObjects objs;
679-
double margin = 0.1;
679+
double min_margin_threshold = 0.1;
680+
double max_margin_threshold = 0.1;
680681
BehaviorPathPlannerParameters param;
681682
param.vehicle_width = 2.0;
682683
param.front_overhang = 1.0;
683684
param.rear_overhang = 1.0;
684685
bool use_offset_ego_point = true;
685686

686-
// Condition: no object
687-
auto rough_object_collision =
688-
checkObjectsCollisionRough(path, objs, margin, param, use_offset_ego_point);
687+
// Condition: no objects
688+
auto rough_object_collision = checkObjectsCollisionRough(
689+
path, objs, min_margin_threshold, max_margin_threshold, param, use_offset_ego_point);
689690
EXPECT_FALSE(rough_object_collision.first);
690691
EXPECT_FALSE(rough_object_collision.second);
691692

692693
// Condition: collides with minimum distance
694+
// min_distance = 0.00464761, max_distance = 2.0
693695
autoware_perception_msgs::msg::PredictedObject obj;
694696
obj.kinematics.initial_pose_with_covariance.pose = createPose(8.0, 3.0, 0.0, 0.0, 0.0, 0.0);
695697
obj.shape.type = autoware_perception_msgs::msg::Shape::BOUNDING_BOX;
696698
obj.shape.dimensions.x = 3.0;
697699
obj.shape.dimensions.y = 1.0;
698700
objs.objects.push_back(obj);
699701

700-
rough_object_collision =
701-
checkObjectsCollisionRough(path, objs, margin, param, use_offset_ego_point);
702+
rough_object_collision = checkObjectsCollisionRough(
703+
path, objs, min_margin_threshold, max_margin_threshold, param, use_offset_ego_point);
702704
EXPECT_TRUE(rough_object_collision.first);
703705
EXPECT_FALSE(rough_object_collision.second);
704706

705707
// Condition: collides with both distance
708+
// min_distance: -1.99535, max_distance: 0.0
706709
obj.kinematics.initial_pose_with_covariance.pose = createPose(2.0, 1.0, 0.0, 0.0, 0.0, 0.0);
707710
objs.objects.clear();
708711
objs.objects.push_back(obj);
709-
rough_object_collision =
710-
checkObjectsCollisionRough(path, objs, margin, param, use_offset_ego_point);
712+
rough_object_collision = checkObjectsCollisionRough(
713+
path, objs, min_margin_threshold, max_margin_threshold, param, use_offset_ego_point);
711714
EXPECT_TRUE(rough_object_collision.first);
712715
EXPECT_TRUE(rough_object_collision.second);
713716

714717
// Condition: use_offset_ego_point set to false
715718
use_offset_ego_point = false;
716-
rough_object_collision =
717-
checkObjectsCollisionRough(path, objs, margin, param, use_offset_ego_point);
719+
rough_object_collision = checkObjectsCollisionRough(
720+
path, objs, min_margin_threshold, max_margin_threshold, param, use_offset_ego_point);
718721
EXPECT_TRUE(rough_object_collision.first);
719722
EXPECT_TRUE(rough_object_collision.second);
723+
724+
// Condition: no collision with lenient min_margin_threshold and
725+
// collision with strict max_margin_threshold.
726+
// min_distance = 0.00464761, max_distance = 2.0
727+
min_margin_threshold = 0.001;
728+
max_margin_threshold = 2.1;
729+
obj.kinematics.initial_pose_with_covariance.pose = createPose(8.0, 3.0, 0.0, 0.0, 0.0, 0.0);
730+
obj.shape.type = autoware_perception_msgs::msg::Shape::BOUNDING_BOX;
731+
obj.shape.dimensions.x = 3.0;
732+
obj.shape.dimensions.y = 1.0;
733+
objs.objects.clear();
734+
objs.objects.push_back(obj);
735+
rough_object_collision = checkObjectsCollisionRough(
736+
path, objs, min_margin_threshold, max_margin_threshold, param, use_offset_ego_point);
737+
EXPECT_FALSE(rough_object_collision.first);
738+
EXPECT_TRUE(rough_object_collision.second);
720739
}
721740

722741
TEST(BehaviorPathPlanningSafetyUtilsTest, calculateRoughDistanceToObjects)

0 commit comments

Comments
 (0)