ros2_control - foxy
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 <memory>
19#include <string>
20#include <tuple>
21#include <vector>
22
23#include "controller_interface/controller_interface.hpp"
24
25#include "controller_manager/controller_spec.hpp"
26#include "controller_manager/visibility_control.h"
27#include "controller_manager_msgs/srv/configure_controller.hpp"
28#include "controller_manager_msgs/srv/configure_start_controller.hpp"
29#include "controller_manager_msgs/srv/list_controller_types.hpp"
30#include "controller_manager_msgs/srv/list_controllers.hpp"
31#include "controller_manager_msgs/srv/list_hardware_interfaces.hpp"
32#include "controller_manager_msgs/srv/load_configure_controller.hpp"
33#include "controller_manager_msgs/srv/load_controller.hpp"
34#include "controller_manager_msgs/srv/load_start_controller.hpp"
35#include "controller_manager_msgs/srv/reload_controller_libraries.hpp"
36#include "controller_manager_msgs/srv/switch_controller.hpp"
37#include "controller_manager_msgs/srv/unload_controller.hpp"
38
39#include "hardware_interface/resource_manager.hpp"
40
41#include "pluginlib/class_loader.hpp"
42
43#include "rclcpp/executor.hpp"
44#include "rclcpp/node.hpp"
45
46namespace controller_manager
47{
48class ControllerManager : public rclcpp::Node
49{
50public:
51 static constexpr bool kWaitForAllResources = false;
52 static constexpr double kInfiniteTimeout = 0.0;
53
54 CONTROLLER_MANAGER_PUBLIC
56 std::unique_ptr<hardware_interface::ResourceManager> resource_manager,
57 std::shared_ptr<rclcpp::Executor> executor,
58 const std::string & manager_node_name = "controller_manager",
59 const std::string & namespace_ = "");
60
61 CONTROLLER_MANAGER_PUBLIC
63 std::shared_ptr<rclcpp::Executor> executor,
64 const std::string & manager_node_name = "controller_manager",
65 const std::string & namespace_ = "");
66
67 CONTROLLER_MANAGER_PUBLIC
68 virtual ~ControllerManager() = default;
69
70 CONTROLLER_MANAGER_PUBLIC
71 controller_interface::ControllerInterfaceSharedPtr load_controller(
72 const std::string & controller_name, const std::string & controller_type);
73
75
80 CONTROLLER_MANAGER_PUBLIC
81 controller_interface::ControllerInterfaceSharedPtr load_controller(
82 const std::string & controller_name);
83
84 CONTROLLER_MANAGER_PUBLIC
85 controller_interface::return_type unload_controller(const std::string & controller_name);
86
87 CONTROLLER_MANAGER_PUBLIC
88 std::vector<ControllerSpec> get_loaded_controllers() const;
89
90 template <
91 typename T, typename std::enable_if<
92 std::is_convertible<T *, controller_interface::ControllerInterface *>::value,
93 T>::type * = nullptr>
94 controller_interface::ControllerInterfaceSharedPtr add_controller(
95 std::shared_ptr<T> controller, const std::string & controller_name,
96 const std::string & controller_type)
97 {
98 ControllerSpec controller_spec;
99 controller_spec.c = controller;
100 controller_spec.info.name = controller_name;
101 controller_spec.info.type = controller_type;
102 return add_controller_impl(controller_spec);
103 }
104
106
111 CONTROLLER_MANAGER_PUBLIC
112 controller_interface::return_type configure_controller(const std::string & controller_name);
113
115
121 CONTROLLER_MANAGER_PUBLIC
122 controller_interface::return_type switch_controller(
123 const std::vector<std::string> & start_controllers,
124 const std::vector<std::string> & stop_controllers, int strictness,
125 bool start_asap = kWaitForAllResources,
126 const rclcpp::Duration & timeout =
127 rclcpp::Duration(static_cast<rcl_duration_value_t>(kInfiniteTimeout)));
128
129 CONTROLLER_MANAGER_PUBLIC
130 void read();
131
132 CONTROLLER_MANAGER_PUBLIC
133 controller_interface::return_type update();
134
135 CONTROLLER_MANAGER_PUBLIC
136 void write();
137
139
143 // TODO(anyone): Due to issues with the MutliThreadedExecutor, this control loop does not rely on
144 // the executor (see issue #260).
145 // rclcpp::CallbackGroup::SharedPtr deterministic_callback_group_;
146
147protected:
148 CONTROLLER_MANAGER_PUBLIC
149 void init_services();
150
151 CONTROLLER_MANAGER_PUBLIC
152 controller_interface::ControllerInterfaceSharedPtr add_controller_impl(
153 const ControllerSpec & controller);
154
155 CONTROLLER_MANAGER_PUBLIC
156 void manage_switch();
157
158 CONTROLLER_MANAGER_PUBLIC
159 void stop_controllers();
160
161 CONTROLLER_MANAGER_PUBLIC
162 void start_controllers();
163
164 CONTROLLER_MANAGER_PUBLIC
165 void start_controllers_asap();
166
167 CONTROLLER_MANAGER_PUBLIC
168 void list_controllers_srv_cb(
169 const std::shared_ptr<controller_manager_msgs::srv::ListControllers::Request> request,
170 std::shared_ptr<controller_manager_msgs::srv::ListControllers::Response> response);
171
172 CONTROLLER_MANAGER_PUBLIC
173 void list_controller_types_srv_cb(
174 const std::shared_ptr<controller_manager_msgs::srv::ListControllerTypes::Request> request,
175 std::shared_ptr<controller_manager_msgs::srv::ListControllerTypes::Response> response);
176
177 CONTROLLER_MANAGER_PUBLIC
178 void list_hardware_interfaces_srv_cb(
179 const std::shared_ptr<controller_manager_msgs::srv::ListHardwareInterfaces::Request> request,
180 std::shared_ptr<controller_manager_msgs::srv::ListHardwareInterfaces::Response> response);
181
182 CONTROLLER_MANAGER_PUBLIC
183 void load_controller_service_cb(
184 const std::shared_ptr<controller_manager_msgs::srv::LoadController::Request> request,
185 std::shared_ptr<controller_manager_msgs::srv::LoadController::Response> response);
186
187 CONTROLLER_MANAGER_PUBLIC
188 void configure_controller_service_cb(
189 const std::shared_ptr<controller_manager_msgs::srv::ConfigureController::Request> request,
190 std::shared_ptr<controller_manager_msgs::srv::ConfigureController::Response> response);
191
192 CONTROLLER_MANAGER_PUBLIC
193 void load_and_configure_controller_service_cb(
194 const std::shared_ptr<controller_manager_msgs::srv::LoadConfigureController::Request> request,
195 std::shared_ptr<controller_manager_msgs::srv::LoadConfigureController::Response> response);
196
197 CONTROLLER_MANAGER_PUBLIC
198 void load_and_start_controller_service_cb(
199 const std::shared_ptr<controller_manager_msgs::srv::LoadStartController::Request> request,
200 std::shared_ptr<controller_manager_msgs::srv::LoadStartController::Response> response);
201
202 CONTROLLER_MANAGER_PUBLIC
203 void configure_and_start_controller_service_cb(
204 const std::shared_ptr<controller_manager_msgs::srv::ConfigureStartController::Request> request,
205 std::shared_ptr<controller_manager_msgs::srv::ConfigureStartController::Response> response);
206
207 CONTROLLER_MANAGER_PUBLIC
208 void reload_controller_libraries_service_cb(
209 const std::shared_ptr<controller_manager_msgs::srv::ReloadControllerLibraries::Request> request,
210 std::shared_ptr<controller_manager_msgs::srv::ReloadControllerLibraries::Response> response);
211
212 CONTROLLER_MANAGER_PUBLIC
213 void switch_controller_service_cb(
214 const std::shared_ptr<controller_manager_msgs::srv::SwitchController::Request> request,
215 std::shared_ptr<controller_manager_msgs::srv::SwitchController::Response> response);
216
217 CONTROLLER_MANAGER_PUBLIC
218 void unload_controller_service_cb(
219 const std::shared_ptr<controller_manager_msgs::srv::UnloadController::Request> request,
220 std::shared_ptr<controller_manager_msgs::srv::UnloadController::Response> response);
221
222private:
223 std::vector<std::string> get_controller_names();
224
225 std::unique_ptr<hardware_interface::ResourceManager> resource_manager_;
226
227 std::shared_ptr<rclcpp::Executor> executor_;
228
229 std::shared_ptr<pluginlib::ClassLoader<controller_interface::ControllerInterface>> loader_;
230
232
236 rclcpp::CallbackGroup::SharedPtr best_effort_callback_group_;
237
249 class RTControllerListWrapper
250 {
251 // *INDENT-OFF*
252 public:
253 // *INDENT-ON*
255
260 std::vector<ControllerSpec> & update_and_get_used_by_rt_list();
261
269 std::vector<ControllerSpec> & get_unused_list(
270 const std::lock_guard<std::recursive_mutex> & guard);
271
273
277 const std::vector<ControllerSpec> & get_updated_list(
278 const std::lock_guard<std::recursive_mutex> & guard) const;
279
285 void switch_updated_list(const std::lock_guard<std::recursive_mutex> & guard);
286
287 // Mutex protecting the controllers list
288 // must be acquired before using any list other than the "used by rt"
289 mutable std::recursive_mutex controllers_lock_;
290
291 // *INDENT-OFF*
292 private:
293 // *INDENT-ON*
295
298 int get_other_list(int index) const;
299
300 void wait_until_rt_not_using(
301 int index, std::chrono::microseconds sleep_delay = std::chrono::microseconds(200)) const;
302
303 std::vector<ControllerSpec> controllers_lists_[2];
305 int updated_controllers_index_ = 0;
307 int used_by_realtime_controllers_index_ = -1;
308 };
309
310 RTControllerListWrapper rt_controllers_wrapper_;
313 std::mutex services_lock_;
314 rclcpp::Service<controller_manager_msgs::srv::ListControllers>::SharedPtr
315 list_controllers_service_;
316 rclcpp::Service<controller_manager_msgs::srv::ListControllerTypes>::SharedPtr
317 list_controller_types_service_;
318 rclcpp::Service<controller_manager_msgs::srv::ListHardwareInterfaces>::SharedPtr
319 list_hardware_interfaces_service_;
320 rclcpp::Service<controller_manager_msgs::srv::LoadController>::SharedPtr load_controller_service_;
321 rclcpp::Service<controller_manager_msgs::srv::ConfigureController>::SharedPtr
322 configure_controller_service_;
323 rclcpp::Service<controller_manager_msgs::srv::LoadConfigureController>::SharedPtr
324 load_and_configure_controller_service_;
325 rclcpp::Service<controller_manager_msgs::srv::LoadStartController>::SharedPtr
326 load_and_start_controller_service_;
327 rclcpp::Service<controller_manager_msgs::srv::ConfigureStartController>::SharedPtr
328 configure_and_start_controller_service_;
329 rclcpp::Service<controller_manager_msgs::srv::ReloadControllerLibraries>::SharedPtr
330 reload_controller_libraries_service_;
331 rclcpp::Service<controller_manager_msgs::srv::SwitchController>::SharedPtr
332 switch_controller_service_;
333 rclcpp::Service<controller_manager_msgs::srv::UnloadController>::SharedPtr
334 unload_controller_service_;
335
336 std::vector<std::string> start_request_, stop_request_;
337 std::vector<std::string> start_command_interface_request_, stop_command_interface_request_;
338
339 struct SwitchParams
340 {
341 bool do_switch = {false};
342 bool started = {false};
343 rclcpp::Time init_time = {rclcpp::Time::max()};
344
345 // Switch options
346 int strictness = {0};
347 bool start_asap = {false};
348 rclcpp::Duration timeout = rclcpp::Duration{0, 0};
349 };
350
351 SwitchParams switch_params_;
352};
353
354} // namespace controller_manager
355
356#endif // CONTROLLER_MANAGER__CONTROLLER_MANAGER_HPP_
Definition controller_manager.hpp:49
CONTROLLER_MANAGER_PUBLIC void init_services()
Deterministic (real-time safe) callback group, e.g., update function.
Definition controller_manager.cpp:93
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 start_asap=kWaitForAllResources, const rclcpp::Duration &timeout=rclcpp::Duration(static_cast< rcl_duration_value_t >(kInfiniteTimeout)))
switch_controller Stops some controllers and start others.
Definition controller_manager.cpp:318
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:259
Controller Specification.
Definition controller_spec.hpp:37
std::string type
Controller type.
Definition controller_info.hpp:33
std::string name
Controller name.
Definition controller_info.hpp:30