ros2_control - kilted
Loading...
Searching...
No Matches
loaned_command_interface.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 HARDWARE_INTERFACE__LOANED_COMMAND_INTERFACE_HPP_
16#define HARDWARE_INTERFACE__LOANED_COMMAND_INTERFACE_HPP_
17
18#include <functional>
19#include <limits>
20#include <optional>
21#include <string>
22#include <thread>
23#include <utility>
24
25#include "hardware_interface/handle.hpp"
26#include "rclcpp/logging.hpp"
27
28namespace hardware_interface
29{
31{
32public:
33 using Deleter = std::function<void(void)>;
34
35 explicit LoanedCommandInterface(CommandInterface::SharedPtr command_interface)
36 : LoanedCommandInterface(command_interface, nullptr)
37 {
38 }
39
40 explicit LoanedCommandInterface(CommandInterface::SharedPtr command_interface, Deleter && deleter)
41 : command_interface_(command_interface),
42 interface_name_(command_interface->get_name()),
43 deleter_(std::forward<Deleter>(deleter))
44 {
45 }
46
47 LoanedCommandInterface(const LoanedCommandInterface & other) = delete;
48
50
52 {
53 if (command_interface_)
54 {
55 auto logger = rclcpp::get_logger(interface_name_);
56 RCLCPP_WARN_EXPRESSION(
57 logger,
58 (get_value_statistics_.failed_counter > 0 || get_value_statistics_.timeout_counter > 0),
59 "LoanedCommandInterface %s has %u (%.4f %%) timeouts and %u (~ %.4f %%) missed calls out "
60 "of "
61 "%u get_value calls",
62 interface_name_.c_str(), get_value_statistics_.timeout_counter,
63 (get_value_statistics_.timeout_counter * 100.0) / get_value_statistics_.total_counter,
64 get_value_statistics_.failed_counter,
65 (get_value_statistics_.failed_counter * 100.0) / get_value_statistics_.total_counter,
66 get_value_statistics_.total_counter);
67 RCLCPP_WARN_EXPRESSION(
68 logger,
69 (set_value_statistics_.failed_counter > 0 || set_value_statistics_.timeout_counter > 0),
70 "LoanedCommandInterface %s has %u (%.4f %%) timeouts and %u (~ %.4f %%) missed calls out "
71 "of "
72 "%u set_value calls",
73 interface_name_.c_str(), set_value_statistics_.timeout_counter,
74 (set_value_statistics_.timeout_counter * 100.0) / set_value_statistics_.total_counter,
75 set_value_statistics_.failed_counter,
76 (set_value_statistics_.failed_counter * 100.0) / set_value_statistics_.total_counter,
77 set_value_statistics_.total_counter);
78 }
79 if (deleter_)
80 {
81 deleter_();
82 }
83 }
84
85 const std::string & get_name() const { return command_interface_->get_name(); }
86
87 const std::string & get_interface_name() const
88 {
89 return command_interface_->get_interface_name();
90 }
91
92 const std::string & get_prefix_name() const { return command_interface_->get_prefix_name(); }
93
109 template <typename T>
110 [[nodiscard]] bool set_value(const T & value, unsigned int max_tries = 10)
111 {
112 unsigned int nr_tries = 0;
113 ++set_value_statistics_.total_counter;
114 while (!command_interface_->set_limited_value(value))
115 {
116 ++set_value_statistics_.failed_counter;
117 ++nr_tries;
118 if (nr_tries == max_tries)
119 {
120 ++set_value_statistics_.timeout_counter;
121 return false;
122 }
123 std::this_thread::yield();
124 }
125 return true;
126 }
127
128 [[deprecated(
129 "Use std::optional<T> get_optional() instead to retrieve the value. This method will be "
130 "removed by the ROS 2 Lyrical Luth release.")]]
131 double get_value() const
132 {
133 std::optional<double> opt_value = get_optional();
134 if (opt_value.has_value())
135 {
136 return opt_value.value();
137 }
138 else
139 {
140 return std::numeric_limits<double>::quiet_NaN();
141 }
142 }
143
158 template <typename T = double>
159 [[nodiscard]] std::optional<T> get_optional(unsigned int max_tries = 10) const
160 {
161 unsigned int nr_tries = 0;
162 do
163 {
164 ++get_value_statistics_.total_counter;
165 const std::optional<T> data = command_interface_->get_optional<T>();
166 if (data.has_value())
167 {
168 return data;
169 }
170 ++get_value_statistics_.failed_counter;
171 ++nr_tries;
172 std::this_thread::yield();
173 } while (nr_tries < max_tries);
174
175 ++get_value_statistics_.timeout_counter;
176 return std::nullopt;
177 }
178
183 HandleDataType get_data_type() const { return command_interface_->get_data_type(); }
184
189 bool is_castable_to_double() const { return command_interface_->is_castable_to_double(); }
190
191protected:
192 CommandInterface::SharedPtr command_interface_;
193 std::string interface_name_;
194 Deleter deleter_;
195
196private:
197 struct HandleRTStatistics
198 {
199 unsigned int total_counter = 0;
200 unsigned int failed_counter = 0;
201 unsigned int timeout_counter = 0;
202 };
203 mutable HandleRTStatistics get_value_statistics_;
204 HandleRTStatistics set_value_statistics_;
205};
206
207} // namespace hardware_interface
208#endif // HARDWARE_INTERFACE__LOANED_COMMAND_INTERFACE_HPP_
Definition hardware_info.hpp:158
Definition loaned_command_interface.hpp:31
bool is_castable_to_double() const
Check if the state interface can be casted to double.
Definition loaned_command_interface.hpp:189
bool set_value(const T &value, unsigned int max_tries=10)
Set the value of the command interface.
Definition loaned_command_interface.hpp:110
HandleDataType get_data_type() const
Get the data type of the command interface.
Definition loaned_command_interface.hpp:183
std::optional< T > get_optional(unsigned int max_tries=10) const
Get the value of the command interface.
Definition loaned_command_interface.hpp:159
Definition mujoco_system_interface.hpp:57