ros2_control - rolling
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 <string>
21#include <thread>
22#include <utility>
23
24#include "hardware_interface/handle.hpp"
25#include "rclcpp/logging.hpp"
26
27namespace hardware_interface
28{
30{
31public:
32 using Deleter = std::function<void(void)>;
33
34 explicit LoanedCommandInterface(CommandInterface::SharedPtr command_interface)
35 : LoanedCommandInterface(command_interface, nullptr)
36 {
37 }
38
39 explicit LoanedCommandInterface(CommandInterface::SharedPtr command_interface, Deleter && deleter)
40 : command_interface_(*command_interface),
41 interface_name_(command_interface->get_name()),
42 deleter_(std::forward<Deleter>(deleter))
43 {
44 }
45
46 LoanedCommandInterface(const LoanedCommandInterface & other) = delete;
47
49
51 {
52 auto logger = rclcpp::get_logger(interface_name_);
53 RCLCPP_WARN_EXPRESSION(
54 logger,
55 (get_value_statistics_.failed_counter > 0 || get_value_statistics_.timeout_counter > 0),
56 "LoanedCommandInterface %s has %u (%.4f %%) timeouts and %u (~ %.4f %%) missed calls out of "
57 "%u get_value calls",
58 interface_name_.c_str(), get_value_statistics_.timeout_counter,
59 (get_value_statistics_.timeout_counter * 100.0) / get_value_statistics_.total_counter,
60 get_value_statistics_.failed_counter,
61 (get_value_statistics_.failed_counter * 100.0) / get_value_statistics_.total_counter,
62 get_value_statistics_.total_counter);
63 RCLCPP_WARN_EXPRESSION(
64 logger,
65 (set_value_statistics_.failed_counter > 0 || set_value_statistics_.timeout_counter > 0),
66 "LoanedCommandInterface %s has %u (%.4f %%) timeouts and %u (~ %.4f %%) missed calls out of "
67 "%u set_value calls",
68 interface_name_.c_str(), set_value_statistics_.timeout_counter,
69 (set_value_statistics_.timeout_counter * 100.0) / set_value_statistics_.total_counter,
70 set_value_statistics_.failed_counter,
71 (set_value_statistics_.failed_counter * 100.0) / set_value_statistics_.total_counter,
72 set_value_statistics_.total_counter);
73 if (deleter_)
74 {
75 deleter_();
76 }
77 }
78
79 const std::string & get_name() const { return command_interface_.get_name(); }
80
81 const std::string & get_interface_name() const { return command_interface_.get_interface_name(); }
82
83 const std::string & get_prefix_name() const { return command_interface_.get_prefix_name(); }
84
100 template <typename T>
101 [[nodiscard]] bool set_value(const T & value, unsigned int max_tries = 10)
102 {
103 unsigned int nr_tries = 0;
104 ++set_value_statistics_.total_counter;
105 while (!command_interface_.set_limited_value(value))
106 {
107 ++set_value_statistics_.failed_counter;
108 ++nr_tries;
109 if (nr_tries == max_tries)
110 {
111 ++set_value_statistics_.timeout_counter;
112 return false;
113 }
114 std::this_thread::yield();
115 }
116 return true;
117 }
118
133 template <typename T = double>
134 [[nodiscard]] std::optional<T> get_optional(unsigned int max_tries = 10) const
135 {
136 unsigned int nr_tries = 0;
137 do
138 {
139 ++get_value_statistics_.total_counter;
140 const std::optional<T> data = command_interface_.get_optional<T>();
141 if (data.has_value())
142 {
143 return data;
144 }
145 ++get_value_statistics_.failed_counter;
146 ++nr_tries;
147 std::this_thread::yield();
148 } while (nr_tries < max_tries);
149
150 ++get_value_statistics_.timeout_counter;
151 return std::nullopt;
152 }
153
158 HandleDataType get_data_type() const { return command_interface_.get_data_type(); }
159
164 bool is_castable_to_double() const { return command_interface_.is_castable_to_double(); }
165
166protected:
167 CommandInterface & command_interface_;
168 Deleter deleter_;
169 std::string interface_name_;
170
171private:
172 struct HandleRTStatistics
173 {
174 unsigned int total_counter = 0;
175 unsigned int failed_counter = 0;
176 unsigned int timeout_counter = 0;
177 };
178 mutable HandleRTStatistics get_value_statistics_;
179 HandleRTStatistics set_value_statistics_;
180};
181
182} // namespace hardware_interface
183#endif // HARDWARE_INTERFACE__LOANED_COMMAND_INTERFACE_HPP_
Definition handle.hpp:700
bool set_limited_value(const T &value)
A setter for the value of the command interface that triggers the limiter.
Definition handle.hpp:727
Definition hardware_info.hpp:146
bool is_castable_to_double() const
Returns true if the handle data type can be casted to double.
Definition handle.hpp:509
std::optional< T > get_optional() const
Get the value of the handle.
Definition handle.hpp:307
Definition loaned_command_interface.hpp:30
bool is_castable_to_double() const
Check if the state interface can be casted to double.
Definition loaned_command_interface.hpp:164
bool set_value(const T &value, unsigned int max_tries=10)
Set the value of the command interface.
Definition loaned_command_interface.hpp:101
HandleDataType get_data_type() const
Get the data type of the command interface.
Definition loaned_command_interface.hpp:158
std::optional< T > get_optional(unsigned int max_tries=10) const
Get the value of the command interface.
Definition loaned_command_interface.hpp:134
Definition actuator.hpp:22