ros2_control - jazzy
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 [[deprecated("Replaced by the new version using shared_ptr")]] explicit LoanedCommandInterface(
36 CommandInterface & command_interface)
37 : LoanedCommandInterface(command_interface, nullptr)
38 {
39 }
40
41 [[deprecated("Replaced by the new version using shared_ptr")]] LoanedCommandInterface(
42 CommandInterface & command_interface, Deleter && deleter)
43 : command_interface_(command_interface),
44 deleter_(std::forward<Deleter>(deleter)),
45 interface_name_(command_interface.get_name())
46 {
47 }
48
49 explicit LoanedCommandInterface(CommandInterface::SharedPtr command_interface, Deleter && deleter)
50 : command_interface_(*command_interface),
51 interface_name_(command_interface->get_name()),
52 deleter_(std::forward<Deleter>(deleter))
53 {
54 }
55
56 LoanedCommandInterface(const LoanedCommandInterface & other) = delete;
57
59
61 {
62 auto logger = rclcpp::get_logger(interface_name_);
63 RCLCPP_WARN_EXPRESSION(
64 logger,
65 (get_value_statistics_.failed_counter > 0 || get_value_statistics_.timeout_counter > 0),
66 "LoanedCommandInterface %s has %u (%.4f %%) timeouts and %u (~ %.4f %%) missed calls out of "
67 "%u get_value calls",
68 interface_name_.c_str(), get_value_statistics_.timeout_counter,
69 (get_value_statistics_.timeout_counter * 100.0) / get_value_statistics_.total_counter,
70 get_value_statistics_.failed_counter,
71 (get_value_statistics_.failed_counter * 100.0) / get_value_statistics_.total_counter,
72 get_value_statistics_.total_counter);
73 RCLCPP_WARN_EXPRESSION(
74 logger,
75 (set_value_statistics_.failed_counter > 0 || set_value_statistics_.timeout_counter > 0),
76 "LoanedCommandInterface %s has %u (%.4f %%) timeouts and %u (~ %.4f %%) missed calls out of "
77 "%u set_value calls",
78 interface_name_.c_str(), set_value_statistics_.timeout_counter,
79 (set_value_statistics_.timeout_counter * 100.0) / set_value_statistics_.total_counter,
80 set_value_statistics_.failed_counter,
81 (set_value_statistics_.failed_counter * 100.0) / set_value_statistics_.total_counter,
82 set_value_statistics_.total_counter);
83 if (deleter_)
84 {
85 deleter_();
86 }
87 }
88
89 const std::string & get_name() const { return command_interface_.get_name(); }
90
91 const std::string & get_interface_name() const { return command_interface_.get_interface_name(); }
92
93 [[deprecated(
94 "Replaced by get_name method, which is semantically more correct")]] const std::string
95 get_full_name() const
96 {
97 return command_interface_.get_name();
98 }
99
100 const std::string & get_prefix_name() const { return command_interface_.get_prefix_name(); }
101
117 template <typename T>
118 [[nodiscard]] bool set_value(const T & value, unsigned int max_tries = 10)
119 {
120 unsigned int nr_tries = 0;
121 ++set_value_statistics_.total_counter;
122 while (!command_interface_.set_limited_value(value))
123 {
124 ++set_value_statistics_.failed_counter;
125 ++nr_tries;
126 if (nr_tries == max_tries)
127 {
128 ++set_value_statistics_.timeout_counter;
129 return false;
130 }
131 std::this_thread::yield();
132 }
133 return true;
134 }
135
136 [[deprecated(
137 "Use std::optional<T> get_optional() instead to retrieve the value. This method will be "
138 "removed by the ROS 2 Kilted Kaiju release.")]]
139 double get_value() const
140 {
141 std::optional<double> opt_value = get_optional();
142 if (opt_value.has_value())
143 {
144 return opt_value.value();
145 }
146 else
147 {
148 return std::numeric_limits<double>::quiet_NaN();
149 }
150 }
151
166 template <typename T = double>
167 [[nodiscard]] std::optional<T> get_optional(unsigned int max_tries = 10) const
168 {
169 unsigned int nr_tries = 0;
170 do
171 {
172 ++get_value_statistics_.total_counter;
173 const std::optional<T> data = command_interface_.get_optional<T>();
174 if (data.has_value())
175 {
176 return data;
177 }
178 ++get_value_statistics_.failed_counter;
179 ++nr_tries;
180 std::this_thread::yield();
181 } while (nr_tries < max_tries);
182
183 ++get_value_statistics_.timeout_counter;
184 return std::nullopt;
185 }
186
202 template <typename T>
203 [[deprecated(
204 "Use std::optional<T> get_optional() instead to retrieve the value. This method will be "
205 "removed by the ROS 2 Kilted Kaiju release.")]] [[nodiscard]] bool
206 get_value(T & value, unsigned int max_tries = 10) const
207 {
208 const auto opt_value = get_optional<T>(max_tries);
209 if (opt_value.has_value())
210 {
211 value = opt_value.value();
212 return true;
213 }
214 return false;
215 }
216
221 HandleDataType get_data_type() const { return command_interface_.get_data_type(); }
222
223protected:
224 CommandInterface & command_interface_;
225 Deleter deleter_;
226 std::string interface_name_;
227
228private:
229 struct HandleRTStatistics
230 {
231 unsigned int total_counter = 0;
232 unsigned int failed_counter = 0;
233 unsigned int timeout_counter = 0;
234 };
235 mutable HandleRTStatistics get_value_statistics_;
236 HandleRTStatistics set_value_statistics_;
237};
238
239} // namespace hardware_interface
240#endif // HARDWARE_INTERFACE__LOANED_COMMAND_INTERFACE_HPP_
Definition handle.hpp:744
bool set_limited_value(const T &value)
A setter for the value of the command interface that triggers the limiter.
Definition handle.hpp:771
Definition hardware_info.hpp:158
std::optional< T > get_optional() const
Get the value of the handle.
Definition handle.hpp:337
Definition loaned_command_interface.hpp:31
bool set_value(const T &value, unsigned int max_tries=10)
Set the value of the command interface.
Definition loaned_command_interface.hpp:118
bool get_value(T &value, unsigned int max_tries=10) const
Get the value of the command interface.
Definition loaned_command_interface.hpp:206
HandleDataType get_data_type() const
Get the data type of the command interface.
Definition loaned_command_interface.hpp:221
std::optional< T > get_optional(unsigned int max_tries=10) const
Get the value of the command interface.
Definition loaned_command_interface.hpp:167
Definition mujoco_system_interface.hpp:57