16
16
17
17
#include " behavior_path_avoidance_module/data_structs.hpp"
18
18
#include " behavior_path_avoidance_module/utils.hpp"
19
+ #include " behavior_path_planner_common/utils/drivable_area_expansion/static_drivable_area.hpp"
19
20
#include " behavior_path_planner_common/utils/path_safety_checker/objects_filtering.hpp"
20
21
#include " behavior_path_planner_common/utils/path_utils.hpp"
21
22
#include " behavior_path_planner_common/utils/traffic_light_utils.hpp"
@@ -818,8 +819,8 @@ bool isNoNeedAvoidanceBehavior(
818
819
return false ;
819
820
}
820
821
821
- const auto shift_length =
822
- calcShiftLength ( isOnRight (object), object.overhang_dist , object.avoid_margin .value ());
822
+ const auto shift_length = calcShiftLength (
823
+ isOnRight (object), object.overhang_points . front (). first , object.avoid_margin .value ());
823
824
if (!isShiftNecessary (isOnRight (object), shift_length)) {
824
825
object.reason = " NotNeedAvoidance" ;
825
826
return true ;
@@ -880,45 +881,41 @@ double getRoadShoulderDistance(
880
881
return 0.0 ;
881
882
}
882
883
883
- const auto centerline_pose =
884
- lanelet::utils::getClosestCenterPose (object.overhang_lanelet , object_pose.position );
885
- const auto & p1_object = object.overhang_pose .position ;
886
- const auto p_tmp =
887
- geometry_msgs::build<Pose>().position (p1_object).orientation (centerline_pose.orientation );
888
- const auto p2_object =
889
- calcOffsetPose (p_tmp, 0.0 , (isOnRight (object) ? 100.0 : -100.0 ), 0.0 ).position ;
890
-
891
- // TODO(Satoshi OTA): check if the basic point is on right or left of bound.
892
- const auto bound = isOnRight (object) ? data.left_bound : data.right_bound ;
893
-
894
- std::vector<Point > intersects;
895
- for (size_t i = 1 ; i < bound.size (); i++) {
896
- const auto p1_bound =
897
- geometry_msgs::build<Point >().x (bound[i - 1 ].x ()).y (bound[i - 1 ].y ()).z (bound[i - 1 ].z ());
898
- const auto p2_bound =
899
- geometry_msgs::build<Point >().x (bound[i].x ()).y (bound[i].y ()).z (bound[i].z ());
900
-
901
- const auto opt_intersect =
902
- tier4_autoware_utils::intersect (p1_object, p2_object, p1_bound, p2_bound);
903
-
904
- if (!opt_intersect) {
905
- continue ;
906
- }
884
+ std::vector<std::pair<Point , Point >> intersects;
885
+ for (const auto & p1 : object.overhang_points ) {
886
+ const auto centerline_pose =
887
+ lanelet::utils::getClosestCenterPose (object.overhang_lanelet , object_pose.position );
888
+ const auto p_tmp =
889
+ geometry_msgs::build<Pose>().position (p1.second ).orientation (centerline_pose.orientation );
890
+ const auto p2 = calcOffsetPose (p_tmp, 0.0 , (isOnRight (object) ? 100.0 : -100.0 ), 0.0 ).position ;
891
+
892
+ // TODO(Satoshi OTA): check if the basic point is on right or left of bound.
893
+ const auto bound = isOnRight (object) ? data.left_bound : data.right_bound ;
907
894
908
- intersects.push_back (opt_intersect.value ());
895
+ for (size_t i = 1 ; i < bound.size (); i++) {
896
+ const auto opt_intersect =
897
+ tier4_autoware_utils::intersect (p1.second , p2, bound.at (i - 1 ), bound.at (i));
898
+
899
+ if (!opt_intersect) {
900
+ continue ;
901
+ }
902
+
903
+ intersects.emplace_back (p1.second , opt_intersect.value ());
904
+ }
909
905
}
910
906
907
+ std::sort (intersects.begin (), intersects.end (), [](const auto & a, const auto & b) {
908
+ return calcDistance2d (a.first , a.second ) < calcDistance2d (b.first , b.second );
909
+ });
910
+
911
911
if (intersects.empty ()) {
912
912
return 0.0 ;
913
913
}
914
914
915
- std::sort (intersects.begin (), intersects.end (), [&p1_object](const auto & a, const auto & b) {
916
- return calcDistance2d (p1_object, a) < calcDistance2d (p1_object, b);
917
- });
918
-
919
- object.nearest_bound_point = intersects.front ();
915
+ object.narrowest_place = intersects.front ();
920
916
921
- return calcDistance2d (p1_object, object.nearest_bound_point .value ());
917
+ return calcDistance2d (
918
+ object.narrowest_place .value ().first , object.narrowest_place .value ().second );
922
919
}
923
920
} // namespace filtering_utils
924
921
@@ -1074,34 +1071,22 @@ void fillLongitudinalAndLengthByClosestEnvelopeFootprint(
1074
1071
return ;
1075
1072
}
1076
1073
1077
- double calcEnvelopeOverhangDistance (
1078
- const ObjectData & object_data, const PathWithLaneId & path, Point & overhang_pose )
1074
+ std::vector<std::pair< double , Point >> calcEnvelopeOverhangDistance (
1075
+ const ObjectData & object_data, const PathWithLaneId & path)
1079
1076
{
1080
- double largest_overhang = isOnRight (object_data) ? - 100.0 : 100.0 ; // large number
1077
+ std::vector<std::pair< double , Point >> overhang_points{};
1081
1078
1082
1079
for (const auto & p : object_data.envelope_poly .outer ()) {
1083
1080
const auto point = tier4_autoware_utils::createPoint (p.x (), p.y (), 0.0 );
1084
1081
// TODO(someone): search around first position where the ego should avoid the object.
1085
1082
const auto idx = findNearestIndex (path.points , point);
1086
1083
const auto lateral = calcLateralDeviation (getPose (path.points .at (idx)), point);
1087
-
1088
- const auto & overhang_pose_on_right = [&overhang_pose, &largest_overhang, &point, &lateral]() {
1089
- if (lateral > largest_overhang) {
1090
- overhang_pose = point;
1091
- }
1092
- return std::max (largest_overhang, lateral);
1093
- };
1094
-
1095
- const auto & overhang_pose_on_left = [&overhang_pose, &largest_overhang, &point, &lateral]() {
1096
- if (lateral < largest_overhang) {
1097
- overhang_pose = point;
1098
- }
1099
- return std::min (largest_overhang, lateral);
1100
- };
1101
-
1102
- largest_overhang = isOnRight (object_data) ? overhang_pose_on_right () : overhang_pose_on_left ();
1084
+ overhang_points.emplace_back (lateral, point);
1103
1085
}
1104
- return largest_overhang;
1086
+ std::sort (overhang_points.begin (), overhang_points.end (), [&](const auto & a, const auto & b) {
1087
+ return isOnRight (object_data) ? b.first < a.first : a.first < b.first ;
1088
+ });
1089
+ return overhang_points;
1105
1090
}
1106
1091
1107
1092
void setEndData (
@@ -1184,24 +1169,21 @@ std::vector<DrivableAreaInfo::Obstacle> generateObstaclePolygonsForDrivableArea(
1184
1169
{
1185
1170
std::vector<DrivableAreaInfo::Obstacle> obstacles_for_drivable_area;
1186
1171
1187
- if (objects.empty () || !parameters-> enable_bound_clipping ) {
1172
+ if (objects.empty ()) {
1188
1173
return obstacles_for_drivable_area;
1189
1174
}
1190
1175
1191
1176
for (const auto & object : objects) {
1192
- // If avoidance is executed by both behavior and motion, only non-avoidable object will be
1193
- // extracted from the drivable area.
1194
- if (!parameters->disable_path_update ) {
1195
- if (object.is_avoidable ) {
1196
- continue ;
1197
- }
1198
- }
1199
-
1200
1177
// check if avoid marin is calculated
1201
1178
if (!object.avoid_margin .has_value ()) {
1202
1179
continue ;
1203
1180
}
1204
1181
1182
+ // check original polygon
1183
+ if (object.envelope_poly .outer ().empty ()) {
1184
+ continue ;
1185
+ }
1186
+
1205
1187
const auto object_type = utils::getHighestProbLabel (object.object .classification );
1206
1188
const auto object_parameter = parameters->object_parameters .at (object_type);
1207
1189
@@ -1449,10 +1431,10 @@ void fillAvoidanceNecessity(
1449
1431
0.5 * vehicle_width + object_parameter.safety_buffer_lateral * object_data.distance_factor ;
1450
1432
1451
1433
const auto check_necessity = [&](const auto hysteresis_factor) {
1452
- return (isOnRight (object_data) &&
1453
- std::abs (object_data. overhang_dist ) < safety_margin * hysteresis_factor) ||
1434
+ return (isOnRight (object_data) && std::abs (object_data. overhang_points . front (). first ) <
1435
+ safety_margin * hysteresis_factor) ||
1454
1436
(!isOnRight (object_data) &&
1455
- object_data.overhang_dist < safety_margin * hysteresis_factor);
1437
+ object_data.overhang_points . front (). first < safety_margin * hysteresis_factor);
1456
1438
};
1457
1439
1458
1440
const auto id = object_data.object .object_id ;
@@ -1615,6 +1597,40 @@ void compensateDetectionLost(
1615
1597
}
1616
1598
}
1617
1599
1600
+ void updateRoadShoulderDistance (
1601
+ AvoidancePlanningData & data, const std::shared_ptr<const PlannerData> & planner_data,
1602
+ const std::shared_ptr<AvoidanceParameters> & parameters)
1603
+ {
1604
+ ObjectDataArray clip_objects;
1605
+ std::for_each (data.other_objects .begin (), data.other_objects .end (), [&](const auto & object) {
1606
+ if (!filtering_utils::isMovingObject (object, parameters)) {
1607
+ clip_objects.push_back (object);
1608
+ }
1609
+ });
1610
+ for (auto & o : clip_objects) {
1611
+ const auto & vehicle_width = planner_data->parameters .vehicle_width ;
1612
+ const auto object_type = utils::getHighestProbLabel (o.object .classification );
1613
+ const auto object_parameter = parameters->object_parameters .at (object_type);
1614
+
1615
+ o.avoid_margin = object_parameter.safety_buffer_lateral + 0.5 * vehicle_width;
1616
+ }
1617
+ const auto extract_obstacles = generateObstaclePolygonsForDrivableArea (
1618
+ clip_objects, parameters, planner_data->parameters .vehicle_width / 2.0 );
1619
+
1620
+ auto tmp_path = data.reference_path ;
1621
+ tmp_path.left_bound = data.left_bound ;
1622
+ tmp_path.right_bound = data.right_bound ;
1623
+ utils::extractObstaclesFromDrivableArea (tmp_path, extract_obstacles);
1624
+
1625
+ data.left_bound = tmp_path.left_bound ;
1626
+ data.right_bound = tmp_path.right_bound ;
1627
+
1628
+ for (auto & o : data.target_objects ) {
1629
+ o.to_road_shoulder_distance = filtering_utils::getRoadShoulderDistance (o, data, planner_data);
1630
+ o.avoid_margin = filtering_utils::getAvoidMargin (o, planner_data, parameters);
1631
+ }
1632
+ }
1633
+
1618
1634
void filterTargetObjects (
1619
1635
ObjectDataArray & objects, AvoidancePlanningData & data, const double forward_detection_range,
1620
1636
const std::shared_ptr<const PlannerData> & planner_data,
@@ -1638,8 +1654,7 @@ void filterTargetObjects(
1638
1654
}
1639
1655
1640
1656
// Find the footprint point closest to the path, set to object_data.overhang_distance.
1641
- o.overhang_dist =
1642
- calcEnvelopeOverhangDistance (o, data.reference_path , o.overhang_pose .position );
1657
+ o.overhang_points = utils::avoidance::calcEnvelopeOverhangDistance (o, data.reference_path );
1643
1658
o.to_road_shoulder_distance = filtering_utils::getRoadShoulderDistance (o, data, planner_data);
1644
1659
o.avoid_margin = filtering_utils::getAvoidMargin (o, planner_data, parameters);
1645
1660
@@ -1846,7 +1861,10 @@ std::vector<ExtendedPredictedObject> getSafetyCheckTargetObjects(
1846
1861
PredictedObjects ret{};
1847
1862
std::for_each (objects.begin (), objects.end (), [&p, &ret, ¶meters](const auto & object) {
1848
1863
if (filtering_utils::isSafetyCheckTargetObjectType (object.object , parameters)) {
1849
- ret.objects .push_back (object.object );
1864
+ // check only moving objects
1865
+ if (filtering_utils::isMovingObject (object, parameters)) {
1866
+ ret.objects .push_back (object.object );
1867
+ }
1850
1868
}
1851
1869
});
1852
1870
return ret;
0 commit comments