Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(dynamic_avoidance): change the logic of longitudinal distance to… #5947

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@
min_object_vel: -0.5 # [m/s] The value is negative considering the noisy velocity of the stopped vehicle.
max_ego_path_lat_cover_ratio: 0.3 # [-] The object will be ignored if the ratio of the object covering the ego's path is higher than this value.

stopped_object:
max_object_vel: 0.5 # [m/s] The object will be determined as stopped if the velocity is smaller than this value.

drivable_area_generation:
polygon_generation_method: "ego_path_base" # choose "ego_path_base" and "object_path_base"
object_path_base:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ struct DynamicAvoidanceParameters
double max_overtaking_crossing_object_angle{0.0};
double min_oncoming_crossing_object_vel{0.0};
double max_oncoming_crossing_object_angle{0.0};
double max_stopped_object_vel{0.0};

// drivable area generation
PolygonGenerationMethod polygon_generation_method{};
Expand All @@ -106,6 +107,12 @@ struct DynamicAvoidanceParameters
double end_duration_to_avoid_oncoming_object{0.0};
};

struct TimeWhileCollision
{
double time_to_start_collision;
double time_to_end_collision;
};

class DynamicAvoidanceModule : public SceneModuleInterface
{
public:
Expand Down Expand Up @@ -324,22 +331,23 @@ class DynamicAvoidanceModule : public SceneModuleInterface
const autoware_auto_perception_msgs::msg::Shape & obj_shape, const double obj_vel) const;
bool isObjectFarFromPath(
const PredictedObject & predicted_object, const double obj_dist_to_path) const;
double calcTimeToCollision(
const std::vector<PathPointWithLaneId> & ego_path, const geometry_msgs::msg::Pose & obj_pose,
const double obj_tangent_vel, const LatLonOffset & lat_lon_offset) const;
TimeWhileCollision calcTimeWhileCollision(
const std::vector<PathPointWithLaneId> & ego_path, const double obj_tangent_vel,
const LatLonOffset & lat_lon_offset) const;
std::optional<std::pair<size_t, size_t>> calcCollisionSection(
const std::vector<PathPointWithLaneId> & ego_path, const PredictedPath & obj_path) const;
LatLonOffset getLateralLongitudinalOffset(
const std::vector<PathPointWithLaneId> & ego_path, const geometry_msgs::msg::Pose & obj_pose,
const autoware_auto_perception_msgs::msg::Shape & obj_shape) const;
double calcValidLengthToAvoid(
const PredictedPath & obj_path, const geometry_msgs::msg::Pose & obj_pose,
const autoware_auto_perception_msgs::msg::Shape & obj_shape) const;
const autoware_auto_perception_msgs::msg::Shape & obj_shape,
const bool is_object_same_direction) const;
MinMaxValue calcMinMaxLongitudinalOffsetToAvoid(
const std::vector<PathPointWithLaneId> & ref_path_points_for_obj_poly,
const geometry_msgs::msg::Pose & obj_pose, const Polygon2d & obj_points, const double obj_vel,
const PredictedPath & obj_path, const autoware_auto_perception_msgs::msg::Shape & obj_shape,
const double time_to_collision) const;
const TimeWhileCollision & time_while_collision) const;
std::optional<MinMaxValue> calcMinMaxLateralOffsetToAvoid(
const std::vector<PathPointWithLaneId> & ref_path_points_for_obj_poly,
const Polygon2d & obj_points, const double obj_vel, const bool is_collision_left,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2023 TIER IV, Inc.

Check warning on line 1 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

CodeScene Delta Analysis / CodeScene Cloud Delta Analysis (main)

❌ New issue: Lines of Code in a Single File

This module has 1042 lines of code, improve code health by reducing it to 1000. The number of Lines of Code in a single file. More Lines of Code lowers the code health.

Check notice on line 1 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

CodeScene Delta Analysis / CodeScene Cloud Delta Analysis (main)

ℹ Getting worse: Overall Code Complexity

The mean cyclomatic complexity increases from 5.54 to 6.00, threshold = 4. This file has many conditional statements (e.g. if, for, while) across its implementation, leading to lower code health. Avoid adding more conditionals.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -570,25 +570,30 @@
// }

// 2.e. check time to collision
const double time_to_collision =
calcTimeToCollision(input_path.points, object.pose, object.vel, lat_lon_offset);
if (
(0 <= object.vel &&
parameters_->max_time_to_collision_overtaking_object < time_to_collision) ||
(object.vel <= 0 && parameters_->max_time_to_collision_oncoming_object < time_to_collision)) {
RCLCPP_INFO_EXPRESSION(
getLogger(), parameters_->enable_debug_info,
"[DynamicAvoidance] Ignore obstacle (%s) since time to collision (%f) is large.",
obj_uuid.c_str(), time_to_collision);
continue;
}
if (time_to_collision < -parameters_->duration_to_hold_avoidance_overtaking_object) {
RCLCPP_INFO_EXPRESSION(
getLogger(), parameters_->enable_debug_info,
"[DynamicAvoidance] Ignore obstacle (%s) since time to collision (%f) is a small negative "
"value.",
obj_uuid.c_str(), time_to_collision);
continue;
const auto time_while_collision =
calcTimeWhileCollision(input_path.points, object.vel, lat_lon_offset);
const double time_to_collision = time_while_collision.time_to_start_collision;
if (parameters_->max_stopped_object_vel < std::hypot(object.vel, object.lat_vel)) {
// NOTE: Only not stopped object is filtered by time to collision.
if (
(0 <= object.vel &&

Check warning on line 579 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L579

Added line #L579 was not covered by tests
parameters_->max_time_to_collision_overtaking_object < time_to_collision) ||
(object.vel <= 0 &&

Check warning on line 581 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L581

Added line #L581 was not covered by tests
parameters_->max_time_to_collision_oncoming_object < time_to_collision)) {
RCLCPP_INFO_EXPRESSION(
getLogger(), parameters_->enable_debug_info,
"[DynamicAvoidance] Ignore obstacle (%s) since time to collision (%f) is large.",
obj_uuid.c_str(), time_to_collision);
continue;
}

Check warning on line 588 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L587-L588

Added lines #L587 - L588 were not covered by tests
if (time_to_collision < -parameters_->duration_to_hold_avoidance_overtaking_object) {
RCLCPP_INFO_EXPRESSION(
getLogger(), parameters_->enable_debug_info,
"[DynamicAvoidance] Ignore obstacle (%s) since time to collision (%f) is a small "
"negative value.",
obj_uuid.c_str(), time_to_collision);
continue;
}

Check warning on line 596 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L595-L596

Added lines #L595 - L596 were not covered by tests
}

// 2.f. calculate which side object will be against ego's path
Expand Down Expand Up @@ -625,7 +630,7 @@
const auto obj_points = tier4_autoware_utils::toPolygon2d(object.pose, object.shape);
const auto lon_offset_to_avoid = calcMinMaxLongitudinalOffsetToAvoid(
ref_path_points_for_obj_poly, object.pose, obj_points, object.vel, obj_path, object.shape,
time_to_collision);
time_while_collision);

Check warning on line 633 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

CodeScene Delta Analysis / CodeScene Cloud Delta Analysis (main)

❌ Getting worse: Complex Method

DynamicAvoidanceModule::updateTargetObjects increases in cyclomatic complexity from 42 to 43, 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.

Check warning on line 633 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

CodeScene Delta Analysis / CodeScene Cloud Delta Analysis (main)

❌ Getting worse: Bumpy Road Ahead

DynamicAvoidanceModule::updateTargetObjects increases from 3 to 4 logical blocks with deeply nested code, threshold is one single block per function. 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.
const auto lat_offset_to_avoid = calcMinMaxLateralOffsetToAvoid(
ref_path_points_for_obj_poly, obj_points, object.vel, is_collision_left, object.lat_vel,
prev_object);
Expand Down Expand Up @@ -711,26 +716,60 @@
return std::make_pair(*collision_start_idx, ego_path.size() - 1);
}

double DynamicAvoidanceModule::calcTimeToCollision(
const std::vector<PathPointWithLaneId> & ego_path, const geometry_msgs::msg::Pose & obj_pose,
const double obj_tangent_vel, const LatLonOffset & lat_lon_offset) const
TimeWhileCollision DynamicAvoidanceModule::calcTimeWhileCollision(
const std::vector<PathPointWithLaneId> & ego_path, const double obj_tangent_vel,
const LatLonOffset & lat_lon_offset) const
{
// Set maximum time-to-collision 0 if the object longitudinally overlaps ego.
// NOTE: This is to avoid objects running right beside ego even if time-to-collision is negative.
const size_t ego_seg_idx = planner_data_->findEgoSegmentIndex(ego_path);
const double lon_offset_ego_to_obj =
motion_utils::calcSignedArcLength(
ego_path, getEgoPose().position, ego_seg_idx, lat_lon_offset.nearest_idx) +
lat_lon_offset.max_lon_offset;
const double maximum_time_to_collision =
(0.0 < lon_offset_ego_to_obj) ? 0.0 : -std::numeric_limits<double>::max();

const double lon_offset_ego_to_obj_idx = motion_utils::calcSignedArcLength(
ego_path, getEgoPose().position, ego_seg_idx, lat_lon_offset.nearest_idx);
const double relative_velocity = getEgoSpeed() - obj_tangent_vel;
const size_t obj_seg_idx = motion_utils::findNearestSegmentIndex(ego_path, obj_pose.position);
const double signed_lon_length = motion_utils::calcSignedArcLength(
ego_path, getEgoPosition(), ego_seg_idx, obj_pose.position, obj_seg_idx);
const double positive_relative_velocity = std::max(relative_velocity, 1.0);
return std::max(maximum_time_to_collision, signed_lon_length / positive_relative_velocity);

const double signed_time_to_start_collision = [&]() {
const double lon_offset_ego_front_to_obj_back = lon_offset_ego_to_obj_idx +

Check warning on line 731 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L731

Added line #L731 was not covered by tests
lat_lon_offset.min_lon_offset -
planner_data_->parameters.front_overhang;

Check warning on line 733 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L733

Added line #L733 was not covered by tests
const double lon_offset_obj_front_to_ego_back = -lon_offset_ego_to_obj_idx -
lat_lon_offset.max_lon_offset -
planner_data_->parameters.rear_overhang;
if (0.0 < lon_offset_ego_front_to_obj_back) { // The object is ahead of the ego.

Check warning on line 737 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L735-L737

Added lines #L735 - L737 were not covered by tests
return lon_offset_ego_front_to_obj_back / relative_velocity;
} else if (0.0 < lon_offset_obj_front_to_ego_back) { // The ego is ahead of the object.
return lon_offset_obj_front_to_ego_back / -relative_velocity;
}

Check warning on line 741 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L739-L741

Added lines #L739 - L741 were not covered by tests
// The ego and object are colliding.
return 0.0;

Check warning on line 743 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L743

Added line #L743 was not covered by tests
}();
const double signed_time_to_end_collision = [&]() {

Check warning on line 745 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L745

Added line #L745 was not covered by tests
const double lon_offset_ego_back_to_obj_front = lon_offset_ego_to_obj_idx +
lat_lon_offset.max_lon_offset +
planner_data_->parameters.rear_overhang;
const double lon_offset_obj_back_to_ego_front = -lon_offset_ego_to_obj_idx -
lat_lon_offset.min_lon_offset +
planner_data_->parameters.front_overhang;
if (0.0 < relative_velocity) {

Check warning on line 752 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L749-L752

Added lines #L749 - L752 were not covered by tests
return lon_offset_ego_back_to_obj_front / relative_velocity;
}
return lon_offset_obj_back_to_ego_front / -relative_velocity;
}();

Check warning on line 756 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L754-L756

Added lines #L754 - L756 were not covered by tests

// NOTE: In order to make time_to_start_collision continuous around the relative_velocity is zero.

Check warning on line 758 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L758

Added line #L758 was not covered by tests
const double time_to_start_collision = [&]() {
if (signed_time_to_start_collision < 0.0) {
return std::numeric_limits<double>::max();

Check warning on line 761 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L760-L761

Added lines #L760 - L761 were not covered by tests
}
return signed_time_to_start_collision;
}();
const double time_to_end_collision = [&]() {
if (signed_time_to_end_collision < 0.0) {
return std::numeric_limits<double>::max();
}

Check warning on line 768 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L768

Added line #L768 was not covered by tests
return signed_time_to_end_collision;
}();

return TimeWhileCollision{time_to_start_collision, time_to_end_collision};
}

bool DynamicAvoidanceModule::isObjectFarFromPath(
Expand Down Expand Up @@ -923,7 +962,7 @@
const std::vector<PathPointWithLaneId> & ref_path_points_for_obj_poly,
const geometry_msgs::msg::Pose & obj_pose, const Polygon2d & obj_points, const double obj_vel,
const PredictedPath & obj_path, const autoware_auto_perception_msgs::msg::Shape & obj_shape,
const double time_to_collision) const
const TimeWhileCollision & time_while_collision) const
{
const size_t obj_seg_idx =
motion_utils::findNearestSegmentIndex(ref_path_points_for_obj_poly, obj_pose.position);
Expand All @@ -938,40 +977,54 @@
obj_lon_offset_vec.push_back(lon_offset);
}

const auto raw_obj_lon_offset = getMinMaxValues(obj_lon_offset_vec);
return getMinMaxValues(obj_lon_offset_vec);

Check warning on line 980 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L980

Added line #L980 was not covered by tests
}();

if (obj_vel < 0) {
return MinMaxValue{
raw_obj_lon_offset.min_value + obj_vel * time_to_collision, raw_obj_lon_offset.max_value};
}
const double relative_velocity = getEgoSpeed() - obj_vel;

// NOTE: If time to collision is considered here, the ego is close to the object when starting
// avoidance.
// The ego should start avoidance before overtaking.
return raw_obj_lon_offset;
// calculate bound start and end length
const double start_length_to_avoid = [&]() {

Check warning on line 986 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L986

Added line #L986 was not covered by tests
if (obj_vel < parameters_->max_stopped_object_vel) {
// The ego and object are the same directional or the object is parked.

Check warning on line 988 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L988

Added line #L988 was not covered by tests
return std::min(time_while_collision.time_to_start_collision, 8.0) * std::abs(obj_vel) +
std::abs(relative_velocity) * parameters_->start_duration_to_avoid_oncoming_object;
}

Check warning on line 991 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L991

Added line #L991 was not covered by tests
// The ego and object are the opposite directional.
const double obj_acc = -1.0;
const double decel_time = 1.0;
const double obj_moving_dist =

Check warning on line 995 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L995

Added line #L995 was not covered by tests
(std::pow(std::max(obj_vel + obj_acc * decel_time, 0.0), 2) - std::pow(obj_vel, 2)) / 2 /
obj_acc;
const double ego_moving_dist = getEgoSpeed() * decel_time;
return std::max(0.0, ego_moving_dist - obj_moving_dist) +
std::abs(relative_velocity) * parameters_->start_duration_to_avoid_overtaking_object;
}();
const double end_length_to_avoid = [&]() {
if (obj_vel < parameters_->max_stopped_object_vel) {
// The ego and object are the same directional or the object is parked.
return std::abs(relative_velocity) * parameters_->end_duration_to_avoid_oncoming_object;
}
// The ego and object are the opposite directional.

Check warning on line 1007 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L1005-L1007

Added lines #L1005 - L1007 were not covered by tests
return std::min(time_while_collision.time_to_end_collision, 3.0) * obj_vel +
std::abs(relative_velocity) * parameters_->end_duration_to_avoid_overtaking_object;
}();

// calculate bound start and end index
const bool is_object_overtaking = (0.0 <= obj_vel);
// TODO(murooka) use getEgoSpeed() instead of obj_vel
const double start_length_to_avoid =
std::abs(obj_vel) * (is_object_overtaking
? parameters_->start_duration_to_avoid_overtaking_object
: parameters_->start_duration_to_avoid_oncoming_object);
const double end_length_to_avoid =
std::abs(obj_vel) * (is_object_overtaking ? parameters_->end_duration_to_avoid_overtaking_object
: parameters_->end_duration_to_avoid_oncoming_object);

const double valid_length_to_avoid = calcValidLengthToAvoid(obj_path, obj_pose, obj_shape);
if (obj_vel < -0.5) {
// calculate valid path for the forked object's path from the ego's path
if (obj_vel < -parameters_->max_stopped_object_vel) {
const bool is_object_same_direction = false;

Check warning on line 1014 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L1014

Added line #L1014 was not covered by tests
const double valid_length_to_avoid =
calcValidLengthToAvoid(obj_path, obj_pose, obj_shape, is_object_same_direction);
return MinMaxValue{
std::max(obj_lon_offset.min_value - start_length_to_avoid, -valid_length_to_avoid),
obj_lon_offset.min_value + std::max(-start_length_to_avoid, -valid_length_to_avoid),
obj_lon_offset.max_value + end_length_to_avoid};
}
if (0.5 < obj_vel) {
if (parameters_->max_stopped_object_vel < obj_vel) {

Check warning on line 1021 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L1021

Added line #L1021 was not covered by tests
const bool is_object_same_direction = true;
const double valid_length_to_avoid =
calcValidLengthToAvoid(obj_path, obj_pose, obj_shape, is_object_same_direction);

Check warning on line 1024 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L1024

Added line #L1024 was not covered by tests
return MinMaxValue{
obj_lon_offset.min_value - start_length_to_avoid,
std::min(obj_lon_offset.max_value + end_length_to_avoid, valid_length_to_avoid)};
obj_lon_offset.max_value + std::min(end_length_to_avoid, valid_length_to_avoid)};
}
return MinMaxValue{
obj_lon_offset.min_value - start_length_to_avoid,
Expand All @@ -980,25 +1033,44 @@

double DynamicAvoidanceModule::calcValidLengthToAvoid(
const PredictedPath & obj_path, const geometry_msgs::msg::Pose & obj_pose,
const autoware_auto_perception_msgs::msg::Shape & obj_shape) const
const autoware_auto_perception_msgs::msg::Shape & obj_shape,

Check warning on line 1036 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L1036

Added line #L1036 was not covered by tests
const bool is_object_same_direction) const
{
const auto input_path_points = getPreviousModuleOutput().path.points;
const auto & input_path_points = getPreviousModuleOutput().path.points;

Check warning on line 1039 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L1039

Added line #L1039 was not covered by tests
const size_t obj_seg_idx =
motion_utils::findNearestSegmentIndex(input_path_points, obj_pose.position);

const double dist_threshold_paths = planner_data_->parameters.vehicle_width / 2.0 +
parameters_->lat_offset_from_obstacle +
calcObstacleMaxLength(obj_shape);

// crop the ego's path by object position
std::vector<PathPointWithLaneId> cropped_ego_path_points;
if (is_object_same_direction) {

Check warning on line 1049 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L1048-L1049

Added lines #L1048 - L1049 were not covered by tests
cropped_ego_path_points = std::vector<PathPointWithLaneId>{
input_path_points.begin() + obj_seg_idx, input_path_points.end()};
} else {
cropped_ego_path_points = std::vector<PathPointWithLaneId>{
input_path_points.begin(), input_path_points.begin() + obj_seg_idx + 1 + 1};
std::reverse(cropped_ego_path_points.begin(), cropped_ego_path_points.end());
}

Check warning on line 1056 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L1056

Added line #L1056 was not covered by tests
if (cropped_ego_path_points.size() < 2) {
return motion_utils::calcArcLength(obj_path.path);
}

Check warning on line 1059 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L1059

Added line #L1059 was not covered by tests

// calculate where the object's path will be forked from (= far from) the ego's path.
std::optional<size_t> last_nearest_ego_path_seg_idx{std::nullopt};
const size_t valid_obj_path_end_idx = [&]() {
int ego_path_idx = obj_seg_idx + 1;
size_t ego_path_seg_idx = 0;
for (size_t obj_path_idx = 0; obj_path_idx < obj_path.path.size(); ++obj_path_idx) {
bool are_paths_close{false};
for (; 0 < ego_path_idx; --ego_path_idx) {
for (; ego_path_seg_idx < cropped_ego_path_points.size() - 1; ++ego_path_seg_idx) {

Check warning on line 1067 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L1067

Added line #L1067 was not covered by tests
const double dist_to_segment = calcDistanceToSegment(
obj_path.path.at(obj_path_idx).position,
input_path_points.at(ego_path_idx).point.pose.position,
input_path_points.at(ego_path_idx - 1).point.pose.position);
if (
dist_to_segment < planner_data_->parameters.vehicle_width / 2.0 +
parameters_->lat_offset_from_obstacle +
calcObstacleMaxLength(obj_shape)) {
cropped_ego_path_points.at(ego_path_seg_idx).point.pose.position,
cropped_ego_path_points.at(ego_path_seg_idx + 1).point.pose.position);
if (dist_to_segment < dist_threshold_paths) {
last_nearest_ego_path_seg_idx = ego_path_seg_idx;

Check warning on line 1073 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L1073

Added line #L1073 was not covered by tests
are_paths_close = true;
break;
}
Expand All @@ -1010,6 +1082,43 @@
}
return obj_path.path.size() - 1;
}();

Check warning on line 1085 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L1085

Added line #L1085 was not covered by tests
// calculate valid length to avoid
if (last_nearest_ego_path_seg_idx && valid_obj_path_end_idx != obj_path.path.size() - 1) {
const auto calc_min_dist = [&](const size_t arg_obj_path_idx) -> std::optional<double> {

Check warning on line 1088 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L1088

Added line #L1088 was not covered by tests
std::optional<double> min_dist{std::nullopt};
for (size_t ego_path_seg_idx = *last_nearest_ego_path_seg_idx;
ego_path_seg_idx < cropped_ego_path_points.size() - 1; ++ego_path_seg_idx) {
const double dist_to_segment = calcDistanceToSegment(
obj_path.path.at(arg_obj_path_idx).position,
cropped_ego_path_points.at(ego_path_seg_idx).point.pose.position,
cropped_ego_path_points.at(ego_path_seg_idx + 1).point.pose.position);

Check warning on line 1095 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L1093-L1095

Added lines #L1093 - L1095 were not covered by tests
if (!min_dist || dist_to_segment < *min_dist) {
min_dist = dist_to_segment;
}

Check warning on line 1098 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L1097-L1098

Added lines #L1097 - L1098 were not covered by tests
if (min_dist && *min_dist < dist_to_segment) {
return *min_dist;
}
}

Check warning on line 1102 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L1102

Added line #L1102 was not covered by tests
return min_dist;
};
const size_t prev_valid_obj_path_end_idx =

Check warning on line 1105 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L1105

Added line #L1105 was not covered by tests
(valid_obj_path_end_idx == 0) ? valid_obj_path_end_idx : valid_obj_path_end_idx - 1;
const size_t next_valid_obj_path_end_idx =
(valid_obj_path_end_idx == 0) ? valid_obj_path_end_idx + 1 : valid_obj_path_end_idx;
const auto prev_min_dist = calc_min_dist(prev_valid_obj_path_end_idx);

Check warning on line 1109 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L1108-L1109

Added lines #L1108 - L1109 were not covered by tests
const auto next_min_dist = calc_min_dist(next_valid_obj_path_end_idx);
if (prev_min_dist && next_min_dist) {
const double segment_length = tier4_autoware_utils::calcDistance2d(
obj_path.path.at(prev_valid_obj_path_end_idx),
obj_path.path.at(next_valid_obj_path_end_idx));
const double partial_segment_length = segment_length *
(dist_threshold_paths - *prev_min_dist) /
(*next_min_dist - *prev_min_dist);
return motion_utils::calcSignedArcLength(obj_path.path, 0, prev_valid_obj_path_end_idx) +
partial_segment_length;
}
}

Check warning on line 1121 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

CodeScene Delta Analysis / CodeScene Cloud Delta Analysis (main)

❌ New issue: Complex Method

DynamicAvoidanceModule::calcValidLengthToAvoid has a cyclomatic complexity of 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.

Check warning on line 1121 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

CodeScene Delta Analysis / CodeScene Cloud Delta Analysis (main)

❌ New issue: Bumpy Road Ahead

DynamicAvoidanceModule::calcValidLengthToAvoid has 2 blocks with nested conditional logic. Any nesting of 2 or deeper is considered. Threshold is one single, nested block per function. 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.

Check warning on line 1121 in planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp

View check run for this annotation

Codecov / codecov/patch

planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp#L1120-L1121

Added lines #L1120 - L1121 were not covered by tests
return motion_utils::calcSignedArcLength(obj_path.path, 0, valid_obj_path_end_idx);
}

Expand Down
Loading
Loading