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() = default;
85
86 CONTROLLER_MANAGER_PUBLIC
87 void robot_description_callback(const std_msgs::msg::String & msg);
88
89 CONTROLLER_MANAGER_PUBLIC
90 void init_resource_manager(const std::string & robot_description);
91
92 CONTROLLER_MANAGER_PUBLIC
93 controller_interface::ControllerInterfaceBaseSharedPtr load_controller(
94 const std::string & controller_name, const std::string & controller_type);
95
97
102 CONTROLLER_MANAGER_PUBLIC
103 controller_interface::ControllerInterfaceBaseSharedPtr load_controller(
104 const std::string & controller_name);
105
106 CONTROLLER_MANAGER_PUBLIC
107 controller_interface::return_type unload_controller(const std::string & controller_name);
108
109 CONTROLLER_MANAGER_PUBLIC
110 std::vector<ControllerSpec> get_loaded_controllers() const;
111
112 template <
113 typename T, typename std::enable_if<
114 std::is_convertible<T *, controller_interface::ControllerInterfaceBase *>::value,
115 T>::type * = nullptr>
116 controller_interface::ControllerInterfaceBaseSharedPtr add_controller(
117 std::shared_ptr<T> controller, const std::string & controller_name,
118 const std::string & controller_type)
119 {
120 ControllerSpec controller_spec;
121 controller_spec.c = controller;
122 controller_spec.info.name = controller_name;
123 controller_spec.info.type = controller_type;
124 return add_controller_impl(controller_spec);
125 }
126
128
133 CONTROLLER_MANAGER_PUBLIC
134 controller_interface::return_type configure_controller(const std::string & controller_name);
135
137
143 CONTROLLER_MANAGER_PUBLIC
144 controller_interface::return_type switch_controller(
145 const std::vector<std::string> & start_controllers,
146 const std::vector<std::string> & stop_controllers, int strictness,
147 bool activate_asap = kWaitForAllResources,
148 const rclcpp::Duration & timeout = rclcpp::Duration::from_nanoseconds(kInfiniteTimeout));
149
151
158 CONTROLLER_MANAGER_PUBLIC
159 void read(const rclcpp::Time & time, const rclcpp::Duration & period);
160
162
169 CONTROLLER_MANAGER_PUBLIC
170 controller_interface::return_type update(
171 const rclcpp::Time & time, const rclcpp::Duration & period);
172
174
181 CONTROLLER_MANAGER_PUBLIC
182 void write(const rclcpp::Time & time, const rclcpp::Duration & period);
183
185
189 // TODO(anyone): Due to issues with the MutliThreadedExecutor, this control loop does not rely on
190 // the executor (see issue #260).
191 // rclcpp::CallbackGroup::SharedPtr deterministic_callback_group_;
192
193 // Per controller update rate support
194 CONTROLLER_MANAGER_PUBLIC
195 unsigned int get_update_rate() const;
196
197protected:
198 CONTROLLER_MANAGER_PUBLIC
199 void init_services();
200
201 CONTROLLER_MANAGER_PUBLIC
202 controller_interface::ControllerInterfaceBaseSharedPtr add_controller_impl(
203 const ControllerSpec & controller);
204
205 CONTROLLER_MANAGER_PUBLIC
206 void manage_switch();
207
208 CONTROLLER_MANAGER_PUBLIC
209 void deactivate_controllers();
210
219 CONTROLLER_MANAGER_PUBLIC
221 const std::vector<std::string> & chained_mode_switch_list, bool to_chained_mode);
222
223 CONTROLLER_MANAGER_PUBLIC
224 void activate_controllers();
225
226 CONTROLLER_MANAGER_PUBLIC
227 void activate_controllers_asap();
228
229 CONTROLLER_MANAGER_PUBLIC
230 void list_controllers_srv_cb(
231 const std::shared_ptr<controller_manager_msgs::srv::ListControllers::Request> request,
232 std::shared_ptr<controller_manager_msgs::srv::ListControllers::Response> response);
233
234 CONTROLLER_MANAGER_PUBLIC
235 void list_hardware_interfaces_srv_cb(
236 const std::shared_ptr<controller_manager_msgs::srv::ListHardwareInterfaces::Request> request,
237 std::shared_ptr<controller_manager_msgs::srv::ListHardwareInterfaces::Response> response);
238
239 CONTROLLER_MANAGER_PUBLIC
240 void load_controller_service_cb(
241 const std::shared_ptr<controller_manager_msgs::srv::LoadController::Request> request,
242 std::shared_ptr<controller_manager_msgs::srv::LoadController::Response> response);
243
244 CONTROLLER_MANAGER_PUBLIC
245 void configure_controller_service_cb(
246 const std::shared_ptr<controller_manager_msgs::srv::ConfigureController::Request> request,
247 std::shared_ptr<controller_manager_msgs::srv::ConfigureController::Response> response);
248
249 CONTROLLER_MANAGER_PUBLIC
250 void reload_controller_libraries_service_cb(
251 const std::shared_ptr<controller_manager_msgs::srv::ReloadControllerLibraries::Request> request,
252 std::shared_ptr<controller_manager_msgs::srv::ReloadControllerLibraries::Response> response);
253
254 CONTROLLER_MANAGER_PUBLIC
255 void switch_controller_service_cb(
256 const std::shared_ptr<controller_manager_msgs::srv::SwitchController::Request> request,
257 std::shared_ptr<controller_manager_msgs::srv::SwitchController::Response> response);
258
259 CONTROLLER_MANAGER_PUBLIC
260 void unload_controller_service_cb(
261 const std::shared_ptr<controller_manager_msgs::srv::UnloadController::Request> request,
262 std::shared_ptr<controller_manager_msgs::srv::UnloadController::Response> response);
263
264 CONTROLLER_MANAGER_PUBLIC
265 void list_controller_types_srv_cb(
266 const std::shared_ptr<controller_manager_msgs::srv::ListControllerTypes::Request> request,
267 std::shared_ptr<controller_manager_msgs::srv::ListControllerTypes::Response> response);
268
269 CONTROLLER_MANAGER_PUBLIC
270 void list_hardware_components_srv_cb(
271 const std::shared_ptr<controller_manager_msgs::srv::ListHardwareComponents::Request> request,
272 std::shared_ptr<controller_manager_msgs::srv::ListHardwareComponents::Response> response);
273
274 CONTROLLER_MANAGER_PUBLIC
275 void set_hardware_component_state_srv_cb(
276 const std::shared_ptr<controller_manager_msgs::srv::SetHardwareComponentState::Request> request,
277 std::shared_ptr<controller_manager_msgs::srv::SetHardwareComponentState::Response> response);
278
279 // Per controller update rate support
280 unsigned int update_loop_counter_ = 0;
281 unsigned int update_rate_ = 100;
282 std::vector<std::vector<std::string>> chained_controllers_configuration_;
283
284 std::unique_ptr<hardware_interface::ResourceManager> resource_manager_;
285
286private:
287 std::vector<std::string> get_controller_names();
288 std::pair<std::string, std::string> split_command_interface(
289 const std::string & command_interface);
290 void subscribe_to_robot_description_topic();
291
296 void clear_requests();
297
304 void propagate_deactivation_of_chained_mode(const std::vector<ControllerSpec> & controllers);
305
308
331 controller_interface::return_type check_following_controllers_for_activate(
332 const std::vector<ControllerSpec> & controllers, int strictness,
333 const ControllersListIterator controller_it);
334
336
354 controller_interface::return_type check_preceeding_controllers_for_deactivate(
355 const std::vector<ControllerSpec> & controllers, int strictness,
356 const ControllersListIterator controller_it);
357
360
377 bool controller_sorting(
378 const ControllerSpec & ctrl_a, const ControllerSpec & ctrl_b,
379 const std::vector<controller_manager::ControllerSpec> & controllers);
380
388 rclcpp::NodeOptions determine_controller_node_options(const ControllerSpec & controller) const;
389
390 std::shared_ptr<rclcpp::Executor> executor_;
391
392 std::shared_ptr<pluginlib::ClassLoader<controller_interface::ControllerInterface>> loader_;
393 std::shared_ptr<pluginlib::ClassLoader<controller_interface::ChainableControllerInterface>>
394 chainable_loader_;
395
397
401 rclcpp::CallbackGroup::SharedPtr best_effort_callback_group_;
402
414 class RTControllerListWrapper
415 {
416 // *INDENT-OFF*
417 public:
418 // *INDENT-ON*
420
425 std::vector<ControllerSpec> & update_and_get_used_by_rt_list();
426
435 std::vector<ControllerSpec> & get_unused_list(
436 const std::lock_guard<std::recursive_mutex> & guard);
437
439
444 const std::vector<ControllerSpec> & get_updated_list(
445 const std::lock_guard<std::recursive_mutex> & guard) const;
446
453 void switch_updated_list(const std::lock_guard<std::recursive_mutex> & guard);
454
455 // Mutex protecting the controllers list
456 // must be acquired before using any list other than the "used by rt"
457 mutable std::recursive_mutex controllers_lock_;
458
459 // *INDENT-OFF*
460 private:
461 // *INDENT-ON*
463
466 int get_other_list(int index) const;
467
468 void wait_until_rt_not_using(
469 int index, std::chrono::microseconds sleep_delay = std::chrono::microseconds(200)) const;
470
471 std::vector<ControllerSpec> controllers_lists_[2];
473 int updated_controllers_index_ = 0;
475 int used_by_realtime_controllers_index_ = -1;
476 };
477
478 RTControllerListWrapper rt_controllers_wrapper_;
481 std::mutex services_lock_;
482 rclcpp::Service<controller_manager_msgs::srv::ListControllers>::SharedPtr
483 list_controllers_service_;
484 rclcpp::Service<controller_manager_msgs::srv::ListControllerTypes>::SharedPtr
485 list_controller_types_service_;
486 rclcpp::Service<controller_manager_msgs::srv::LoadController>::SharedPtr load_controller_service_;
487 rclcpp::Service<controller_manager_msgs::srv::ConfigureController>::SharedPtr
488 configure_controller_service_;
489 rclcpp::Service<controller_manager_msgs::srv::ReloadControllerLibraries>::SharedPtr
490 reload_controller_libraries_service_;
491 rclcpp::Service<controller_manager_msgs::srv::SwitchController>::SharedPtr
492 switch_controller_service_;
493 rclcpp::Service<controller_manager_msgs::srv::UnloadController>::SharedPtr
494 unload_controller_service_;
495
496 rclcpp::Service<controller_manager_msgs::srv::ListHardwareComponents>::SharedPtr
497 list_hardware_components_service_;
498 rclcpp::Service<controller_manager_msgs::srv::ListHardwareInterfaces>::SharedPtr
499 list_hardware_interfaces_service_;
500 rclcpp::Service<controller_manager_msgs::srv::SetHardwareComponentState>::SharedPtr
501 set_hardware_component_state_service_;
502
503 std::vector<std::string> activate_request_, deactivate_request_;
504 std::vector<std::string> to_chained_mode_request_, from_chained_mode_request_;
505 std::vector<std::string> activate_command_interface_request_,
506 deactivate_command_interface_request_;
507
508 rclcpp::Subscription<std_msgs::msg::String>::SharedPtr robot_description_subscription_;
509
510 struct SwitchParams
511 {
512 void reset()
513 {
514 do_switch = false;
515 started = false;
516 strictness = 0;
517 activate_asap = false;
518 }
519
520 bool do_switch;
521 bool started;
522
523 // Switch options
524 int strictness;
525 bool activate_asap;
526 std::chrono::nanoseconds timeout;
527
528 // conditional variable and mutex to wait for the switch to complete
529 std::condition_variable cv;
530 std::mutex mutex;
531 };
532
533 SwitchParams switch_params_;
534};
535
536} // namespace controller_manager
537
538#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:2083
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:872
CONTROLLER_MANAGER_PUBLIC unsigned int get_update_rate() const
Deterministic (real-time safe) callback group, e.g., update function.
Definition controller_manager.cpp:2222
CONTROLLER_MANAGER_PUBLIC controller_interface::return_type update(const rclcpp::Time &time, const rclcpp::Duration &period)
Run update on controllers.
Definition controller_manager.cpp:2088
CONTROLLER_MANAGER_PUBLIC void switch_chained_mode(const std::vector< std::string > &chained_mode_switch_list, bool to_chained_mode)
Definition controller_manager.cpp:1449
CONTROLLER_MANAGER_PUBLIC void write(const rclcpp::Time &time, const rclcpp::Duration &period)
Write values from command interfaces.
Definition controller_manager.cpp:2143
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:723
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