Skip to content

Commit 3fa7509

Browse files
authored
feat(behavior_path_planner): add goal planner (autowarefoundation#3454)
* feat(behavior_path_planner): add goal planner Signed-off-by: kosuke55 <kosuke.tnp@gmail.com> * fix test Signed-off-by: kosuke55 <kosuke.tnp@gmail.com> --------- Signed-off-by: kosuke55 <kosuke.tnp@gmail.com>
1 parent f2b7687 commit 3fa7509

File tree

8 files changed

+220
-46
lines changed

8 files changed

+220
-46
lines changed

planning/behavior_path_planner/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ set(common_src
3333
src/utils/pull_over/geometric_pull_over.cpp
3434
src/utils/pull_over/freespace_pull_over.cpp
3535
src/utils/pull_over/goal_searcher.cpp
36+
src/utils/pull_over/default_fixed_goal_planner.cpp
3637
src/utils/pull_out/util.cpp
3738
src/utils/pull_out/shift_pull_out.cpp
3839
src/utils/pull_out/geometric_pull_out.cpp

planning/behavior_path_planner/include/behavior_path_planner/behavior_path_planner_node.hpp

-6
Original file line numberDiff line numberDiff line change
@@ -208,12 +208,6 @@ class BehaviorPathPlannerNode : public rclcpp::Node
208208
const std::shared_ptr<PlannerManager> & planner_manager);
209209
#endif
210210

211-
/**
212-
* @brief skip smooth goal connection
213-
*/
214-
bool skipSmoothGoalConnection(
215-
const std::vector<std::shared_ptr<SceneModuleStatus>> & statuses) const;
216-
217211
bool keepInputPoints(const std::vector<std::shared_ptr<SceneModuleStatus>> & statuses) const;
218212

219213
/**

planning/behavior_path_planner/include/behavior_path_planner/scene_module/pull_over/pull_over_module.hpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "behavior_path_planner/scene_module/scene_module_interface.hpp"
1919
#include "behavior_path_planner/utils/geometric_parallel_parking/geometric_parallel_parking.hpp"
2020
#include "behavior_path_planner/utils/occupancy_grid_based_collision_detector/occupancy_grid_based_collision_detector.hpp"
21+
#include "behavior_path_planner/utils/pull_over/default_fixed_goal_planner.hpp"
2122
#include "behavior_path_planner/utils/pull_over/freespace_pull_over.hpp"
2223
#include "behavior_path_planner/utils/pull_over/geometric_pull_over.hpp"
2324
#include "behavior_path_planner/utils/pull_over/goal_searcher.hpp"
@@ -127,6 +128,7 @@ class PullOverModule : public SceneModuleInterface
127128

128129
std::vector<std::shared_ptr<PullOverPlannerBase>> pull_over_planners_;
129130
std::unique_ptr<PullOverPlannerBase> freespace_planner_;
131+
std::unique_ptr<FixedGoalPlannerBase> fixed_goal_planner_;
130132
std::shared_ptr<GoalSearcherBase> goal_searcher_;
131133
PullOverPath shift_parking_path_;
132134
vehicle_info_util::VehicleInfo vehicle_info_;
@@ -157,7 +159,7 @@ class PullOverModule : public SceneModuleInterface
157159
double approximate_pull_over_distance_{20.0};
158160

159161
bool left_side_parking_{true};
160-
bool enable_goal_search_{false};
162+
bool allow_goal_modification_{false};
161163

162164
bool incrementPathIndex();
163165
PathWithLaneId getCurrentPath() const;
@@ -195,6 +197,9 @@ class PullOverModule : public SceneModuleInterface
195197
bool returnToLaneParking();
196198
bool isStuck();
197199

200+
BehaviorModuleOutput planWithGoalModification();
201+
BehaviorModuleOutput planWaitingApprovalWithGoalModification();
202+
198203
// timer for generating pull over path candidates
199204
void onTimer();
200205
rclcpp::TimerBase::SharedPtr lane_parking_timer_;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright 2023 TIER IV, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef BEHAVIOR_PATH_PLANNER__UTILS__PULL_OVER__DEFAULT_FIXED_GOAL_PLANNER_HPP_
16+
#define BEHAVIOR_PATH_PLANNER__UTILS__PULL_OVER__DEFAULT_FIXED_GOAL_PLANNER_HPP_
17+
18+
#include "behavior_path_planner/utils/pull_over/fixed_goal_planner_base.hpp"
19+
20+
#include <autoware_auto_planning_msgs/msg/path_with_lane_id.hpp>
21+
22+
#include <memory>
23+
#include <vector>
24+
25+
namespace behavior_path_planner
26+
{
27+
28+
class DefaultFixedGoalPlanner : public FixedGoalPlannerBase
29+
{
30+
public:
31+
DefaultFixedGoalPlanner() = default;
32+
BehaviorModuleOutput plan(const std::shared_ptr<const PlannerData> & planner_data) const override;
33+
34+
protected:
35+
boost::optional<BehaviorModuleOutput> getReferencePath(
36+
const std::shared_ptr<const PlannerData> & planner_data) const;
37+
PathWithLaneId modifyPathForSmoothGoalConnection(
38+
const PathWithLaneId & path, const std::shared_ptr<const PlannerData> & planner_data) const;
39+
};
40+
} // namespace behavior_path_planner
41+
42+
#endif // BEHAVIOR_PATH_PLANNER__UTILS__PULL_OVER__DEFAULT_FIXED_GOAL_PLANNER_HPP_
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright 2023 TIER IV, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef BEHAVIOR_PATH_PLANNER__UTILS__PULL_OVER__FIXED_GOAL_PLANNER_BASE_HPP_
16+
#define BEHAVIOR_PATH_PLANNER__UTILS__PULL_OVER__FIXED_GOAL_PLANNER_BASE_HPP_
17+
18+
#include "behavior_path_planner/data_manager.hpp"
19+
#include "behavior_path_planner/parameters.hpp"
20+
21+
#include <autoware_auto_planning_msgs/msg/path_with_lane_id.hpp>
22+
#include <geometry_msgs/msg/pose_stamped.hpp>
23+
24+
#include <memory>
25+
#include <vector>
26+
27+
using autoware_auto_planning_msgs::msg::PathWithLaneId;
28+
using geometry_msgs::msg::Pose;
29+
using tier4_autoware_utils::LinearRing2d;
30+
31+
namespace behavior_path_planner
32+
{
33+
34+
class FixedGoalPlannerBase
35+
{
36+
public:
37+
FixedGoalPlannerBase() = default;
38+
virtual ~FixedGoalPlannerBase() = default;
39+
40+
virtual BehaviorModuleOutput plan(
41+
const std::shared_ptr<const PlannerData> & planner_data) const = 0;
42+
};
43+
} // namespace behavior_path_planner
44+
45+
#endif // BEHAVIOR_PATH_PLANNER__UTILS__PULL_OVER__FIXED_GOAL_PLANNER_BASE_HPP_

planning/behavior_path_planner/src/behavior_path_planner_node.cpp

+1-28
Original file line numberDiff line numberDiff line change
@@ -1346,39 +1346,12 @@ PathWithLaneId::SharedPtr BehaviorPathPlannerNode::getPath(
13461346
#else
13471347
const auto module_status_ptr_vec = planner_manager->getSceneModuleStatus();
13481348
#endif
1349-
if (skipSmoothGoalConnection(module_status_ptr_vec)) {
1350-
connected_path = *path;
1351-
} else {
1352-
connected_path = modifyPathForSmoothGoalConnection(*path, planner_data);
1353-
}
13541349

13551350
const auto resampled_path = utils::resamplePathWithSpline(
1356-
connected_path, planner_data->parameters.output_path_interval,
1357-
keepInputPoints(module_status_ptr_vec));
1351+
*path, planner_data->parameters.output_path_interval, keepInputPoints(module_status_ptr_vec));
13581352
return std::make_shared<PathWithLaneId>(resampled_path);
13591353
}
13601354

1361-
bool BehaviorPathPlannerNode::skipSmoothGoalConnection(
1362-
const std::vector<std::shared_ptr<SceneModuleStatus>> & statuses) const
1363-
{
1364-
#ifdef USE_OLD_ARCHITECTURE
1365-
const auto target_module = "PullOver";
1366-
#else
1367-
const auto target_module = "pull_over";
1368-
#endif
1369-
1370-
const auto target_status = ModuleStatus::RUNNING;
1371-
1372-
for (auto & status : statuses) {
1373-
if (status->is_waiting_approval || status->status == target_status) {
1374-
if (target_module == status->module_name) {
1375-
return true;
1376-
}
1377-
}
1378-
}
1379-
return false;
1380-
}
1381-
13821355
// This is a temporary process until motion planning can take the terminal pose into account
13831356
bool BehaviorPathPlannerNode::keepInputPoints(
13841357
const std::vector<std::shared_ptr<SceneModuleStatus>> & statuses) const

planning/behavior_path_planner/src/scene_module/pull_over/pull_over_module.cpp

+41-11
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ PullOverModule::PullOverModule(
7272

7373
left_side_parking_ = parameters_->parking_policy == ParkingPolicy::LEFT_SIDE;
7474

75+
// planner when goal modification is not allowed
76+
fixed_goal_planner_ = std::make_unique<DefaultFixedGoalPlanner>();
77+
7578
// set enabled planner
7679
if (parameters_->enable_shift_parking) {
7780
pull_over_planners_.push_back(std::make_shared<ShiftPullOver>(
@@ -289,7 +292,7 @@ void PullOverModule::processOnEntry()
289292
// todo: remove `checkOriginalGoalIsInShoulder()`
290293
// the function here is temporary condition for backward compatibility.
291294
// if the goal is in shoulder, allow goal_modification
292-
enable_goal_search_ =
295+
allow_goal_modification_ =
293296
route_handler->isAllowedGoalModification() || checkOriginalGoalIsInShoulder();
294297

295298
// initialize when receiving new route
@@ -301,7 +304,7 @@ void PullOverModule::processOnEntry()
301304
// calculate goal candidates
302305
const Pose goal_pose = route_handler->getGoalPose();
303306
refined_goal_pose_ = calcRefinedGoal(goal_pose);
304-
if (enable_goal_search_) {
307+
if (allow_goal_modification_) {
305308
goal_searcher_->setPlannerData(planner_data_);
306309
goal_candidates_ = goal_searcher_->search(refined_goal_pose_);
307310
} else {
@@ -336,15 +339,24 @@ bool PullOverModule::isExecutionRequested() const
336339
lanelet::utils::query::getClosestLanelet(current_lanes, current_pose, &current_lane);
337340
const double self_to_goal_arc_length =
338341
utils::getSignedDistance(current_pose, goal_pose, current_lanes);
339-
if (self_to_goal_arc_length > calcModuleRequestLength()) {
342+
const bool allow_goal_modification =
343+
route_handler->isAllowedGoalModification() || checkOriginalGoalIsInShoulder();
344+
const double request_length =
345+
allow_goal_modification ? calcModuleRequestLength() : parameters_->minimum_request_length;
346+
if (self_to_goal_arc_length > request_length) {
340347
return false;
341348
}
342349

343-
// check if target lane is shoulder lane and goal_pose is in the lane
344-
const bool goal_is_in_shoulder = checkOriginalGoalIsInShoulder();
345-
// if allow_goal_modification is set false and goal is in road lane, do not execute pull over
346-
if (!route_handler->isAllowedGoalModification() && !goal_is_in_shoulder) {
347-
return false;
350+
// if goal modification is not allowed and goal_pose in current_lanes,
351+
// plan path to the original fixed goal
352+
if (!allow_goal_modification) {
353+
if (std::any_of(
354+
current_lanes.begin(), current_lanes.end(),
355+
[&](const lanelet::ConstLanelet & current_lane) {
356+
return lanelet::utils::isInLanelet(goal_pose, current_lane);
357+
})) {
358+
return true;
359+
}
348360
}
349361

350362
// if (A) or (B) is met execute pull over
@@ -490,6 +502,15 @@ bool PullOverModule::returnToLaneParking()
490502
}
491503

492504
BehaviorModuleOutput PullOverModule::plan()
505+
{
506+
if (allow_goal_modification_) {
507+
return planWithGoalModification();
508+
} else {
509+
return fixed_goal_planner_->plan(planner_data_);
510+
}
511+
}
512+
513+
BehaviorModuleOutput PullOverModule::planWithGoalModification()
493514
{
494515
const auto & current_pose = planner_data_->self_odometry->pose.pose;
495516
const double current_vel = planner_data_->self_odometry->twist.twist.linear.x;
@@ -686,7 +707,7 @@ BehaviorModuleOutput PullOverModule::plan()
686707

687708
// Publish the modified goal only when it is updated
688709
if (
689-
enable_goal_search_ && status_.is_safe && modified_goal_pose_ &&
710+
allow_goal_modification_ && status_.is_safe && modified_goal_pose_ &&
690711
(!prev_goal_id_ || *prev_goal_id_ != modified_goal_pose_->id)) {
691712
PoseWithUuidStamped modified_goal{};
692713
modified_goal.uuid = route_handler->getRouteUuid();
@@ -731,6 +752,15 @@ CandidateOutput PullOverModule::planCandidate() const
731752
}
732753

733754
BehaviorModuleOutput PullOverModule::planWaitingApproval()
755+
{
756+
if (allow_goal_modification_) {
757+
return planWaitingApprovalWithGoalModification();
758+
} else {
759+
return fixed_goal_planner_->plan(planner_data_);
760+
}
761+
}
762+
763+
BehaviorModuleOutput PullOverModule::planWaitingApprovalWithGoalModification()
734764
{
735765
updateOccupancyGrid();
736766
BehaviorModuleOutput out;
@@ -1215,7 +1245,7 @@ bool PullOverModule::isCrossingPossible(
12151245
return true;
12161246
}
12171247

1218-
// Travesing is not allowed between road lanes
1248+
// Traversing is not allowed between road lanes
12191249
if (!is_shoulder_lane) {
12201250
continue;
12211251
}
@@ -1273,7 +1303,7 @@ void PullOverModule::setDebugData()
12731303
tier4_autoware_utils::appendMarkerArray(added, &debug_marker_);
12741304
};
12751305

1276-
if (enable_goal_search_) {
1306+
if (allow_goal_modification_) {
12771307
// Visualize pull over areas
12781308
const auto color = status_.has_decided_path ? createMarkerColor(1.0, 1.0, 0.0, 0.999) // yellow
12791309
: createMarkerColor(0.0, 1.0, 0.0, 0.999); // green
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// Copyright 2023 TIER IV, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "behavior_path_planner/utils/pull_over/default_fixed_goal_planner.hpp"
16+
17+
#include "behavior_path_planner/utils/path_utils.hpp"
18+
#include "behavior_path_planner/utils/pull_over/util.hpp"
19+
20+
#include <lanelet2_extension/utility/query.hpp>
21+
#include <lanelet2_extension/utility/utilities.hpp>
22+
23+
#include <memory>
24+
#include <vector>
25+
26+
namespace behavior_path_planner
27+
{
28+
29+
BehaviorModuleOutput DefaultFixedGoalPlanner::plan(
30+
const std::shared_ptr<const PlannerData> & planner_data) const
31+
{
32+
auto output = getReferencePath(planner_data);
33+
if (!output) {
34+
return {};
35+
}
36+
const PathWithLaneId smoothed_path =
37+
modifyPathForSmoothGoalConnection(*(output->path), planner_data);
38+
39+
output->path = std::make_shared<PathWithLaneId>(smoothed_path);
40+
output->reference_path = std::make_shared<PathWithLaneId>(smoothed_path);
41+
return *output;
42+
}
43+
44+
boost::optional<BehaviorModuleOutput> DefaultFixedGoalPlanner::getReferencePath(
45+
const std::shared_ptr<const PlannerData> & planner_data) const
46+
{
47+
const auto & route_handler = planner_data->route_handler;
48+
const auto current_pose = planner_data->self_odometry->pose.pose;
49+
const double dist_threshold = planner_data->parameters.ego_nearest_dist_threshold;
50+
const double yaw_threshold = planner_data->parameters.ego_nearest_yaw_threshold;
51+
52+
lanelet::ConstLanelet current_lane{};
53+
if (!route_handler->getClosestLaneletWithConstrainsWithinRoute(
54+
current_pose, &current_lane, dist_threshold, yaw_threshold)) {
55+
return {}; // TODO(Horibe)
56+
}
57+
58+
return utils::getReferencePath(current_lane, planner_data);
59+
}
60+
61+
PathWithLaneId DefaultFixedGoalPlanner::modifyPathForSmoothGoalConnection(
62+
const PathWithLaneId & path, const std::shared_ptr<const PlannerData> & planner_data) const
63+
{
64+
const auto goal = planner_data->route_handler->getGoalPose();
65+
const auto goal_lane_id = planner_data->route_handler->getGoalLaneId();
66+
67+
Pose refined_goal{};
68+
{
69+
lanelet::ConstLanelet goal_lanelet;
70+
if (planner_data->route_handler->getGoalLanelet(&goal_lanelet)) {
71+
refined_goal = utils::refineGoal(goal, goal_lanelet);
72+
} else {
73+
refined_goal = goal;
74+
}
75+
}
76+
77+
auto refined_path = utils::refinePathForGoal(
78+
planner_data->parameters.refine_goal_search_radius_range, M_PI * 0.5, path, refined_goal,
79+
goal_lane_id);
80+
81+
return refined_path;
82+
}
83+
84+
} // namespace behavior_path_planner

0 commit comments

Comments
 (0)