Skip to content

Commit fbd9183

Browse files
authored
Merge pull request #1241 from tier4/cp-lane-change
fix(lane_change): cherry pick small fixes
2 parents cbd60c6 + 071333e commit fbd9183

File tree

13 files changed

+91
-8
lines changed

13 files changed

+91
-8
lines changed

planning/behavior_path_lane_change_module/README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,8 @@ The following parameters are configurable in [lane_change.param.yaml](https://gi
524524
| Name | Unit | Type | Description | Default value |
525525
| :------------------------------------------------------- | ----- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
526526
| `enable_collision_check_for_prepare_phase.general_lanes` | [-] | boolean | Perform collision check starting from the prepare phase for situations not explicitly covered by other settings (e.g., intersections). If `false`, collision check only evaluated for lane changing phase. | false |
527-
| `enable_collision_check_for_prepare_phase.intersection` | [-] | boolean | Perform collision check starting from prepare phase when ego is in intersection. If `false`, collision check only evaluated for lane changing phase. | false |
527+
| `enable_collision_check_for_prepare_phase.intersection` | [-] | boolean | Perform collision check starting from prepare phase when ego is in intersection. If `false`, collision check only evaluated for lane changing phase. | true |
528+
| `enable_collision_check_for_prepare_phase.turns` | [-] | boolean | Perform collision check starting from prepare phase when ego is in lanelet with turn direction tags. If `false`, collision check only evaluated for lane changing phase. | true |
528529
| `prepare_phase_ignore_target_speed_thresh` | [m/s] | double | Ignore collision check in prepare phase of object speed that is lesser that the configured value. `enable_collision_check_at_prepare_phase` must be `true` | 0.1 |
529530
| `check_objects_on_current_lanes` | [-] | boolean | If true, the lane change module check objects on current lanes when performing collision assessment. | false |
530531
| `check_objects_on_other_lanes` | [-] | boolean | If true, the lane change module include objects on other lanes. when performing collision assessment | false |

planning/behavior_path_lane_change_module/config/lane_change.param.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@
9292
enable_collision_check_for_prepare_phase:
9393
general_lanes: false
9494
intersection: true
95+
turns: true
9596
prepare_segment_ignore_object_velocity_thresh: 0.1 # [m/s]
9697
check_objects_on_current_lanes: true
9798
check_objects_on_other_lanes: true

planning/behavior_path_lane_change_module/include/behavior_path_lane_change_module/scene.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,8 @@ class NormalLaneChange : public LaneChangeBase
170170
bool isVehicleStuck(
171171
const lanelet::ConstLanelets & current_lanes, const double obstacle_check_distance) const;
172172

173+
double get_max_velocity_for_safety_check() const;
174+
173175
bool isVehicleStuck(const lanelet::ConstLanelets & current_lanes) const;
174176

175177
bool check_prepare_phase() const;

planning/behavior_path_lane_change_module/include/behavior_path_lane_change_module/utils/data_structs.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ struct LaneChangeParameters
109109
// collision check
110110
bool enable_collision_check_for_prepare_phase_in_general_lanes{false};
111111
bool enable_collision_check_for_prepare_phase_in_intersection{true};
112+
bool enable_collision_check_for_prepare_phase_in_turns{true};
112113
double prepare_segment_ignore_object_velocity_thresh{0.1};
113114
bool check_objects_on_current_lanes{true};
114115
bool check_objects_on_other_lanes{true};

planning/behavior_path_lane_change_module/include/behavior_path_lane_change_module/utils/utils.hpp

+15
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,21 @@ bool isWithinIntersection(
262262
const std::shared_ptr<RouteHandler> & route_handler, const lanelet::ConstLanelet & lanelet,
263263
const Polygon2d & polygon);
264264

265+
/**
266+
* @brief Determines if a polygon is within lanes designated for turning.
267+
*
268+
* Checks if a polygon overlaps with lanelets tagged for turning directions (excluding 'straight').
269+
* It evaluates the lanelet's 'turn_direction' attribute and determines overlap with the lanelet's
270+
* area.
271+
*
272+
* @param lanelet Lanelet representing the road segment whose turn direction is to be evaluated.
273+
* @param polygon The polygon to be checked for its presence within turn direction lanes.
274+
*
275+
* @return bool True if the polygon is within a lane designated for turning, false if it is within a
276+
* straight lane or no turn direction is specified.
277+
*/
278+
bool isWithinTurnDirectionLanes(const lanelet::ConstLanelet & lanelet, const Polygon2d & polygon);
279+
265280
/**
266281
* @brief Calculates the distance required during a lane change operation.
267282
*

planning/behavior_path_lane_change_module/src/manager.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ void LaneChangeModuleManager::initParams(rclcpp::Node * node)
7272
*node, parameter("enable_collision_check_for_prepare_phase.general_lanes"));
7373
p.enable_collision_check_for_prepare_phase_in_intersection = getOrDeclareParameter<bool>(
7474
*node, parameter("enable_collision_check_for_prepare_phase.intersection"));
75+
p.enable_collision_check_for_prepare_phase_in_turns =
76+
getOrDeclareParameter<bool>(*node, parameter("enable_collision_check_for_prepare_phase.turns"));
7577
p.prepare_segment_ignore_object_velocity_thresh = getOrDeclareParameter<double>(
7678
*node, parameter("prepare_segment_ignore_object_velocity_thresh"));
7779
p.check_objects_on_current_lanes =

planning/behavior_path_lane_change_module/src/scene.cpp

+21-2
Original file line numberDiff line numberDiff line change
@@ -1976,7 +1976,7 @@ PathSafetyStatus NormalLaneChange::isLaneChangePathSafe(
19761976
for (const auto & obj_path : obj_predicted_paths) {
19771977
const auto collided_polygons = utils::path_safety_checker::getCollidedPolygons(
19781978
path, ego_predicted_path, obj, obj_path, common_parameters, rss_params, 1.0,
1979-
current_debug_data.second);
1979+
get_max_velocity_for_safety_check(), current_debug_data.second);
19801980

19811981
if (collided_polygons.empty()) {
19821982
utils::path_safety_checker::updateCollisionCheckDebugMap(
@@ -2071,6 +2071,17 @@ bool NormalLaneChange::isVehicleStuck(
20712071
return false;
20722072
}
20732073

2074+
double NormalLaneChange::get_max_velocity_for_safety_check() const
2075+
{
2076+
const auto external_velocity_limit_ptr = planner_data_->external_limit_max_velocity;
2077+
if (external_velocity_limit_ptr) {
2078+
return std::min(
2079+
static_cast<double>(external_velocity_limit_ptr->max_velocity), getCommonParam().max_vel);
2080+
}
2081+
2082+
return getCommonParam().max_vel;
2083+
}
2084+
20742085
bool NormalLaneChange::isVehicleStuck(const lanelet::ConstLanelets & current_lanes) const
20752086
{
20762087
if (current_lanes.empty()) {
@@ -2147,7 +2158,15 @@ bool NormalLaneChange::check_prepare_phase() const
21472158
return utils::lane_change::isWithinIntersection(route_handler, current_lane, ego_footprint);
21482159
});
21492160

2150-
return check_in_intersection || check_in_general_lanes;
2161+
const auto check_in_turns = std::invoke([&]() {
2162+
if (!lane_change_parameters_->enable_collision_check_for_prepare_phase_in_turns) {
2163+
return false;
2164+
}
2165+
2166+
return utils::lane_change::isWithinTurnDirectionLanes(current_lane, ego_footprint);
2167+
});
2168+
2169+
return check_in_intersection || check_in_turns || check_in_general_lanes;
21512170
}
21522171

21532172
} // namespace behavior_path_planner

planning/behavior_path_lane_change_module/src/utils/utils.cpp

+13
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737

3838
#include <geometry_msgs/msg/detail/pose__struct.hpp>
3939

40+
#include <boost/geometry/algorithms/detail/disjoint/interface.hpp>
41+
4042
#include <lanelet2_core/LaneletMap.h>
4143
#include <lanelet2_core/geometry/LineString.h>
4244
#include <lanelet2_core/geometry/Point.h>
@@ -1222,6 +1224,17 @@ bool isWithinIntersection(
12221224
polygon, utils::toPolygon2d(lanelet::utils::to2D(lanelet_polygon.basicPolygon())));
12231225
}
12241226

1227+
bool isWithinTurnDirectionLanes(const lanelet::ConstLanelet & lanelet, const Polygon2d & polygon)
1228+
{
1229+
const std::string turn_direction = lanelet.attributeOr("turn_direction", "else");
1230+
if (turn_direction == "else" || turn_direction == "straight") {
1231+
return false;
1232+
}
1233+
1234+
return !boost::geometry::disjoint(
1235+
polygon, utils::toPolygon2d(lanelet::utils::to2D(lanelet.polygon2d().basicPolygon())));
1236+
}
1237+
12251238
double calcPhaseLength(
12261239
const double velocity, const double maximum_velocity, const double acceleration,
12271240
const double duration)

planning/behavior_path_planner/include/behavior_path_planner/behavior_path_planner_node.hpp

+6
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include <tier4_planning_msgs/msg/reroute_availability.hpp>
3939
#include <tier4_planning_msgs/msg/scenario.hpp>
4040
#include <tier4_planning_msgs/msg/stop_reason_array.hpp>
41+
#include <tier4_planning_msgs/msg/velocity_limit.hpp>
4142
#include <visualization_msgs/msg/marker.hpp>
4243

4344
#include <map>
@@ -101,6 +102,8 @@ class BehaviorPathPlannerNode : public rclcpp::Node
101102
rclcpp::Publisher<PoseWithUuidStamped>::SharedPtr modified_goal_publisher_;
102103
rclcpp::Publisher<StopReasonArray>::SharedPtr stop_reason_publisher_;
103104
rclcpp::Publisher<RerouteAvailability>::SharedPtr reroute_availability_publisher_;
105+
rclcpp::Subscription<tier4_planning_msgs::msg::VelocityLimit>::SharedPtr
106+
external_limit_max_velocity_subscriber_;
104107
rclcpp::TimerBase::SharedPtr timer_;
105108

106109
std::map<std::string, rclcpp::Publisher<Path>::SharedPtr> path_candidate_publishers_;
@@ -140,6 +143,9 @@ class BehaviorPathPlannerNode : public rclcpp::Node
140143
void onRoute(const LaneletRoute::ConstSharedPtr route_msg);
141144
void onOperationMode(const OperationModeState::ConstSharedPtr msg);
142145
void onLateralOffset(const LateralOffset::ConstSharedPtr msg);
146+
void on_external_velocity_limiter(
147+
const tier4_planning_msgs::msg::VelocityLimit::ConstSharedPtr msg);
148+
143149
SetParametersResult onSetParam(const std::vector<rclcpp::Parameter> & parameters);
144150

145151
OnSetParametersCallbackHandle::SharedPtr m_set_param_res;

planning/behavior_path_planner/src/behavior_path_planner_node.cpp

+18
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ BehaviorPathPlannerNode::BehaviorPathPlannerNode(const rclcpp::NodeOptions & nod
112112
current_scenario_ = std::make_shared<Scenario>(*msg);
113113
},
114114
createSubscriptionOptions(this));
115+
external_limit_max_velocity_subscriber_ =
116+
create_subscription<tier4_planning_msgs::msg::VelocityLimit>(
117+
"/planning/scenario_planning/max_velocity", 1,
118+
std::bind(&BehaviorPathPlannerNode::on_external_velocity_limiter, this, _1),
119+
createSubscriptionOptions(this));
115120

116121
// route_handler
117122
vector_map_subscriber_ = create_subscription<HADMapBin>(
@@ -815,6 +820,19 @@ void BehaviorPathPlannerNode::onOperationMode(const OperationModeState::ConstSha
815820
const std::lock_guard<std::mutex> lock(mutex_pd_);
816821
planner_data_->operation_mode = msg;
817822
}
823+
824+
void BehaviorPathPlannerNode::on_external_velocity_limiter(
825+
const tier4_planning_msgs::msg::VelocityLimit::ConstSharedPtr msg)
826+
{
827+
// Note: Using this parameter during path planning might cause unexpected deceleration or jerk.
828+
// Therefore, do not use it for anything other than safety checks.
829+
if (!msg) {
830+
return;
831+
}
832+
833+
const std::lock_guard<std::mutex> lock(mutex_pd_);
834+
planner_data_->external_limit_max_velocity = msg;
835+
}
818836
void BehaviorPathPlannerNode::onLateralOffset(const LateralOffset::ConstSharedPtr msg)
819837
{
820838
std::lock_guard<std::mutex> lock(mutex_pd_);

planning/behavior_path_planner_common/include/behavior_path_planner_common/data_manager.hpp

+3
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include <geometry_msgs/msg/pose_stamped.hpp>
3838
#include <nav_msgs/msg/occupancy_grid.hpp>
3939
#include <nav_msgs/msg/odometry.hpp>
40+
#include <tier4_planning_msgs/msg/detail/velocity_limit__struct.hpp>
4041
#include <tier4_planning_msgs/msg/lateral_offset.hpp>
4142

4243
#include <limits>
@@ -64,6 +65,7 @@ using route_handler::RouteHandler;
6465
using tier4_planning_msgs::msg::LateralOffset;
6566
using PlanResult = PathWithLaneId::SharedPtr;
6667
using lanelet::TrafficLight;
68+
using tier4_planning_msgs::msg::VelocityLimit;
6769
using unique_identifier_msgs::msg::UUID;
6870

6971
struct TrafficSignalStamped
@@ -160,6 +162,7 @@ struct PlannerData
160162
std::map<int64_t, TrafficSignalStamped> traffic_light_id_map;
161163
BehaviorPathPlannerParameters parameters{};
162164
drivable_area_expansion::DrivableAreaExpansionParameters drivable_area_expansion_parameters{};
165+
VelocityLimit::ConstSharedPtr external_limit_max_velocity{};
163166

164167
mutable std::vector<geometry_msgs::msg::Pose> drivable_area_expansion_prev_path_poses{};
165168
mutable std::vector<double> drivable_area_expansion_prev_curvatures{};

planning/behavior_path_planner_common/include/behavior_path_planner_common/utils/path_safety_checker/safety_check.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ std::vector<Polygon2d> getCollidedPolygons(
141141
const ExtendedPredictedObject & target_object,
142142
const PredictedPathWithPolygon & target_object_path,
143143
const BehaviorPathPlannerParameters & common_parameters, const RSSparams & rss_parameters,
144-
const double hysteresis_factor, CollisionCheckDebug & debug);
144+
const double hysteresis_factor, const double max_velocity_limit, CollisionCheckDebug & debug);
145145

146146
bool checkPolygonsIntersects(
147147
const std::vector<Polygon2d> & polys_1, const std::vector<Polygon2d> & polys_2);

planning/behavior_path_planner_common/src/utils/path_safety_checker/safety_check.cpp

+6-4
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
#include <boost/geometry/algorithms/union.hpp>
2727
#include <boost/geometry/strategies/strategies.hpp>
2828

29+
#include <limits>
30+
2931
namespace behavior_path_planner::utils::path_safety_checker
3032
{
3133

@@ -478,7 +480,7 @@ bool checkCollision(
478480
{
479481
const auto collided_polygons = getCollidedPolygons(
480482
planned_path, predicted_ego_path, target_object, target_object_path, common_parameters,
481-
rss_parameters, hysteresis_factor, debug);
483+
rss_parameters, hysteresis_factor, std::numeric_limits<double>::max(), debug);
482484
return collided_polygons.empty();
483485
}
484486

@@ -488,7 +490,7 @@ std::vector<Polygon2d> getCollidedPolygons(
488490
const ExtendedPredictedObject & target_object,
489491
const PredictedPathWithPolygon & target_object_path,
490492
const BehaviorPathPlannerParameters & common_parameters, const RSSparams & rss_parameters,
491-
double hysteresis_factor, CollisionCheckDebug & debug)
493+
double hysteresis_factor, const double max_velocity_limit, CollisionCheckDebug & debug)
492494
{
493495
{
494496
debug.ego_predicted_path = predicted_ego_path;
@@ -504,7 +506,7 @@ std::vector<Polygon2d> getCollidedPolygons(
504506
// get object information at current time
505507
const auto & obj_pose = obj_pose_with_poly.pose;
506508
const auto & obj_polygon = obj_pose_with_poly.poly;
507-
const auto & object_velocity = obj_pose_with_poly.velocity;
509+
const auto object_velocity = obj_pose_with_poly.velocity;
508510

509511
// get ego information at current time
510512
// Note: we can create these polygons in advance. However, it can decrease the readability and
@@ -517,7 +519,7 @@ std::vector<Polygon2d> getCollidedPolygons(
517519
}
518520
const auto & ego_pose = interpolated_data->pose;
519521
const auto & ego_polygon = interpolated_data->poly;
520-
const auto & ego_velocity = interpolated_data->velocity;
522+
const auto ego_velocity = std::min(interpolated_data->velocity, max_velocity_limit);
521523

522524
// check overlap
523525
if (boost::geometry::overlaps(ego_polygon, obj_polygon)) {

0 commit comments

Comments
 (0)