ros2_control - humble
Loading...
Searching...
No Matches
controller_manager.hpp
1// Copyright 2020 Open Source Robotics Foundation, 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 CONTROLLER_MANAGER__CONTROLLER_MANAGER_HPP_
16#define CONTROLLER_MANAGER__CONTROLLER_MANAGER_HPP_
17
18#include <map>
19#include <memory>
20#include <string>
21#include <tuple>
22#include <unordered_map>
23#include <utility>
24#include <vector>
25
26#include "controller_interface/chainable_controller_interface.hpp"
27#include "controller_interface/controller_interface.hpp"
28#include "controller_interface/controller_interface_base.hpp"
29
30#include "controller_manager/controller_spec.hpp"
31#include "controller_manager/visibility_control.h"
32#include "controller_manager_msgs/srv/configure_controller.hpp"
33#include "controller_manager_msgs/srv/list_controller_types.hpp"
34#include "controller_manager_msgs/srv/list_controllers.hpp"
35#include "controller_manager_msgs/srv/list_hardware_components.hpp"
36#include "controller_manager_msgs/srv/list_hardware_interfaces.hpp"
37#include "controller_manager_msgs/srv/load_controller.hpp"
38#include "controller_manager_msgs/srv/reload_controller_libraries.hpp"
39#include "controller_manager_msgs/srv/set_hardware_component_state.hpp"
40#include "controller_manager_msgs/srv/switch_controller.hpp"
41#include "controller_manager_msgs/srv/unload_controller.hpp"
42
43#include "hardware_interface/handle.hpp"
44#include "hardware_interface/resource_manager.hpp"
45
46#include "pluginlib/class_loader.hpp"
47
48#include "rclcpp/executor.hpp"
49#include "rclcpp/node.hpp"
50#include "rclcpp/node_interfaces/node_logging_interface.hpp"
51#include "rclcpp/node_interfaces/node_parameters_interface.hpp"
52#include "rclcpp/parameter.hpp"
53#include "rclcpp/rclcpp.hpp"
54#include "std_msgs/msg/string.hpp"
55
56namespace controller_manager
57{
58using ControllersListIterator = std::vector<controller_manager::ControllerSpec>::const_iterator;
59
60CONTROLLER_MANAGER_PUBLIC rclcpp::NodeOptions get_cm_node_options();
61
62class ControllerManager : public rclcpp::Node
63{
64public:
65 static constexpr bool kWaitForAllResources = false;
66 static constexpr auto kInfiniteTimeout = 0;
67
68 CONTROLLER_MANAGER_PUBLIC
70 std::unique_ptr<hardware_interface::ResourceManager> resource_manager,
71 std::shared_ptr<rclcpp::Executor> executor,
72 const std::string & manager_node_name = "controller_manager",
73 const std::string & namespace_ = "",
74 const rclcpp::NodeOptions & options = get_cm_node_options());
75
76 CONTROLLER_MANAGER_PUBLIC
78 std::shared_ptr<rclcpp::Executor> executor,
79 const std::string & manager_node_name = "controller_manager",
80 const std::string & namespace_ = "",
81 const rclcpp::NodeOptions & options = get_cm_node_options());
82
83 CONTROLLER_MANAGER_PUBLIC
84 virtual ~ControllerManager();
85
87
90 CONTROLLER_MANAGER_PUBLIC
92
93 CONTROLLER_MANAGER_PUBLIC
94 void robot_description_callback(const std_msgs::msg::String & msg);
95
96 CONTROLLER_MANAGER_PUBLIC
97 void init_resource_manager(const std::string & robot_description);
98
99 CONTROLLER_MANAGER_PUBLIC
100 controller_interface::ControllerInterfaceBaseSharedPtr load_controller(
101 const std::string & controller_name, const std::string & controller_type);
102
104
109 CONTROLLER_MANAGER_PUBLIC
110 controller_interface::ControllerInterfaceBaseSharedPtr load_controller(
111 const std::string & controller_name);
112
113 CONTROLLER_MANAGER_PUBLIC
114 controller_interface::return_type unload_controller(const std::string & controller_name);
115
116 CONTROLLER_MANAGER_PUBLIC
117 std::vector<ControllerSpec> get_loaded_controllers() const;
118
119 template <
120 typename T, typename std::enable_if<
121 std::is_convertible<T *, controller_interface::ControllerInterfaceBase *>::value,
122 T>::type * = nullptr>
123 controller_interface::ControllerInterfaceBaseSharedPtr add_controller(
124 std::shared_ptr<T> controller, const std::string & controller_name,
125 const std::string & controller_type)
126 {
127 ControllerSpec controller_spec;
128 controller_spec.c = controller;
129 controller_spec.info.name = controller_name;
130 controller_spec.info.type = controller_type;
131 return add_controller_impl(controller_spec);
132 }
133
135
140 CONTROLLER_MANAGER_PUBLIC
141 controller_interface::return_type configure_controller(const std::string & controller_name);
142
144
150 CONTROLLER_MANAGER_PUBLIC
151 controller_interface::return_type switch_controller(
152 const std::vector<std::string> & start_controllers,
153 const std::vector<std::string> & stop_controllers, int strictness,
154 bool activate_asap = kWaitForAllResources,
155 const rclcpp::Duration & timeout = rclcpp::Duration::from_nanoseconds(kInfiniteTimeout));
156
158
165 CONTROLLER_MANAGER_PUBLIC
166 void read(const rclcpp::Time & time, const rclcpp::Duration & period);
167
169
176 CONTROLLER_MANAGER_PUBLIC
177 controller_interface::return_type update(
178 const rclcpp::Time & time, const rclcpp::Duration & period);
179
181
188 CONTROLLER_MANAGER_PUBLIC
189 void write(const rclcpp::Time & time, const rclcpp::Duration & period);
190
192
196 // TODO(anyone): Due to issues with the MutliThreadedExecutor, this control loop does not rely on
197 // the executor (see issue #260).
198 // rclcpp::CallbackGroup::SharedPtr deterministic_callback_group_;
199
200 // Per controller update rate support
201 CONTROLLER_MANAGER_PUBLIC
202 unsigned int get_update_rate() const;
203
204protected:
205 CONTROLLER_MANAGER_PUBLIC
206 void init_services();
207
208 CONTROLLER_MANAGER_PUBLIC
209 controller_interface::ControllerInterfaceBaseSharedPtr add_controller_impl(
210 const ControllerSpec & controller);
211
212 CONTROLLER_MANAGER_PUBLIC
213 void manage_switch();
214
215 CONTROLLER_MANAGER_PUBLIC
216 void deactivate_controllers();
217
226 CONTROLLER_MANAGER_PUBLIC
228 const std::vector<std::string> & chained_mode_switch_list, bool to_chained_mode);
229
230 CONTROLLER_MANAGER_PUBLIC
231 void activate_controllers();
232
233 CONTROLLER_MANAGER_PUBLIC
234 void activate_controllers_asap();
235
236 CONTROLLER_MANAGER_PUBLIC
237 void list_controllers_srv_cb(
238 const std::shared_ptr<controller_manager_msgs::srv::ListControllers::Request> request,
239 std::shared_ptr<controller_manager_msgs::srv::ListControllers::Response> response);
240
241 CONTROLLER_MANAGER_PUBLIC
242 void list_hardware_interfaces_srv_cb(
243 const std::shared_ptr<controller_manager_msgs::srv::ListHardwareInterfaces::Request> request,
244 std::shared_ptr<controller_manager_msgs::srv::ListHardwareInterfaces::Response> response);
245
246 CONTROLLER_MANAGER_PUBLIC
247 void load_controller_service_cb(
248 const std::shared_ptr<controller_manager_msgs::srv::LoadController::Request> request,
249 std::shared_ptr<controller_manager_msgs::srv::LoadController::Response> response);
250
251 CONTROLLER_MANAGER_PUBLIC
252 void configure_controller_service_cb(
253 const std::shared_ptr<controller_manager_msgs::srv::ConfigureController::Request> request,
254 std::shared_ptr<controller_manager_msgs::srv::ConfigureController::Response> response);
255
256 CONTROLLER_MANAGER_PUBLIC
257 void reload_controller_libraries_service_cb(
258 const std::shared_ptr<controller_manager_msgs::srv::ReloadControllerLibraries::Request> request,
259 std::shared_ptr<controller_manager_msgs::srv::ReloadControllerLibraries::Response> response);
260
261 CONTROLLER_MANAGER_PUBLIC
262 void switch_controller_service_cb(
263 const std::shared_ptr<controller_manager_msgs::srv::SwitchController::Request> request,
264 std::shared_ptr<controller_manager_msgs::srv::SwitchController::Response> response);
265
266 CONTROLLER_MANAGER_PUBLIC
267 void unload_controller_service_cb(
268 const std::shared_ptr<controller_manager_msgs::srv::UnloadController::Request> request,
269 std::shared_ptr<controller_manager_msgs::srv::UnloadController::Response> response);
270
271 CONTROLLER_MANAGER_PUBLIC
272 void list_controller_types_srv_cb(
273 const std::shared_ptr<controller_manager_msgs::srv::ListControllerTypes::Request> request,
274 std::shared_ptr<controller_manager_msgs::srv::ListControllerTypes::Response> response);
275
276 CONTROLLER_MANAGER_PUBLIC
277 void list_hardware_components_srv_cb(
278 const std::shared_ptr<controller_manager_msgs::srv::ListHardwareComponents::Request> request,
279 std::shared_ptr<controller_manager_msgs::srv::ListHardwareComponents::Response> response);
280
281 CONTROLLER_MANAGER_PUBLIC
282 void set_hardware_component_state_srv_cb(
283 const std::shared_ptr<controller_manager_msgs::srv::SetHardwareComponentState::Request> request,
284 std::shared_ptr<controller_manager_msgs::srv::SetHardwareComponentState::Response> response);
285
286 // Per controller update rate support
287 unsigned int update_loop_counter_ = 0;
288 unsigned int update_rate_ = 100;
289 std::vector<std::vector<std::string>> chained_controllers_configuration_;
290
291 std::unique_ptr<hardware_interface::ResourceManager> resource_manager_;
292
293private:
294 std::vector<std::string> get_controller_names();
295 std::pair<std::string, std::string> split_command_interface(
296 const std::string & command_interface);
297 void subscribe_to_robot_description_topic();
298
303 void clear_requests();
304
311 void propagate_deactivation_of_chained_mode(const std::vector<ControllerSpec> & controllers);
312
315
338 controller_interface::return_type check_following_controllers_for_activate(
339 const std::vector<ControllerSpec> & controllers, int strictness,
340 const ControllersListIterator controller_it);
341
343
361 controller_interface::return_type check_preceeding_controllers_for_deactivate(
362 const std::vector<ControllerSpec> & controllers, int strictness,
363 const ControllersListIterator controller_it);
364
367
384 bool controller_sorting(
385 const ControllerSpec & ctrl_a, const ControllerSpec & ctrl_b,
386 const std::vector<controller_manager::ControllerSpec> & controllers);
387
395 rclcpp::NodeOptions determine_controller_node_options(const ControllerSpec & controller) const;
396
397 std::shared_ptr<rclcpp::Executor> executor_;
398
399 std::shared_ptr<pluginlib::ClassLoader<controller_interface::ControllerInterface>> loader_;
400 std::shared_ptr<pluginlib::ClassLoader<controller_interface::ChainableControllerInterface>>
401 chainable_loader_;
402
404
408 rclcpp::CallbackGroup::SharedPtr best_effort_callback_group_;
409
421 class RTControllerListWrapper
422 {
423 // *INDENT-OFF*
424 public:
425 // *INDENT-ON*
427
432 std::vector<ControllerSpec> & update_and_get_used_by_rt_list();
433
442 std::vector<ControllerSpec> & get_unused_list(
443 const std::lock_guard<std::recursive_mutex> & guard);
444
446
451 const std::vector<ControllerSpec> & get_updated_list(
452 const std::lock_guard<std::recursive_mutex> & guard) const;
453
460 void switch_updated_list(const std::lock_guard<std::recursive_mutex> & guard);
461
462 // Mutex protecting the controllers list
463 // must be acquired before using any list other than the "used by rt"
464 mutable std::recursive_mutex controllers_lock_;
465
466 // *INDENT-OFF*
467 private:
468 // *INDENT-ON*
470
473 int get_other_list(int index) const;
474
475 void wait_until_rt_not_using(
476 int index, std::chrono::microseconds sleep_delay = std::chrono::microseconds(200)) const;
477
478 std::vector<ControllerSpec> controllers_lists_[2];
480 int updated_controllers_index_ = 0;
482 int used_by_realtime_controllers_index_ = -1;
483 };
484
485 std::unique_ptr<rclcpp::PreShutdownCallbackHandle> preshutdown_cb_handle_{nullptr};
486 RTControllerListWrapper rt_controllers_wrapper_;
489 std::mutex services_lock_;
490 rclcpp::Service<controller_manager_msgs::srv::ListControllers>::SharedPtr
491 list_controllers_service_;
492 rclcpp::Service<controller_manager_msgs::srv::ListControllerTypes>::SharedPtr
493 list_controller_types_service_;
494 rclcpp::Service<controller_manager_msgs::srv::LoadController>::SharedPtr load_controller_service_;
495 rclcpp::Service<controller_manager_msgs::srv::ConfigureController>::SharedPtr
496 configure_controller_service_;
497 rclcpp::Service<controller_manager_msgs::srv::ReloadControllerLibraries>::SharedPtr
498 reload_controller_libraries_service_;
499 rclcpp::Service<controller_manager_msgs::srv::SwitchController>::SharedPtr
500 switch_controller_service_;
501 rclcpp::Service<controller_manager_msgs::srv::UnloadController>::SharedPtr
502 unload_controller_service_;
503
504 rclcpp::Service<controller_manager_msgs::srv::ListHardwareComponents>::SharedPtr
505 list_hardware_components_service_;
506 rclcpp::Service<controller_manager_msgs::srv::ListHardwareInterfaces>::SharedPtr
507 list_hardware_interfaces_service_;
508 rclcpp::Service<controller_manager_msgs::srv::SetHardwareComponentState>::SharedPtr
509 set_hardware_component_state_service_;
510
511 std::vector<std::string> activate_request_, deactivate_request_;
512 std::vector<std::string> to_chained_mode_request_, from_chained_mode_request_;
513 std::vector<std::string> activate_command_interface_request_,
514 deactivate_command_interface_request_;
515
516 rclcpp::Subscription<std_msgs::msg::String>::SharedPtr robot_description_subscription_;
517
518 struct SwitchParams
519 {
520 void reset()
521 {
522 do_switch = false;
523 started = false;
524 strictness = 0;
525 activate_asap = false;
526 }
527
528 bool do_switch;
529 bool started;
530
531 // Switch options
532 int strictness;
533 bool activate_asap;
534 std::chrono::nanoseconds timeout;
535
536 // conditional variable and mutex to wait for the switch to complete
537 std::condition_variable cv;
538 std::mutex mutex;
539 };
540
541 SwitchParams switch_params_;
542};
543
544} // namespace controller_manager
545
546#endif // CONTROLLER_MANAGER__CONTROLLER_MANAGER_HPP_
Definition controller_manager.hpp:63
CONTROLLER_MANAGER_PUBLIC void read(const rclcpp::Time &time, const rclcpp::Duration &period)
Read values to state interfaces.
Definition controller_manager.cpp:2173
CONTROLLER_MANAGER_PUBLIC controller_interface::return_type switch_controller(const std::vector< std::string > &start_controllers, const std::vector< std::string > &stop_controllers, int strictness, bool activate_asap=kWaitForAllResources, const rclcpp::Duration &timeout=rclcpp::Duration::from_nanoseconds(kInfiniteTimeout))
switch_controller Stops some controllers and start others.
Definition controller_manager.cpp:943
CONTROLLER_MANAGER_PUBLIC unsigned int get_update_rate() const
Deterministic (real-time safe) callback group, e.g., update function.
Definition controller_manager.cpp:2312
CONTROLLER_MANAGER_PUBLIC controller_interface::return_type update(const rclcpp::Time &time, const rclcpp::Duration &period)
Run update on controllers.
Definition controller_manager.cpp:2178
CONTROLLER_MANAGER_PUBLIC bool shutdown_controllers()
Shutdown all controllers in the controller manager.
Definition controller_manager.cpp:343
CONTROLLER_MANAGER_PUBLIC void switch_chained_mode(const std::vector< std::string > &chained_mode_switch_list, bool to_chained_mode)
Definition controller_manager.cpp:1520
CONTROLLER_MANAGER_PUBLIC void write(const rclcpp::Time &time, const rclcpp::Duration &period)
Write values from command interfaces.
Definition controller_manager.cpp:2233
CONTROLLER_MANAGER_PUBLIC controller_interface::return_type configure_controller(const std::string &controller_name)
configure_controller Configure controller by name calling their "configure" method.
Definition controller_manager.cpp:794
Controller Specification.
Definition controller_spec.hpp:37
std::string type
Controller type.
Definition controller_info.hpp:34
std::string name
Controller name.
Definition controller_info.hpp:31