Skip to content

Commit

Permalink
feat(avoidance/goal_planner): execute avoidance and pull over simulta…
Browse files Browse the repository at this point in the history
…neously

Signed-off-by: kosuke55 <[email protected]>

tmp

Signed-off-by: kosuke55 <[email protected]>

tmp

Signed-off-by: kosuke55 <[email protected]>

tmp

Signed-off-by: kosuke55 <[email protected]>

tmp

tmp

Signed-off-by: kosuke55 <[email protected]>

tmp

Signed-off-by: kosuke55 <[email protected]>

fix

tmp

Signed-off-by: kosuke55 <[email protected]>

feat(mission_planner): check shoulder lanelets for check_goal_footprint

Signed-off-by: kosuke55 <[email protected]>

tmp

Signed-off-by: kosuke55 <[email protected]>

tmp

tmp
  • Loading branch information
kosuke55 committed Jan 11, 2024
1 parent 9b736d5 commit 8f66df0
Show file tree
Hide file tree
Showing 19 changed files with 500 additions and 104 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ void AvoidanceByLaneChangeModuleManager::init(rclcpp::Node * node)

p.object_check_goal_distance =
getOrDeclareParameter<double>(*node, ns + "object_check_goal_distance");
p.object_check_return_pose_distance =
getOrDeclareParameter<double>(*node, ns + "object_check_return_pose_distance");

Check warning on line 123 in planning/behavior_path_avoidance_by_lane_change_module/src/manager.cpp

View check run for this annotation

CodeScene Delta Analysis / CodeScene Cloud Delta Analysis (main)

❌ Getting worse: Large Method

AvoidanceByLaneChangeModuleManager::init increases from 123 to 125 lines of code, threshold = 70. Large functions with many lines of code are generally harder to understand and lower the code health. Avoid adding more lines to this function.
p.threshold_distance_object_is_on_center =
getOrDeclareParameter<double>(*node, ns + "threshold_distance_object_is_on_center");
p.object_check_shiftable_ratio =
Expand Down
5 changes: 4 additions & 1 deletion planning/behavior_path_avoidance_module/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -833,7 +833,10 @@ namespace: `avoidance.target_filtering.`
| object_ignore_section_crosswalk_behind_distance | [m] | double | If the back distance between crosswalk and vehicle is less than this parameter, this module will ignore it. | 30.0 |
| object_check_forward_distance | [m] | double | Forward distance to search the avoidance target. | 150.0 |
| object_check_backward_distance | [m] | double | Backward distance to search the avoidance target. | 2.0 |
| object_check_goal_distance | [m] | double | Backward distance to search the avoidance target. | 20.0 |
| object_check_goal_distance | [m] | double | If the distance between object and goal position is less than this parameter, the module do not |
| return center line target. | 20.0 |
| object_check_return_pose_distance | [m] | double | If the distance between object and return position is less than this parameter, the module do |
| // not return center line target. | 20.0 |
| object_check_shiftable_ratio | [m] | double | Vehicles around the center line within this distance will be excluded from avoidance target. | 0.6 |
| object_check_min_road_shoulder_width | [m] | double | Width considered as a road shoulder if the lane does not have a road shoulder target. | 0.5 |
| object_last_seen_threshold | [s] | double | For the compensation of the detection lost. The object is registered once it is observed as an avoidance target. When the detection loses, the timer will start and the object will be un-registered when the time exceeds this limit. | 2.0 |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,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 # [-]
Expand Down Expand Up @@ -215,9 +216,6 @@
nominal_avoidance_speed: 8.33 # [m/s]
# return dead line
return_dead_line:
goal:
enable: true # [-]
buffer: 30.0 # [m]
traffic_light:
enable: true # [-]
buffer: 3.0 # [m]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,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};

Expand Down Expand Up @@ -462,14 +466,14 @@ using AvoidLineArray = std::vector<AvoidLine>;

struct AvoidOutline
{
AvoidOutline(AvoidLine avoid_line, AvoidLine return_line)
AvoidOutline(AvoidLine avoid_line, const std::optional<AvoidLine> return_line)
: avoid_line{std::move(avoid_line)}, return_line{std::move(return_line)}
{
}

AvoidLine avoid_line{};

AvoidLine return_line{};
std::optional<AvoidLine> return_line{};

AvoidLineArray middle_lines{};
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ AvoidanceParameters getParameter(rclcpp::Node * node)

p.object_check_goal_distance =
getOrDeclareParameter<double>(*node, ns + "object_check_goal_distance");
p.object_check_return_pose_distance =
getOrDeclareParameter<double>(*node, ns + "object_check_return_pose_distance");
p.threshold_distance_object_is_on_center =
getOrDeclareParameter<double>(*node, ns + "threshold_distance_object_is_on_center");
p.object_check_shiftable_ratio =
Expand Down Expand Up @@ -270,10 +272,8 @@ AvoidanceParameters getParameter(rclcpp::Node * node)
// avoidance maneuver (return shift dead line)
{
const std::string ns = "avoidance.avoidance.return_dead_line.";
p.enable_dead_line_for_goal = getOrDeclareParameter<bool>(*node, ns + "goal.enable");
p.enable_dead_line_for_traffic_light =
getOrDeclareParameter<bool>(*node, ns + "traffic_light.enable");
p.dead_line_buffer_for_goal = getOrDeclareParameter<double>(*node, ns + "goal.buffer");
p.dead_line_buffer_for_traffic_light =
getOrDeclareParameter<double>(*node, ns + "traffic_light.buffer");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down Expand Up @@ -341,7 +343,20 @@ 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 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 return_to_goal = std::abs(al_return.end_longitudinal - goal_longitudinal_distance) <
parameters_->object_check_return_pose_distance;

const auto & object_pos = o.object.kinematics.initial_pose_with_covariance.pose.position;
const bool is_near_goal = tier4_autoware_utils::calcDistance2d(goal_pose.position, object_pos) <
parameters_->object_check_goal_distance;

if (is_near_goal || return_to_goal) {
// if the object is close to goal or ego is about to return near GOAL, do not reuturn
outlines.emplace_back(al_avoid, std::nullopt);
} else if (is_valid_shift_line(al_avoid) && is_valid_shift_line(al_return)) {

Check warning on line 359 in planning/behavior_path_avoidance_module/src/shift_line_generator.cpp

View check run for this annotation

CodeScene Delta Analysis / CodeScene Cloud Delta Analysis (main)

❌ Getting worse: Complex Method

ShiftLineGenerator::generateAvoidOutline increases in cyclomatic complexity from 43 to 45, threshold = 9. This function has many conditional statements (e.g. if, for, while), leading to lower code health. Avoid adding more conditionals and code to it without refactoring.
outlines.emplace_back(al_avoid, al_return);
} else {
o.reason = "InvalidShiftLine";
Expand Down Expand Up @@ -637,35 +652,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)) {

Check warning on line 691 in planning/behavior_path_avoidance_module/src/shift_line_generator.cpp

View check run for this annotation

CodeScene Delta Analysis / CodeScene Cloud Delta Analysis (main)

❌ Getting worse: Complex Method

ShiftLineGenerator::applyMergeProcess increases in cyclomatic complexity from 17 to 18, threshold = 9. This function has many conditional statements (e.g. if, for, while), leading to lower code health. Avoid adding more conditionals and code to it without refactoring.
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);
Expand All @@ -686,7 +709,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);
}
Expand All @@ -701,8 +727,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);
}
Expand Down Expand Up @@ -973,6 +1002,18 @@ AvoidLineArray ShiftLineGenerator::addReturnShiftLine(
const bool has_candidate_point = !ret.empty();
const bool has_registered_point = last_.has_value();

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; });
Expand Down Expand Up @@ -1027,6 +1068,17 @@ AvoidLineArray ShiftLineGenerator::addReturnShiftLine(
}
}

// if last shift line is near the objects, do not add return shift.
if (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;
})) {
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.
Expand Down Expand Up @@ -1070,8 +1122,7 @@ 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 = data.to_return_point;

Check warning on line 1125 in planning/behavior_path_avoidance_module/src/shift_line_generator.cpp

View check run for this annotation

CodeScene Delta Analysis / CodeScene Cloud Delta Analysis (main)

❌ Getting worse: Complex Method

ShiftLineGenerator::addReturnShiftLine increases in cyclomatic complexity from 28 to 30, threshold = 9. This function has many conditional statements (e.g. if, for, while), leading to lower code health. Avoid adding more conditionals and code to it without refactoring.

// 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);
Expand Down
22 changes: 3 additions & 19 deletions planning/behavior_path_avoidance_module/src/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -678,13 +678,6 @@ bool isSatisfiedWithCommonCondition(
return false;
}

if (
object.longitudinal + object.length / 2 + parameters->object_check_goal_distance >
to_goal_distance) {
object.reason = "TooNearToGoal";
return false;
}

return true;
}

Expand Down Expand Up @@ -1663,7 +1656,9 @@ void fillAdditionalInfoFromLongitudinal(
{
for (auto & outline : outlines) {
fillAdditionalInfoFromLongitudinal(data, outline.avoid_line);
fillAdditionalInfoFromLongitudinal(data, outline.return_line);
if (outline.return_line.has_value()) {
fillAdditionalInfoFromLongitudinal(data, outline.return_line.value());
}

std::for_each(outline.middle_lines.begin(), outline.middle_lines.end(), [&](auto & line) {
fillAdditionalInfoFromLongitudinal(data, line);
Expand Down Expand Up @@ -2145,17 +2140,6 @@ double calcDistanceToReturnDeadLine(
}
}

Check notice on line 2142 in planning/behavior_path_avoidance_module/src/utils.cpp

View check run for this annotation

CodeScene Delta Analysis / CodeScene Cloud Delta Analysis (main)

✅ No longer an issue: Bumpy Road Ahead

calcDistanceToReturnDeadLine is no longer above the threshold for logical blocks with deeply nested code. The Bumpy Road code smell is a function that contains multiple chunks of nested conditional logic. The deeper the nesting and the more bumps, the lower the code health.
// dead line for goal
if (parameters->enable_dead_line_for_goal) {
if (planner_data->route_handler->isInGoalRouteSection(lanelets.back())) {
const auto & ego_pos = planner_data->self_odometry->pose.pose.position;
const auto to_goal_distance =
calcSignedArcLength(path.points, ego_pos, path.points.size() - 1);
distance_to_return_dead_line = std::min(
distance_to_return_dead_line, to_goal_distance - parameters->dead_line_buffer_for_goal);
}
}

return distance_to_return_dead_line;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,10 @@ class GoalPlannerModule : public SceneModuleInterface
// new turn signal
TurnSignalInfo calcTurnSignalInfo() const;

std::optional<BehaviorModuleOutput> last_previous_module_output_{};
bool hasPreviousModulePathShapeChanged() const;
bool hasDeviatedFromLastPreviousModulePath() const;

// timer for generating pull over path candidates in a separate thread
void onTimer();
void onFreespaceParkingTimer();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ class PullOverPlannerBase
}
virtual ~PullOverPlannerBase() = default;

void setPreviousModuleOutput(const BehaviorModuleOutput & previous_module_output)
{
previous_module_output_ = previous_module_output;
}

void setPlannerData(const std::shared_ptr<const PlannerData> planner_data)
{
planner_data_ = planner_data;
Expand All @@ -132,6 +137,8 @@ class PullOverPlannerBase
vehicle_info_util::VehicleInfo vehicle_info_;
LinearRing2d vehicle_footprint_;
GoalPlannerParameters parameters_;

BehaviorModuleOutput previous_module_output_;
};
} // namespace behavior_path_planner

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ class ShiftPullOver : public PullOverPlannerBase
protected:
PathWithLaneId generateReferencePath(
const lanelet::ConstLanelets & road_lanes, const Pose & end_pose) const;
std::optional<PathWithLaneId> extendPrevModulePath(
const PathWithLaneId & road_lane_reference_path_to_shift_end, const Pose & shift_end_pose,
const PathWithLaneId & prev_module_path) const;
std::optional<PathWithLaneId> cropPrevModulePath(
const PathWithLaneId & prev_module_path, const Pose & shift_end_pose) const;
std::optional<PullOverPath> generatePullOverPath(
const lanelet::ConstLanelets & road_lanes, const lanelet::ConstLanelets & shoulder_lanes,
const Pose & goal_pose, const double lateral_jerk) const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,18 @@ PredictedObjects filterObjectsByLateralDistance(

bool isAllowedGoalModification(const std::shared_ptr<RouteHandler> & route_handler);
bool checkOriginalGoalIsInShoulder(const std::shared_ptr<RouteHandler> & route_handler);
double calcLateralDeviationBetweenPaths(
const PathWithLaneId & reference_path, const PathWithLaneId & target_path);
bool isRerencePath(
const PathWithLaneId & reference_path, const PathWithLaneId & target_path,
const double lateral_deviation_thresh);

PathWithLaneId extendPath(
const PathWithLaneId & prev_module_path, const PathWithLaneId & reference_path,
const double extend_length);
PathWithLaneId extendPath(
const PathWithLaneId & prev_module_path, const PathWithLaneId & reference_path,
const Pose & extend_pose);

// debug
MarkerArray createPullOverAreaMarkerArray(
Expand Down
Loading

0 comments on commit 8f66df0

Please sign in to comment.