ros2_control - iron
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 "diagnostic_updater/diagnostic_updater.hpp"
44#include "hardware_interface/handle.hpp"
45#include "hardware_interface/resource_manager.hpp"
46
47#include "pluginlib/class_loader.hpp"
48
49#include "rclcpp/executor.hpp"
50#include "rclcpp/node.hpp"
51#include "rclcpp/node_interfaces/node_logging_interface.hpp"
52#include "rclcpp/node_interfaces/node_parameters_interface.hpp"
53#include "rclcpp/parameter.hpp"
54#include "rclcpp/rclcpp.hpp"
55#include "std_msgs/msg/string.hpp"
56
57namespace controller_manager
58{
59using ControllersListIterator = std::vector<controller_manager::ControllerSpec>::const_iterator;
60
61CONTROLLER_MANAGER_PUBLIC rclcpp::NodeOptions get_cm_node_options();
62
63class ControllerManager : public rclcpp::Node
64{
65public:
66 static constexpr bool kWaitForAllResources = false;
67 static constexpr auto kInfiniteTimeout = 0;
68
69 CONTROLLER_MANAGER_PUBLIC
71 std::unique_ptr<hardware_interface::ResourceManager> resource_manager,
72 std::shared_ptr<rclcpp::Executor> executor,
73 const std::string & manager_node_name = "controller_manager",
74 const std::string & namespace_ = "",
75 const rclcpp::NodeOptions & options = get_cm_node_options());
76
77 CONTROLLER_MANAGER_PUBLIC
79 std::shared_ptr<rclcpp::Executor> executor,
80 const std::string & manager_node_name = "controller_manager",
81 const std::string & namespace_ = "",
82 const rclcpp::NodeOptions & options = get_cm_node_options());
83
84 CONTROLLER_MANAGER_PUBLIC
85 virtual ~ControllerManager() = default;
86
87 CONTROLLER_MANAGER_PUBLIC
88 void robot_description_callback(const std_msgs::msg::String & msg);
89
90 CONTROLLER_MANAGER_PUBLIC
91 void init_resource_manager(const std::string & robot_description);
92
93 CONTROLLER_MANAGER_PUBLIC
94 controller_interface::ControllerInterfaceBaseSharedPtr load_controller(
95 const std::string & controller_name, const std::string & controller_type);
96
98
103 CONTROLLER_MANAGER_PUBLIC
104 controller_interface::ControllerInterfaceBaseSharedPtr load_controller(
105 const std::string & controller_name);
106
107 CONTROLLER_MANAGER_PUBLIC
108 controller_interface::return_type unload_controller(const std::string & controller_name);
109
110 CONTROLLER_MANAGER_PUBLIC
111 std::vector<ControllerSpec> get_loaded_controllers() const;
112
113 template <
114 typename T, typename std::enable_if<
115 std::is_convertible<T *, controller_interface::ControllerInterfaceBase *>::value,
116 T>::type * = nullptr>
117 controller_interface::ControllerInterfaceBaseSharedPtr add_controller(
118 std::shared_ptr<T> controller, const std::string & controller_name,
119 const std::string & controller_type)
120 {
121 ControllerSpec controller_spec;
122 controller_spec.c = controller;
123 controller_spec.info.name = controller_name;
124 controller_spec.info.type = controller_type;
125 controller_spec.last_update_cycle_time = std::make_shared<rclcpp::Time>(0);
126 return add_controller_impl(controller_spec);
127 }
128
130
135 CONTROLLER_MANAGER_PUBLIC
136 controller_interface::return_type configure_controller(const std::string & controller_name);
137
139
145 CONTROLLER_MANAGER_PUBLIC
146 controller_interface::return_type switch_controller(
147 const std::vector<std::string> & activate_controllers,
148 const std::vector<std::string> & deactivate_controllers, int strictness,
149 bool activate_asap = kWaitForAllResources,
150 const rclcpp::Duration & timeout = rclcpp::Duration::from_nanoseconds(kInfiniteTimeout));
151
153
160 CONTROLLER_MANAGER_PUBLIC
161 void read(const rclcpp::Time & time, const rclcpp::Duration & period);
162
164
171 CONTROLLER_MANAGER_PUBLIC
172 controller_interface::return_type update(
173 const rclcpp::Time & time, const rclcpp::Duration & period);
174
176
183 CONTROLLER_MANAGER_PUBLIC
184 void write(const rclcpp::Time & time, const rclcpp::Duration & period);
185
187
191 // TODO(anyone): Due to issues with the MutliThreadedExecutor, this control loop does not rely on
192 // the executor (see issue #260).
193 // rclcpp::CallbackGroup::SharedPtr deterministic_callback_group_;
194
195 // Per controller update rate support
196 CONTROLLER_MANAGER_PUBLIC
197 unsigned int get_update_rate() const;
198
199protected:
200 CONTROLLER_MANAGER_PUBLIC
201 void init_services();
202
203 CONTROLLER_MANAGER_PUBLIC
204 controller_interface::ControllerInterfaceBaseSharedPtr add_controller_impl(
205 const ControllerSpec & controller);
206
207 CONTROLLER_MANAGER_PUBLIC
208 void manage_switch();
209
211
218 CONTROLLER_MANAGER_PUBLIC
220 const std::vector<ControllerSpec> & rt_controller_list,
221 const std::vector<std::string> controllers_to_deactivate);
222
231 CONTROLLER_MANAGER_PUBLIC
233 const std::vector<std::string> & chained_mode_switch_list, bool to_chained_mode);
234
236
243 CONTROLLER_MANAGER_PUBLIC
245 const std::vector<ControllerSpec> & rt_controller_list,
246 const std::vector<std::string> controllers_to_activate);
247
249
259 CONTROLLER_MANAGER_PUBLIC
261 const std::vector<ControllerSpec> & rt_controller_list,
262 const std::vector<std::string> controllers_to_activate);
263
264 CONTROLLER_MANAGER_PUBLIC
265 void list_controllers_srv_cb(
266 const std::shared_ptr<controller_manager_msgs::srv::ListControllers::Request> request,
267 std::shared_ptr<controller_manager_msgs::srv::ListControllers::Response> response);
268
269 CONTROLLER_MANAGER_PUBLIC
270 void list_hardware_interfaces_srv_cb(
271 const std::shared_ptr<controller_manager_msgs::srv::ListHardwareInterfaces::Request> request,
272 std::shared_ptr<controller_manager_msgs::srv::ListHardwareInterfaces::Response> response);
273
274 CONTROLLER_MANAGER_PUBLIC
275 void load_controller_service_cb(
276 const std::shared_ptr<controller_manager_msgs::srv::LoadController::Request> request,
277 std::shared_ptr<controller_manager_msgs::srv::LoadController::Response> response);
278
279 CONTROLLER_MANAGER_PUBLIC
280 void configure_controller_service_cb(
281 const std::shared_ptr<controller_manager_msgs::srv::ConfigureController::Request> request,
282 std::shared_ptr<controller_manager_msgs::srv::ConfigureController::Response> response);
283
284 CONTROLLER_MANAGER_PUBLIC
285 void reload_controller_libraries_service_cb(
286 const std::shared_ptr<controller_manager_msgs::srv::ReloadControllerLibraries::Request> request,
287 std::shared_ptr<controller_manager_msgs::srv::ReloadControllerLibraries::Response> response);
288
289 CONTROLLER_MANAGER_PUBLIC
290 void switch_controller_service_cb(
291 const std::shared_ptr<controller_manager_msgs::srv::SwitchController::Request> request,
292 std::shared_ptr<controller_manager_msgs::srv::SwitchController::Response> response);
293
294 CONTROLLER_MANAGER_PUBLIC
295 void unload_controller_service_cb(
296 const std::shared_ptr<controller_manager_msgs::srv::UnloadController::Request> request,
297 std::shared_ptr<controller_manager_msgs::srv::UnloadController::Response> response);
298
299 CONTROLLER_MANAGER_PUBLIC
300 void list_controller_types_srv_cb(
301 const std::shared_ptr<controller_manager_msgs::srv::ListControllerTypes::Request> request,
302 std::shared_ptr<controller_manager_msgs::srv::ListControllerTypes::Response> response);
303
304 CONTROLLER_MANAGER_PUBLIC
305 void list_hardware_components_srv_cb(
306 const std::shared_ptr<controller_manager_msgs::srv::ListHardwareComponents::Request> request,
307 std::shared_ptr<controller_manager_msgs::srv::ListHardwareComponents::Response> response);
308
309 CONTROLLER_MANAGER_PUBLIC
310 void set_hardware_component_state_srv_cb(
311 const std::shared_ptr<controller_manager_msgs::srv::SetHardwareComponentState::Request> request,
312 std::shared_ptr<controller_manager_msgs::srv::SetHardwareComponentState::Response> response);
313
314 // Per controller update rate support
315 unsigned int update_loop_counter_ = 0;
316 unsigned int update_rate_ = 100;
317 std::vector<std::vector<std::string>> chained_controllers_configuration_;
318
319 std::unique_ptr<hardware_interface::ResourceManager> resource_manager_;
320
321private:
322 std::vector<std::string> get_controller_names();
323 std::pair<std::string, std::string> split_command_interface(
324 const std::string & command_interface);
325 void subscribe_to_robot_description_topic();
326
331 void clear_requests();
332
339 void propagate_deactivation_of_chained_mode(const std::vector<ControllerSpec> & controllers);
340
343
366 controller_interface::return_type check_following_controllers_for_activate(
367 const std::vector<ControllerSpec> & controllers, int strictness,
368 const ControllersListIterator controller_it);
369
371
389 controller_interface::return_type check_preceeding_controllers_for_deactivate(
390 const std::vector<ControllerSpec> & controllers, int strictness,
391 const ControllersListIterator controller_it);
392
395
412 bool controller_sorting(
413 const ControllerSpec & ctrl_a, const ControllerSpec & ctrl_b,
414 const std::vector<controller_manager::ControllerSpec> & controllers);
415
416 void controller_activity_diagnostic_callback(diagnostic_updater::DiagnosticStatusWrapper & stat);
417
425 rclcpp::NodeOptions determine_controller_node_options(const ControllerSpec & controller) const;
426
427 diagnostic_updater::Updater diagnostics_updater_;
428
429 std::shared_ptr<rclcpp::Executor> executor_;
430
431 std::shared_ptr<pluginlib::ClassLoader<controller_interface::ControllerInterface>> loader_;
432 std::shared_ptr<pluginlib::ClassLoader<controller_interface::ChainableControllerInterface>>
433 chainable_loader_;
434
436
440 rclcpp::CallbackGroup::SharedPtr best_effort_callback_group_;
441
453 class RTControllerListWrapper
454 {
455 // *INDENT-OFF*
456 public:
457 // *INDENT-ON*
459
464 std::vector<ControllerSpec> & update_and_get_used_by_rt_list();
465
474 std::vector<ControllerSpec> & get_unused_list(
475 const std::lock_guard<std::recursive_mutex> & guard);
476
478
483 const std::vector<ControllerSpec> & get_updated_list(
484 const std::lock_guard<std::recursive_mutex> & guard) const;
485
492 void switch_updated_list(const std::lock_guard<std::recursive_mutex> & guard);
493
494 // Mutex protecting the controllers list
495 // must be acquired before using any list other than the "used by rt"
496 mutable std::recursive_mutex controllers_lock_;
497
498 // *INDENT-OFF*
499 private:
500 // *INDENT-ON*
502
505 int get_other_list(int index) const;
506
507 void wait_until_rt_not_using(
508 int index, std::chrono::microseconds sleep_delay = std::chrono::microseconds(200)) const;
509
510 std::vector<ControllerSpec> controllers_lists_[2];
512 int updated_controllers_index_ = 0;
514 int used_by_realtime_controllers_index_ = -1;
515 };
516
517 RTControllerListWrapper rt_controllers_wrapper_;
520 std::mutex services_lock_;
521 rclcpp::Service<controller_manager_msgs::srv::ListControllers>::SharedPtr
522 list_controllers_service_;
523 rclcpp::Service<controller_manager_msgs::srv::ListControllerTypes>::SharedPtr
524 list_controller_types_service_;
525 rclcpp::Service<controller_manager_msgs::srv::LoadController>::SharedPtr load_controller_service_;
526 rclcpp::Service<controller_manager_msgs::srv::ConfigureController>::SharedPtr
527 configure_controller_service_;
528 rclcpp::Service<controller_manager_msgs::srv::ReloadControllerLibraries>::SharedPtr
529 reload_controller_libraries_service_;
530 rclcpp::Service<controller_manager_msgs::srv::SwitchController>::SharedPtr
531 switch_controller_service_;
532 rclcpp::Service<controller_manager_msgs::srv::UnloadController>::SharedPtr
533 unload_controller_service_;
534
535 rclcpp::Service<controller_manager_msgs::srv::ListHardwareComponents>::SharedPtr
536 list_hardware_components_service_;
537 rclcpp::Service<controller_manager_msgs::srv::ListHardwareInterfaces>::SharedPtr
538 list_hardware_interfaces_service_;
539 rclcpp::Service<controller_manager_msgs::srv::SetHardwareComponentState>::SharedPtr
540 set_hardware_component_state_service_;
541
542 std::vector<std::string> activate_request_, deactivate_request_;
543 std::vector<std::string> to_chained_mode_request_, from_chained_mode_request_;
544 std::vector<std::string> activate_command_interface_request_,
545 deactivate_command_interface_request_;
546
547 rclcpp::Subscription<std_msgs::msg::String>::SharedPtr robot_description_subscription_;
548
549 struct SwitchParams
550 {
551 void reset()
552 {
553 do_switch = false;
554 started = false;
555 strictness = 0;
556 activate_asap = false;
557 }
558
559 bool do_switch;
560 bool started;
561
562 // Switch options
563 int strictness;
564 bool activate_asap;
565 std::chrono::nanoseconds timeout;
566
567 // conditional variable and mutex to wait for the switch to complete
568 std::condition_variable cv;
569 std::mutex mutex;
570 };
571
572 SwitchParams switch_params_;
573
574 class ControllerThreadWrapper
575 {
576 public:
577 ControllerThreadWrapper(
578 std::shared_ptr<controller_interface::ControllerInterfaceBase> & controller,
579 int cm_update_rate)
580 : terminated_(false), controller_(controller), thread_{}, cm_update_rate_(cm_update_rate)
581 {
582 }
583
584 ControllerThreadWrapper(const ControllerThreadWrapper & t) = delete;
585 ControllerThreadWrapper(ControllerThreadWrapper && t) = default;
586 ~ControllerThreadWrapper()
587 {
588 terminated_.store(true, std::memory_order_seq_cst);
589 if (thread_.joinable())
590 {
591 thread_.join();
592 }
593 }
594
595 void activate()
596 {
597 thread_ = std::thread(&ControllerThreadWrapper::call_controller_update, this);
598 }
599
600 void call_controller_update()
601 {
602 using TimePoint = std::chrono::system_clock::time_point;
603 unsigned int used_update_rate =
604 controller_->get_update_rate() == 0
605 ? cm_update_rate_
606 : controller_
607 ->get_update_rate(); // determines if the controller's or CM's update rate is used
608
609 while (!terminated_.load(std::memory_order_relaxed))
610 {
611 auto const period = std::chrono::nanoseconds(1'000'000'000 / used_update_rate);
612 TimePoint next_iteration_time =
613 TimePoint(std::chrono::nanoseconds(controller_->get_node()->now().nanoseconds()));
614
615 if (controller_->get_state().id() == lifecycle_msgs::msg::State::PRIMARY_STATE_ACTIVE)
616 {
617 // critical section, not implemented yet
618 }
619
620 next_iteration_time += period;
621 std::this_thread::sleep_until(next_iteration_time);
622 }
623 }
624
625 private:
626 std::atomic<bool> terminated_;
627 std::shared_ptr<controller_interface::ControllerInterfaceBase> controller_;
628 std::thread thread_;
629 unsigned int cm_update_rate_;
630 };
631
632 std::unordered_map<std::string, std::unique_ptr<ControllerThreadWrapper>>
633 async_controller_threads_;
634};
635
636} // namespace controller_manager
637
638#endif // CONTROLLER_MANAGER__CONTROLLER_MANAGER_HPP_
Definition controller_manager.hpp:64
CONTROLLER_MANAGER_PUBLIC void activate_controllers_asap(const std::vector< ControllerSpec > &rt_controller_list, const std::vector< std::string > controllers_to_activate)
Activate chosen controllers from real-time controller list.
Definition controller_manager.cpp:1658
CONTROLLER_MANAGER_PUBLIC void read(const rclcpp::Time &time, const rclcpp::Duration &period)
Read values to state interfaces.
Definition controller_manager.cpp:2098
CONTROLLER_MANAGER_PUBLIC controller_interface::return_type switch_controller(const std::vector< std::string > &activate_controllers, const std::vector< std::string > &deactivate_controllers, int strictness, bool activate_asap=kWaitForAllResources, const rclcpp::Duration &timeout=rclcpp::Duration::from_nanoseconds(kInfiniteTimeout))
switch_controller Deactivates some controllers and activates others.
Definition controller_manager.cpp:881
CONTROLLER_MANAGER_PUBLIC unsigned int get_update_rate() const
Deterministic (real-time safe) callback group, e.g., update function.
Definition controller_manager.cpp:2310
CONTROLLER_MANAGER_PUBLIC controller_interface::return_type update(const rclcpp::Time &time, const rclcpp::Duration &period)
Run update on controllers.
Definition controller_manager.cpp:2119
CONTROLLER_MANAGER_PUBLIC void switch_chained_mode(const std::vector< std::string > &chained_mode_switch_list, bool to_chained_mode)
Definition controller_manager.cpp:1472
CONTROLLER_MANAGER_PUBLIC void activate_controllers(const std::vector< ControllerSpec > &rt_controller_list, const std::vector< std::string > controllers_to_activate)
Activate chosen controllers from real-time controller list.
Definition controller_manager.cpp:1529
CONTROLLER_MANAGER_PUBLIC void write(const rclcpp::Time &time, const rclcpp::Duration &period)
Write values from command interfaces.
Definition controller_manager.cpp:2215
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:728
CONTROLLER_MANAGER_PUBLIC void deactivate_controllers(const std::vector< ControllerSpec > &rt_controller_list, const std::vector< std::string > controllers_to_deactivate)
Deactivate chosen controllers from real-time controller list.
Definition controller_manager.cpp:1439
Controller Specification.
Definition controller_spec.hpp:38
std::string type
Controller type.
Definition controller_info.hpp:34
std::string name
Controller name.
Definition controller_info.hpp:31