Skip to content

Commit ca05df7

Browse files
authored
Merge branch 'main' into feature/parallel_ndt_build
2 parents 73ac31b + 4da69c9 commit ca05df7

File tree

23 files changed

+310
-82
lines changed

23 files changed

+310
-82
lines changed

.github/workflows/build-and-test-differential.yaml

-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ jobs:
2424
rosdistro:
2525
- humble
2626
container-suffix:
27-
- ""
2827
- -cuda
2928
include:
3029
- rosdistro: humble

common/tier4_autoware_utils/include/tier4_autoware_utils/geometry/boost_geometry.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <boost/geometry/core/cs.hpp>
1919
#include <boost/geometry/geometries/geometries.hpp>
2020
#include <boost/geometry/geometries/register/point.hpp>
21+
#include <boost/geometry/geometries/register/ring.hpp>
2122

2223
#define EIGEN_MPL2_ONLY
2324
#include <Eigen/Core>
@@ -98,5 +99,6 @@ BOOST_GEOMETRY_REGISTER_POINT_2D( // NOLIN
9899
tier4_autoware_utils::Point2d, double, cs::cartesian, x(), y()) // NOLINT
99100
BOOST_GEOMETRY_REGISTER_POINT_3D( // NOLINT
100101
tier4_autoware_utils::Point3d, double, cs::cartesian, x(), y(), z()) // NOLINT
102+
BOOST_GEOMETRY_REGISTER_RING(tier4_autoware_utils::LinearRing2d) // NOLINT
101103

102104
#endif // TIER4_AUTOWARE_UTILS__GEOMETRY__BOOST_GEOMETRY_HPP_

control/lane_departure_checker/include/lane_departure_checker/lane_departure_checker.hpp

+20-1
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,20 @@
2929
#include <geometry_msgs/msg/twist_stamped.hpp>
3030
#include <nav_msgs/msg/odometry.hpp>
3131

32+
#include <boost/geometry/algorithms/envelope.hpp>
33+
#include <boost/geometry/algorithms/union.hpp>
3234
#include <boost/geometry/index/rtree.hpp>
33-
#include <boost/optional.hpp>
3435

3536
#include <lanelet2_core/LaneletMap.h>
37+
#include <lanelet2_core/geometry/BoundingBox.h>
38+
#include <lanelet2_core/geometry/LaneletMap.h>
39+
#include <lanelet2_core/geometry/LineString.h>
40+
#include <lanelet2_core/geometry/Polygon.h>
3641

3742
#include <map>
3843
#include <memory>
3944
#include <string>
45+
#include <utility>
4046
#include <vector>
4147

4248
namespace lane_departure_checker
@@ -112,6 +118,19 @@ class LaneDepartureChecker
112118
bool checkPathWillLeaveLane(
113119
const lanelet::ConstLanelets & lanelets, const PathWithLaneId & path) const;
114120

121+
std::vector<std::pair<double, lanelet::Lanelet>> getLaneletsFromPath(
122+
const lanelet::LaneletMapPtr lanelet_map_ptr, const PathWithLaneId & path) const;
123+
124+
std::optional<lanelet::BasicPolygon2d> getFusedLaneletPolygonForPath(
125+
const lanelet::LaneletMapPtr lanelet_map_ptr, const PathWithLaneId & path) const;
126+
127+
bool checkPathWillLeaveLane(
128+
const lanelet::LaneletMapPtr lanelet_map_ptr, const PathWithLaneId & path) const;
129+
130+
PathWithLaneId cropPointsOutsideOfLanes(
131+
const lanelet::LaneletMapPtr lanelet_map_ptr, const PathWithLaneId & path,
132+
const size_t end_index);
133+
115134
static bool isOutOfLane(
116135
const lanelet::ConstLanelets & candidate_lanelets, const LinearRing2d & vehicle_footprint);
117136

control/lane_departure_checker/src/lane_departure_checker_node/lane_departure_checker.cpp

+89
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ using motion_utils::calcArcLength;
3434
using tier4_autoware_utils::LinearRing2d;
3535
using tier4_autoware_utils::LineString2d;
3636
using tier4_autoware_utils::MultiPoint2d;
37+
using tier4_autoware_utils::MultiPolygon2d;
3738
using tier4_autoware_utils::Point2d;
3839

3940
namespace
@@ -92,6 +93,7 @@ lanelet::ConstLanelets getCandidateLanelets(
9293

9394
return candidate_lanelets;
9495
}
96+
9597
} // namespace
9698

9799
namespace lane_departure_checker
@@ -298,6 +300,92 @@ bool LaneDepartureChecker::willLeaveLane(
298300
return false;
299301
}
300302

303+
std::vector<std::pair<double, lanelet::Lanelet>> LaneDepartureChecker::getLaneletsFromPath(
304+
const lanelet::LaneletMapPtr lanelet_map_ptr, const PathWithLaneId & path) const
305+
{
306+
// Get Footprint Hull basic polygon
307+
std::vector<LinearRing2d> vehicle_footprints = createVehicleFootprints(path);
308+
LinearRing2d footprint_hull = createHullFromFootprints(vehicle_footprints);
309+
auto to_basic_polygon = [](const LinearRing2d & footprint_hull) -> lanelet::BasicPolygon2d {
310+
lanelet::BasicPolygon2d basic_polygon;
311+
for (const auto & point : footprint_hull) {
312+
Eigen::Vector2d p(point.x(), point.y());
313+
basic_polygon.push_back(p);
314+
}
315+
return basic_polygon;
316+
};
317+
lanelet::BasicPolygon2d footprint_hull_basic_polygon = to_basic_polygon(footprint_hull);
318+
319+
// Find all lanelets that intersect the footprint hull
320+
return lanelet::geometry::findWithin2d(
321+
lanelet_map_ptr->laneletLayer, footprint_hull_basic_polygon, 0.0);
322+
}
323+
324+
std::optional<lanelet::BasicPolygon2d> LaneDepartureChecker::getFusedLaneletPolygonForPath(
325+
const lanelet::LaneletMapPtr lanelet_map_ptr, const PathWithLaneId & path) const
326+
{
327+
const auto lanelets_distance_pair = getLaneletsFromPath(lanelet_map_ptr, path);
328+
// Fuse lanelets into a single BasicPolygon2d
329+
auto fused_lanelets = [&lanelets_distance_pair]() -> std::optional<lanelet::BasicPolygon2d> {
330+
if (lanelets_distance_pair.empty()) return std::nullopt;
331+
if (lanelets_distance_pair.size() == 1)
332+
return lanelets_distance_pair.at(0).second.polygon2d().basicPolygon();
333+
334+
lanelet::BasicPolygon2d merged_polygon =
335+
lanelets_distance_pair.at(0).second.polygon2d().basicPolygon();
336+
for (size_t i = 1; i < lanelets_distance_pair.size(); ++i) {
337+
const auto & route_lanelet = lanelets_distance_pair.at(i).second;
338+
const auto & poly = route_lanelet.polygon2d().basicPolygon();
339+
340+
std::vector<lanelet::BasicPolygon2d> lanelet_union_temp;
341+
boost::geometry::union_(poly, merged_polygon, lanelet_union_temp);
342+
343+
// Update merged_polygon by accumulating all merged results
344+
merged_polygon.clear();
345+
for (const auto & temp_poly : lanelet_union_temp) {
346+
merged_polygon.insert(merged_polygon.end(), temp_poly.begin(), temp_poly.end());
347+
}
348+
}
349+
if (merged_polygon.empty()) return std::nullopt;
350+
return merged_polygon;
351+
}();
352+
353+
return fused_lanelets;
354+
}
355+
356+
bool LaneDepartureChecker::checkPathWillLeaveLane(
357+
const lanelet::LaneletMapPtr lanelet_map_ptr, const PathWithLaneId & path) const
358+
{
359+
// check if the footprint is not fully contained within the fused lanelets polygon
360+
const std::vector<LinearRing2d> vehicle_footprints = createVehicleFootprints(path);
361+
const auto fused_lanelets_polygon = getFusedLaneletPolygonForPath(lanelet_map_ptr, path);
362+
if (!fused_lanelets_polygon) return true;
363+
return !std::all_of(
364+
vehicle_footprints.begin(), vehicle_footprints.end(),
365+
[&fused_lanelets_polygon](const auto & footprint) {
366+
return boost::geometry::within(footprint, fused_lanelets_polygon.value());
367+
});
368+
}
369+
370+
PathWithLaneId LaneDepartureChecker::cropPointsOutsideOfLanes(
371+
const lanelet::LaneletMapPtr lanelet_map_ptr, const PathWithLaneId & path, const size_t end_index)
372+
{
373+
PathWithLaneId temp_path;
374+
const auto fused_lanelets_polygon = getFusedLaneletPolygonForPath(lanelet_map_ptr, path);
375+
if (path.points.empty() || !fused_lanelets_polygon) return temp_path;
376+
const auto vehicle_footprints = createVehicleFootprints(path);
377+
size_t idx = 0;
378+
std::for_each(vehicle_footprints.begin(), vehicle_footprints.end(), [&](const auto & footprint) {
379+
if (idx > end_index || boost::geometry::within(footprint, fused_lanelets_polygon.value())) {
380+
temp_path.points.push_back(path.points.at(idx));
381+
}
382+
++idx;
383+
});
384+
PathWithLaneId cropped_path = path;
385+
cropped_path.points = temp_path.points;
386+
return cropped_path;
387+
}
388+
301389
bool LaneDepartureChecker::isOutOfLane(
302390
const lanelet::ConstLanelets & candidate_lanelets, const LinearRing2d & vehicle_footprint)
303391
{
@@ -364,4 +452,5 @@ bool LaneDepartureChecker::willCrossBoundary(
364452
}
365453
return false;
366454
}
455+
367456
} // namespace lane_departure_checker

planning/.pages

+2-2
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ nav:
7777
- 'Additional Tools':
7878
- 'RTC Replayer': planning/rtc_replayer
7979
- 'Planning Debug Tools':
80-
- ['About Planning Debug Tools'](https://github.com/autowarefoundation/autoware_tools/tree/main/planning_debug_tools)
81-
- ['Stop Reason Visualizer'](https://github.com/autowarefoundation/autoware_tools/tree/main/planning_debug_tools/doc-stop-reason-visualizer)
80+
- 'About Planning Debug Tools': https://github.com/autowarefoundation/autoware_tools/tree/main/planning/planning_debug_tools
81+
- 'Stop Reason Visualizer': https://github.com/autowarefoundation/autoware_tools/blob/main/planning/planning_debug_tools/doc-stop-reason-visualizer.md
8282
- 'Planning Test Utils': planning/planning_test_utils
8383
- 'Planning Topic Converter': planning/planning_topic_converter
8484
- 'Planning Validator': planning/planning_validator

planning/behavior_path_avoidance_module/config/avoidance.param.yaml

+5
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,11 @@
208208
max_right_shift_length: 5.0
209209
max_left_shift_length: 5.0
210210
max_deviation_from_lane: 0.5 # [m]
211+
# approve the next shift line after reaching this percentage of the current shift line length.
212+
# this parameter should be within range of 0.0 to 1.0.
213+
# this parameter is added to allow waiting for the return of shift approval until the occlusion behind the avoid target is clear.
214+
# this feature can be disabled by setting this parameter to 1.0. (in that case, avoidance module creates return shift as soon as possible.)
215+
ratio_for_return_shift_approval: 0.5 # [-]
211216
# avoidance distance parameters
212217
longitudinal:
213218
min_prepare_time: 1.0 # [s]

planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/data_structs.hpp

+5
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,9 @@ struct AvoidanceParameters
276276
// use for judge if the ego is shifting or not.
277277
double lateral_avoid_check_threshold{0.0};
278278

279+
// use for return shift approval.
280+
double ratio_for_return_shift_approval{0.0};
281+
279282
// For shift line generation process. The continuous shift length is quantized by this value.
280283
double quantize_filter_threshold{0.0};
281284

@@ -539,6 +542,8 @@ struct AvoidancePlanningData
539542

540543
bool valid{false};
541544

545+
bool ready{false};
546+
542547
bool success{false};
543548

544549
bool comfortable{false};

planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/helper.hpp

+27
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,33 @@ class AvoidanceHelper
270270
});
271271
}
272272

273+
bool isReady(const AvoidLineArray & new_shift_lines, const double current_shift_length) const
274+
{
275+
if (std::abs(current_shift_length) < 1e-3) {
276+
return true;
277+
}
278+
279+
if (new_shift_lines.empty()) {
280+
return true;
281+
}
282+
283+
const auto front_shift_relative_length = new_shift_lines.front().getRelativeLength();
284+
285+
// same direction shift.
286+
if (current_shift_length > 0.0 && front_shift_relative_length > 0.0) {
287+
return true;
288+
}
289+
290+
// same direction shift.
291+
if (current_shift_length < 0.0 && front_shift_relative_length < 0.0) {
292+
return true;
293+
}
294+
295+
// keep waiting the other side shift approval until the ego reaches shift length threshold.
296+
const auto ego_shift_ratio = (current_shift_length - getEgoShift()) / current_shift_length;
297+
return ego_shift_ratio < parameters_->ratio_for_return_shift_approval + 1e-3;
298+
}
299+
273300
bool isShifted() const
274301
{
275302
return std::abs(getEgoShift()) > parameters_->lateral_avoid_check_threshold;

planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/parameter_helper.hpp

+6
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,12 @@ AvoidanceParameters getParameter(rclcpp::Node * node)
258258
p.max_left_shift_length = getOrDeclareParameter<double>(*node, ns + "max_left_shift_length");
259259
p.max_deviation_from_lane =
260260
getOrDeclareParameter<double>(*node, ns + "max_deviation_from_lane");
261+
p.ratio_for_return_shift_approval =
262+
getOrDeclareParameter<double>(*node, ns + "ratio_for_return_shift_approval");
263+
if (p.ratio_for_return_shift_approval < 0.0 || p.ratio_for_return_shift_approval > 1.0) {
264+
throw std::domain_error(
265+
"ratio_for_return_shift_approval should be within range of 0.0 to 1.0");
266+
}
261267
}
262268

263269
// avoidance maneuver (longitudinal)

planning/behavior_path_avoidance_module/src/scene.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ bool AvoidanceModule::isExecutionRequested() const
133133
bool AvoidanceModule::isExecutionReady() const
134134
{
135135
DEBUG_PRINT("AVOIDANCE isExecutionReady");
136-
return avoid_data_.safe && avoid_data_.comfortable && avoid_data_.valid;
136+
return avoid_data_.safe && avoid_data_.comfortable && avoid_data_.valid && avoid_data_.ready;
137137
}
138138

139139
bool AvoidanceModule::isSatisfiedSuccessCondition(const AvoidancePlanningData & data) const
@@ -513,6 +513,7 @@ void AvoidanceModule::fillShiftLine(AvoidancePlanningData & data, DebugData & de
513513
*/
514514
data.comfortable = helper_->isComfortable(data.new_shift_line);
515515
data.safe = isSafePath(data.candidate_path, debug);
516+
data.ready = helper_->isReady(data.new_shift_line, path_shifter_.getLastShiftLength());
516517
}
517518

518519
void AvoidanceModule::fillEgoStatus(

planning/behavior_path_planner_common/include/behavior_path_planner_common/utils/parking_departure/geometric_parallel_parking.hpp

+6-2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include "behavior_path_planner_common/data_manager.hpp"
1919
#include "behavior_path_planner_common/parameters.hpp"
2020

21+
#include <lane_departure_checker/lane_departure_checker.hpp>
22+
2123
#include <autoware_auto_perception_msgs/msg/predicted_objects.hpp>
2224
#include <autoware_auto_planning_msgs/msg/path_with_lane_id.hpp>
2325
#include <geometry_msgs/msg/point.hpp>
@@ -72,7 +74,8 @@ class GeometricParallelParking
7274
const bool left_side_parking);
7375
bool planPullOut(
7476
const Pose & start_pose, const Pose & goal_pose, const lanelet::ConstLanelets & road_lanes,
75-
const lanelet::ConstLanelets & shoulder_lanes, const bool left_side_start);
77+
const lanelet::ConstLanelets & shoulder_lanes, const bool left_side_start,
78+
const std::shared_ptr<lane_departure_checker::LaneDepartureChecker> lane_departure_checker);
7679
void setParameters(const ParallelParkingParameters & parameters) { parameters_ = parameters; }
7780
void setPlannerData(const std::shared_ptr<const PlannerData> & planner_data)
7881
{
@@ -115,7 +118,8 @@ class GeometricParallelParking
115118
const Pose & start_pose, const Pose & goal_pose, const double R_E_far,
116119
const lanelet::ConstLanelets & road_lanes, const lanelet::ConstLanelets & shoulder_lanes,
117120
const bool is_forward, const bool left_side_parking, const double end_pose_offset,
118-
const double lane_departure_margin, const double arc_path_interval);
121+
const double lane_departure_margin, const double arc_path_interval,
122+
const std::shared_ptr<lane_departure_checker::LaneDepartureChecker> lane_departure_checker);
119123
PathWithLaneId generateArcPath(
120124
const Pose & center, const double radius, const double start_yaw, double end_yaw,
121125
const double arc_path_interval, const bool is_left_turn, const bool is_forward);

planning/behavior_path_planner_common/package.xml

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
<depend>freespace_planning_algorithms</depend>
5050
<depend>geometry_msgs</depend>
5151
<depend>interpolation</depend>
52+
<depend>lane_departure_checker</depend>
5253
<depend>lanelet2_extension</depend>
5354
<depend>magic_enum</depend>
5455
<depend>motion_utils</depend>

planning/behavior_path_planner_common/src/utils/parking_departure/geometric_parallel_parking.cpp

+24-4
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ std::vector<PathWithLaneId> GeometricParallelParking::generatePullOverPaths(
116116
: parameters_.backward_parking_path_interval;
117117
auto arc_paths = planOneTrial(
118118
start_pose, goal_pose, R_E_far, road_lanes, shoulder_lanes, is_forward, left_side_parking,
119-
end_pose_offset, lane_departure_margin, arc_path_interval);
119+
end_pose_offset, lane_departure_margin, arc_path_interval, {});
120120
if (arc_paths.empty()) {
121121
return std::vector<PathWithLaneId>{};
122122
}
@@ -222,7 +222,8 @@ bool GeometricParallelParking::planPullOver(
222222

223223
bool GeometricParallelParking::planPullOut(
224224
const Pose & start_pose, const Pose & goal_pose, const lanelet::ConstLanelets & road_lanes,
225-
const lanelet::ConstLanelets & shoulder_lanes, const bool left_side_start)
225+
const lanelet::ConstLanelets & shoulder_lanes, const bool left_side_start,
226+
const std::shared_ptr<lane_departure_checker::LaneDepartureChecker> lane_departure_checker)
226227
{
227228
constexpr bool is_forward = false; // parking backward means pull_out forward
228229
constexpr double start_pose_offset = 0.0; // start_pose is current_pose
@@ -242,7 +243,7 @@ bool GeometricParallelParking::planPullOut(
242243
auto arc_paths = planOneTrial(
243244
*end_pose, start_pose, R_E_min_, road_lanes, shoulder_lanes, is_forward, left_side_start,
244245
start_pose_offset, parameters_.pull_out_lane_departure_margin,
245-
parameters_.pull_out_path_interval);
246+
parameters_.pull_out_path_interval, lane_departure_checker);
246247
if (arc_paths.empty()) {
247248
// not found path
248249
continue;
@@ -362,7 +363,8 @@ std::vector<PathWithLaneId> GeometricParallelParking::planOneTrial(
362363
const Pose & start_pose, const Pose & goal_pose, const double R_E_far,
363364
const lanelet::ConstLanelets & road_lanes, const lanelet::ConstLanelets & shoulder_lanes,
364365
const bool is_forward, const bool left_side_parking, const double end_pose_offset,
365-
const double lane_departure_margin, const double arc_path_interval)
366+
const double lane_departure_margin, const double arc_path_interval,
367+
const std::shared_ptr<lane_departure_checker::LaneDepartureChecker> lane_departure_checker)
366368
{
367369
clearPaths();
368370

@@ -496,6 +498,24 @@ std::vector<PathWithLaneId> GeometricParallelParking::planOneTrial(
496498
setLaneIdsToPath(path_turn_first);
497499
setLaneIdsToPath(path_turn_second);
498500

501+
if (lane_departure_checker) {
502+
const auto lanelet_map_ptr = planner_data_->route_handler->getLaneletMapPtr();
503+
504+
const bool is_path_turn_first_outside_lanes =
505+
lane_departure_checker->checkPathWillLeaveLane(lanelet_map_ptr, path_turn_first);
506+
507+
if (is_path_turn_first_outside_lanes) {
508+
return std::vector<PathWithLaneId>{};
509+
}
510+
511+
const bool is_path_turn_second_outside_lanes =
512+
lane_departure_checker->checkPathWillLeaveLane(lanelet_map_ptr, path_turn_second);
513+
514+
if (is_path_turn_second_outside_lanes) {
515+
return std::vector<PathWithLaneId>{};
516+
}
517+
}
518+
499519
// generate arc path vector
500520
paths_.push_back(path_turn_first);
501521
paths_.push_back(path_turn_second);

0 commit comments

Comments
 (0)