diff --git a/planning/behavior_path_avoidance_by_lane_change_module/config/avoidance_by_lc.param.yaml b/planning/behavior_path_avoidance_by_lane_change_module/config/avoidance_by_lc.param.yaml
index 3e8907cdccdf6..ad5fe0b123f1d 100644
--- a/planning/behavior_path_avoidance_by_lane_change_module/config/avoidance_by_lc.param.yaml
+++ b/planning/behavior_path_avoidance_by_lane_change_module/config/avoidance_by_lc.param.yaml
@@ -12,64 +12,80 @@
moving_time_threshold: 1.0 # [s]
max_expand_ratio: 0.0 # [-]
envelope_buffer_margin: 0.3 # [m]
- avoid_margin_lateral: 1.0 # [m]
- safety_buffer_lateral: 0.7 # [m]
+ lateral_margin:
+ soft_margin: 0.0 # [m]
+ hard_margin: 0.0 # [m]
+ hard_margin_for_parked_vehicle: 0.0 # [m]
truck:
execute_num: 2
moving_speed_threshold: 1.0 # 3.6km/h
moving_time_threshold: 1.0
max_expand_ratio: 0.0
envelope_buffer_margin: 0.3
- avoid_margin_lateral: 1.0
- safety_buffer_lateral: 0.7
+ lateral_margin:
+ soft_margin: 0.0 # [m]
+ hard_margin: 0.0 # [m]
+ hard_margin_for_parked_vehicle: 0.0 # [m]
bus:
execute_num: 2
moving_speed_threshold: 1.0 # 3.6km/h
moving_time_threshold: 1.0
max_expand_ratio: 0.0
envelope_buffer_margin: 0.3
- avoid_margin_lateral: 1.0
- safety_buffer_lateral: 0.7
+ lateral_margin:
+ soft_margin: 0.0 # [m]
+ hard_margin: 0.0 # [m]
+ hard_margin_for_parked_vehicle: 0.0 # [m]
trailer:
execute_num: 2
moving_speed_threshold: 1.0 # 3.6km/h
moving_time_threshold: 1.0
max_expand_ratio: 0.0
envelope_buffer_margin: 0.3
- avoid_margin_lateral: 1.0
- safety_buffer_lateral: 0.7
+ lateral_margin:
+ soft_margin: 0.0 # [m]
+ hard_margin: 0.0 # [m]
+ hard_margin_for_parked_vehicle: 0.0 # [m]
unknown:
execute_num: 1
moving_speed_threshold: 0.28 # 1.0km/h
moving_time_threshold: 1.0
max_expand_ratio: 0.0
envelope_buffer_margin: 0.3
- avoid_margin_lateral: 1.0
- safety_buffer_lateral: 0.0
+ lateral_margin:
+ soft_margin: 0.0 # [m]
+ hard_margin: 0.0 # [m]
+ hard_margin_for_parked_vehicle: 0.0 # [m]
bicycle:
execute_num: 2
moving_speed_threshold: 0.28 # 1.0km/h
moving_time_threshold: 1.0
max_expand_ratio: 0.0
envelope_buffer_margin: 0.8
- avoid_margin_lateral: 1.0
- safety_buffer_lateral: 1.0
+ lateral_margin:
+ soft_margin: 0.0 # [m]
+ hard_margin: 0.0 # [m]
+ hard_margin_for_parked_vehicle: 0.0 # [m]
motorcycle:
execute_num: 2
moving_speed_threshold: 1.0 # 3.6km/h
moving_time_threshold: 1.0
max_expand_ratio: 0.0
envelope_buffer_margin: 0.8
- avoid_margin_lateral: 1.0
- safety_buffer_lateral: 1.0
+ lateral_margin:
+ soft_margin: 0.0 # [m]
+ hard_margin: 0.0 # [m]
+ hard_margin_for_parked_vehicle: 0.0 # [m]
pedestrian:
execute_num: 2
moving_speed_threshold: 0.28 # 1.0km/h
moving_time_threshold: 1.0
max_expand_ratio: 0.0
envelope_buffer_margin: 0.8
- avoid_margin_lateral: 1.0
- safety_buffer_lateral: 1.0
+ lateral_margin:
+ soft_margin: 0.0 # [m]
+ hard_margin: 0.0 # [m]
+ hard_margin_for_parked_vehicle: 0.0 # [m]
lower_distance_for_polygon_expansion: 0.0 # [m]
upper_distance_for_polygon_expansion: 1.0 # [m]
diff --git a/planning/behavior_path_avoidance_by_lane_change_module/package.xml b/planning/behavior_path_avoidance_by_lane_change_module/package.xml
index 3a4f42f2d2a6c..0f9f3f6dc9d42 100644
--- a/planning/behavior_path_avoidance_by_lane_change_module/package.xml
+++ b/planning/behavior_path_avoidance_by_lane_change_module/package.xml
@@ -22,6 +22,7 @@
behavior_path_lane_change_module
behavior_path_planner
behavior_path_planner_common
+ lanelet2_extension
motion_utils
pluginlib
rclcpp
diff --git a/planning/behavior_path_avoidance_by_lane_change_module/src/manager.cpp b/planning/behavior_path_avoidance_by_lane_change_module/src/manager.cpp
index 3f810710ef37b..c53c272bcb6fa 100644
--- a/planning/behavior_path_avoidance_by_lane_change_module/src/manager.cpp
+++ b/planning/behavior_path_avoidance_by_lane_change_module/src/manager.cpp
@@ -72,10 +72,12 @@ void AvoidanceByLaneChangeModuleManager::init(rclcpp::Node * node)
param.max_expand_ratio = getOrDeclareParameter(*node, ns + "max_expand_ratio");
param.envelope_buffer_margin =
getOrDeclareParameter(*node, ns + "envelope_buffer_margin");
- param.avoid_margin_lateral =
- getOrDeclareParameter(*node, ns + "avoid_margin_lateral");
- param.safety_buffer_lateral =
- getOrDeclareParameter(*node, ns + "safety_buffer_lateral");
+ param.lateral_soft_margin =
+ getOrDeclareParameter(*node, ns + "lateral_margin.soft_margin");
+ param.lateral_hard_margin =
+ getOrDeclareParameter(*node, ns + "lateral_margin.hard_margin");
+ param.lateral_hard_margin_for_parked_vehicle =
+ getOrDeclareParameter(*node, ns + "lateral_margin.hard_margin_for_parked_vehicle");
return param;
};
@@ -130,11 +132,14 @@ void AvoidanceByLaneChangeModuleManager::init(rclcpp::Node * node)
}
{
- const std::string ns = "avoidance.target_filtering.force_avoidance.";
- p.enable_force_avoidance_for_stopped_vehicle =
- getOrDeclareParameter(*node, ns + "enable");
- p.threshold_time_force_avoidance_for_stopped_vehicle =
- getOrDeclareParameter(*node, ns + "time_threshold");
+ const std::string ns = "avoidance.target_filtering.avoidance_for_ambiguous_vehicle.";
+ p.enable_avoidance_for_ambiguous_vehicle = getOrDeclareParameter(*node, ns + "enable");
+ p.closest_distance_to_wait_and_see_for_ambiguous_vehicle =
+ getOrDeclareParameter(*node, ns + "closest_distance_to_wait_and_see");
+ p.time_threshold_for_ambiguous_vehicle =
+ getOrDeclareParameter(*node, ns + "condition.time_threshold");
+ p.distance_threshold_for_ambiguous_vehicle =
+ getOrDeclareParameter(*node, ns + "condition.distance_threshold");
p.object_ignore_section_traffic_light_in_front_distance =
getOrDeclareParameter(*node, ns + "ignore_area.traffic_light.front_distance");
p.object_ignore_section_crosswalk_in_front_distance =
diff --git a/planning/behavior_path_avoidance_by_lane_change_module/src/scene.cpp b/planning/behavior_path_avoidance_by_lane_change_module/src/scene.cpp
index 619cbc515f816..efd169c937abc 100644
--- a/planning/behavior_path_avoidance_by_lane_change_module/src/scene.cpp
+++ b/planning/behavior_path_avoidance_by_lane_change_module/src/scene.cpp
@@ -20,6 +20,7 @@
#include "behavior_path_planner_common/utils/path_utils.hpp"
#include "behavior_path_planner_common/utils/utils.hpp"
+#include
#include
#include
@@ -29,16 +30,6 @@
namespace behavior_path_planner
{
-namespace
-{
-lanelet::BasicLineString3d toLineString3d(const std::vector & bound)
-{
- lanelet::BasicLineString3d ret{};
- std::for_each(
- bound.begin(), bound.end(), [&](const auto & p) { ret.emplace_back(p.x, p.y, p.z); });
- return ret;
-}
-} // namespace
AvoidanceByLaneChange::AvoidanceByLaneChange(
const std::shared_ptr & parameters,
std::shared_ptr avoidance_parameters)
@@ -95,9 +86,11 @@ bool AvoidanceByLaneChange::specialRequiredCheck() const
const auto nearest_object_type = utils::getHighestProbLabel(nearest_object.object.classification);
const auto nearest_object_parameter =
avoidance_parameters_->object_parameters.at(nearest_object_type);
- const auto avoid_margin =
- nearest_object_parameter.safety_buffer_lateral * nearest_object.distance_factor +
- nearest_object_parameter.avoid_margin_lateral + 0.5 * ego_width;
+ const auto lateral_hard_margin = std::max(
+ nearest_object_parameter.lateral_hard_margin,
+ nearest_object_parameter.lateral_hard_margin_for_parked_vehicle);
+ const auto avoid_margin = lateral_hard_margin * nearest_object.distance_factor +
+ nearest_object_parameter.lateral_soft_margin + 0.5 * ego_width;
avoidance_helper_->setData(planner_data_);
const auto shift_length = avoidance_helper_->getShiftLength(
@@ -161,19 +154,17 @@ AvoidancePlanningData AvoidanceByLaneChange::calcAvoidancePlanningData(
// expand drivable lanes
std::for_each(
data.current_lanelets.begin(), data.current_lanelets.end(), [&](const auto & lanelet) {
- data.drivable_lanes.push_back(utils::avoidance::generateExpandDrivableLanes(
+ data.drivable_lanes.push_back(utils::avoidance::generateExpandedDrivableLanes(
lanelet, planner_data_, avoidance_parameters_));
});
// calc drivable bound
const auto shorten_lanes =
utils::cutOverlappedLanes(data.reference_path_rough, data.drivable_lanes);
- data.left_bound = toLineString3d(utils::calcBound(
- planner_data_->route_handler, shorten_lanes, avoidance_parameters_->use_hatched_road_markings,
- avoidance_parameters_->use_intersection_areas, true));
- data.right_bound = toLineString3d(utils::calcBound(
- planner_data_->route_handler, shorten_lanes, avoidance_parameters_->use_hatched_road_markings,
- avoidance_parameters_->use_intersection_areas, false));
+ data.left_bound = utils::calcBound(
+ data.reference_path_rough, planner_data_, shorten_lanes, false, false, false, true);
+ data.right_bound = utils::calcBound(
+ data.reference_path_rough, planner_data_, shorten_lanes, false, false, false, false);
// get related objects from dynamic_objects, and then separates them as target objects and non
// target objects
@@ -183,7 +174,7 @@ AvoidancePlanningData AvoidanceByLaneChange::calcAvoidancePlanningData(
}
void AvoidanceByLaneChange::fillAvoidanceTargetObjects(
- AvoidancePlanningData & data, DebugData & debug) const
+ AvoidancePlanningData & data, [[maybe_unused]] DebugData & debug) const
{
const auto p = std::dynamic_pointer_cast(avoidance_parameters_);
@@ -223,7 +214,9 @@ void AvoidanceByLaneChange::fillAvoidanceTargetObjects(
[&](const auto & object) { return createObjectData(data, object); });
}
- utils::avoidance::filterTargetObjects(target_lane_objects, data, debug, planner_data_, p);
+ utils::avoidance::filterTargetObjects(
+ target_lane_objects, data, avoidance_parameters_->object_check_max_forward_distance,
+ planner_data_, p);
}
ObjectData AvoidanceByLaneChange::createObjectData(
@@ -232,6 +225,7 @@ ObjectData AvoidanceByLaneChange::createObjectData(
using boost::geometry::return_centroid;
using motion_utils::findNearestIndex;
using tier4_autoware_utils::calcDistance2d;
+ using tier4_autoware_utils::calcLateralDeviation;
const auto p = std::dynamic_pointer_cast(avoidance_parameters_);
@@ -263,12 +257,15 @@ ObjectData AvoidanceByLaneChange::createObjectData(
utils::avoidance::fillObjectMovingTime(object_data, stopped_objects_, p);
// Calc lateral deviation from path to target object.
- object_data.lateral =
- tier4_autoware_utils::calcLateralDeviation(object_closest_pose, object_pose.position);
+ object_data.to_centerline =
+ lanelet::utils::getArcCoordinates(data.current_lanelets, object_pose).distance;
+ object_data.direction = calcLateralDeviation(object_closest_pose, object_pose.position) > 0.0
+ ? Direction::LEFT
+ : Direction::RIGHT;
// Find the footprint point closest to the path, set to object_data.overhang_distance.
- object_data.overhang_dist = utils::avoidance::calcEnvelopeOverhangDistance(
- object_data, data.reference_path, object_data.overhang_pose.position);
+ object_data.overhang_points =
+ utils::avoidance::calcEnvelopeOverhangDistance(object_data, data.reference_path);
// Check whether the the ego should avoid the object.
const auto & vehicle_width = planner_data_->parameters.vehicle_width;
diff --git a/planning/behavior_path_avoidance_by_lane_change_module/test/test_behavior_path_planner_node_interface.cpp b/planning/behavior_path_avoidance_by_lane_change_module/test/test_behavior_path_planner_node_interface.cpp
index 3041ae7e1112e..581aafa6c860c 100644
--- a/planning/behavior_path_avoidance_by_lane_change_module/test/test_behavior_path_planner_node_interface.cpp
+++ b/planning/behavior_path_avoidance_by_lane_change_module/test/test_behavior_path_planner_node_interface.cpp
@@ -12,10 +12,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "ament_index_cpp/get_package_share_directory.hpp"
#include "behavior_path_planner/behavior_path_planner_node.hpp"
-#include "planning_interface_test_manager/planning_interface_test_manager.hpp"
-#include "planning_interface_test_manager/planning_interface_test_manager_utils.hpp"
+
+#include
+#include
+#include
#include
diff --git a/planning/behavior_path_avoidance_module/config/avoidance.param.yaml b/planning/behavior_path_avoidance_module/config/avoidance.param.yaml
index c68c10f2a9489..4cfc76b6ffae1 100644
--- a/planning/behavior_path_avoidance_module/config/avoidance.param.yaml
+++ b/planning/behavior_path_avoidance_module/config/avoidance.param.yaml
@@ -9,8 +9,6 @@
# avoidance module common setting
enable_bound_clipping: false
- enable_yield_maneuver: true
- enable_yield_maneuver_during_shifting: false
enable_cancel_maneuver: true
disable_path_update: false
@@ -19,6 +17,7 @@
use_opposite_lane: true
use_intersection_areas: true
use_hatched_road_markings: true
+ use_freespace_areas: true
# for debug
publish_debug_marker: false
@@ -29,81 +28,97 @@
car:
execute_num: 1 # [-]
moving_speed_threshold: 1.0 # [m/s]
- moving_time_threshold: 1.0 # [s]
+ moving_time_threshold: 2.0 # [s]
+ lateral_margin:
+ soft_margin: 0.7 # [m]
+ hard_margin: 0.3 # [m]
+ hard_margin_for_parked_vehicle: 0.3 # [m]
max_expand_ratio: 0.0 # [-]
- envelope_buffer_margin: 0.3 # [m]
- avoid_margin_lateral: 1.0 # [m]
- safety_buffer_lateral: 0.7 # [m]
+ envelope_buffer_margin: 0.5 # [m]
safety_buffer_longitudinal: 0.0 # [m]
use_conservative_buffer_longitudinal: true # [-] When set to true, the base_link2front is added to the longitudinal buffer before avoidance.
truck:
execute_num: 1
moving_speed_threshold: 1.0 # 3.6km/h
- moving_time_threshold: 1.0
+ moving_time_threshold: 2.0
+ lateral_margin:
+ soft_margin: 0.9 # [m]
+ hard_margin: 0.1 # [m]
+ hard_margin_for_parked_vehicle: 0.1 # [m]
max_expand_ratio: 0.0
- envelope_buffer_margin: 0.3
- avoid_margin_lateral: 1.0
- safety_buffer_lateral: 0.7
+ envelope_buffer_margin: 0.5
safety_buffer_longitudinal: 0.0
use_conservative_buffer_longitudinal: true
bus:
execute_num: 1
moving_speed_threshold: 1.0 # 3.6km/h
- moving_time_threshold: 1.0
+ moving_time_threshold: 2.0
+ lateral_margin:
+ soft_margin: 0.9 # [m]
+ hard_margin: 0.1 # [m]
+ hard_margin_for_parked_vehicle: 0.1 # [m]
max_expand_ratio: 0.0
- envelope_buffer_margin: 0.3
- avoid_margin_lateral: 1.0
- safety_buffer_lateral: 0.7
+ envelope_buffer_margin: 0.5
safety_buffer_longitudinal: 0.0
use_conservative_buffer_longitudinal: true
trailer:
execute_num: 1
moving_speed_threshold: 1.0 # 3.6km/h
- moving_time_threshold: 1.0
+ moving_time_threshold: 2.0
+ lateral_margin:
+ soft_margin: 0.9 # [m]
+ hard_margin: 0.1 # [m]
+ hard_margin_for_parked_vehicle: 0.1 # [m]
max_expand_ratio: 0.0
- envelope_buffer_margin: 0.3
- avoid_margin_lateral: 1.0
- safety_buffer_lateral: 0.7
+ envelope_buffer_margin: 0.5
safety_buffer_longitudinal: 0.0
use_conservative_buffer_longitudinal: true
unknown:
execute_num: 1
moving_speed_threshold: 0.28 # 1.0km/h
moving_time_threshold: 1.0
+ lateral_margin:
+ soft_margin: 0.7 # [m]
+ hard_margin: -0.2 # [m]
+ hard_margin_for_parked_vehicle: -0.2 # [m]
max_expand_ratio: 0.0
- envelope_buffer_margin: 0.3
- avoid_margin_lateral: 1.0
- safety_buffer_lateral: 0.7
+ envelope_buffer_margin: 0.1
safety_buffer_longitudinal: 0.0
use_conservative_buffer_longitudinal: true
bicycle:
execute_num: 1
moving_speed_threshold: 0.28 # 1.0km/h
moving_time_threshold: 1.0
+ lateral_margin:
+ soft_margin: 0.7 # [m]
+ hard_margin: 0.5 # [m]
+ hard_margin_for_parked_vehicle: 0.5 # [m]
max_expand_ratio: 0.0
- envelope_buffer_margin: 0.8
- avoid_margin_lateral: 1.0
- safety_buffer_lateral: 1.0
+ envelope_buffer_margin: 0.5
safety_buffer_longitudinal: 1.0
use_conservative_buffer_longitudinal: true
motorcycle:
execute_num: 1
moving_speed_threshold: 1.0 # 3.6km/h
moving_time_threshold: 1.0
+ lateral_margin:
+ soft_margin: 0.7 # [m]
+ hard_margin: 0.3 # [m]
+ hard_margin_for_parked_vehicle: 0.3 # [m]
max_expand_ratio: 0.0
- envelope_buffer_margin: 0.8
- avoid_margin_lateral: 1.0
- safety_buffer_lateral: 1.0
+ envelope_buffer_margin: 0.5
safety_buffer_longitudinal: 1.0
use_conservative_buffer_longitudinal: true
pedestrian:
execute_num: 1
moving_speed_threshold: 0.28 # 1.0km/h
moving_time_threshold: 1.0
+ lateral_margin:
+ soft_margin: 0.7 # [m]
+ hard_margin: 0.5 # [m]
+ hard_margin_for_parked_vehicle: 0.5 # [m]
max_expand_ratio: 0.0
- envelope_buffer_margin: 0.8
- avoid_margin_lateral: 1.0
- safety_buffer_lateral: 1.0
+ envelope_buffer_margin: 0.5
safety_buffer_longitudinal: 1.0
use_conservative_buffer_longitudinal: true
lower_distance_for_polygon_expansion: 30.0 # [m]
@@ -122,7 +137,8 @@
motorcycle: true # [-]
pedestrian: true # [-]
# detection range
- object_check_goal_distance: 20.0 # [m]
+ object_check_goal_distance: 20.0 # [m]
+ object_check_return_pose_distance: 20.0 # [m]
# filtering parking objects
threshold_distance_object_is_on_center: 1.0 # [m]
object_check_shiftable_ratio: 0.6 # [-]
@@ -138,9 +154,12 @@
backward_distance: 10.0 # [m]
# params for avoidance of vehicle type objects that are ambiguous as to whether they are parked.
- force_avoidance:
+ avoidance_for_ambiguous_vehicle:
enable: false # [-]
- time_threshold: 1.0 # [s]
+ closest_distance_to_wait_and_see: 10.0 # [m]
+ condition:
+ time_threshold: 1.0 # [s]
+ distance_threshold: 1.0 # [m]
ignore_area:
traffic_light:
front_distance: 100.0 # [m]
@@ -184,6 +203,7 @@
time_horizon_for_rear_object: 10.0 # [s]
delay_until_departure: 0.0 # [s]
# rss parameters
+ extended_polygon_policy: "along_path" # [-] select "rectangle" or "along_path"
expected_front_deceleration: -1.0 # [m/ss]
expected_rear_deceleration: -1.0 # [m/ss]
rear_vehicle_reaction_time: 2.0 # [s]
@@ -204,6 +224,11 @@
max_right_shift_length: 5.0
max_left_shift_length: 5.0
max_deviation_from_lane: 0.5 # [m]
+ # approve the next shift line after reaching this percentage of the current shift line length.
+ # this parameter should be within range of 0.0 to 1.0.
+ # this parameter is added to allow waiting for the return of shift approval until the occlusion behind the avoid target is clear.
+ # this feature can be disabled by setting this parameter to 1.0. (in that case, avoidance module creates return shift as soon as possible.)
+ ratio_for_return_shift_approval: 0.5 # [-]
# avoidance distance parameters
longitudinal:
min_prepare_time: 1.0 # [s]
@@ -223,7 +248,8 @@
# For yield maneuver
yield:
- yield_velocity: 2.78 # [m/s]
+ enable: true # [-]
+ enable_during_shifting: false # [-]
# For stop maneuver
stop:
@@ -264,7 +290,8 @@
nominal_jerk: 0.5 # [m/sss]
max_deceleration: -1.5 # [m/ss]
max_jerk: 1.0 # [m/sss]
- max_acceleration: 1.0 # [m/ss]
+ max_acceleration: 0.5 # [m/ss]
+ min_velocity_to_limit_max_acceleration: 2.78 # [m/ss]
shift_line_pipeline:
trim:
diff --git a/planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/data_structs.hpp b/planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/data_structs.hpp
index 8e294e9e3237e..48b16f1ff2b69 100644
--- a/planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/data_structs.hpp
+++ b/planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/data_structs.hpp
@@ -19,12 +19,11 @@
#include "behavior_path_planner_common/utils/path_safety_checker/path_safety_checker_parameters.hpp"
#include "behavior_path_planner_common/utils/path_shifter/path_shifter.hpp"
-#include
+#include
#include
#include
#include
-#include
#include
#include
@@ -34,6 +33,7 @@
#include
#include
#include
+#include
#include
namespace behavior_path_planner
@@ -48,10 +48,11 @@ using tier4_planning_msgs::msg::AvoidanceDebugMsgArray;
using geometry_msgs::msg::Point;
using geometry_msgs::msg::Pose;
-using geometry_msgs::msg::TransformStamped;
using behavior_path_planner::utils::path_safety_checker::CollisionCheckDebug;
+using route_handler::Direction;
+
struct ObjectParameter
{
bool is_avoidance_target{false};
@@ -68,9 +69,11 @@ struct ObjectParameter
double envelope_buffer_margin{0.0};
- double avoid_margin_lateral{1.0};
+ double lateral_soft_margin{1.0};
+
+ double lateral_hard_margin{1.0};
- double safety_buffer_lateral{1.0};
+ double lateral_hard_margin_for_parked_vehicle{1.0};
double safety_buffer_longitudinal{0.0};
@@ -97,7 +100,7 @@ struct AvoidanceParameters
bool enable_cancel_maneuver{false};
// enable avoidance for all parking vehicle
- bool enable_force_avoidance_for_stopped_vehicle{false};
+ bool enable_avoidance_for_ambiguous_vehicle{false};
// enable yield maneuver.
bool enable_yield_maneuver{false};
@@ -114,6 +117,9 @@ struct AvoidanceParameters
// use intersection area for avoidance
bool use_intersection_areas{false};
+ // use freespace area for avoidance
+ bool use_freespace_areas{false};
+
// consider avoidance return dead line
bool enable_dead_line_for_goal{false};
bool enable_dead_line_for_traffic_light{false};
@@ -137,6 +143,9 @@ struct AvoidanceParameters
// To prevent large acceleration while avoidance.
double max_acceleration{0.0};
+ // To prevent large acceleration while avoidance.
+ double min_velocity_to_limit_max_acceleration{0.0};
+
// upper distance for envelope polygon expansion.
double upper_distance_for_polygon_expansion{0.0};
@@ -163,10 +172,14 @@ struct AvoidanceParameters
double object_check_backward_distance{0.0};
double object_check_yaw_deviation{0.0};
- // if the distance between object and goal position is less than this parameter, the module ignore
- // the object.
+ // if the distance between object and goal position is less than this parameter, the module do not
+ // return center line.
double object_check_goal_distance{0.0};
+ // if the distance between object and return position is less than this parameter, the module do
+ // not return center line.
+ double object_check_return_pose_distance{0.0};
+
// use in judge whether the vehicle is parking object on road shoulder
double object_check_shiftable_ratio{0.0};
@@ -174,7 +187,9 @@ struct AvoidanceParameters
double object_check_min_road_shoulder_width{0.0};
// force avoidance
- double threshold_time_force_avoidance_for_stopped_vehicle{0.0};
+ double closest_distance_to_wait_and_see_for_ambiguous_vehicle{0.0};
+ double time_threshold_for_ambiguous_vehicle{0.0};
+ double distance_threshold_for_ambiguous_vehicle{0.0};
// when complete avoidance motion, there is a distance margin with the object
// for longitudinal direction
@@ -204,9 +219,6 @@ struct AvoidanceParameters
size_t hysteresis_factor_safe_count;
double hysteresis_factor_expand_rate{0.0};
- // keep target velocity in yield maneuver
- double yield_velocity{0.0};
-
// maximum stop distance
double stop_max_distance{0.0};
@@ -267,6 +279,9 @@ struct AvoidanceParameters
// use for judge if the ego is shifting or not.
double lateral_avoid_check_threshold{0.0};
+ // use for return shift approval.
+ double ratio_for_return_shift_approval{0.0};
+
// For shift line generation process. The continuous shift length is quantized by this value.
double quantize_filter_threshold{0.0};
@@ -326,24 +341,31 @@ struct AvoidanceParameters
struct ObjectData // avoidance target
{
ObjectData() = default;
- ObjectData(const PredictedObject & obj, double lat, double lon, double len, double overhang)
- : object(obj), lateral(lat), longitudinal(lon), length(len), overhang_dist(overhang)
+
+ ObjectData(PredictedObject obj, double lat, double lon, double len)
+ : object(std::move(obj)), to_centerline(lat), longitudinal(lon), length(len)
{
}
PredictedObject object;
+ // object behavior.
+ enum class Behavior {
+ NONE = 0,
+ MERGING,
+ DEVIATING,
+ };
+ Behavior behavior{Behavior::NONE};
+
// lateral position of the CoM, in Frenet coordinate from ego-pose
- double lateral;
+
+ double to_centerline{0.0};
// longitudinal position of the CoM, in Frenet coordinate from ego-pose
- double longitudinal;
+ double longitudinal{0.0};
// longitudinal length of vehicle, in Frenet coordinate
- double length;
-
- // lateral distance to the closest footprint, in Frenet coordinate
- double overhang_dist;
+ double length{0.0};
// lateral shiftable ratio
double shiftable_ratio{0.0};
@@ -363,11 +385,12 @@ struct ObjectData // avoidance target
rclcpp::Time last_move;
double stop_time{0.0};
- // store the information of the lanelet which the object's overhang is currently occupying
+ // It is one of the ego driving lanelets (closest lanelet to the object) and used in the logic to
+ // check whether the object is on the ego lane.
lanelet::ConstLanelet overhang_lanelet;
- // the position of the overhang
- Pose overhang_pose;
+ // the position at the detected moment
+ Pose init_pose;
// envelope polygon
Polygon2d envelope_poly{};
@@ -396,14 +419,29 @@ struct ObjectData // avoidance target
// is within intersection area
bool is_within_intersection{false};
+ // is parked vehicle on road shoulder
+ bool is_parked{false};
+
+ // is driving on ego current lane
+ bool is_on_ego_lane{false};
+
+ // is ambiguous stopped vehicle.
+ bool is_ambiguous{false};
+
+ // object direction.
+ Direction direction{Direction::NONE};
+
+ // overhang points (sort by distance)
+ std::vector> overhang_points{};
+
// unavoidable reason
- std::string reason{""};
+ std::string reason{};
// lateral avoid margin
std::optional avoid_margin{std::nullopt};
// the nearest bound point (use in road shoulder distance calculation)
- std::optional nearest_bound_point{std::nullopt};
+ std::optional> narrowest_place{std::nullopt};
};
using ObjectDataArray = std::vector;
@@ -440,14 +478,14 @@ using AvoidLineArray = std::vector;
struct AvoidOutline
{
- AvoidOutline(const AvoidLine & avoid_line, const AvoidLine & return_line)
- : avoid_line{avoid_line}, return_line{return_line}
+ AvoidOutline(AvoidLine avoid_line, const std::optional return_line)
+ : avoid_line{std::move(avoid_line)}, return_line{std::move(return_line)}
{
}
AvoidLine avoid_line{};
- AvoidLine return_line{};
+ std::optional return_line{};
AvoidLineArray middle_lines{};
};
@@ -512,14 +550,16 @@ struct AvoidancePlanningData
std::vector drivable_lanes{};
- lanelet::BasicLineString3d right_bound{};
+ std::vector right_bound{};
- lanelet::BasicLineString3d left_bound{};
+ std::vector left_bound{};
bool safe{false};
bool valid{false};
+ bool ready{false};
+
bool success{false};
bool comfortable{false};
@@ -566,9 +606,7 @@ struct ShiftLineData
*/
struct DebugData
{
- std::shared_ptr current_lanelets;
-
- geometry_msgs::msg::Polygon detection_area;
+ std::vector detection_areas;
lanelet::ConstLineStrings3d bounds;
@@ -618,6 +656,9 @@ struct DebugData
// tmp for plot
PathWithLaneId center_line;
+ // safety check area
+ lanelet::ConstLanelets safety_check_lanes;
+
// collision check debug map
utils::path_safety_checker::CollisionCheckDebugMap collision_check;
diff --git a/planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/debug.hpp b/planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/debug.hpp
index 2705af5af4020..f49f457ddd066 100644
--- a/planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/debug.hpp
+++ b/planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/debug.hpp
@@ -16,33 +16,23 @@
#define BEHAVIOR_PATH_AVOIDANCE_MODULE__DEBUG_HPP_
#include "behavior_path_avoidance_module/data_structs.hpp"
-#include "behavior_path_planner_common/marker_utils/utils.hpp"
#include
-#include
#include
-#include
#include
-#include
-
#include
-#include
namespace marker_utils::avoidance_marker
{
-using autoware_auto_perception_msgs::msg::PredictedObjects;
using autoware_auto_planning_msgs::msg::PathWithLaneId;
using behavior_path_planner::AvoidancePlanningData;
-using behavior_path_planner::AvoidanceState;
using behavior_path_planner::AvoidLineArray;
using behavior_path_planner::DebugData;
using behavior_path_planner::ObjectDataArray;
using behavior_path_planner::PathShifter;
using behavior_path_planner::ShiftLineArray;
-using geometry_msgs::msg::Point;
-using geometry_msgs::msg::Polygon;
using geometry_msgs::msg::Pose;
using visualization_msgs::msg::MarkerArray;
@@ -50,7 +40,7 @@ MarkerArray createEgoStatusMarkerArray(
const AvoidancePlanningData & data, const Pose & p_ego, std::string && ns);
MarkerArray createAvoidLineMarkerArray(
- const AvoidLineArray & shift_points, std::string && ns, const float & r, const float & g,
+ const AvoidLineArray & shift_lines, std::string && ns, const float & r, const float & g,
const float & b, const double & w);
MarkerArray createPredictedVehiclePositions(const PathWithLaneId & path, std::string && ns);
@@ -63,11 +53,11 @@ MarkerArray createDebugMarkerArray(
const AvoidancePlanningData & data, const PathShifter & shifter, const DebugData & debug);
} // namespace marker_utils::avoidance_marker
-std::string toStrInfo(const behavior_path_planner::ShiftLineArray & sp_arr);
+std::string toStrInfo(const behavior_path_planner::ShiftLineArray & sl_arr);
std::string toStrInfo(const behavior_path_planner::AvoidLineArray & ap_arr);
-std::string toStrInfo(const behavior_path_planner::ShiftLine & sp);
+std::string toStrInfo(const behavior_path_planner::ShiftLine & sl);
std::string toStrInfo(const behavior_path_planner::AvoidLine & ap);
diff --git a/planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/helper.hpp b/planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/helper.hpp
index df9640fa75626..4ff02df97bd89 100644
--- a/planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/helper.hpp
+++ b/planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/helper.hpp
@@ -17,12 +17,14 @@
#include "behavior_path_avoidance_module/data_structs.hpp"
#include "behavior_path_avoidance_module/utils.hpp"
+#include "behavior_path_planner_common/utils/utils.hpp"
#include
#include
#include
#include
+#include
#include
namespace behavior_path_planner::helper::avoidance
@@ -31,7 +33,10 @@ namespace behavior_path_planner::helper::avoidance
using behavior_path_planner::PathShifter;
using behavior_path_planner::PlannerData;
using motion_utils::calcDecelDistWithJerkAndAccConstraints;
+using motion_utils::calcLongitudinalOffsetPose;
+using motion_utils::calcSignedArcLength;
using motion_utils::findNearestIndex;
+using tier4_autoware_utils::getPose;
class AvoidanceHelper
{
@@ -60,7 +65,12 @@ class AvoidanceHelper
geometry_msgs::msg::Pose getEgoPose() const { return data_->self_odometry->pose.pose; }
- size_t getConstraintsMapIndex(const double velocity, const std::vector & values) const
+ geometry_msgs::msg::Point getEgoPosition() const
+ {
+ return data_->self_odometry->pose.pose.position;
+ }
+
+ static size_t getConstraintsMapIndex(const double velocity, const std::vector & values)
{
const auto itr = std::find_if(
values.begin(), values.end(), [&](const auto value) { return velocity < value; });
@@ -134,6 +144,24 @@ class AvoidanceHelper
shift_length, getLateralMaxJerkLimit(), getAvoidanceEgoSpeed());
}
+ double getFrontConstantDistance(const ObjectData & object) const
+ {
+ const auto object_type = utils::getHighestProbLabel(object.object.classification);
+ const auto object_parameter = parameters_->object_parameters.at(object_type);
+ const auto & additional_buffer_longitudinal =
+ object_parameter.use_conservative_buffer_longitudinal ? data_->parameters.base_link2front
+ : 0.0;
+ return object_parameter.safety_buffer_longitudinal + additional_buffer_longitudinal;
+ }
+
+ double getRearConstantDistance(const ObjectData & object) const
+ {
+ const auto object_type = utils::getHighestProbLabel(object.object.classification);
+ const auto object_parameter = parameters_->object_parameters.at(object_type);
+ return object_parameter.safety_buffer_longitudinal + data_->parameters.base_link2rear +
+ object.length;
+ }
+
double getEgoShift() const
{
validate();
@@ -176,7 +204,8 @@ class AvoidanceHelper
{
using utils::avoidance::calcShiftLength;
- const auto shift_length = calcShiftLength(is_on_right, object.overhang_dist, margin);
+ const auto shift_length =
+ calcShiftLength(is_on_right, object.overhang_points.front().first, margin);
return is_on_right ? std::min(shift_length, getLeftShiftBound())
: std::max(shift_length, getRightShiftBound());
}
@@ -242,6 +271,20 @@ class AvoidanceHelper
return *itr;
}
+ std::pair getDistanceToAccelEndPoint(const PathWithLaneId & path)
+ {
+ updateAccelEndPoint(path);
+
+ if (!max_v_point_.has_value()) {
+ return std::make_pair(0.0, std::numeric_limits::max());
+ }
+
+ const auto start_idx = data_->findEgoIndex(path.points);
+ const auto distance =
+ calcSignedArcLength(path.points, start_idx, max_v_point_.value().first.position);
+ return std::make_pair(distance, max_v_point_.value().second);
+ }
+
double getFeasibleDecelDistance(
const double target_velocity, const bool use_hard_constraints = true) const
{
@@ -261,13 +304,70 @@ class AvoidanceHelper
bool isComfortable(const AvoidLineArray & shift_lines) const
{
+ const auto JERK_BUFFER = 0.1; // [m/sss]
return std::all_of(shift_lines.begin(), shift_lines.end(), [&](const auto & line) {
return PathShifter::calcJerkFromLatLonDistance(
line.getRelativeLength(), line.getRelativeLongitudinal(), getAvoidanceEgoSpeed()) <
- getLateralMaxJerkLimit();
+ getLateralMaxJerkLimit() + JERK_BUFFER;
});
}
+ bool isReady(const ObjectDataArray & objects) const
+ {
+ if (objects.empty()) {
+ return true;
+ }
+
+ const auto object = objects.front();
+
+ if (!object.is_ambiguous) {
+ return true;
+ }
+
+ if (!object.avoid_margin.has_value()) {
+ return true;
+ }
+
+ const auto is_object_on_right = utils::avoidance::isOnRight(object);
+ const auto desire_shift_length =
+ getShiftLength(object, is_object_on_right, object.avoid_margin.value());
+
+ const auto prepare_distance = getMinimumPrepareDistance();
+ const auto constant_distance = getFrontConstantDistance(object);
+ const auto avoidance_distance = getMinAvoidanceDistance(desire_shift_length);
+
+ return object.longitudinal <
+ prepare_distance + constant_distance + avoidance_distance +
+ parameters_->closest_distance_to_wait_and_see_for_ambiguous_vehicle;
+ }
+
+ bool isReady(const AvoidLineArray & new_shift_lines, const double current_shift_length) const
+ {
+ if (std::abs(current_shift_length) < 1e-3) {
+ return true;
+ }
+
+ if (new_shift_lines.empty()) {
+ return true;
+ }
+
+ const auto front_shift_relative_length = new_shift_lines.front().getRelativeLength();
+
+ // same direction shift.
+ if (current_shift_length > 0.0 && front_shift_relative_length > 0.0) {
+ return true;
+ }
+
+ // same direction shift.
+ if (current_shift_length < 0.0 && front_shift_relative_length < 0.0) {
+ return true;
+ }
+
+ // keep waiting the other side shift approval until the ego reaches shift length threshold.
+ const auto ego_shift_ratio = (current_shift_length - getEgoShift()) / current_shift_length;
+ return ego_shift_ratio < parameters_->ratio_for_return_shift_approval + 1e-3;
+ }
+
bool isShifted() const
{
return std::abs(getEgoShift()) > parameters_->lateral_avoid_check_threshold;
@@ -290,6 +390,56 @@ class AvoidanceHelper
return true;
}
+ void updateAccelEndPoint(const PathWithLaneId & path)
+ {
+ const auto & p = parameters_;
+ const auto & a_now = data_->self_acceleration->accel.accel.linear.x;
+ if (a_now < 0.0) {
+ max_v_point_ = std::nullopt;
+ return;
+ }
+
+ if (getEgoSpeed() < p->min_velocity_to_limit_max_acceleration) {
+ max_v_point_ = std::nullopt;
+ return;
+ }
+
+ if (max_v_point_.has_value()) {
+ return;
+ }
+
+ const auto v0 = getEgoSpeed() + p->buf_slow_down_speed;
+
+ const auto t_neg_jerk = std::max(0.0, a_now - p->max_acceleration) / p->max_jerk;
+ const auto v_neg_jerk = v0 + a_now * t_neg_jerk + std::pow(t_neg_jerk, 2.0) / 2.0;
+ const auto x_neg_jerk = v0 * t_neg_jerk + a_now * std::pow(t_neg_jerk, 2.0) / 2.0 +
+ p->max_jerk * std::pow(t_neg_jerk, 3.0) / 6.0;
+
+ const auto & v_max = data_->parameters.max_vel;
+ if (v_max < v_neg_jerk) {
+ max_v_point_ = std::nullopt;
+ return;
+ }
+
+ const auto t_max_accel = (v_max - v_neg_jerk) / p->max_acceleration;
+ const auto x_max_accel =
+ v_neg_jerk * t_max_accel + p->max_acceleration * std::pow(t_max_accel, 2.0) / 2.0;
+
+ const auto point =
+ calcLongitudinalOffsetPose(path.points, getEgoPosition(), x_neg_jerk + x_max_accel);
+ if (point.has_value()) {
+ max_v_point_ = std::make_pair(point.value(), v_max);
+ return;
+ }
+
+ const auto x_end = calcSignedArcLength(path.points, getEgoPosition(), path.points.size() - 1);
+ const auto t_end =
+ (std::sqrt(v0 * v0 + 2.0 * p->max_acceleration * x_end) - v0) / p->max_acceleration;
+ const auto v_end = v0 + p->max_acceleration * t_end;
+
+ max_v_point_ = std::make_pair(getPose(path.points.back()), v_end);
+ }
+
void reset()
{
prev_reference_path_ = PathWithLaneId();
@@ -340,6 +490,8 @@ class AvoidanceHelper
ShiftedPath prev_linear_shift_path_;
lanelet::ConstLanelets prev_driving_lanes_;
+
+ std::optional> max_v_point_;
};
} // namespace behavior_path_planner::helper::avoidance
diff --git a/planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/manager.hpp b/planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/manager.hpp
index 72cfbe6f0a1ed..e23a8a96ee7da 100644
--- a/planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/manager.hpp
+++ b/planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/manager.hpp
@@ -19,11 +19,10 @@
#include "behavior_path_avoidance_module/scene.hpp"
#include "behavior_path_planner_common/interface/scene_module_manager_interface.hpp"
-#include
+#include
+#include
#include
-#include
-#include
#include
namespace behavior_path_planner
diff --git a/planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/parameter_helper.hpp b/planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/parameter_helper.hpp
index 212ed04ade6c6..fbfec58abe4da 100644
--- a/planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/parameter_helper.hpp
+++ b/planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/parameter_helper.hpp
@@ -41,9 +41,6 @@ AvoidanceParameters getParameter(rclcpp::Node * node)
getOrDeclareParameter(*node, ns + "resample_interval_for_output");
p.enable_bound_clipping = getOrDeclareParameter(*node, ns + "enable_bound_clipping");
p.enable_cancel_maneuver = getOrDeclareParameter(*node, ns + "enable_cancel_maneuver");
- p.enable_yield_maneuver = getOrDeclareParameter(*node, ns + "enable_yield_maneuver");
- p.enable_yield_maneuver_during_shifting =
- getOrDeclareParameter(*node, ns + "enable_yield_maneuver_during_shifting");
p.disable_path_update = getOrDeclareParameter(*node, ns + "disable_path_update");
p.publish_debug_marker = getOrDeclareParameter(*node, ns + "publish_debug_marker");
p.print_debug_info = getOrDeclareParameter(*node, ns + "print_debug_info");
@@ -57,6 +54,7 @@ AvoidanceParameters getParameter(rclcpp::Node * node)
p.use_intersection_areas = getOrDeclareParameter(*node, ns + "use_intersection_areas");
p.use_hatched_road_markings =
getOrDeclareParameter(*node, ns + "use_hatched_road_markings");
+ p.use_freespace_areas = getOrDeclareParameter(*node, ns + "use_freespace_areas");
}
// target object
@@ -71,10 +69,12 @@ AvoidanceParameters getParameter(rclcpp::Node * node)
param.max_expand_ratio = getOrDeclareParameter(*node, ns + "max_expand_ratio");
param.envelope_buffer_margin =
getOrDeclareParameter(*node, ns + "envelope_buffer_margin");
- param.avoid_margin_lateral =
- getOrDeclareParameter(*node, ns + "avoid_margin_lateral");
- param.safety_buffer_lateral =
- getOrDeclareParameter(*node, ns + "safety_buffer_lateral");
+ param.lateral_soft_margin =
+ getOrDeclareParameter(*node, ns + "lateral_margin.soft_margin");
+ param.lateral_hard_margin =
+ getOrDeclareParameter(*node, ns + "lateral_margin.hard_margin");
+ param.lateral_hard_margin_for_parked_vehicle =
+ getOrDeclareParameter(*node, ns + "lateral_margin.hard_margin_for_parked_vehicle");
param.safety_buffer_longitudinal =
getOrDeclareParameter(*node, ns + "safety_buffer_longitudinal");
param.use_conservative_buffer_longitudinal =
@@ -122,6 +122,8 @@ AvoidanceParameters getParameter(rclcpp::Node * node)
p.object_check_goal_distance =
getOrDeclareParameter(*node, ns + "object_check_goal_distance");
+ p.object_check_return_pose_distance =
+ getOrDeclareParameter(*node, ns + "object_check_return_pose_distance");
p.threshold_distance_object_is_on_center =
getOrDeclareParameter(*node, ns + "threshold_distance_object_is_on_center");
p.object_check_shiftable_ratio =
@@ -135,11 +137,14 @@ AvoidanceParameters getParameter(rclcpp::Node * node)
}
{
- const std::string ns = "avoidance.target_filtering.force_avoidance.";
- p.enable_force_avoidance_for_stopped_vehicle =
- getOrDeclareParameter(*node, ns + "enable");
- p.threshold_time_force_avoidance_for_stopped_vehicle =
- getOrDeclareParameter(*node, ns + "time_threshold");
+ const std::string ns = "avoidance.target_filtering.avoidance_for_ambiguous_vehicle.";
+ p.enable_avoidance_for_ambiguous_vehicle = getOrDeclareParameter(*node, ns + "enable");
+ p.closest_distance_to_wait_and_see_for_ambiguous_vehicle =
+ getOrDeclareParameter(*node, ns + "closest_distance_to_wait_and_see");
+ p.time_threshold_for_ambiguous_vehicle =
+ getOrDeclareParameter(*node, ns + "condition.time_threshold");
+ p.distance_threshold_for_ambiguous_vehicle =
+ getOrDeclareParameter(*node, ns + "condition.distance_threshold");
p.object_ignore_section_traffic_light_in_front_distance =
getOrDeclareParameter(*node, ns + "ignore_area.traffic_light.front_distance");
p.object_ignore_section_crosswalk_in_front_distance =
@@ -205,6 +210,8 @@ AvoidanceParameters getParameter(rclcpp::Node * node)
getOrDeclareParameter(*node, ns + "max_velocity");
p.ego_predicted_path_params.acceleration =
getOrDeclareParameter(*node, "avoidance.constraints.longitudinal.max_acceleration");
+ p.ego_predicted_path_params.time_horizon_for_front_object =
+ getOrDeclareParameter(*node, ns + "time_horizon_for_front_object");
p.ego_predicted_path_params.time_horizon_for_rear_object =
getOrDeclareParameter(*node, ns + "time_horizon_for_rear_object");
p.ego_predicted_path_params.time_resolution =
@@ -216,6 +223,8 @@ AvoidanceParameters getParameter(rclcpp::Node * node)
// safety check rss params
{
const std::string ns = "avoidance.safety_check.";
+ p.rss_params.extended_polygon_policy =
+ getOrDeclareParameter(*node, ns + "extended_polygon_policy");
p.rss_params.longitudinal_distance_min_threshold =
getOrDeclareParameter(*node, ns + "longitudinal_distance_min_threshold");
p.rss_params.longitudinal_velocity_delta_time =
@@ -249,6 +258,12 @@ AvoidanceParameters getParameter(rclcpp::Node * node)
p.max_left_shift_length = getOrDeclareParameter(*node, ns + "max_left_shift_length");
p.max_deviation_from_lane =
getOrDeclareParameter(*node, ns + "max_deviation_from_lane");
+ p.ratio_for_return_shift_approval =
+ getOrDeclareParameter(*node, ns + "ratio_for_return_shift_approval");
+ if (p.ratio_for_return_shift_approval < 0.0 || p.ratio_for_return_shift_approval > 1.0) {
+ throw std::domain_error(
+ "ratio_for_return_shift_approval should be within range of 0.0 to 1.0");
+ }
}
// avoidance maneuver (longitudinal)
@@ -277,7 +292,9 @@ AvoidanceParameters getParameter(rclcpp::Node * node)
// yield
{
const std::string ns = "avoidance.yield.";
- p.yield_velocity = getOrDeclareParameter(*node, ns + "yield_velocity");
+ p.enable_yield_maneuver = getOrDeclareParameter(*node, ns + "enable");
+ p.enable_yield_maneuver_during_shifting =
+ getOrDeclareParameter(*node, ns + "enable_during_shifting");
}
// stop
@@ -296,6 +313,10 @@ AvoidanceParameters getParameter(rclcpp::Node * node)
p.use_shorten_margin_immediately =
getOrDeclareParameter(*node, ns + "use_shorten_margin_immediately");
+ if (p.policy_approval != "per_shift_line" && p.policy_approval != "per_avoidance_maneuver") {
+ throw std::domain_error("invalid policy. please select 'best_effort' or 'reliable'.");
+ }
+
if (p.policy_deceleration != "best_effort" && p.policy_deceleration != "reliable") {
throw std::domain_error("invalid policy. please select 'best_effort' or 'reliable'.");
}
@@ -313,6 +334,8 @@ AvoidanceParameters getParameter(rclcpp::Node * node)
p.max_deceleration = getOrDeclareParameter(*node, ns + "max_deceleration");
p.max_jerk = getOrDeclareParameter(*node, ns + "max_jerk");
p.max_acceleration = getOrDeclareParameter(*node, ns + "max_acceleration");
+ p.min_velocity_to_limit_max_acceleration =
+ getOrDeclareParameter(*node, ns + "min_velocity_to_limit_max_acceleration");
}
// constraints (lateral)
diff --git a/planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/scene.hpp b/planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/scene.hpp
index 882806177b4e0..ead834c68d01f 100644
--- a/planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/scene.hpp
+++ b/planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/scene.hpp
@@ -20,9 +20,10 @@
#include "behavior_path_avoidance_module/shift_line_generator.hpp"
#include "behavior_path_planner_common/interface/scene_module_interface.hpp"
#include "behavior_path_planner_common/interface/scene_module_visitor.hpp"
-#include "behavior_path_planner_common/utils/path_safety_checker/safety_check.hpp"
-#include
+#include
+#include
+#include
#include
#include
@@ -30,11 +31,9 @@
#include
#include
-#include
#include
#include
#include
-#include
#include
namespace behavior_path_planner
@@ -113,13 +112,12 @@ class AvoidanceModule : public SceneModuleInterface
*/
void updateRegisteredRTCStatus(const PathWithLaneId & path)
{
- const Point ego_position = planner_data_->self_odometry->pose.pose.position;
+ const auto ego_idx = planner_data_->findEgoIndex(path.points);
for (const auto & left_shift : left_shift_array_) {
const double start_distance =
- calcSignedArcLength(path.points, ego_position, left_shift.start_pose.position);
- const double finish_distance =
- calcSignedArcLength(path.points, ego_position, left_shift.finish_pose.position);
+ calcSignedArcLength(path.points, ego_idx, left_shift.start_pose.position);
+ const double finish_distance = start_distance + left_shift.relative_longitudinal;
rtc_interface_ptr_map_.at("left")->updateCooperateStatus(
left_shift.uuid, true, start_distance, finish_distance, clock_->now());
if (finish_distance > -1.0e-03) {
@@ -131,9 +129,8 @@ class AvoidanceModule : public SceneModuleInterface
for (const auto & right_shift : right_shift_array_) {
const double start_distance =
- calcSignedArcLength(path.points, ego_position, right_shift.start_pose.position);
- const double finish_distance =
- calcSignedArcLength(path.points, ego_position, right_shift.finish_pose.position);
+ calcSignedArcLength(path.points, ego_idx, right_shift.start_pose.position);
+ const double finish_distance = start_distance + right_shift.relative_longitudinal;
rtc_interface_ptr_map_.at("right")->updateCooperateStatus(
right_shift.uuid, true, start_distance, finish_distance, clock_->now());
if (finish_distance > -1.0e-03) {
@@ -239,11 +236,10 @@ class AvoidanceModule : public SceneModuleInterface
void insertPrepareVelocity(ShiftedPath & shifted_path) const;
/**
- * @brief insert decel point in output path in order to yield. the ego decelerates within
- * accel/jerk constraints.
+ * @brief insert max velocity in output path to limit acceleration.
* @param target path.
*/
- void insertYieldVelocity(ShiftedPath & shifted_path) const;
+ void insertAvoidanceVelocity(ShiftedPath & shifted_path) const;
/**
* @brief calculate stop distance based on object's overhang.
@@ -326,13 +322,6 @@ class AvoidanceModule : public SceneModuleInterface
// generate output data
- /**
- * @brief calculate turn signal infomation.
- * @param avoidance path.
- * @return turn signal command.
- */
- TurnSignalInfo calcTurnSignalInfo(const ShiftedPath & path) const;
-
/**
* @brief fill debug markers.
*/
@@ -374,8 +363,8 @@ class AvoidanceModule : public SceneModuleInterface
*/
void removeRegisteredShiftLines()
{
- constexpr double THRESHOLD = 0.1;
- if (std::abs(path_shifter_.getBaseOffset()) > THRESHOLD) {
+ constexpr double threshold = 0.1;
+ if (std::abs(path_shifter_.getBaseOffset()) > threshold) {
RCLCPP_INFO(getLogger(), "base offset is not zero. can't reset registered shift lines.");
return;
}
@@ -396,7 +385,7 @@ class AvoidanceModule : public SceneModuleInterface
* @brief remove behind shift lines.
* @param path shifter.
*/
- void postProcess()
+ void postProcess() override
{
const size_t idx = planner_data_->findEgoIndex(path_shifter_.getReferencePath().points);
path_shifter_.removeBehindShiftLineAndSetBaseOffset(idx);
@@ -407,12 +396,11 @@ class AvoidanceModule : public SceneModuleInterface
UUID uuid;
Pose start_pose;
Pose finish_pose;
+ double relative_longitudinal{0.0};
};
using RegisteredShiftLineArray = std::vector;
- bool is_avoidance_maneuver_starts;
-
bool arrived_path_end_{false};
bool safe_{true};
@@ -433,14 +421,20 @@ class AvoidanceModule : public SceneModuleInterface
UUID candidate_uuid_;
+ // TODO(Satoshi OTA) create detected object manager.
ObjectDataArray registered_objects_;
- mutable size_t safe_count_{0};
+ // TODO(Satoshi OTA) remove mutable.
+ mutable ObjectDataArray detected_objects_;
+ // TODO(Satoshi OTA) remove this variable.
mutable ObjectDataArray ego_stopped_objects_;
+ // TODO(Satoshi OTA) remove this variable.
mutable ObjectDataArray stopped_objects_;
+ mutable size_t safe_count_{0};
+
mutable DebugData debug_data_;
mutable std::shared_ptr debug_msg_ptr_;
diff --git a/planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/shift_line_generator.hpp b/planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/shift_line_generator.hpp
index edfe9ab9663ce..efdda622a664c 100644
--- a/planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/shift_line_generator.hpp
+++ b/planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/shift_line_generator.hpp
@@ -17,11 +17,8 @@
#include "behavior_path_avoidance_module/data_structs.hpp"
#include "behavior_path_avoidance_module/helper.hpp"
-#include "behavior_path_planner_common/data_manager.hpp"
#include "behavior_path_planner_common/utils/path_shifter/path_shifter.hpp"
-#include
-
#include
namespace behavior_path_planner::utils::avoidance
@@ -29,8 +26,6 @@ namespace behavior_path_planner::utils::avoidance
using behavior_path_planner::PathShifter;
using behavior_path_planner::helper::avoidance::AvoidanceHelper;
-using motion_utils::calcSignedArcLength;
-using motion_utils::findNearestIndex;
class ShiftLineGenerator
{
diff --git a/planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/utils.hpp b/planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/utils.hpp
index 521058e3a43c9..14d3bd1800dad 100644
--- a/planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/utils.hpp
+++ b/planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/utils.hpp
@@ -36,6 +36,9 @@ bool isOnRight(const ObjectData & obj);
double calcShiftLength(
const bool & is_object_on_right, const double & overhang_dist, const double & avoid_margin);
+bool isWithinLanes(
+ const lanelet::ConstLanelets & lanelets, std::shared_ptr & planner_data);
+
bool isShiftNecessary(const bool & is_object_on_right, const double & shift_length);
bool isSameDirectionShift(const bool & is_object_on_right, const double & shift_length);
@@ -56,8 +59,8 @@ double lerpShiftLengthOnArc(double arc, const AvoidLine & al);
void fillLongitudinalAndLengthByClosestEnvelopeFootprint(
const PathWithLaneId & path, const Point & ego_pos, ObjectData & obj);
-double calcEnvelopeOverhangDistance(
- const ObjectData & object_data, const PathWithLaneId & path, Point & overhang_pose);
+std::vector> calcEnvelopeOverhangDistance(
+ const ObjectData & object_data, const PathWithLaneId & path);
void setEndData(
AvoidLine & al, const double length, const geometry_msgs::msg::Pose & end, const size_t end_idx,
@@ -77,19 +80,11 @@ std::vector generateObstaclePolygonsForDrivableArea(
const ObjectDataArray & objects, const std::shared_ptr & parameters,
const double vehicle_width);
-double getLongitudinalVelocity(const Pose & p_ref, const Pose & p_target, const double v);
-
-bool isCentroidWithinLanelets(
- const PredictedObject & object, const lanelet::ConstLanelets & target_lanelets);
-
lanelet::ConstLanelets getAdjacentLane(
+ const lanelet::ConstLanelet & current_lane,
const std::shared_ptr & planner_data,
const std::shared_ptr & parameters, const bool is_right_shift);
-lanelet::ConstLanelets getTargetLanelets(
- const std::shared_ptr & planner_data, lanelet::ConstLanelets & route_lanelets,
- const double left_offset, const double right_offset);
-
lanelet::ConstLanelets getCurrentLanesFromPath(
const PathWithLaneId & path, const std::shared_ptr & planner_data);
@@ -117,6 +112,8 @@ void fillObjectStoppableJudge(
ObjectData & object_data, const ObjectDataArray & registered_objects,
const double feasible_stop_distance, const std::shared_ptr & parameters);
+void fillInitialPose(ObjectData & object_data, ObjectDataArray & detected_objects);
+
void updateRegisteredObject(
ObjectDataArray & registered_objects, const ObjectDataArray & now_objects,
const std::shared_ptr & parameters);
@@ -126,13 +123,12 @@ void compensateDetectionLost(
ObjectDataArray & other_objects);
void filterTargetObjects(
- ObjectDataArray & objects, AvoidancePlanningData & data, DebugData & debug,
+ ObjectDataArray & objects, AvoidancePlanningData & data, const double forward_detection_range,
const std::shared_ptr & planner_data,
const std::shared_ptr & parameters);
-double getRoadShoulderDistance(
- ObjectData & object, const AvoidancePlanningData & data,
- const std::shared_ptr & planner_data,
+void updateRoadShoulderDistance(
+ AvoidancePlanningData & data, const std::shared_ptr & planner_data,
const std::shared_ptr & parameters);
void fillAdditionalInfoFromPoint(const AvoidancePlanningData & data, AvoidLineArray & lines);
@@ -151,14 +147,18 @@ AvoidLineArray combineRawShiftLinesWithUniqueCheck(
std::vector getSafetyCheckTargetObjects(
const AvoidancePlanningData & data, const std::shared_ptr & planner_data,
- const std::shared_ptr & parameters, const bool is_right_shift);
+ const std::shared_ptr & parameters, const bool has_left_shift,
+ const bool has_right_shift, DebugData & debug);
std::pair separateObjectsByPath(
- const PathWithLaneId & path, const std::shared_ptr & planner_data,
- const AvoidancePlanningData & data, const std::shared_ptr & parameters,
- const double object_check_forward_distance, const bool is_running, DebugData & debug);
+ const PathWithLaneId & reference_path, const PathWithLaneId & spline_path,
+ const std::shared_ptr & planner_data, const AvoidancePlanningData & data,
+ const std::shared_ptr & parameters,
+ const double object_check_forward_distance, DebugData & debug);
-DrivableLanes generateExpandDrivableLanes(
+DrivableLanes generateNotExpandedDrivableLanes(const lanelet::ConstLanelet & lanelet);
+
+DrivableLanes generateExpandedDrivableLanes(
const lanelet::ConstLanelet & lanelet, const std::shared_ptr & planner_data,
const std::shared_ptr & parameters);
@@ -171,6 +171,10 @@ double calcDistanceToAvoidStartLine(
const lanelet::ConstLanelets & lanelets, const PathWithLaneId & path,
const std::shared_ptr & planner_data,
const std::shared_ptr & parameters);
+
+TurnSignalInfo calcTurnSignalInfo(
+ const ShiftedPath & path, const ShiftLine & shift_line, const double current_shift_length,
+ const AvoidancePlanningData & data, const std::shared_ptr & planner_data);
} // namespace behavior_path_planner::utils::avoidance
#endif // BEHAVIOR_PATH_AVOIDANCE_MODULE__UTILS_HPP_
diff --git a/planning/behavior_path_avoidance_module/package.xml b/planning/behavior_path_avoidance_module/package.xml
index 642f83497acfb..fc34172bb2ce9 100644
--- a/planning/behavior_path_avoidance_module/package.xml
+++ b/planning/behavior_path_avoidance_module/package.xml
@@ -6,6 +6,7 @@
The behavior_path_avoidance_module package
Takamasa Horibe
+ Zulfaqar Azmi
Satoshi Ota
Fumiya Watanabe
Kyoichi Sugahara
@@ -27,7 +28,6 @@
behavior_path_planner_common
geometry_msgs
lanelet2_extension
- libboost-dev
magic_enum
motion_utils
objects_of_interest_marker_interface
diff --git a/planning/behavior_path_avoidance_module/src/debug.cpp b/planning/behavior_path_avoidance_module/src/debug.cpp
index 310613ee19678..7d029277fcbc4 100644
--- a/planning/behavior_path_avoidance_module/src/debug.cpp
+++ b/planning/behavior_path_avoidance_module/src/debug.cpp
@@ -14,16 +14,15 @@
#include "behavior_path_avoidance_module/debug.hpp"
+#include "behavior_path_planner_common/marker_utils/utils.hpp"
#include "behavior_path_planner_common/utils/utils.hpp"
+#include
#include
#include
#include
-#include
-#include
-
#include
#include
@@ -48,7 +47,7 @@ int32_t uuidToInt32(const unique_identifier_msgs::msg::UUID & uuid)
int32_t ret = 0;
for (size_t i = 0; i < sizeof(int32_t) / sizeof(int8_t); ++i) {
- ret <<= sizeof(int8_t);
+ ret <<= sizeof(int8_t) * 8;
ret |= uuid.uuid.at(i);
}
@@ -114,7 +113,7 @@ MarkerArray createToDrivableBoundDistance(const ObjectDataArray & objects, std::
MarkerArray msg;
for (const auto & object : objects) {
- if (!object.nearest_bound_point.has_value()) {
+ if (!object.narrowest_place.has_value()) {
continue;
}
@@ -123,8 +122,8 @@ MarkerArray createToDrivableBoundDistance(const ObjectDataArray & objects, std::
"map", rclcpp::Clock{RCL_ROS_TIME}.now(), ns, 0L, Marker::LINE_STRIP,
createMarkerScale(0.1, 0.0, 0.0), createMarkerColor(1.0, 0.0, 0.42, 0.999));
- marker.points.push_back(object.overhang_pose.position);
- marker.points.push_back(object.nearest_bound_point.value());
+ marker.points.push_back(object.narrowest_place.value().first);
+ marker.points.push_back(object.narrowest_place.value().second);
marker.id = uuidToInt32(object.object.object_id);
msg.markers.push_back(marker);
}
@@ -134,7 +133,7 @@ MarkerArray createToDrivableBoundDistance(const ObjectDataArray & objects, std::
"map", rclcpp::Clock{RCL_ROS_TIME}.now(), ns, 0L, Marker::TEXT_VIEW_FACING,
createMarkerScale(0.5, 0.5, 0.5), createMarkerColor(1.0, 1.0, 0.0, 1.0));
- marker.pose.position = object.nearest_bound_point.value();
+ marker.pose.position = object.narrowest_place.value().second;
std::ostringstream string_stream;
string_stream << object.to_road_shoulder_distance << "[m]";
marker.text = string_stream.str();
@@ -160,7 +159,7 @@ MarkerArray createObjectInfoMarkerArray(const ObjectDataArray & objects, std::st
std::ostringstream string_stream;
string_stream << std::fixed << std::setprecision(2) << std::boolalpha;
string_stream << "ratio:" << object.shiftable_ratio << " [-]\n"
- << "lateral:" << object.lateral << " [m]\n"
+ << "lateral:" << object.to_centerline << " [m]\n"
<< "necessity:" << object.avoid_required << " [-]\n"
<< "stoppable:" << object.is_stoppable << " [-]\n"
<< "stop_factor:" << object.to_stop_factor_distance << " [m]\n"
@@ -177,7 +176,7 @@ MarkerArray createObjectInfoMarkerArray(const ObjectDataArray & objects, std::st
marker.id = uuidToInt32(object.object.object_id);
marker.pose.position.z += 2.0;
std::ostringstream string_stream;
- string_stream << object.reason;
+ string_stream << object.reason << (object.is_parked ? "(PARKED)" : "");
marker.text = string_stream.str();
marker.color = createMarkerColor(1.0, 1.0, 1.0, 0.999);
marker.scale = createMarkerScale(0.6, 0.6, 0.6);
@@ -189,10 +188,25 @@ MarkerArray createObjectInfoMarkerArray(const ObjectDataArray & objects, std::st
return msg;
}
+MarkerArray createOverhangLaneletMarkerArray(const ObjectDataArray & objects, std::string && ns)
+{
+ MarkerArray msg;
+ msg.markers.reserve(objects.size());
+
+ for (const auto & object : objects) {
+ appendMarkerArray(
+ marker_utils::createLaneletsAreaMarkerArray(
+ {object.overhang_lanelet}, std::string(ns), 0.0, 0.0, 1.0),
+ &msg);
+ }
+
+ return msg;
+}
+
MarkerArray avoidableObjectsMarkerArray(const ObjectDataArray & objects, std::string && ns)
{
MarkerArray msg;
- msg.markers.reserve(objects.size() * 4);
+ msg.markers.reserve(objects.size() * 5);
appendMarkerArray(
createObjectsCubeMarkerArray(
@@ -203,6 +217,7 @@ MarkerArray avoidableObjectsMarkerArray(const ObjectDataArray & objects, std::st
appendMarkerArray(createObjectInfoMarkerArray(objects, ns + "_info"), &msg);
appendMarkerArray(createObjectPolygonMarkerArray(objects, ns + "_envelope_polygon"), &msg);
appendMarkerArray(createToDrivableBoundDistance(objects, ns + "_to_drivable_bound"), &msg);
+ appendMarkerArray(createOverhangLaneletMarkerArray(objects, ns + "_overhang_lanelet"), &msg);
return msg;
}
@@ -210,7 +225,7 @@ MarkerArray avoidableObjectsMarkerArray(const ObjectDataArray & objects, std::st
MarkerArray unAvoidableObjectsMarkerArray(const ObjectDataArray & objects, std::string && ns)
{
MarkerArray msg;
- msg.markers.reserve(objects.size() * 4);
+ msg.markers.reserve(objects.size() * 5);
appendMarkerArray(
createObjectsCubeMarkerArray(
@@ -221,6 +236,7 @@ MarkerArray unAvoidableObjectsMarkerArray(const ObjectDataArray & objects, std::
appendMarkerArray(createObjectInfoMarkerArray(objects, ns + "_info"), &msg);
appendMarkerArray(createObjectPolygonMarkerArray(objects, ns + "_envelope_polygon"), &msg);
appendMarkerArray(createToDrivableBoundDistance(objects, ns + "_to_drivable_bound"), &msg);
+ appendMarkerArray(createOverhangLaneletMarkerArray(objects, ns + "_overhang_lanelet"), &msg);
return msg;
}
@@ -452,6 +468,10 @@ MarkerArray createOtherObjectsMarkerArray(const ObjectDataArray & objects, const
appendMarkerArray(
createObjectInfoMarkerArray(filtered_objects, "others_" + convertToSnakeCase(ns) + "_info"),
&msg);
+ appendMarkerArray(
+ createOverhangLaneletMarkerArray(
+ filtered_objects, "others_" + convertToSnakeCase(ns) + "_overhang_lanelet"),
+ &msg);
return msg;
}
@@ -470,7 +490,7 @@ MarkerArray createDrivableBounds(
createMarkerColor(r, g, b, 0.999));
for (const auto & p : data.right_bound) {
- marker.points.push_back(createPoint(p.x(), p.y(), p.z()));
+ marker.points.push_back(p);
}
msg.markers.push_back(marker);
@@ -483,7 +503,7 @@ MarkerArray createDrivableBounds(
createMarkerColor(r, g, b, 0.999));
for (const auto & p : data.left_bound) {
- marker.points.push_back(createPoint(p.x(), p.y(), p.z()));
+ marker.points.push_back(p);
}
msg.markers.push_back(marker);
@@ -495,6 +515,8 @@ MarkerArray createDrivableBounds(
MarkerArray createDebugMarkerArray(
const AvoidancePlanningData & data, const PathShifter & shifter, const DebugData & debug)
{
+ using behavior_path_planner::utils::transformToLanelets;
+ using lanelet::visualization::laneletsAsTriangleMarkerArray;
using marker_utils::createLaneletsAreaMarkerArray;
using marker_utils::createObjectsMarkerArray;
using marker_utils::createPathMarkerArray;
@@ -554,6 +576,11 @@ MarkerArray createDebugMarkerArray(
addObjects(data.other_objects, std::string("NotNeedAvoidance"));
addObjects(data.other_objects, std::string("LessThanExecutionThreshold"));
addObjects(data.other_objects, std::string("TooNearToGoal"));
+ addObjects(data.other_objects, std::string("ParallelToEgoLane"));
+ addObjects(data.other_objects, std::string("MergingToEgoLane"));
+ addObjects(data.other_objects, std::string("UnstableObject"));
+ addObjects(data.other_objects, std::string("AmbiguousStoppedVehicle"));
+ addObjects(data.other_objects, std::string("AmbiguousStoppedVehicle(wait-and-see)"));
}
// shift line pre-process
@@ -605,12 +632,23 @@ MarkerArray createDebugMarkerArray(
addShiftGrad(debug.total_backward_grad, debug.total_shift, "grad_backward", 0.4, 0.2, 0.9);
}
+ // detection area
+ size_t i = 0;
+ for (const auto & detection_area : debug.detection_areas) {
+ add(createPolygonMarkerArray(detection_area, "detection_area", i++, 0.16, 1.0, 0.69, 0.1));
+ }
+
// misc
{
add(createPathMarkerArray(path, "centerline_resampled", 0, 0.0, 0.9, 0.5));
- add(createLaneletsAreaMarkerArray(*debug.current_lanelets, "current_lanelet", 0.0, 1.0, 0.0));
- add(createPolygonMarkerArray(debug.detection_area, "detection_area", 0L, 0.16, 1.0, 0.69, 0.1));
add(createDrivableBounds(data, "drivable_bound", 1.0, 0.0, 0.42));
+ add(laneletsAsTriangleMarkerArray(
+ "drivable_lanes", transformToLanelets(data.drivable_lanes),
+ createMarkerColor(0.16, 1.0, 0.69, 0.2)));
+ add(laneletsAsTriangleMarkerArray(
+ "current_lanes", data.current_lanelets, createMarkerColor(1.0, 1.0, 1.0, 0.2)));
+ add(laneletsAsTriangleMarkerArray(
+ "safety_check_lanes", debug.safety_check_lanes, createMarkerColor(1.0, 0.0, 0.42, 0.2)));
}
return msg;
diff --git a/planning/behavior_path_avoidance_module/src/manager.cpp b/planning/behavior_path_avoidance_module/src/manager.cpp
index 68cee1aa2b523..5ce63987621ed 100644
--- a/planning/behavior_path_avoidance_module/src/manager.cpp
+++ b/planning/behavior_path_avoidance_module/src/manager.cpp
@@ -60,8 +60,11 @@ void AvoidanceModuleManager::updateModuleParams(const std::vector(parameters, ns + "moving_time_threshold", config.moving_time_threshold);
updateParam(parameters, ns + "max_expand_ratio", config.max_expand_ratio);
updateParam(parameters, ns + "envelope_buffer_margin", config.envelope_buffer_margin);
- updateParam(parameters, ns + "avoid_margin_lateral", config.avoid_margin_lateral);
- updateParam(parameters, ns + "safety_buffer_lateral", config.safety_buffer_lateral);
+ updateParam(parameters, ns + "lateral_margin.soft_margin", config.lateral_soft_margin);
+ updateParam(parameters, ns + "lateral_margin.hard_margin", config.lateral_hard_margin);
+ updateParam(
+ parameters, ns + "lateral_margin.hard_margin_for_parked_vehicle",
+ config.lateral_hard_margin_for_parked_vehicle);
updateParam(
parameters, ns + "safety_buffer_longitudinal", config.safety_buffer_longitudinal);
updateParam(
@@ -88,6 +91,76 @@ void AvoidanceModuleManager::updateModuleParams(const std::vectorupper_distance_for_polygon_expansion);
}
+ {
+ const auto set_target_flag = [&](const uint8_t & object_type, const std::string & ns) {
+ if (p->object_parameters.count(object_type) == 0) {
+ return;
+ }
+ updateParam(parameters, ns, p->object_parameters.at(object_type).is_avoidance_target);
+ };
+
+ const std::string ns = "avoidance.target_filtering.";
+ set_target_flag(ObjectClassification::CAR, ns + "target_type.car");
+ set_target_flag(ObjectClassification::TRUCK, ns + "target_type.truck");
+ set_target_flag(ObjectClassification::TRAILER, ns + "target_type.trailer");
+ set_target_flag(ObjectClassification::BUS, ns + "target_type.bus");
+ set_target_flag(ObjectClassification::PEDESTRIAN, ns + "target_type.pedestrian");
+ set_target_flag(ObjectClassification::BICYCLE, ns + "target_type.bicycle");
+ set_target_flag(ObjectClassification::MOTORCYCLE, ns + "target_type.motorcycle");
+ set_target_flag(ObjectClassification::UNKNOWN, ns + "target_type.unknown");
+
+ updateParam(
+ parameters, ns + "object_check_goal_distance", p->object_check_goal_distance);
+ updateParam(
+ parameters, ns + "object_check_return_pose_distance", p->object_check_return_pose_distance);
+ updateParam(
+ parameters, ns + "threshold_distance_object_is_on_center",
+ p->threshold_distance_object_is_on_center);
+ updateParam(
+ parameters, ns + "object_check_shiftable_ratio", p->object_check_shiftable_ratio);
+ updateParam(
+ parameters, ns + "object_check_min_road_shoulder_width",
+ p->object_check_min_road_shoulder_width);
+ updateParam(
+ parameters, ns + "object_last_seen_threshold", p->object_last_seen_threshold);
+ }
+
+ {
+ const std::string ns = "avoidance.target_filtering.detection_area.";
+ updateParam(parameters, ns + "static", p->use_static_detection_area);
+ updateParam(
+ parameters, ns + "min_forward_distance", p->object_check_min_forward_distance);
+ updateParam(
+ parameters, ns + "max_forward_distance", p->object_check_max_forward_distance);
+ updateParam(parameters, ns + "backward_distance", p->object_check_backward_distance);
+ }
+
+ {
+ const std::string ns = "avoidance.avoidance.lateral.avoidance_for_ambiguous_vehicle.";
+ updateParam(parameters, ns + "enable", p->enable_avoidance_for_ambiguous_vehicle);
+ updateParam(
+ parameters, ns + "closest_distance_to_wait_and_see",
+ p->closest_distance_to_wait_and_see_for_ambiguous_vehicle);
+ updateParam(
+ parameters, ns + "condition.time_threshold", p->time_threshold_for_ambiguous_vehicle);
+ updateParam(
+ parameters, ns + "condition.distance_threshold", p->distance_threshold_for_ambiguous_vehicle);
+ updateParam(
+ parameters, ns + "ignore_area.traffic_light.front_distance",
+ p->object_ignore_section_traffic_light_in_front_distance);
+ updateParam(
+ parameters, ns + "ignore_area.crosswalk.front_distance",
+ p->object_ignore_section_crosswalk_in_front_distance);
+ updateParam(
+ parameters, ns + "ignore_area.crosswalk.behind_distance",
+ p->object_ignore_section_crosswalk_behind_distance);
+ }
+
+ {
+ const std::string ns = "avoidance.target_filtering.intersection.";
+ updateParam(parameters, ns + "yaw_deviation", p->object_check_yaw_deviation);
+ }
+
{
const std::string ns = "avoidance.avoidance.lateral.";
updateParam(
@@ -104,6 +177,7 @@ void AvoidanceModuleManager::updateModuleParams(const std::vector(parameters, ns + "min_prepare_time", p->min_prepare_time);
updateParam(parameters, ns + "max_prepare_time", p->max_prepare_time);
+ updateParam(parameters, ns + "min_prepare_distance", p->min_prepare_distance);
updateParam(parameters, ns + "min_slow_down_speed", p->min_slow_down_speed);
updateParam(parameters, ns + "buf_slow_down_speed", p->buf_slow_down_speed);
}
@@ -114,6 +188,33 @@ void AvoidanceModuleManager::updateModuleParams(const std::vector(parameters, ns + "stop_buffer", p->stop_buffer);
}
+ {
+ const std::string ns = "avoidance.policy.";
+ updateParam(parameters, ns + "make_approval_request", p->policy_approval);
+ updateParam(parameters, ns + "deceleration", p->policy_deceleration);
+ updateParam(parameters, ns + "lateral_margin", p->policy_lateral_margin);
+ updateParam(
+ parameters, ns + "use_shorten_margin_immediately", p->use_shorten_margin_immediately);
+
+ if (p->policy_approval != "per_shift_line" && p->policy_approval != "per_avoidance_maneuver") {
+ RCLCPP_ERROR(
+ rclcpp::get_logger(__func__),
+ "invalid policy. please select 'per_shift_line' or 'per_avoidance_maneuver'.");
+ }
+
+ if (p->policy_deceleration != "best_effort" && p->policy_deceleration != "reliable") {
+ RCLCPP_ERROR(
+ rclcpp::get_logger(__func__),
+ "invalid deceleration policy. Please select 'best_effort' or 'reliable'.");
+ }
+
+ if (p->policy_lateral_margin != "best_effort" && p->policy_lateral_margin != "reliable") {
+ RCLCPP_ERROR(
+ rclcpp::get_logger(__func__),
+ "invalid lateral margin policy. Please select 'best_effort' or 'reliable'.");
+ }
+ }
+
{
const std::string ns = "avoidance.constrains.lateral.";
@@ -143,6 +244,19 @@ void AvoidanceModuleManager::updateModuleParams(const std::vector(parameters, ns + "nominal_deceleration", p->nominal_deceleration);
+ updateParam(parameters, ns + "nominal_jerk", p->nominal_jerk);
+ updateParam(parameters, ns + "max_deceleration", p->max_deceleration);
+ updateParam(parameters, ns + "max_jerk", p->max_jerk);
+ updateParam(parameters, ns + "max_acceleration", p->max_acceleration);
+ updateParam(
+ parameters, ns + "min_velocity_to_limit_max_acceleration",
+ p->min_velocity_to_limit_max_acceleration);
+ }
+
{
const std::string ns = "avoidance.shift_line_pipeline.";
updateParam(
diff --git a/planning/behavior_path_avoidance_module/src/scene.cpp b/planning/behavior_path_avoidance_module/src/scene.cpp
index ebe42f73d538b..9ed189ac29adc 100644
--- a/planning/behavior_path_avoidance_module/src/scene.cpp
+++ b/planning/behavior_path_avoidance_module/src/scene.cpp
@@ -17,10 +17,11 @@
#include "behavior_path_avoidance_module/debug.hpp"
#include "behavior_path_avoidance_module/utils.hpp"
#include "behavior_path_planner_common/interface/scene_module_visitor.hpp"
-#include "behavior_path_planner_common/utils/create_vehicle_footprint.hpp"
#include "behavior_path_planner_common/utils/drivable_area_expansion/static_drivable_area.hpp"
#include "behavior_path_planner_common/utils/path_safety_checker/objects_filtering.hpp"
+#include "behavior_path_planner_common/utils/path_safety_checker/safety_check.hpp"
#include "behavior_path_planner_common/utils/path_utils.hpp"
+#include "behavior_path_planner_common/utils/traffic_light_utils.hpp"
#include "behavior_path_planner_common/utils/utils.hpp"
#include
@@ -28,14 +29,9 @@
#include
#include
#include
-#include
-#include
-#include
-#include
-
-#include
-#include
+#include "tier4_planning_msgs/msg/detail/avoidance_debug_msg_array__struct.hpp"
+#include
#include
#include
@@ -137,7 +133,7 @@ bool AvoidanceModule::isExecutionRequested() const
bool AvoidanceModule::isExecutionReady() const
{
DEBUG_PRINT("AVOIDANCE isExecutionReady");
- return avoid_data_.safe && avoid_data_.comfortable && avoid_data_.valid;
+ return avoid_data_.safe && avoid_data_.comfortable && avoid_data_.valid && avoid_data_.ready;
}
bool AvoidanceModule::isSatisfiedSuccessCondition(const AvoidancePlanningData & data) const
@@ -226,21 +222,52 @@ void AvoidanceModule::fillFundamentalData(AvoidancePlanningData & data, DebugDat
utils::avoidance::getExtendLanes(data.current_lanelets, getEgoPose(), planner_data_);
// expand drivable lanes
+ const auto is_within_current_lane =
+ utils::avoidance::isWithinLanes(data.current_lanelets, planner_data_);
+ const auto red_signal_lane_itr = std::find_if(
+ data.current_lanelets.begin(), data.current_lanelets.end(), [&](const auto & lanelet) {
+ const auto next_lanes = planner_data_->route_handler->getNextLanelets(lanelet);
+ return utils::traffic_light::isTrafficSignalStop(next_lanes, planner_data_);
+ });
+ const auto not_use_adjacent_lane =
+ is_within_current_lane && red_signal_lane_itr != data.current_lanelets.end();
+
std::for_each(
data.current_lanelets.begin(), data.current_lanelets.end(), [&](const auto & lanelet) {
- data.drivable_lanes.push_back(
- utils::avoidance::generateExpandDrivableLanes(lanelet, planner_data_, parameters_));
+ if (!not_use_adjacent_lane) {
+ data.drivable_lanes.push_back(
+ utils::avoidance::generateExpandedDrivableLanes(lanelet, planner_data_, parameters_));
+ } else if (red_signal_lane_itr->id() != lanelet.id()) {
+ data.drivable_lanes.push_back(
+ utils::avoidance::generateExpandedDrivableLanes(lanelet, planner_data_, parameters_));
+ } else {
+ data.drivable_lanes.push_back(utils::avoidance::generateNotExpandedDrivableLanes(lanelet));
+ }
});
// calc drivable bound
auto tmp_path = getPreviousModuleOutput().path;
const auto shorten_lanes = utils::cutOverlappedLanes(tmp_path, data.drivable_lanes);
- data.left_bound = toLineString3d(utils::calcBound(
- planner_data_->route_handler, shorten_lanes, parameters_->use_hatched_road_markings,
- parameters_->use_intersection_areas, true));
- data.right_bound = toLineString3d(utils::calcBound(
- planner_data_->route_handler, shorten_lanes, parameters_->use_hatched_road_markings,
- parameters_->use_intersection_areas, false));
+ const auto use_left_side_hatched_road_marking_area = [&]() {
+ if (!not_use_adjacent_lane) {
+ return true;
+ }
+ return !planner_data_->route_handler->getRoutingGraphPtr()->left(*red_signal_lane_itr);
+ }();
+ const auto use_right_side_hatched_road_marking_area = [&]() {
+ if (!not_use_adjacent_lane) {
+ return true;
+ }
+ return !planner_data_->route_handler->getRoutingGraphPtr()->right(*red_signal_lane_itr);
+ }();
+ data.left_bound = utils::calcBound(
+ getPreviousModuleOutput().path, planner_data_, shorten_lanes,
+ use_left_side_hatched_road_marking_area, parameters_->use_intersection_areas,
+ parameters_->use_freespace_areas, true);
+ data.right_bound = utils::calcBound(
+ getPreviousModuleOutput().path, planner_data_, shorten_lanes,
+ use_right_side_hatched_road_marking_area, parameters_->use_intersection_areas,
+ parameters_->use_freespace_areas, false);
// reference path
if (isDrivingSameLane(helper_->getPreviousDrivingLanes(), data.current_lanelets)) {
@@ -288,25 +315,21 @@ void AvoidanceModule::fillFundamentalData(AvoidancePlanningData & data, DebugDat
void AvoidanceModule::fillAvoidanceTargetObjects(
AvoidancePlanningData & data, DebugData & debug) const
{
+ using utils::avoidance::fillAvoidanceNecessity;
using utils::avoidance::fillObjectStoppableJudge;
using utils::avoidance::filterTargetObjects;
- using utils::avoidance::getTargetLanelets;
-
- // Add margin in order to prevent avoidance request chattering only when the module is running.
- const auto is_running = getCurrentStatus() == ModuleStatus::RUNNING ||
- getCurrentStatus() == ModuleStatus::WAITING_APPROVAL;
+ using utils::avoidance::separateObjectsByPath;
+ using utils::avoidance::updateRoadShoulderDistance;
// Separate dynamic objects based on whether they are inside or outside of the expanded lanelets.
- const auto sparse_resample_path = utils::resamplePathWithSpline(
- helper_->getPreviousSplineShiftPath().path, parameters_->resample_interval_for_output);
- const auto [object_within_target_lane, object_outside_target_lane] =
- utils::avoidance::separateObjectsByPath(
- sparse_resample_path, planner_data_, data, parameters_, helper_->getForwardDetectionRange(),
- is_running, debug);
+ constexpr double MARGIN = 10.0;
+ const auto forward_detection_range = helper_->getForwardDetectionRange();
+ const auto [object_within_target_lane, object_outside_target_lane] = separateObjectsByPath(
+ helper_->getPreviousReferencePath(), helper_->getPreviousSplineShiftPath().path, planner_data_,
+ data, parameters_, forward_detection_range + MARGIN, debug);
for (const auto & object : object_outside_target_lane.objects) {
- ObjectData other_object;
- other_object.object = object;
+ ObjectData other_object = createObjectData(data, object);
other_object.reason = "OutOfTargetArea";
data.other_objects.push_back(other_object);
}
@@ -317,25 +340,26 @@ void AvoidanceModule::fillAvoidanceTargetObjects(
}
// Filter out the objects to determine the ones to be avoided.
- filterTargetObjects(objects, data, debug, planner_data_, parameters_);
+ filterTargetObjects(objects, data, forward_detection_range, planner_data_, parameters_);
+ updateRoadShoulderDistance(data, planner_data_, parameters_);
// Calculate the distance needed to safely decelerate the ego vehicle to a stop line.
+ const auto & vehicle_width = planner_data_->parameters.vehicle_width;
const auto feasible_stop_distance = helper_->getFeasibleDecelDistance(0.0, false);
std::for_each(data.target_objects.begin(), data.target_objects.end(), [&, this](auto & o) {
+ fillAvoidanceNecessity(o, registered_objects_, vehicle_width, parameters_);
o.to_stop_line = calcDistanceToStopLine(o);
fillObjectStoppableJudge(o, registered_objects_, feasible_stop_distance, parameters_);
});
// debug
{
- debug.current_lanelets = std::make_shared(data.current_lanelets);
-
std::vector debug_info_array;
const auto append = [&](const auto & o) {
AvoidanceDebugMsg debug_info;
debug_info.object_id = toHexString(o.object.object_id);
debug_info.longitudinal_distance = o.longitudinal;
- debug_info.lateral_distance_from_centerline = o.lateral;
+ debug_info.lateral_distance_from_centerline = o.to_centerline;
debug_info.allow_avoidance = o.reason == "";
debug_info.failed_reason = o.reason;
debug_info_array.push_back(debug_info);
@@ -379,17 +403,13 @@ ObjectData AvoidanceModule::createObjectData(
// Calc moving time.
utils::avoidance::fillObjectMovingTime(object_data, stopped_objects_, parameters_);
- // Calc lateral deviation from path to target object.
- object_data.lateral = calcLateralDeviation(object_closest_pose, object_pose.position);
-
- // Find the footprint point closest to the path, set to object_data.overhang_distance.
- object_data.overhang_dist = utils::avoidance::calcEnvelopeOverhangDistance(
- object_data, data.reference_path, object_data.overhang_pose.position);
+ // Fill init pose.
+ utils::avoidance::fillInitialPose(object_data, detected_objects_);
- // Check whether the the ego should avoid the object.
- const auto & vehicle_width = planner_data_->parameters.vehicle_width;
- utils::avoidance::fillAvoidanceNecessity(
- object_data, registered_objects_, vehicle_width, parameters_);
+ // Calc lateral deviation from path to target object.
+ object_data.direction = calcLateralDeviation(object_closest_pose, object_pose.position) > 0.0
+ ? Direction::LEFT
+ : Direction::RIGHT;
return object_data;
}
@@ -492,6 +512,8 @@ void AvoidanceModule::fillShiftLine(AvoidancePlanningData & data, DebugData & de
*/
data.comfortable = helper_->isComfortable(data.new_shift_line);
data.safe = isSafePath(data.candidate_path, debug);
+ data.ready = helper_->isReady(data.new_shift_line, path_shifter_.getLastShiftLength()) &&
+ helper_->isReady(data.target_objects);
}
void AvoidanceModule::fillEgoStatus(
@@ -607,21 +629,19 @@ void AvoidanceModule::fillDebugData(
const auto o_front = data.stop_target_object.value();
const auto object_type = utils::getHighestProbLabel(o_front.object.classification);
const auto object_parameter = parameters_->object_parameters.at(object_type);
- const auto & additional_buffer_longitudinal =
- object_parameter.use_conservative_buffer_longitudinal
- ? planner_data_->parameters.base_link2front
- : 0.0;
+ const auto constant_distance = helper_->getFrontConstantDistance(o_front);
const auto & vehicle_width = planner_data_->parameters.vehicle_width;
- const auto max_avoid_margin = object_parameter.safety_buffer_lateral * o_front.distance_factor +
- object_parameter.avoid_margin_lateral + 0.5 * vehicle_width;
+ const auto lateral_hard_margin = o_front.is_parked
+ ? object_parameter.lateral_hard_margin_for_parked_vehicle
+ : object_parameter.lateral_hard_margin;
+ const auto max_avoid_margin = lateral_hard_margin * o_front.distance_factor +
+ object_parameter.lateral_soft_margin + 0.5 * vehicle_width;
- const auto variable = helper_->getSharpAvoidanceDistance(
+ const auto avoidance_distance = helper_->getSharpAvoidanceDistance(
helper_->getShiftLength(o_front, utils::avoidance::isOnRight(o_front), max_avoid_margin));
- const auto constant = helper_->getNominalPrepareDistance() +
- object_parameter.safety_buffer_longitudinal +
- additional_buffer_longitudinal;
- const auto total_avoid_distance = variable + constant;
+ const auto prepare_distance = helper_->getNominalPrepareDistance();
+ const auto total_avoid_distance = prepare_distance + avoidance_distance + constant_distance;
dead_pose_ = calcLongitudinalOffsetPose(
data.reference_path.points, getEgoPosition(), o_front.longitudinal - total_avoid_distance);
@@ -659,13 +679,13 @@ void AvoidanceModule::updateEgoBehavior(const AvoidancePlanningData & data, Shif
}
insertPrepareVelocity(path);
+ insertAvoidanceVelocity(path);
switch (data.state) {
case AvoidanceState::NOT_AVOID: {
break;
}
case AvoidanceState::YIELD: {
- insertYieldVelocity(path);
insertWaitPoint(isBestEffort(parameters_->policy_deceleration), path);
break;
}
@@ -699,43 +719,56 @@ bool AvoidanceModule::isSafePath(
return true; // if safety check is disabled, it always return safe.
}
- const bool limit_to_max_velocity = false;
- const auto ego_predicted_path_params =
- std::make_shared(
- parameters_->ego_predicted_path_params);
- const size_t ego_seg_idx = planner_data_->findEgoSegmentIndex(shifted_path.path.points);
- const auto ego_predicted_path_for_front_object = utils::path_safety_checker::createPredictedPath(
- ego_predicted_path_params, shifted_path.path.points, getEgoPose(), getEgoSpeed(), ego_seg_idx,
- true, limit_to_max_velocity);
- const auto ego_predicted_path_for_rear_object = utils::path_safety_checker::createPredictedPath(
- ego_predicted_path_params, shifted_path.path.points, getEgoPose(), getEgoSpeed(), ego_seg_idx,
- false, limit_to_max_velocity);
-
const auto ego_idx = planner_data_->findEgoIndex(shifted_path.path.points);
- const auto is_right_shift = [&]() -> std::optional {
+
+ const auto has_left_shift = [&]() {
for (size_t i = ego_idx; i < shifted_path.shift_length.size(); i++) {
const auto length = shifted_path.shift_length.at(i);
if (parameters_->lateral_avoid_check_threshold < length) {
- return false;
+ return true;
}
+ }
+
+ return false;
+ }();
+
+ const auto has_right_shift = [&]() {
+ for (size_t i = ego_idx; i < shifted_path.shift_length.size(); i++) {
+ const auto length = shifted_path.shift_length.at(i);
if (parameters_->lateral_avoid_check_threshold < -1.0 * length) {
return true;
}
}
- return std::nullopt;
+ return false;
}();
- if (!is_right_shift.has_value()) {
+ if (!has_left_shift && !has_right_shift) {
return true;
}
const auto hysteresis_factor = safe_ ? 1.0 : parameters_->hysteresis_factor_expand_rate;
const auto safety_check_target_objects = utils::avoidance::getSafetyCheckTargetObjects(
- avoid_data_, planner_data_, parameters_, is_right_shift.value());
+ avoid_data_, planner_data_, parameters_, has_left_shift, has_right_shift, debug);
+
+ if (safety_check_target_objects.empty()) {
+ return true;
+ }
+
+ const bool limit_to_max_velocity = false;
+ const auto ego_predicted_path_params =
+ std::make_shared(
+ parameters_->ego_predicted_path_params);
+ const size_t ego_seg_idx = planner_data_->findEgoSegmentIndex(shifted_path.path.points);
+ const auto ego_predicted_path_for_front_object = utils::path_safety_checker::createPredictedPath(
+ ego_predicted_path_params, shifted_path.path.points, getEgoPose(), getEgoSpeed(), ego_seg_idx,
+ true, limit_to_max_velocity);
+ const auto ego_predicted_path_for_rear_object = utils::path_safety_checker::createPredictedPath(
+ ego_predicted_path_params, shifted_path.path.points, getEgoPose(), getEgoSpeed(), ego_seg_idx,
+ false, limit_to_max_velocity);
for (const auto & object : safety_check_target_objects) {
auto current_debug_data = utils::path_safety_checker::createObjectDebug(object);
@@ -789,15 +822,16 @@ PathWithLaneId AvoidanceModule::extendBackwardLength(const PathWithLaneId & orig
const auto longest_dist_to_shift_point = [&]() {
double max_dist = 0.0;
- for (const auto & pnt : path_shifter_.getShiftLines()) {
- max_dist = std::max(
- max_dist, calcSignedArcLength(previous_path.points, pnt.start.position, getEgoPosition()));
- }
- for (const auto & sp : generator_.getRawRegisteredShiftLine()) {
- max_dist = std::max(
- max_dist, calcSignedArcLength(previous_path.points, sp.start.position, getEgoPosition()));
+ auto lines = path_shifter_.getShiftLines();
+ if (lines.empty()) {
+ return max_dist;
}
- return max_dist;
+ std::sort(lines.begin(), lines.end(), [](const auto & a, const auto & b) {
+ return a.start_idx < b.start_idx;
+ });
+ return std::max(
+ max_dist,
+ calcSignedArcLength(previous_path.points, lines.front().start.position, getEgoPosition()));
}();
const auto extra_margin = 10.0; // Since distance does not consider arclength, but just line.
@@ -871,7 +905,7 @@ BehaviorModuleOutput AvoidanceModule::plan()
if (success_spline_path_generation && success_linear_path_generation) {
helper_->setPreviousLinearShiftPath(linear_shift_path);
helper_->setPreviousSplineShiftPath(spline_shift_path);
- helper_->setPreviousReferencePath(data.reference_path);
+ helper_->setPreviousReferencePath(path_shifter_.getReferencePath());
} else {
spline_shift_path = helper_->getPreviousSplineShiftPath();
}
@@ -884,9 +918,13 @@ BehaviorModuleOutput AvoidanceModule::plan()
BehaviorModuleOutput output;
// turn signal info
- {
+ if (path_shifter_.getShiftLines().empty()) {
+ output.turn_signal_info = getPreviousModuleOutput().turn_signal_info;
+ } else {
const auto original_signal = getPreviousModuleOutput().turn_signal_info;
- const auto new_signal = calcTurnSignalInfo(spline_shift_path);
+ const auto new_signal = utils::avoidance::calcTurnSignalInfo(
+ linear_shift_path, path_shifter_.getShiftLines().front(), helper_->getEgoShift(), avoid_data_,
+ planner_data_);
const auto current_seg_idx = planner_data_->findEgoSegmentIndex(spline_shift_path.path.points);
output.turn_signal_info = planner_data_->turn_signal_decider.use_prior_turn_signal(
spline_shift_path.path, getEgoPose(), current_seg_idx, original_signal, new_signal,
@@ -926,17 +964,34 @@ BehaviorModuleOutput AvoidanceModule::plan()
{
DrivableAreaInfo current_drivable_area_info;
// generate drivable lanes
- current_drivable_area_info.drivable_lanes = avoid_data_.drivable_lanes;
- // generate obstacle polygons
- current_drivable_area_info.obstacles =
- utils::avoidance::generateObstaclePolygonsForDrivableArea(
- avoid_data_.target_objects, parameters_, planner_data_->parameters.vehicle_width / 2.0);
+ std::for_each(
+ data.current_lanelets.begin(), data.current_lanelets.end(), [&](const auto & lanelet) {
+ current_drivable_area_info.drivable_lanes.push_back(
+ utils::avoidance::generateExpandedDrivableLanes(lanelet, planner_data_, parameters_));
+ });
// expand hatched road markings
current_drivable_area_info.enable_expanding_hatched_road_markings =
parameters_->use_hatched_road_markings;
// expand intersection areas
current_drivable_area_info.enable_expanding_intersection_areas =
parameters_->use_intersection_areas;
+ // expand freespace areas
+ current_drivable_area_info.enable_expanding_freespace_areas = parameters_->use_freespace_areas;
+ // generate obstacle polygons
+ if (parameters_->enable_bound_clipping) {
+ ObjectDataArray clip_objects;
+ // If avoidance is executed by both behavior and motion, only non-avoidable object will be
+ // extracted from the drivable area.
+ std::for_each(
+ data.target_objects.begin(), data.target_objects.end(), [&](const auto & object) {
+ if (!object.is_avoidable) clip_objects.push_back(object);
+ });
+ current_drivable_area_info.obstacles =
+ utils::avoidance::generateObstaclePolygonsForDrivableArea(
+ clip_objects, parameters_, planner_data_->parameters.vehicle_width / 2.0);
+ } else {
+ current_drivable_area_info.obstacles.clear();
+ }
output.drivable_area_info = utils::combineDrivableAreaInfo(
current_drivable_area_info, getPreviousModuleOutput().drivable_area_info);
@@ -1021,11 +1076,14 @@ void AvoidanceModule::updatePathShifter(const AvoidLineArray & shift_lines)
const auto sl = helper_->getMainShiftLine(shift_lines);
const auto sl_front = shift_lines.front();
const auto sl_back = shift_lines.back();
+ const auto relative_longitudinal = sl_back.end_longitudinal - sl_front.start_longitudinal;
if (helper_->getRelativeShiftToPath(sl) > 0.0) {
- left_shift_array_.push_back({uuid_map_.at("left"), sl_front.start, sl_back.end});
+ left_shift_array_.push_back(
+ {uuid_map_.at("left"), sl_front.start, sl_back.end, relative_longitudinal});
} else if (helper_->getRelativeShiftToPath(sl) < 0.0) {
- right_shift_array_.push_back({uuid_map_.at("right"), sl_front.start, sl_back.end});
+ right_shift_array_.push_back(
+ {uuid_map_.at("right"), sl_front.start, sl_back.end, relative_longitudinal});
}
uuid_map_.at("left") = generateUUID();
@@ -1142,15 +1200,19 @@ bool AvoidanceModule::isValidShiftLine(
const size_t start_idx = shift_lines.front().start_idx;
const size_t end_idx = shift_lines.back().end_idx;
+ const auto path = shifter_for_validate.getReferencePath();
+ const auto left_bound = lanelet::utils::to2D(toLineString3d(avoid_data_.left_bound));
+ const auto right_bound = lanelet::utils::to2D(toLineString3d(avoid_data_.right_bound));
for (size_t i = start_idx; i <= end_idx; ++i) {
- const auto p = getPoint(shifter_for_validate.getReferencePath().points.at(i));
+ const auto p = getPoint(path.points.at(i));
lanelet::BasicPoint2d basic_point{p.x, p.y};
const auto shift_length = proposed_shift_path.shift_length.at(i);
- const auto bound = shift_length > 0.0 ? avoid_data_.left_bound : avoid_data_.right_bound;
const auto THRESHOLD = minimum_distance + std::abs(shift_length);
- if (boost::geometry::distance(basic_point, lanelet::utils::to2D(bound)) < THRESHOLD) {
+ if (
+ boost::geometry::distance(basic_point, (shift_length > 0.0 ? left_bound : right_bound)) <
+ THRESHOLD) {
RCLCPP_DEBUG_THROTTLE(
getLogger(), *clock_, 1000,
"following latest new shift line may cause deviation from drivable area.");
@@ -1205,6 +1267,12 @@ void AvoidanceModule::updateData()
// update rtc status.
updateRTCData();
+ // update interest objects data
+ for (const auto & [uuid, data] : debug_data_.collision_check) {
+ const auto color = data.is_safe ? ColorName::GREEN : ColorName::RED;
+ setObjectsOfInterestData(data.current_obj_pose, data.obj_shape, color);
+ }
+
safe_ = avoid_data_.safe;
}
@@ -1229,7 +1297,6 @@ void AvoidanceModule::initVariables()
debug_marker_.markers.clear();
resetPathCandidate();
resetPathReference();
- is_avoidance_maneuver_starts = false;
arrived_path_end_ = false;
}
@@ -1266,8 +1333,8 @@ void AvoidanceModule::updateRTCData()
CandidateOutput output;
- const auto sl_front = candidates.front();
- const auto sl_back = candidates.back();
+ const auto & sl_front = candidates.front();
+ const auto & sl_back = candidates.back();
output.path_candidate = data.candidate_path.path;
output.lateral_shift = helper_->getRelativeShiftToPath(shift_line);
@@ -1277,118 +1344,6 @@ void AvoidanceModule::updateRTCData()
updateCandidateRTCStatus(output);
}
-TurnSignalInfo AvoidanceModule::calcTurnSignalInfo(const ShiftedPath & path) const
-{
- const auto shift_lines = path_shifter_.getShiftLines();
- if (shift_lines.empty()) {
- return {};
- }
-
- const auto front_shift_line = shift_lines.front();
- const size_t start_idx = front_shift_line.start_idx;
- const size_t end_idx = front_shift_line.end_idx;
-
- const auto current_shift_length = helper_->getEgoShift();
- const double start_shift_length = path.shift_length.at(start_idx);
- const double end_shift_length = path.shift_length.at(end_idx);
- const double segment_shift_length = end_shift_length - start_shift_length;
-
- const double turn_signal_shift_length_threshold =
- planner_data_->parameters.turn_signal_shift_length_threshold;
- const double turn_signal_search_time = planner_data_->parameters.turn_signal_search_time;
- const double turn_signal_minimum_search_distance =
- planner_data_->parameters.turn_signal_minimum_search_distance;
-
- // If shift length is shorter than the threshold, it does not need to turn on blinkers
- if (std::fabs(segment_shift_length) < turn_signal_shift_length_threshold) {
- return {};
- }
-
- // If the vehicle does not shift anymore, we turn off the blinker
- if (std::fabs(end_shift_length - current_shift_length) < 0.1) {
- return {};
- }
-
- // compute blinker start idx and end idx
- size_t blinker_start_idx = [&]() {
- for (size_t idx = start_idx; idx <= end_idx; ++idx) {
- const double current_shift_length = path.shift_length.at(idx);
- if (current_shift_length > 0.1) {
- return idx;
- }
- }
- return start_idx;
- }();
- size_t blinker_end_idx = end_idx;
-
- // prevent invalid access for out-of-range
- blinker_start_idx =
- std::min(std::max(std::size_t(0), blinker_start_idx), path.path.points.size() - 1);
- blinker_end_idx =
- std::min(std::max(blinker_start_idx, blinker_end_idx), path.path.points.size() - 1);
-
- const auto blinker_start_pose = path.path.points.at(blinker_start_idx).point.pose;
- const auto blinker_end_pose = path.path.points.at(blinker_end_idx).point.pose;
-
- const double ego_vehicle_offset =
- planner_data_->parameters.vehicle_info.max_longitudinal_offset_m;
- const auto signal_prepare_distance =
- std::max(getEgoSpeed() * turn_signal_search_time, turn_signal_minimum_search_distance);
- const auto ego_front_to_shift_start =
- calcSignedArcLength(path.path.points, getEgoPosition(), blinker_start_pose.position) -
- ego_vehicle_offset;
-
- if (signal_prepare_distance < ego_front_to_shift_start) {
- return {};
- }
-
- bool turn_signal_on_swerving = planner_data_->parameters.turn_signal_on_swerving;
-
- TurnSignalInfo turn_signal_info{};
- if (turn_signal_on_swerving) {
- if (segment_shift_length > 0.0) {
- turn_signal_info.turn_signal.command = TurnIndicatorsCommand::ENABLE_LEFT;
- } else {
- turn_signal_info.turn_signal.command = TurnIndicatorsCommand::ENABLE_RIGHT;
- }
- } else {
- const lanelet::ConstLanelets current_lanes = utils::getCurrentLanes(planner_data_);
- const auto local_vehicle_footprint =
- createVehicleFootprint(planner_data_->parameters.vehicle_info);
- boost::geometry::model::ring shifted_vehicle_footprint;
- for (const auto & cl : current_lanes) {
- // get left and right bounds of current lane
- const auto lane_left_bound = cl.leftBound2d().basicLineString();
- const auto lane_right_bound = cl.rightBound2d().basicLineString();
- for (size_t i = start_idx; i < end_idx; ++i) {
- // transform vehicle footprint onto path points
- shifted_vehicle_footprint = transformVector(
- local_vehicle_footprint,
- tier4_autoware_utils::pose2transform(path.path.points.at(i).point.pose));
- if (
- boost::geometry::intersects(lane_left_bound, shifted_vehicle_footprint) ||
- boost::geometry::intersects(lane_right_bound, shifted_vehicle_footprint)) {
- if (segment_shift_length > 0.0) {
- turn_signal_info.turn_signal.command = TurnIndicatorsCommand::ENABLE_LEFT;
- } else {
- turn_signal_info.turn_signal.command = TurnIndicatorsCommand::ENABLE_RIGHT;
- }
- }
- }
- }
- }
- if (ego_front_to_shift_start > 0.0) {
- turn_signal_info.desired_start_point = planner_data_->self_odometry->pose.pose;
- } else {
- turn_signal_info.desired_start_point = blinker_start_pose;
- }
- turn_signal_info.desired_end_point = blinker_end_pose;
- turn_signal_info.required_start_point = blinker_start_pose;
- turn_signal_info.required_end_point = blinker_end_pose;
-
- return turn_signal_info;
-}
-
void AvoidanceModule::updateInfoMarker(const AvoidancePlanningData & data) const
{
using marker_utils::avoidance_marker::createTargetObjectsMarkerArray;
@@ -1451,18 +1406,19 @@ double AvoidanceModule::calcDistanceToStopLine(const ObjectData & object) const
const auto object_type = utils::getHighestProbLabel(object.object.classification);
const auto object_parameter = parameters_->object_parameters.at(object_type);
- const auto avoid_margin = object_parameter.safety_buffer_lateral * object.distance_factor +
- object_parameter.avoid_margin_lateral + 0.5 * vehicle_width;
- const auto variable = helper_->getMinAvoidanceDistance(
+ const auto lateral_hard_margin = object.is_parked
+ ? object_parameter.lateral_hard_margin_for_parked_vehicle
+ : object_parameter.lateral_hard_margin;
+ const auto avoid_margin = lateral_hard_margin * object.distance_factor +
+ object_parameter.lateral_soft_margin + 0.5 * vehicle_width;
+ const auto avoidance_distance = helper_->getMinAvoidanceDistance(
helper_->getShiftLength(object, utils::avoidance::isOnRight(object), avoid_margin));
- const auto & additional_buffer_longitudinal =
- object_parameter.use_conservative_buffer_longitudinal
- ? planner_data_->parameters.base_link2front
- : 0.0;
- const auto constant = p->min_prepare_distance + object_parameter.safety_buffer_longitudinal +
- additional_buffer_longitudinal + p->stop_buffer;
-
- return object.longitudinal - std::min(variable + constant, p->stop_max_distance);
+ const auto constant_distance = helper_->getFrontConstantDistance(object);
+
+ return object.longitudinal -
+ std::min(
+ avoidance_distance + constant_distance + p->min_prepare_distance + p->stop_buffer,
+ p->stop_max_distance);
}
void AvoidanceModule::insertReturnDeadLine(
@@ -1489,7 +1445,8 @@ void AvoidanceModule::insertReturnDeadLine(
shifted_path.path.points, getEgoPosition(), shifted_path.path.points.size() - 1);
const auto buffer = std::max(0.0, to_shifted_path_end - to_reference_path_end);
- const auto min_return_distance = helper_->getMinAvoidanceDistance(shift_length);
+ const auto min_return_distance =
+ helper_->getMinAvoidanceDistance(shift_length) + helper_->getMinimumPrepareDistance();
const auto to_stop_line = data.to_return_point - min_return_distance - buffer;
// If we don't need to consider deceleration constraints, insert a deceleration point
@@ -1545,6 +1502,11 @@ void AvoidanceModule::insertWaitPoint(
{
const auto & data = avoid_data_;
+ // If avoidance path is NOT valid, don't insert any stop points.
+ if (!data.valid) {
+ return;
+ }
+
if (!data.stop_target_object) {
return;
}
@@ -1631,28 +1593,20 @@ void AvoidanceModule::insertStopPoint(
getEgoPosition(), stop_distance - MARGIN, 0.0, shifted_path.path, stop_pose_);
}
-void AvoidanceModule::insertYieldVelocity(ShiftedPath & shifted_path) const
+void AvoidanceModule::insertPrepareVelocity(ShiftedPath & shifted_path) const
{
- const auto & p = parameters_;
const auto & data = avoid_data_;
- if (data.target_objects.empty()) {
+ // If avoidance path is NOT safe, don't insert any slow down sections.
+ if (!data.safe && !data.stop_target_object) {
return;
}
- if (helper_->isShifted()) {
+ // If avoidance path is NOT safe, don't insert any slow down sections.
+ if (!data.valid) {
return;
}
- const auto decel_distance = helper_->getFeasibleDecelDistance(p->yield_velocity, false);
- utils::avoidance::insertDecelPoint(
- getEgoPosition(), decel_distance, p->yield_velocity, shifted_path.path, slow_pose_);
-}
-
-void AvoidanceModule::insertPrepareVelocity(ShiftedPath & shifted_path) const
-{
- const auto & data = avoid_data_;
-
// do nothing if there is no avoidance target.
if (data.target_objects.empty()) {
return;
@@ -1668,26 +1622,48 @@ void AvoidanceModule::insertPrepareVelocity(ShiftedPath & shifted_path) const
return;
}
- const auto object = data.target_objects.front();
+ const auto itr = std::find_if(
+ data.target_objects.begin(), data.target_objects.end(),
+ [](const auto & o) { return o.avoid_required; });
+
+ const auto object = [&]() -> std::optional {
+ if (!data.yield_required) {
+ return data.target_objects.front();
+ }
+
+ if (itr == data.target_objects.end()) {
+ return std::nullopt;
+ }
+
+ return *itr;
+ }();
+
+ // do nothing if it can't avoid at the moment and avoidance is NOT definitely necessary.
+ if (!object.has_value()) {
+ return;
+ }
const auto enough_space =
- object.is_avoidable || object.reason == AvoidanceDebugFactor::TOO_LARGE_JERK;
+ object.value().is_avoidable || object.value().reason == AvoidanceDebugFactor::TOO_LARGE_JERK;
if (!enough_space) {
return;
}
// calculate shift length for front object.
const auto & vehicle_width = planner_data_->parameters.vehicle_width;
- const auto object_type = utils::getHighestProbLabel(object.object.classification);
+ const auto object_type = utils::getHighestProbLabel(object.value().object.classification);
const auto object_parameter = parameters_->object_parameters.at(object_type);
- const auto avoid_margin = object_parameter.safety_buffer_lateral * object.distance_factor +
- object_parameter.avoid_margin_lateral + 0.5 * vehicle_width;
- const auto shift_length =
- helper_->getShiftLength(object, utils::avoidance::isOnRight(object), avoid_margin);
+ const auto lateral_hard_margin = object.value().is_parked
+ ? object_parameter.lateral_hard_margin_for_parked_vehicle
+ : object_parameter.lateral_hard_margin;
+ const auto avoid_margin = lateral_hard_margin * object.value().distance_factor +
+ object_parameter.lateral_soft_margin + 0.5 * vehicle_width;
+ const auto shift_length = helper_->getShiftLength(
+ object.value(), utils::avoidance::isOnRight(object.value()), avoid_margin);
// check slow down feasibility
const auto min_avoid_distance = helper_->getMinAvoidanceDistance(shift_length);
- const auto distance_to_object = object.longitudinal;
+ const auto distance_to_object = object.value().longitudinal;
const auto remaining_distance = distance_to_object - min_avoid_distance;
const auto decel_distance = helper_->getFeasibleDecelDistance(parameters_->velocity_map.front());
if (remaining_distance < decel_distance) {
@@ -1695,7 +1671,7 @@ void AvoidanceModule::insertPrepareVelocity(ShiftedPath & shifted_path) const
}
// decide slow down lower limit.
- const auto lower_speed = object.avoid_required ? 0.0 : parameters_->min_slow_down_speed;
+ const auto lower_speed = object.value().avoid_required ? 0.0 : parameters_->min_slow_down_speed;
// insert slow down speed.
const double current_target_velocity = PathShifter::calcFeasibleVelocityFromJerk(
@@ -1730,6 +1706,52 @@ void AvoidanceModule::insertPrepareVelocity(ShiftedPath & shifted_path) const
shifted_path.path.points, start_idx, distance_to_object);
}
+void AvoidanceModule::insertAvoidanceVelocity(ShiftedPath & shifted_path) const
+{
+ const auto & data = avoid_data_;
+
+ // do nothing if no shift line is approved.
+ if (path_shifter_.getShiftLines().empty()) {
+ return;
+ }
+
+ // do nothing if there is no avoidance target.
+ if (data.target_objects.empty()) {
+ return;
+ }
+
+ const auto [distance_to_accel_end_point, v_max] =
+ helper_->getDistanceToAccelEndPoint(shifted_path.path);
+ if (distance_to_accel_end_point < 1e-3) {
+ return;
+ }
+
+ const auto start_idx = planner_data_->findEgoIndex(shifted_path.path.points);
+ for (size_t i = start_idx; i < shifted_path.path.points.size(); ++i) {
+ const auto distance_from_ego = calcSignedArcLength(shifted_path.path.points, start_idx, i);
+
+ // slow down speed is inserted only in front of the object.
+ const auto accel_distance = distance_to_accel_end_point - distance_from_ego;
+ if (accel_distance < 0.0) {
+ break;
+ }
+
+ const double v_target_square =
+ v_max * v_max - 2.0 * parameters_->max_acceleration * accel_distance;
+ if (v_target_square < 1e-3) {
+ break;
+ }
+
+ // target speed with nominal jerk limits.
+ const double v_target = std::max(getEgoSpeed(), std::sqrt(v_target_square));
+ const double v_original = shifted_path.path.points.at(i).point.longitudinal_velocity_mps;
+ shifted_path.path.points.at(i).point.longitudinal_velocity_mps = std::min(v_original, v_target);
+ }
+
+ slow_pose_ = motion_utils::calcLongitudinalOffsetPose(
+ shifted_path.path.points, start_idx, distance_to_accel_end_point);
+}
+
std::shared_ptr AvoidanceModule::get_debug_msg_array() const
{
debug_data_.avoidance_debug_msg_array.header.stamp = clock_->now();
diff --git a/planning/behavior_path_avoidance_module/src/shift_line_generator.cpp b/planning/behavior_path_avoidance_module/src/shift_line_generator.cpp
index 4332008b95e70..5a8fd35f6d618 100644
--- a/planning/behavior_path_avoidance_module/src/shift_line_generator.cpp
+++ b/planning/behavior_path_avoidance_module/src/shift_line_generator.cpp
@@ -19,7 +19,7 @@
#include
-#include
+#include
namespace behavior_path_planner::utils::avoidance
{
@@ -81,7 +81,9 @@ AvoidLineArray toArray(const AvoidOutlines & outlines)
AvoidLineArray ret{};
for (const auto & outline : outlines) {
ret.push_back(outline.avoid_line);
- ret.push_back(outline.return_line);
+ if (outline.return_line.has_value()) {
+ ret.push_back(outline.return_line.value());
+ }
std::for_each(
outline.middle_lines.begin(), outline.middle_lines.end(),
@@ -121,7 +123,6 @@ AvoidOutlines ShiftLineGenerator::generateAvoidOutline(
{
// To be consistent with changes in the ego position, the current shift length is considered.
const auto current_ego_shift = helper_->getEgoShift();
- const auto & base_link2rear = data_->parameters.base_link2rear;
// Calculate feasible shift length
const auto get_shift_profile =
@@ -138,13 +139,10 @@ AvoidOutlines ShiftLineGenerator::generateAvoidOutline(
// calculate remaining distance.
const auto prepare_distance = helper_->getNominalPrepareDistance();
- const auto & additional_buffer_longitudinal =
- object_parameter.use_conservative_buffer_longitudinal ? data_->parameters.base_link2front
- : 0.0;
- const auto constant = object_parameter.safety_buffer_longitudinal +
- additional_buffer_longitudinal + prepare_distance;
- const auto has_enough_distance = object.longitudinal > constant + nominal_avoid_distance;
- const auto remaining_distance = object.longitudinal - constant;
+ const auto constant_distance = helper_->getFrontConstantDistance(object);
+ const auto has_enough_distance =
+ object.longitudinal > constant_distance + prepare_distance + nominal_avoid_distance;
+ const auto remaining_distance = object.longitudinal - constant_distance - prepare_distance;
const auto avoidance_distance =
has_enough_distance ? nominal_avoid_distance : remaining_distance;
@@ -183,29 +181,36 @@ AvoidOutlines ShiftLineGenerator::generateAvoidOutline(
}
// prepare distance is not enough. unavoidable.
- if (remaining_distance < 1e-3) {
+ if (avoidance_distance < 1e-3) {
object.reason = AvoidanceDebugFactor::REMAINING_DISTANCE_LESS_THAN_ZERO;
return std::nullopt;
}
// calculate lateral jerk.
const auto required_jerk = PathShifter::calcJerkFromLatLonDistance(
- avoiding_shift, remaining_distance, helper_->getAvoidanceEgoSpeed());
+ avoiding_shift, avoidance_distance, helper_->getAvoidanceEgoSpeed());
// relax lateral jerk limit. avoidable.
if (required_jerk < helper_->getLateralMaxJerkLimit()) {
return std::make_pair(desire_shift_length, avoidance_distance);
}
+ constexpr double LON_DIST_BUFFER = 1e-3;
+
// avoidance distance is not enough. unavoidable.
if (!isBestEffort(parameters_->policy_deceleration)) {
- object.reason = AvoidanceDebugFactor::TOO_LARGE_JERK;
- return std::nullopt;
+ if (avoidance_distance < helper_->getMinAvoidanceDistance(avoiding_shift) + LON_DIST_BUFFER) {
+ object.reason = AvoidanceDebugFactor::REMAINING_DISTANCE_LESS_THAN_ZERO;
+ return std::nullopt;
+ } else {
+ object.reason = AvoidanceDebugFactor::TOO_LARGE_JERK;
+ return std::nullopt;
+ }
}
// output avoidance path under lateral jerk constraints.
const auto feasible_relative_shift_length = PathShifter::calcLateralDistFromJerk(
- remaining_distance, helper_->getLateralMaxJerkLimit(), helper_->getAvoidanceEgoSpeed());
+ avoidance_distance, helper_->getLateralMaxJerkLimit(), helper_->getAvoidanceEgoSpeed());
if (std::abs(feasible_relative_shift_length) < parameters_->lateral_execution_threshold) {
object.reason = "LessThanExecutionThreshold";
@@ -216,16 +221,28 @@ AvoidOutlines ShiftLineGenerator::generateAvoidOutline(
desire_shift_length > 0.0 ? feasible_relative_shift_length + current_ego_shift
: -1.0 * feasible_relative_shift_length + current_ego_shift;
+ if (
+ avoidance_distance <
+ helper_->getMinAvoidanceDistance(feasible_shift_length) + LON_DIST_BUFFER) {
+ object.reason = AvoidanceDebugFactor::REMAINING_DISTANCE_LESS_THAN_ZERO;
+ return std::nullopt;
+ }
+
+ const double LAT_DIST_BUFFER = desire_shift_length > 0.0 ? 1e-3 : -1e-3;
+
+ const auto lateral_hard_margin = object.is_parked
+ ? object_parameter.lateral_hard_margin_for_parked_vehicle
+ : object_parameter.lateral_hard_margin;
const auto infeasible =
- std::abs(feasible_shift_length - object.overhang_dist) <
- 0.5 * data_->parameters.vehicle_width + object_parameter.safety_buffer_lateral;
+ std::abs(feasible_shift_length - object.overhang_points.front().first) - LAT_DIST_BUFFER <
+ 0.5 * data_->parameters.vehicle_width + lateral_hard_margin;
if (infeasible) {
RCLCPP_DEBUG(rclcpp::get_logger(""), "feasible shift length is not enough to avoid. ");
object.reason = AvoidanceDebugFactor::TOO_LARGE_JERK;
return std::nullopt;
}
- return std::make_pair(feasible_shift_length, avoidance_distance);
+ return std::make_pair(feasible_shift_length - LAT_DIST_BUFFER, avoidance_distance);
};
const auto is_forward_object = [](const auto & object) { return object.longitudinal > 0.0; };
@@ -257,11 +274,8 @@ AvoidOutlines ShiftLineGenerator::generateAvoidOutline(
}
}
- // use each object param
- const auto object_type = utils::getHighestProbLabel(o.object.classification);
- const auto object_parameter = parameters_->object_parameters.at(object_type);
+ // calculate feasible shift length based on behavior policy
const auto feasible_shift_profile = get_shift_profile(o, desire_shift_length);
-
if (!feasible_shift_profile.has_value()) {
if (o.avoid_required && is_forward_object(o)) {
break;
@@ -276,12 +290,8 @@ AvoidOutlines ShiftLineGenerator::generateAvoidOutline(
AvoidLine al_avoid;
{
- const auto & additional_buffer_longitudinal =
- object_parameter.use_conservative_buffer_longitudinal ? data_->parameters.base_link2front
- : 0.0;
- const auto offset =
- object_parameter.safety_buffer_longitudinal + additional_buffer_longitudinal;
- const auto to_shift_end = o.longitudinal - offset;
+ const auto constant_distance = helper_->getFrontConstantDistance(o);
+ const auto to_shift_end = o.longitudinal - constant_distance;
const auto path_front_to_ego = data.arclength_from_ego.at(data.ego_closest_path_index);
// start point (use previous linear shift length as start shift length.)
@@ -317,8 +327,8 @@ AvoidOutlines ShiftLineGenerator::generateAvoidOutline(
AvoidLine al_return;
{
- const auto offset = object_parameter.safety_buffer_longitudinal + base_link2rear + o.length;
- const auto to_shift_start = o.longitudinal + offset;
+ const auto constant_distance = helper_->getRearConstantDistance(o);
+ const auto to_shift_start = o.longitudinal + constant_distance;
// start point
al_return.start_shift_length = feasible_shift_profile.value().first;
@@ -341,7 +351,30 @@ AvoidOutlines ShiftLineGenerator::generateAvoidOutline(
al_return.object_on_right = utils::avoidance::isOnRight(o);
}
- if (is_valid_shift_line(al_avoid) && is_valid_shift_line(al_return)) {
+ const bool skip_return_shift = [&]() {
+ if (!utils::isAllowedGoalModification(data_->route_handler)) {
+ return false;
+ }
+ const auto goal_pose = data_->route_handler->getGoalPose();
+ const double goal_longitudinal_distance =
+ motion_utils::calcSignedArcLength(data.reference_path.points, 0, goal_pose.position);
+ const bool is_return_shift_to_goal =
+ std::abs(al_return.end_longitudinal - goal_longitudinal_distance) <
+ parameters_->object_check_return_pose_distance;
+ if (is_return_shift_to_goal) {
+ return true;
+ }
+ const auto & object_pos = o.object.kinematics.initial_pose_with_covariance.pose.position;
+ const bool has_object_near_goal =
+ tier4_autoware_utils::calcDistance2d(goal_pose.position, object_pos) <
+ parameters_->object_check_goal_distance;
+ return has_object_near_goal;
+ }();
+
+ if (skip_return_shift) {
+ // if the object is close to goal or ego is about to return near GOAL, do not return
+ outlines.emplace_back(al_avoid, std::nullopt);
+ } else if (is_valid_shift_line(al_avoid) && is_valid_shift_line(al_return)) {
outlines.emplace_back(al_avoid, al_return);
} else {
o.reason = "InvalidShiftLine";
@@ -637,35 +670,43 @@ AvoidOutlines ShiftLineGenerator::applyMergeProcess(
auto & next_outline = outlines.at(i);
const auto & return_line = last_outline.return_line;
- const auto & avoid_line = next_outline.avoid_line;
+ if (!return_line.has_value()) {
+ ret.push_back(outlines.at(i));
+ break;
+ }
- if (no_conflict(return_line, avoid_line)) {
+ const auto & avoid_line = next_outline.avoid_line;
+ if (no_conflict(return_line.value(), avoid_line)) {
ret.push_back(outlines.at(i));
continue;
}
- const auto merged_shift_line = merge(return_line, avoid_line, generateUUID());
+ const auto merged_shift_line = merge(return_line.value(), avoid_line, generateUUID());
if (!helper_->isComfortable(AvoidLineArray{merged_shift_line})) {
ret.push_back(outlines.at(i));
continue;
}
- if (same_side_shift(return_line, avoid_line)) {
+ if (same_side_shift(return_line.value(), avoid_line)) {
last_outline.middle_lines.push_back(merged_shift_line);
last_outline.return_line = next_outline.return_line;
debug.step1_merged_shift_line.push_back(merged_shift_line);
continue;
}
- if (within(return_line, avoid_line.end_idx) && within(avoid_line, return_line.start_idx)) {
+ if (
+ within(return_line.value(), avoid_line.end_idx) &&
+ within(avoid_line, return_line->start_idx)) {
last_outline.middle_lines.push_back(merged_shift_line);
last_outline.return_line = next_outline.return_line;
debug.step1_merged_shift_line.push_back(merged_shift_line);
continue;
}
- if (within(return_line, avoid_line.start_idx) && within(avoid_line, return_line.end_idx)) {
+ if (
+ within(return_line.value(), avoid_line.start_idx) &&
+ within(avoid_line, return_line->end_idx)) {
last_outline.middle_lines.push_back(merged_shift_line);
last_outline.return_line = next_outline.return_line;
debug.step1_merged_shift_line.push_back(merged_shift_line);
@@ -686,7 +727,10 @@ AvoidOutlines ShiftLineGenerator::applyFillGapProcess(
for (auto & outline : ret) {
if (outline.middle_lines.empty()) {
- const auto new_line = fill(outline.avoid_line, outline.return_line, generateUUID());
+ const auto new_line =
+ outline.return_line.has_value()
+ ? fill(outline.avoid_line, outline.return_line.value(), generateUUID())
+ : outline.avoid_line;
outline.middle_lines.push_back(new_line);
debug.step1_filled_shift_line.push_back(new_line);
}
@@ -701,8 +745,11 @@ AvoidOutlines ShiftLineGenerator::applyFillGapProcess(
helper_->alignShiftLinesOrder(outline.middle_lines, false);
- if (outline.middle_lines.back().end_longitudinal < outline.return_line.start_longitudinal) {
- const auto new_line = fill(outline.middle_lines.back(), outline.return_line, generateUUID());
+ if (
+ outline.return_line.has_value() &&
+ outline.middle_lines.back().end_longitudinal < outline.return_line->start_longitudinal) {
+ const auto new_line =
+ fill(outline.middle_lines.back(), outline.return_line.value(), generateUUID());
outline.middle_lines.push_back(new_line);
debug.step1_filled_shift_line.push_back(new_line);
}
@@ -890,7 +937,7 @@ void ShiftLineGenerator::applySmallShiftFilter(
continue;
}
- if (s.start_longitudinal < helper_->getMinimumPrepareDistance()) {
+ if (s.start_longitudinal + 1e-3 < helper_->getMinimumPrepareDistance()) {
continue;
}
@@ -973,6 +1020,20 @@ AvoidLineArray ShiftLineGenerator::addReturnShiftLine(
const bool has_candidate_point = !ret.empty();
const bool has_registered_point = last_.has_value();
+ if (utils::isAllowedGoalModification(data_->route_handler)) {
+ const auto has_object_near_goal =
+ std::any_of(data.target_objects.begin(), data.target_objects.end(), [&](const auto & o) {
+ return tier4_autoware_utils::calcDistance2d(
+ data_->route_handler->getGoalPose().position,
+ o.object.kinematics.initial_pose_with_covariance.pose.position) <
+ parameters_->object_check_goal_distance;
+ });
+ if (has_object_near_goal) {
+ RCLCPP_DEBUG(rclcpp::get_logger(""), "object near goal exists so skip adding return shift");
+ return ret;
+ }
+ }
+
const auto exist_unavoidable_object = std::any_of(
data.target_objects.begin(), data.target_objects.end(),
[](const auto & o) { return !o.is_avoidable && o.longitudinal > 0.0; });
@@ -1027,6 +1088,21 @@ AvoidLineArray ShiftLineGenerator::addReturnShiftLine(
}
}
+ // if last shift line is near the objects, do not add return shift.
+ if (utils::isAllowedGoalModification(data_->route_handler)) {
+ const bool has_last_shift_near_goal =
+ std::any_of(data.target_objects.begin(), data.target_objects.end(), [&](const auto & o) {
+ return tier4_autoware_utils::calcDistance2d(
+ last_sl.end.position,
+ o.object.kinematics.initial_pose_with_covariance.pose.position) <
+ parameters_->object_check_goal_distance;
+ });
+ if (has_last_shift_near_goal) {
+ RCLCPP_DEBUG(rclcpp::get_logger(""), "last shift line is near the objects");
+ return ret;
+ }
+ }
+
// There already is a shift point candidates to go back to center line, but it could be too sharp
// due to detection noise or timing.
// Here the return-shift from ego is added for the in case.
@@ -1070,8 +1146,11 @@ AvoidLineArray ShiftLineGenerator::addReturnShiftLine(
return ret;
}
- const auto remaining_distance = std::min(
- arclength_from_ego.back() - parameters_->dead_line_buffer_for_goal, data.to_return_point);
+ const auto remaining_distance =
+ utils::isAllowedGoalModification(data_->route_handler)
+ ? data.to_return_point
+ : std::min(
+ arclength_from_ego.back() - parameters_->dead_line_buffer_for_goal, data.to_return_point);
// If the avoidance point has already been set, the return shift must be set after the point.
const auto last_sl_distance = data.arclength_from_ego.at(last_sl.end_idx);
@@ -1101,12 +1180,14 @@ AvoidLineArray ShiftLineGenerator::addReturnShiftLine(
const double variable_prepare_distance =
std::max(nominal_prepare_distance - last_sl_distance, 0.0);
- double prepare_distance_scaled = std::max(nominal_prepare_distance, last_sl_distance);
+ double prepare_distance_scaled = std::max(
+ helper_->getMinimumPrepareDistance(), std::max(nominal_prepare_distance, last_sl_distance));
double avoid_distance_scaled = nominal_avoid_distance;
if (remaining_distance < prepare_distance_scaled + avoid_distance_scaled) {
const auto scale = (remaining_distance - last_sl_distance) /
std::max(nominal_avoid_distance + variable_prepare_distance, 0.1);
- prepare_distance_scaled = last_sl_distance + scale * nominal_prepare_distance;
+ prepare_distance_scaled = std::max(
+ helper_->getMinimumPrepareDistance(), last_sl_distance + scale * nominal_prepare_distance);
avoid_distance_scaled *= scale;
}
@@ -1120,7 +1201,7 @@ AvoidLineArray ShiftLineGenerator::addReturnShiftLine(
al.end_idx =
utils::avoidance::findPathIndexFromArclength(arclength_from_ego, prepare_distance_scaled);
al.end = data.reference_path.points.at(al.end_idx).point.pose;
- al.end_longitudinal = arclength_from_ego.at(al.end_idx);
+ al.end_longitudinal = prepare_distance_scaled;
al.end_shift_length = last_sl.end_shift_length;
al.start_shift_length = last_sl.end_shift_length;
ret.push_back(al);
@@ -1134,7 +1215,7 @@ AvoidLineArray ShiftLineGenerator::addReturnShiftLine(
al.start_idx =
utils::avoidance::findPathIndexFromArclength(arclength_from_ego, prepare_distance_scaled);
al.start = data.reference_path.points.at(al.start_idx).point.pose;
- al.start_longitudinal = arclength_from_ego.at(al.start_idx);
+ al.start_longitudinal = prepare_distance_scaled;
al.end_idx = utils::avoidance::findPathIndexFromArclength(
arclength_from_ego, prepare_distance_scaled + avoid_distance_scaled);
al.end = data.reference_path.points.at(al.end_idx).point.pose;
@@ -1219,7 +1300,7 @@ AvoidLineArray ShiftLineGenerator::findNewShiftLine(
const auto & candidate = shift_lines.at(i);
// prevent sudden steering.
- if (candidate.start_longitudinal < helper_->getMinimumPrepareDistance()) {
+ if (candidate.start_longitudinal + 1e-3 < helper_->getMinimumPrepareDistance()) {
break;
}
diff --git a/planning/behavior_path_avoidance_module/src/utils.cpp b/planning/behavior_path_avoidance_module/src/utils.cpp
index fd120bdd8a069..ee1d2dd8726fd 100644
--- a/planning/behavior_path_avoidance_module/src/utils.cpp
+++ b/planning/behavior_path_avoidance_module/src/utils.cpp
@@ -16,34 +16,31 @@
#include "behavior_path_avoidance_module/data_structs.hpp"
#include "behavior_path_avoidance_module/utils.hpp"
+#include "behavior_path_planner_common/utils/create_vehicle_footprint.hpp"
+#include "behavior_path_planner_common/utils/drivable_area_expansion/static_drivable_area.hpp"
#include "behavior_path_planner_common/utils/path_safety_checker/objects_filtering.hpp"
#include "behavior_path_planner_common/utils/path_utils.hpp"
#include "behavior_path_planner_common/utils/traffic_light_utils.hpp"
#include "tier4_autoware_utils/geometry/boost_polygon_utils.hpp"
-#include
-#include
-#include
+#include