Skip to content

Commit 07a9127

Browse files
doisygGuillaume DoisySteveMacenski
authored
[controller_server] [FollowPath] Allow multiple progress checkers (ros-navigation#3555)
* allow multiple progress checker plugin * merge conflict * handle change of progress checker during a preempt * reset pc on preempt * fix default declaration * Handle deprecated progress_checker_plugin * improve readability * Update nav2_controller/src/controller_server.cpp --------- Co-authored-by: Guillaume Doisy <[email protected]> Co-authored-by: Steve Macenski <[email protected]>
1 parent 85fd06f commit 07a9127

File tree

14 files changed

+141
-36
lines changed

14 files changed

+141
-36
lines changed

nav2_behavior_tree/include/nav2_behavior_tree/plugins/action/follow_path_action.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ class FollowPathAction : public BtActionNode<nav2_msgs::action::FollowPath>
8484
BT::InputPort<nav_msgs::msg::Path>("path", "Path to follow"),
8585
BT::InputPort<std::string>("controller_id", ""),
8686
BT::InputPort<std::string>("goal_checker_id", ""),
87+
BT::InputPort<std::string>("progress_checker_id", ""),
8788
BT::OutputPort<ActionResult::_error_code_type>(
8889
"error_code_id", "The follow path error code"),
8990
});

nav2_behavior_tree/nav2_tree_nodes.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,8 @@
114114
<input_port name="controller_id" default="FollowPath"/>
115115
<input_port name="path">Path to follow</input_port>
116116
<input_port name="goal_checker_id">Goal checker</input_port>
117-
<input_port name="server_name">Server name</input_port>
117+
<input_port name="progress_checker_id">Progress checker</input_port>
118+
<input_port name="service_name">Service name</input_port>
118119
<input_port name="server_timeout">Server timeout</input_port>
119120
<output_port name="error_code_id">Follow Path error code</output_port>
120121
</Action>

nav2_behavior_tree/plugins/action/follow_path_action.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ void FollowPathAction::on_tick()
3333
getInput("path", goal_.path);
3434
getInput("controller_id", goal_.controller_id);
3535
getInput("goal_checker_id", goal_.goal_checker_id);
36+
getInput("progress_checker_id", goal_.progress_checker_id);
3637
}
3738

3839
BT::NodeStatus FollowPathAction::on_success()
@@ -83,6 +84,14 @@ void FollowPathAction::on_wait_for_result(
8384
goal_.goal_checker_id = new_goal_checker_id;
8485
goal_updated_ = true;
8586
}
87+
88+
std::string new_progress_checker_id;
89+
getInput("progress_checker_id", new_progress_checker_id);
90+
91+
if (goal_.progress_checker_id != new_progress_checker_id) {
92+
goal_.progress_checker_id = new_progress_checker_id;
93+
goal_updated_ = true;
94+
}
8695
}
8796

8897
} // namespace nav2_behavior_tree

nav2_bringup/params/nav2_multirobot_params_1.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ controller_server:
116116
min_x_velocity_threshold: 0.001
117117
min_y_velocity_threshold: 0.5
118118
min_theta_velocity_threshold: 0.001
119-
progress_checker_plugin: "progress_checker"
119+
progress_checker_plugins: ["progress_checker"]
120120
goal_checker_plugins: ["goal_checker"]
121121
controller_plugins: ["FollowPath"]
122122

nav2_bringup/params/nav2_multirobot_params_2.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ controller_server:
116116
min_x_velocity_threshold: 0.001
117117
min_y_velocity_threshold: 0.5
118118
min_theta_velocity_threshold: 0.001
119-
progress_checker_plugin: "progress_checker"
119+
progress_checker_plugins: ["progress_checker"]
120120
goal_checker_plugins: ["goal_checker"]
121121
controller_plugins: ["FollowPath"]
122122

nav2_bringup/params/nav2_params.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ controller_server:
117117
min_y_velocity_threshold: 0.5
118118
min_theta_velocity_threshold: 0.001
119119
failure_tolerance: 0.3
120-
progress_checker_plugin: "progress_checker"
120+
progress_checker_plugins: ["progress_checker"]
121121
goal_checker_plugins: ["general_goal_checker"] # "precise_goal_checker"
122122
controller_plugins: ["FollowPath"]
123123

nav2_controller/include/nav2_controller/controller_server.hpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ class ControllerServer : public nav2_util::LifecycleNode
5050
public:
5151
using ControllerMap = std::unordered_map<std::string, nav2_core::Controller::Ptr>;
5252
using GoalCheckerMap = std::unordered_map<std::string, nav2_core::GoalChecker::Ptr>;
53+
using ProgressCheckerMap = std::unordered_map<std::string, nav2_core::ProgressChecker::Ptr>;
5354

5455
/**
5556
* @brief Constructor for nav2_controller::ControllerServer
@@ -142,6 +143,15 @@ class ControllerServer : public nav2_util::LifecycleNode
142143
*/
143144
bool findGoalCheckerId(const std::string & c_name, std::string & name);
144145

146+
/**
147+
* @brief Find the valid progress checker ID name for the specified parameter
148+
*
149+
* @param c_name The progress checker name
150+
* @param name Reference to the name to use for progress checking if any valid available
151+
* @return bool Whether it found a valid progress checker to use
152+
*/
153+
bool findProgressCheckerId(const std::string & c_name, std::string & name);
154+
145155
/**
146156
* @brief Assigns path to controller
147157
* @param path Path received from action server
@@ -224,11 +234,12 @@ class ControllerServer : public nav2_util::LifecycleNode
224234

225235
// Progress Checker Plugin
226236
pluginlib::ClassLoader<nav2_core::ProgressChecker> progress_checker_loader_;
227-
nav2_core::ProgressChecker::Ptr progress_checker_;
228-
std::string default_progress_checker_id_;
229-
std::string default_progress_checker_type_;
230-
std::string progress_checker_id_;
231-
std::string progress_checker_type_;
237+
ProgressCheckerMap progress_checkers_;
238+
std::vector<std::string> default_progress_checker_ids_;
239+
std::vector<std::string> default_progress_checker_types_;
240+
std::vector<std::string> progress_checker_ids_;
241+
std::vector<std::string> progress_checker_types_;
242+
std::string progress_checker_ids_concat_, current_progress_checker_;
232243

233244
// Goal Checker Plugin
234245
pluginlib::ClassLoader<nav2_core::GoalChecker> goal_checker_loader_;

nav2_controller/src/controller_server.cpp

Lines changed: 104 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ namespace nav2_controller
3737
ControllerServer::ControllerServer(const rclcpp::NodeOptions & options)
3838
: nav2_util::LifecycleNode("controller_server", "", options),
3939
progress_checker_loader_("nav2_core", "nav2_core::ProgressChecker"),
40-
default_progress_checker_id_{"progress_checker"},
41-
default_progress_checker_type_{"nav2_controller::SimpleProgressChecker"},
40+
default_progress_checker_ids_{"progress_checker"},
41+
default_progress_checker_types_{"nav2_controller::SimpleProgressChecker"},
4242
goal_checker_loader_("nav2_core", "nav2_core::GoalChecker"),
4343
default_goal_checker_ids_{"goal_checker"},
4444
default_goal_checker_types_{"nav2_controller::SimpleGoalChecker"},
@@ -50,7 +50,7 @@ ControllerServer::ControllerServer(const rclcpp::NodeOptions & options)
5050

5151
declare_parameter("controller_frequency", 20.0);
5252

53-
declare_parameter("progress_checker_plugin", default_progress_checker_id_);
53+
declare_parameter("progress_checker_plugins", default_progress_checker_ids_);
5454
declare_parameter("goal_checker_plugins", default_goal_checker_ids_);
5555
declare_parameter("controller_plugins", default_ids_);
5656
declare_parameter("min_x_velocity_threshold", rclcpp::ParameterValue(0.0001));
@@ -69,7 +69,7 @@ ControllerServer::ControllerServer(const rclcpp::NodeOptions & options)
6969

7070
ControllerServer::~ControllerServer()
7171
{
72-
progress_checker_.reset();
72+
progress_checkers_.clear();
7373
goal_checkers_.clear();
7474
controllers_.clear();
7575
costmap_thread_.reset();
@@ -82,11 +82,28 @@ ControllerServer::on_configure(const rclcpp_lifecycle::State & /*state*/)
8282

8383
RCLCPP_INFO(get_logger(), "Configuring controller interface");
8484

85-
get_parameter("progress_checker_plugin", progress_checker_id_);
86-
if (progress_checker_id_ == default_progress_checker_id_) {
85+
RCLCPP_INFO(get_logger(), "getting progress checker plugins..");
86+
get_parameter("progress_checker_plugins", progress_checker_ids_);
87+
try {
8788
nav2_util::declare_parameter_if_not_declared(
88-
node, default_progress_checker_id_ + ".plugin",
89-
rclcpp::ParameterValue(default_progress_checker_type_));
89+
node, "progress_checker_plugin", rclcpp::PARAMETER_STRING);
90+
std::string progress_checker_plugin;
91+
progress_checker_plugin = node->get_parameter("progress_checker_plugin").as_string();
92+
progress_checker_ids_.clear();
93+
progress_checker_ids_.push_back(progress_checker_plugin);
94+
RCLCPP_WARN(
95+
get_logger(),
96+
"\"progress_checker_plugin\" parameter was deprecated and will be removed soon. Use "
97+
"\"progress_checker_plugins\" instead to specify a list of plugins");
98+
} catch (const std::exception &) {
99+
// This is normal situation: progress_checker_plugin parameter should not being declared
100+
}
101+
if (progress_checker_ids_ == default_progress_checker_ids_) {
102+
for (size_t i = 0; i < default_progress_checker_ids_.size(); ++i) {
103+
nav2_util::declare_parameter_if_not_declared(
104+
node, default_progress_checker_ids_[i] + ".plugin",
105+
rclcpp::ParameterValue(default_progress_checker_types_[i]));
106+
}
90107
}
91108

92109
RCLCPP_INFO(get_logger(), "getting goal checker plugins..");
@@ -110,6 +127,7 @@ ControllerServer::on_configure(const rclcpp_lifecycle::State & /*state*/)
110127

111128
controller_types_.resize(controller_ids_.size());
112129
goal_checker_types_.resize(goal_checker_ids_.size());
130+
progress_checker_types_.resize(progress_checker_ids_.size());
113131

114132
get_parameter("controller_frequency", controller_frequency_);
115133
get_parameter("min_x_velocity_threshold", min_x_velocity_threshold_);
@@ -125,20 +143,33 @@ ControllerServer::on_configure(const rclcpp_lifecycle::State & /*state*/)
125143
// Launch a thread to run the costmap node
126144
costmap_thread_ = std::make_unique<nav2_util::NodeThread>(costmap_ros_);
127145

128-
try {
129-
progress_checker_type_ = nav2_util::get_plugin_type_param(node, progress_checker_id_);
130-
progress_checker_ = progress_checker_loader_.createUniqueInstance(progress_checker_type_);
131-
RCLCPP_INFO(
132-
get_logger(), "Created progress_checker : %s of type %s",
133-
progress_checker_id_.c_str(), progress_checker_type_.c_str());
134-
progress_checker_->initialize(node, progress_checker_id_);
135-
} catch (const pluginlib::PluginlibException & ex) {
136-
RCLCPP_FATAL(
137-
get_logger(),
138-
"Failed to create progress_checker. Exception: %s", ex.what());
139-
return nav2_util::CallbackReturn::FAILURE;
146+
for (size_t i = 0; i != progress_checker_ids_.size(); i++) {
147+
try {
148+
progress_checker_types_[i] = nav2_util::get_plugin_type_param(
149+
node, progress_checker_ids_[i]);
150+
nav2_core::ProgressChecker::Ptr progress_checker =
151+
progress_checker_loader_.createUniqueInstance(progress_checker_types_[i]);
152+
RCLCPP_INFO(
153+
get_logger(), "Created progress_checker : %s of type %s",
154+
progress_checker_ids_[i].c_str(), progress_checker_types_[i].c_str());
155+
progress_checker->initialize(node, progress_checker_ids_[i]);
156+
progress_checkers_.insert({progress_checker_ids_[i], progress_checker});
157+
} catch (const pluginlib::PluginlibException & ex) {
158+
RCLCPP_FATAL(
159+
get_logger(),
160+
"Failed to create progress_checker. Exception: %s", ex.what());
161+
return nav2_util::CallbackReturn::FAILURE;
162+
}
163+
}
164+
165+
for (size_t i = 0; i != progress_checker_ids_.size(); i++) {
166+
progress_checker_ids_concat_ += progress_checker_ids_[i] + std::string(" ");
140167
}
141168

169+
RCLCPP_INFO(
170+
get_logger(),
171+
"Controller Server has %s progress checkers available.", progress_checker_ids_concat_.c_str());
172+
142173
for (size_t i = 0; i != goal_checker_ids_.size(); i++) {
143174
try {
144175
goal_checker_types_[i] = nav2_util::get_plugin_type_param(node, goal_checker_ids_[i]);
@@ -284,6 +315,7 @@ ControllerServer::on_cleanup(const rclcpp_lifecycle::State & /*state*/)
284315
controllers_.clear();
285316

286317
goal_checkers_.clear();
318+
progress_checkers_.clear();
287319
if (costmap_ros_->get_current_state().id() ==
288320
lifecycle_msgs::msg::State::PRIMARY_STATE_INACTIVE)
289321
{
@@ -359,6 +391,32 @@ bool ControllerServer::findGoalCheckerId(
359391
return true;
360392
}
361393

394+
bool ControllerServer::findProgressCheckerId(
395+
const std::string & c_name,
396+
std::string & current_progress_checker)
397+
{
398+
if (progress_checkers_.find(c_name) == progress_checkers_.end()) {
399+
if (progress_checkers_.size() == 1 && c_name.empty()) {
400+
RCLCPP_WARN_ONCE(
401+
get_logger(), "No progress checker was specified in parameter 'current_progress_checker'."
402+
" Server will use only plugin loaded %s. "
403+
"This warning will appear once.", progress_checker_ids_concat_.c_str());
404+
current_progress_checker = progress_checkers_.begin()->first;
405+
} else {
406+
RCLCPP_ERROR(
407+
get_logger(), "FollowPath called with progress_checker name %s in parameter"
408+
" 'current_progress_checker', which does not exist. Available progress checkers are: %s.",
409+
c_name.c_str(), progress_checker_ids_concat_.c_str());
410+
return false;
411+
}
412+
} else {
413+
RCLCPP_DEBUG(get_logger(), "Selected progress checker: %s.", c_name.c_str());
414+
current_progress_checker = c_name;
415+
}
416+
417+
return true;
418+
}
419+
362420
void ControllerServer::computeControl()
363421
{
364422
std::lock_guard<std::mutex> lock(dynamic_params_lock_);
@@ -382,8 +440,16 @@ void ControllerServer::computeControl()
382440
throw nav2_core::ControllerException("Failed to find goal checker name: " + gc_name);
383441
}
384442

443+
std::string pc_name = action_server_->get_current_goal()->progress_checker_id;
444+
std::string current_progress_checker;
445+
if (findProgressCheckerId(pc_name, current_progress_checker)) {
446+
current_progress_checker_ = current_progress_checker;
447+
} else {
448+
throw nav2_core::ControllerException("Failed to find progress checker name: " + pc_name);
449+
}
450+
385451
setPlannerPath(action_server_->get_current_goal()->path);
386-
progress_checker_->reset();
452+
progress_checkers_[current_progress_checker_]->reset();
387453

388454
last_valid_cmd_time_ = now();
389455
rclcpp::WallRate loop_rate(controller_frequency_);
@@ -516,7 +582,7 @@ void ControllerServer::computeAndPublishVelocity()
516582
throw nav2_core::ControllerTFError("Failed to obtain robot pose");
517583
}
518584

519-
if (!progress_checker_->check(pose)) {
585+
if (!progress_checkers_[current_progress_checker_]->check(pose)) {
520586
throw nav2_core::FailedToMakeProgress("Failed to make progress");
521587
}
522588

@@ -607,6 +673,22 @@ void ControllerServer::updateGlobalPath()
607673
action_server_->terminate_current();
608674
return;
609675
}
676+
std::string current_progress_checker;
677+
if (findProgressCheckerId(goal->progress_checker_id, current_progress_checker)) {
678+
if (current_progress_checker_ != current_progress_checker) {
679+
RCLCPP_INFO(
680+
get_logger(), "Change of progress checker %s requested, resetting it",
681+
goal->progress_checker_id.c_str());
682+
current_progress_checker_ = current_progress_checker;
683+
progress_checkers_[current_progress_checker_]->reset();
684+
}
685+
} else {
686+
RCLCPP_INFO(
687+
get_logger(), "Terminating action, invalid progress checker %s requested.",
688+
goal->progress_checker_id.c_str());
689+
action_server_->terminate_current();
690+
return;
691+
}
610692
setPlannerPath(goal->path);
611693
}
612694
}

nav2_msgs/action/FollowPath.action

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ uint16 NO_VALID_CONTROL=106
1313
nav_msgs/Path path
1414
string controller_id
1515
string goal_checker_id
16+
string progress_checker_id
1617
---
1718
#result definition
1819
std_msgs/Empty result

nav2_regulated_pure_pursuit_controller/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ controller_server:
8888
min_x_velocity_threshold: 0.001
8989
min_y_velocity_threshold: 0.5
9090
min_theta_velocity_threshold: 0.001
91-
progress_checker_plugin: "progress_checker"
91+
progress_checker_plugins: ["progress_checker"]
9292
goal_checker_plugins: "goal_checker"
9393
controller_plugins: ["FollowPath"]
9494

nav2_rotation_shim_controller/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ controller_server:
4545
min_x_velocity_threshold: 0.001
4646
min_y_velocity_threshold: 0.5
4747
min_theta_velocity_threshold: 0.001
48-
progress_checker_plugin: "progress_checker"
48+
progress_checker_plugins: ["progress_checker"]
4949
goal_checker_plugins: "goal_checker"
5050
controller_plugins: ["FollowPath"]
5151

nav2_system_tests/src/costmap_filters/keepout_params.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ controller_server:
9999
min_x_velocity_threshold: 0.001
100100
min_y_velocity_threshold: 0.5
101101
min_theta_velocity_threshold: 0.001
102-
progress_checker_plugin: "progress_checker"
102+
progress_checker_plugins: ["progress_checker"]
103103
goal_checker_plugins: ["goal_checker"]
104104
controller_plugins: ["FollowPath"]
105105

nav2_system_tests/src/costmap_filters/speed_global_params.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ controller_server:
101101
min_y_velocity_threshold: 0.5
102102
min_theta_velocity_threshold: 0.001
103103
speed_limit_topic: "/speed_limit"
104-
progress_checker_plugin: "progress_checker"
104+
progress_checker_plugins: ["progress_checker"]
105105
goal_checker_plugins: ["goal_checker"]
106106
controller_plugins: ["FollowPath"]
107107

nav2_system_tests/src/costmap_filters/speed_local_params.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ controller_server:
101101
min_y_velocity_threshold: 0.5
102102
min_theta_velocity_threshold: 0.001
103103
speed_limit_topic: "/speed_limit"
104-
progress_checker_plugin: "progress_checker"
104+
progress_checker_plugins: ["progress_checker"]
105105
goal_checker_plugins: ["goal_checker"]
106106
controller_plugins: ["FollowPath"]
107107

0 commit comments

Comments
 (0)