@@ -37,8 +37,8 @@ namespace nav2_controller
37
37
ControllerServer::ControllerServer (const rclcpp::NodeOptions & options)
38
38
: nav2_util::LifecycleNode(" controller_server" , " " , options),
39
39
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" },
42
42
goal_checker_loader_ (" nav2_core" , " nav2_core::GoalChecker" ),
43
43
default_goal_checker_ids_{" goal_checker" },
44
44
default_goal_checker_types_{" nav2_controller::SimpleGoalChecker" },
@@ -50,7 +50,7 @@ ControllerServer::ControllerServer(const rclcpp::NodeOptions & options)
50
50
51
51
declare_parameter (" controller_frequency" , 20.0 );
52
52
53
- declare_parameter (" progress_checker_plugin " , default_progress_checker_id_ );
53
+ declare_parameter (" progress_checker_plugins " , default_progress_checker_ids_ );
54
54
declare_parameter (" goal_checker_plugins" , default_goal_checker_ids_);
55
55
declare_parameter (" controller_plugins" , default_ids_);
56
56
declare_parameter (" min_x_velocity_threshold" , rclcpp::ParameterValue (0.0001 ));
@@ -69,7 +69,7 @@ ControllerServer::ControllerServer(const rclcpp::NodeOptions & options)
69
69
70
70
ControllerServer::~ControllerServer ()
71
71
{
72
- progress_checker_. reset ();
72
+ progress_checkers_. clear ();
73
73
goal_checkers_.clear ();
74
74
controllers_.clear ();
75
75
costmap_thread_.reset ();
@@ -82,11 +82,28 @@ ControllerServer::on_configure(const rclcpp_lifecycle::State & /*state*/)
82
82
83
83
RCLCPP_INFO (get_logger (), " Configuring controller interface" );
84
84
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 {
87
88
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
+ }
90
107
}
91
108
92
109
RCLCPP_INFO (get_logger (), " getting goal checker plugins.." );
@@ -110,6 +127,7 @@ ControllerServer::on_configure(const rclcpp_lifecycle::State & /*state*/)
110
127
111
128
controller_types_.resize (controller_ids_.size ());
112
129
goal_checker_types_.resize (goal_checker_ids_.size ());
130
+ progress_checker_types_.resize (progress_checker_ids_.size ());
113
131
114
132
get_parameter (" controller_frequency" , controller_frequency_);
115
133
get_parameter (" min_x_velocity_threshold" , min_x_velocity_threshold_);
@@ -125,20 +143,33 @@ ControllerServer::on_configure(const rclcpp_lifecycle::State & /*state*/)
125
143
// Launch a thread to run the costmap node
126
144
costmap_thread_ = std::make_unique<nav2_util::NodeThread>(costmap_ros_);
127
145
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 (" " );
140
167
}
141
168
169
+ RCLCPP_INFO (
170
+ get_logger (),
171
+ " Controller Server has %s progress checkers available." , progress_checker_ids_concat_.c_str ());
172
+
142
173
for (size_t i = 0 ; i != goal_checker_ids_.size (); i++) {
143
174
try {
144
175
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*/)
284
315
controllers_.clear ();
285
316
286
317
goal_checkers_.clear ();
318
+ progress_checkers_.clear ();
287
319
if (costmap_ros_->get_current_state ().id () ==
288
320
lifecycle_msgs::msg::State::PRIMARY_STATE_INACTIVE)
289
321
{
@@ -359,6 +391,32 @@ bool ControllerServer::findGoalCheckerId(
359
391
return true ;
360
392
}
361
393
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
+
362
420
void ControllerServer::computeControl ()
363
421
{
364
422
std::lock_guard<std::mutex> lock (dynamic_params_lock_);
@@ -382,8 +440,16 @@ void ControllerServer::computeControl()
382
440
throw nav2_core::ControllerException (" Failed to find goal checker name: " + gc_name);
383
441
}
384
442
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
+
385
451
setPlannerPath (action_server_->get_current_goal ()->path );
386
- progress_checker_ ->reset ();
452
+ progress_checkers_[current_progress_checker_] ->reset ();
387
453
388
454
last_valid_cmd_time_ = now ();
389
455
rclcpp::WallRate loop_rate (controller_frequency_);
@@ -516,7 +582,7 @@ void ControllerServer::computeAndPublishVelocity()
516
582
throw nav2_core::ControllerTFError (" Failed to obtain robot pose" );
517
583
}
518
584
519
- if (!progress_checker_ ->check (pose)) {
585
+ if (!progress_checkers_[current_progress_checker_] ->check (pose)) {
520
586
throw nav2_core::FailedToMakeProgress (" Failed to make progress" );
521
587
}
522
588
@@ -607,6 +673,22 @@ void ControllerServer::updateGlobalPath()
607
673
action_server_->terminate_current ();
608
674
return ;
609
675
}
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
+ }
610
692
setPlannerPath (goal->path );
611
693
}
612
694
}
0 commit comments