ros2_control - kilted
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 <unordered_map>
22#include <utility>
23#include <vector>
24
25#include "controller_interface/chainable_controller_interface.hpp"
26#include "controller_interface/controller_interface.hpp"
27#include "controller_interface/controller_interface_base.hpp"
28
29#include "controller_manager/controller_spec.hpp"
30#include "controller_manager_msgs/msg/controller_manager_activity.hpp"
31#include "controller_manager_msgs/srv/configure_controller.hpp"
32#include "controller_manager_msgs/srv/list_controller_types.hpp"
33#include "controller_manager_msgs/srv/list_controllers.hpp"
34#include "controller_manager_msgs/srv/list_hardware_components.hpp"
35#include "controller_manager_msgs/srv/list_hardware_interfaces.hpp"
36#include "controller_manager_msgs/srv/load_controller.hpp"
37#include "controller_manager_msgs/srv/reload_controller_libraries.hpp"
38#include "controller_manager_msgs/srv/set_hardware_component_state.hpp"
39#include "controller_manager_msgs/srv/switch_controller.hpp"
40#include "controller_manager_msgs/srv/unload_controller.hpp"
41
42#include "diagnostic_updater/diagnostic_updater.hpp"
43#include "hardware_interface/helpers.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 "std_msgs/msg/string.hpp"
51
52namespace controller_manager
53{
54class ParamListener;
55struct Params;
56using ControllersListIterator = std::vector<controller_manager::ControllerSpec>::const_iterator;
57
58rclcpp::NodeOptions get_cm_node_options();
59
60class ControllerManager : public rclcpp::Node
61{
62public:
63 static constexpr bool kWaitForAllResources = false;
64 static constexpr auto kInfiniteTimeout = 0;
65
67 std::unique_ptr<hardware_interface::ResourceManager> resource_manager,
68 std::shared_ptr<rclcpp::Executor> executor,
69 const std::string & manager_node_name = "controller_manager",
70 const std::string & node_namespace = "",
71 const rclcpp::NodeOptions & options = get_cm_node_options());
72
74 std::shared_ptr<rclcpp::Executor> executor,
75 const std::string & manager_node_name = "controller_manager",
76 const std::string & node_namespace = "",
77 const rclcpp::NodeOptions & options = get_cm_node_options());
78
80 std::shared_ptr<rclcpp::Executor> executor, const std::string & urdf,
81 bool activate_all_hw_components, const std::string & manager_node_name = "controller_manager",
82 const std::string & node_namespace = "",
83 const rclcpp::NodeOptions & options = get_cm_node_options());
84
85 virtual ~ControllerManager();
86
88
92
93 void robot_description_callback(const std_msgs::msg::String & msg);
94
95 void init_resource_manager(const std::string & robot_description);
96
97 controller_interface::ControllerInterfaceBaseSharedPtr load_controller(
98 const std::string & controller_name, const std::string & controller_type);
99
101
106 controller_interface::ControllerInterfaceBaseSharedPtr load_controller(
107 const std::string & controller_name);
108
109 controller_interface::return_type unload_controller(const std::string & controller_name);
110
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
129 controller_interface::ControllerInterfaceBaseSharedPtr add_controller(
130 const ControllerSpec & controller_spec)
131 {
132 return add_controller_impl(controller_spec);
133 }
134
136
141 controller_interface::return_type configure_controller(const std::string & controller_name);
142
144
152 controller_interface::return_type switch_controller(
153 const std::vector<std::string> & activate_controllers,
154 const std::vector<std::string> & deactivate_controllers, int strictness,
155 bool activate_asap = kWaitForAllResources,
156 const rclcpp::Duration & timeout = rclcpp::Duration::from_nanoseconds(kInfiniteTimeout));
157
159
168 controller_interface::return_type switch_controller_cb(
169 const std::vector<std::string> & activate_controllers,
170 const std::vector<std::string> & deactivate_controllers, int strictness, bool activate_asap,
171 const rclcpp::Duration & timeout, std::string & message);
172
174
181 void read(const rclcpp::Time & time, const rclcpp::Duration & period);
182
184
191 controller_interface::return_type update(
192 const rclcpp::Time & time, const rclcpp::Duration & period);
193
195
202 void write(const rclcpp::Time & time, const rclcpp::Duration & period);
203
205
209 // TODO(anyone): Due to issues with the MutliThreadedExecutor, this control loop does not rely on
210 // the executor (see issue #260).
211 // rclcpp::CallbackGroup::SharedPtr deterministic_callback_group_;
212
214
219 {
220 return resource_manager_ && resource_manager_->are_components_initialized();
221 }
222
224
230 unsigned int get_update_rate() const;
231
233
243 rclcpp::Clock::SharedPtr get_trigger_clock() const;
244
245protected:
246 void init_services();
247
248 controller_interface::ControllerInterfaceBaseSharedPtr add_controller_impl(
249 const ControllerSpec & controller);
250
251 void manage_switch();
252
254
262 const std::vector<ControllerSpec> & rt_controller_list,
263 const std::vector<std::string> & controllers_to_deactivate);
264
274 const std::vector<std::string> & chained_mode_switch_list, bool to_chained_mode);
275
277
286 const std::vector<ControllerSpec> & rt_controller_list,
287 const std::vector<std::string> & controllers_to_activate, int strictness);
288
289 void list_controllers_srv_cb(
290 const std::shared_ptr<controller_manager_msgs::srv::ListControllers::Request> request,
291 std::shared_ptr<controller_manager_msgs::srv::ListControllers::Response> response);
292
293 void list_hardware_interfaces_srv_cb(
294 const std::shared_ptr<controller_manager_msgs::srv::ListHardwareInterfaces::Request> request,
295 std::shared_ptr<controller_manager_msgs::srv::ListHardwareInterfaces::Response> response);
296
297 void load_controller_service_cb(
298 const std::shared_ptr<controller_manager_msgs::srv::LoadController::Request> request,
299 std::shared_ptr<controller_manager_msgs::srv::LoadController::Response> response);
300
301 void configure_controller_service_cb(
302 const std::shared_ptr<controller_manager_msgs::srv::ConfigureController::Request> request,
303 std::shared_ptr<controller_manager_msgs::srv::ConfigureController::Response> response);
304
305 void reload_controller_libraries_service_cb(
306 const std::shared_ptr<controller_manager_msgs::srv::ReloadControllerLibraries::Request> request,
307 std::shared_ptr<controller_manager_msgs::srv::ReloadControllerLibraries::Response> response);
308
309 void switch_controller_service_cb(
310 const std::shared_ptr<controller_manager_msgs::srv::SwitchController::Request> request,
311 std::shared_ptr<controller_manager_msgs::srv::SwitchController::Response> response);
312
313 void unload_controller_service_cb(
314 const std::shared_ptr<controller_manager_msgs::srv::UnloadController::Request> request,
315 std::shared_ptr<controller_manager_msgs::srv::UnloadController::Response> response);
316
317 void list_controller_types_srv_cb(
318 const std::shared_ptr<controller_manager_msgs::srv::ListControllerTypes::Request> request,
319 std::shared_ptr<controller_manager_msgs::srv::ListControllerTypes::Response> response);
320
321 void list_hardware_components_srv_cb(
322 const std::shared_ptr<controller_manager_msgs::srv::ListHardwareComponents::Request> request,
323 std::shared_ptr<controller_manager_msgs::srv::ListHardwareComponents::Response> response);
324
325 void set_hardware_component_state_srv_cb(
326 const std::shared_ptr<controller_manager_msgs::srv::SetHardwareComponentState::Request> request,
327 std::shared_ptr<controller_manager_msgs::srv::SetHardwareComponentState::Response> response);
328
329 // Per controller update rate support
330 unsigned int update_loop_counter_ = 0;
331 unsigned int update_rate_;
332 std::vector<std::vector<std::string>> chained_controllers_configuration_;
333
334 std::unique_ptr<hardware_interface::ResourceManager> resource_manager_;
335
336private:
337 std::vector<std::string> get_controller_names();
338 std::pair<std::string, std::string> split_command_interface(
339 const std::string & command_interface);
340 void init_controller_manager();
341
342 void initialize_parameters();
343
349 controller_interface::return_type cleanup_controller(
350 const controller_manager::ControllerSpec & controller);
351
357 void shutdown_controller(const controller_manager::ControllerSpec & controller) const;
358
363 void clear_requests();
364
375 void perform_hardware_command_mode_change(
376 const std::vector<ControllerSpec> & rt_controller_list,
377 const std::vector<std::string> & activate_controllers_list,
378 const std::vector<std::string> & deactivate_controllers_list,
379 const std::string & rt_cycle_name);
380
387 void propagate_deactivation_of_chained_mode(const std::vector<ControllerSpec> & controllers);
388
391
415 controller_interface::return_type check_following_controllers_for_activate(
416 const std::vector<ControllerSpec> & controllers, int strictness,
417 const ControllersListIterator controller_it, std::string & message);
418
420
439 controller_interface::return_type check_preceding_controllers_for_deactivate(
440 const std::vector<ControllerSpec> & controllers, int strictness,
441 const ControllersListIterator controller_it, std::string & message);
442
445
452 controller_interface::return_type check_fallback_controllers_state_pre_activation(
453 const std::vector<ControllerSpec> & controllers, const ControllersListIterator controller_it,
454 std::string & message);
455
465 controller_interface::return_type check_for_interfaces_availability_to_activate(
466 const std::vector<ControllerSpec> & controllers, const std::vector<std::string> activation_list,
467 const std::vector<std::string> deactivation_list, std::string & message);
468
488 void update_list_with_controller_chain(
489 const std::string & ctrl_name, std::vector<std::string>::iterator controller_iterator,
490 bool append_to_controller);
491
498 void build_controllers_topology_info(const std::vector<ControllerSpec> & controllers);
499
505 void publish_activity();
506
507 void controller_activity_diagnostic_callback(diagnostic_updater::DiagnosticStatusWrapper & stat);
508
509 void hardware_components_diagnostic_callback(diagnostic_updater::DiagnosticStatusWrapper & stat);
510
511 void controller_manager_diagnostic_callback(diagnostic_updater::DiagnosticStatusWrapper & stat);
512
520 rclcpp::NodeOptions determine_controller_node_options(const ControllerSpec & controller) const;
521
527 void cleanup_controller_exported_interfaces(const ControllerSpec & controller);
528
529 std::shared_ptr<controller_manager::ParamListener> cm_param_listener_;
530 std::shared_ptr<controller_manager::Params> params_;
531 diagnostic_updater::Updater diagnostics_updater_;
532
533 std::shared_ptr<rclcpp::Executor> executor_;
534
535 std::shared_ptr<pluginlib::ClassLoader<controller_interface::ControllerInterface>> loader_;
536 std::shared_ptr<pluginlib::ClassLoader<controller_interface::ChainableControllerInterface>>
537 chainable_loader_;
538
540
544 rclcpp::CallbackGroup::SharedPtr best_effort_callback_group_;
545
557 class RTControllerListWrapper
558 {
559 // *INDENT-OFF*
560 public:
561 // *INDENT-ON*
563
568 std::vector<ControllerSpec> & update_and_get_used_by_rt_list();
569
578 std::vector<ControllerSpec> & get_unused_list(
579 const std::lock_guard<std::recursive_mutex> & guard);
580
582
587 const std::vector<ControllerSpec> & get_updated_list(
588 const std::lock_guard<std::recursive_mutex> & guard) const;
589
596 void switch_updated_list(const std::lock_guard<std::recursive_mutex> & guard);
597
599
602 void set_on_switch_callback(std::function<void()> callback);
603
604 // Mutex protecting the controllers list
605 // must be acquired before using any list other than the "used by rt"
606 mutable std::recursive_mutex controllers_lock_;
607
608 // *INDENT-OFF*
609 private:
610 // *INDENT-ON*
612
615 int get_other_list(int index) const;
616
617 void wait_until_rt_not_using(
618 int index, std::chrono::microseconds sleep_delay = std::chrono::microseconds(200)) const;
619
620 std::vector<ControllerSpec> controllers_lists_[2];
622 int updated_controllers_index_ = 0;
624 int used_by_realtime_controllers_index_ = -1;
626 std::function<void()> on_switch_callback_ = nullptr;
627 };
628
629 bool use_sim_time_;
630 rclcpp::Clock::SharedPtr trigger_clock_ = nullptr;
631 std::unique_ptr<rclcpp::PreShutdownCallbackHandle> preshutdown_cb_handle_{nullptr};
632 RTControllerListWrapper rt_controllers_wrapper_;
633 std::unordered_map<std::string, ControllerChainSpec> controller_chain_spec_;
634 std::vector<std::string> ordered_controllers_names_;
637 std::mutex services_lock_;
638 rclcpp::Publisher<controller_manager_msgs::msg::ControllerManagerActivity>::SharedPtr
639 controller_manager_activity_publisher_;
640 rclcpp::Service<controller_manager_msgs::srv::ListControllers>::SharedPtr
641 list_controllers_service_;
642 rclcpp::Service<controller_manager_msgs::srv::ListControllerTypes>::SharedPtr
643 list_controller_types_service_;
644 rclcpp::Service<controller_manager_msgs::srv::LoadController>::SharedPtr load_controller_service_;
645 rclcpp::Service<controller_manager_msgs::srv::ConfigureController>::SharedPtr
646 configure_controller_service_;
647 rclcpp::Service<controller_manager_msgs::srv::ReloadControllerLibraries>::SharedPtr
648 reload_controller_libraries_service_;
649 rclcpp::Service<controller_manager_msgs::srv::SwitchController>::SharedPtr
650 switch_controller_service_;
651 rclcpp::Service<controller_manager_msgs::srv::UnloadController>::SharedPtr
652 unload_controller_service_;
653
654 rclcpp::Service<controller_manager_msgs::srv::ListHardwareComponents>::SharedPtr
655 list_hardware_components_service_;
656 rclcpp::Service<controller_manager_msgs::srv::ListHardwareInterfaces>::SharedPtr
657 list_hardware_interfaces_service_;
658 rclcpp::Service<controller_manager_msgs::srv::SetHardwareComponentState>::SharedPtr
659 set_hardware_component_state_service_;
660
661 std::map<std::string, std::vector<std::string>> controller_chained_reference_interfaces_cache_;
662 std::map<std::string, std::vector<std::string>> controller_chained_state_interfaces_cache_;
663
664 rclcpp::NodeOptions cm_node_options_;
665 std::string robot_description_;
666 rclcpp::Subscription<std_msgs::msg::String>::SharedPtr robot_description_subscription_;
667 rclcpp::TimerBase::SharedPtr robot_description_notification_timer_;
668
669 struct ControllerManagerExecutionTime
670 {
671 double read_time = 0.0;
672 double update_time = 0.0;
673 double write_time = 0.0;
674 double switch_time = 0.0;
675 double total_time = 0.0;
676 double switch_chained_mode_time = 0.0;
677 double switch_perform_mode_time = 0.0;
678 double deactivation_time = 0.0;
679 double activation_time = 0.0;
680 };
681
682 ControllerManagerExecutionTime execution_time_;
683
685
686 struct SwitchParams
687 {
688 void reset()
689 {
690 do_switch = false;
691 started = false;
692 strictness = 0;
693 activate_asap = false;
694 }
695
696 std::atomic_bool do_switch;
697 bool started;
698
699 // Switch options
700 int strictness;
701 std::atomic_bool activate_asap;
702 std::chrono::nanoseconds timeout;
703
704 // conditional variable and mutex to wait for the switch to complete
705 std::condition_variable cv;
706 std::mutex mutex;
707
708 bool skip_cycle(const controller_manager::ControllerSpec & spec) const
709 {
710 const std::string controller_name = spec.info.name;
711 return ros2_control::has_item(activate_request, controller_name) ||
712 ros2_control::has_item(deactivate_request, controller_name) ||
713 ros2_control::has_item(to_chained_mode_request, controller_name) ||
714 ros2_control::has_item(from_chained_mode_request, controller_name);
715 }
716
717 // The controllers list to activate and deactivate
718 std::vector<std::string> activate_request;
719 std::vector<std::string> deactivate_request;
720 std::vector<std::string> to_chained_mode_request;
721 std::vector<std::string> from_chained_mode_request;
722 std::vector<std::string> activate_command_interface_request;
723 std::vector<std::string> deactivate_command_interface_request;
724 };
725
726 SwitchParams switch_params_;
727
728 struct RTBufferVariables
729 {
730 RTBufferVariables()
731 {
732 deactivate_controllers_list.reserve(1000);
733 activate_controllers_using_interfaces_list.reserve(1000);
734 fallback_controllers_list.reserve(1000);
735 interfaces_to_start.reserve(1000);
736 interfaces_to_stop.reserve(1000);
737 concatenated_string.reserve(5000);
738 }
739
740 const std::string & get_concatenated_string(
741 const std::vector<std::string> & strings, bool clear_string = true)
742 {
743 if (clear_string)
744 {
745 concatenated_string.clear();
746 }
747 for (const auto & str : strings)
748 {
749 concatenated_string.append(str);
750 concatenated_string.append(" ");
751 }
752 return concatenated_string;
753 }
754
755 std::vector<std::string> deactivate_controllers_list;
756 std::vector<std::string> activate_controllers_using_interfaces_list;
757 std::vector<std::string> fallback_controllers_list;
758 std::vector<std::string> interfaces_to_start;
759 std::vector<std::string> interfaces_to_stop;
760 std::string concatenated_string;
761 };
762 RTBufferVariables rt_buffer_;
763};
764
765} // namespace controller_manager
766
767#endif // CONTROLLER_MANAGER__CONTROLLER_MANAGER_HPP_
Definition controller_manager.hpp:61
void read(const rclcpp::Time &time, const rclcpp::Duration &period)
Read values to state interfaces.
Definition controller_manager.cpp:2927
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:1488
unsigned int get_update_rate() const
Update rate of the main control loop in the controller manager.
Definition controller_manager.cpp:3443
controller_interface::return_type update(const rclcpp::Time &time, const rclcpp::Duration &period)
Run update on controllers.
Definition controller_manager.cpp:3024
bool shutdown_controllers()
Shutdown all controllers in the controller manager.
Definition controller_manager.cpp:510
controller_interface::return_type switch_controller_cb(const std::vector< std::string > &activate_controllers, const std::vector< std::string > &deactivate_controllers, int strictness, bool activate_asap, const rclcpp::Duration &timeout, std::string &message)
switch_controller Deactivates some controllers and activates others.
Definition controller_manager.cpp:1498
void switch_chained_mode(const std::vector< std::string > &chained_mode_switch_list, bool to_chained_mode)
Definition controller_manager.cpp:2235
rclcpp::Clock::SharedPtr get_trigger_clock() const
Get the trigger clock of the controller manager.
Definition controller_manager.cpp:3445
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:2174
void activate_controllers(const std::vector< ControllerSpec > &rt_controller_list, const std::vector< std::string > &controllers_to_activate, int strictness)
Activate chosen controllers from real-time controller list.
Definition controller_manager.cpp:2281
void write(const rclcpp::Time &time, const rclcpp::Duration &period)
Write values from command interfaces.
Definition controller_manager.cpp:3244
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:1231
bool is_resource_manager_initialized() const
Deterministic (real-time safe) callback group, e.g., update function.
Definition controller_manager.hpp:218
Definition statistics_types.hpp:49
Controller Specification.
Definition controller_spec.hpp:40
std::string type
Controller type.
Definition controller_info.hpp:34
std::string name
Controller name.
Definition controller_info.hpp:31