ros2_control - rolling
Loading...
Searching...
No Matches
handle.hpp
1// Copyright 2020 PAL Robotics S.L.
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__HANDLE_HPP_
16#define HARDWARE_INTERFACE__HANDLE_HPP_
17
18#include <limits>
19#include <memory>
20#include <mutex>
21#include <shared_mutex>
22#include <string>
23#include <utility>
24#include <variant>
25
26#include "hardware_interface/hardware_info.hpp"
27#include "hardware_interface/macros.hpp"
28
29namespace hardware_interface
30{
31
32using HANDLE_DATATYPE = std::variant<double>;
33
35class Handle
36{
37public:
38 [[deprecated("Use InterfaceDescription for initializing the Interface")]]
39
40 Handle(
41 const std::string & prefix_name, const std::string & interface_name,
42 double * value_ptr = nullptr)
43 : prefix_name_(prefix_name),
44 interface_name_(interface_name),
45 handle_name_(prefix_name_ + "/" + interface_name_),
46 value_ptr_(value_ptr)
47 {
48 }
49
50 explicit Handle(const InterfaceDescription & interface_description)
51 : prefix_name_(interface_description.get_prefix_name()),
52 interface_name_(interface_description.get_interface_name()),
53 handle_name_(interface_description.get_name())
54 {
55 // As soon as multiple datatypes are used in HANDLE_DATATYPE
56 // we need to initialize according the type passed in interface description
57 value_ = std::numeric_limits<double>::quiet_NaN();
58 value_ptr_ = std::get_if<double>(&value_);
59 }
60
61 [[deprecated("Use InterfaceDescription for initializing the Interface")]]
62
63 explicit Handle(const std::string & interface_name)
64 : interface_name_(interface_name), handle_name_("/" + interface_name_), value_ptr_(nullptr)
65 {
66 }
67
68 [[deprecated("Use InterfaceDescription for initializing the Interface")]]
69
70 explicit Handle(const char * interface_name)
71 : interface_name_(interface_name), handle_name_("/" + interface_name_), value_ptr_(nullptr)
72 {
73 }
74
75 Handle(const Handle & other) noexcept
76 {
77 std::unique_lock<std::shared_mutex> lock(other.handle_mutex_);
78 std::unique_lock<std::shared_mutex> lock_this(handle_mutex_);
79 prefix_name_ = other.prefix_name_;
80 interface_name_ = other.interface_name_;
81 handle_name_ = other.handle_name_;
82 value_ = other.value_;
83 value_ptr_ = other.value_ptr_;
84 }
85
86 Handle(Handle && other) noexcept
87 {
88 std::unique_lock<std::shared_mutex> lock(other.handle_mutex_);
89 std::unique_lock<std::shared_mutex> lock_this(handle_mutex_);
90 prefix_name_ = std::move(other.prefix_name_);
91 interface_name_ = std::move(other.interface_name_);
92 handle_name_ = std::move(other.handle_name_);
93 value_ = std::move(other.value_);
94 value_ptr_ = std::move(other.value_ptr_);
95 }
96
97 Handle & operator=(const Handle & other)
98 {
99 if (this != &other)
100 {
101 std::unique_lock<std::shared_mutex> lock(other.handle_mutex_);
102 std::unique_lock<std::shared_mutex> lock_this(handle_mutex_);
103 prefix_name_ = other.prefix_name_;
104 interface_name_ = other.interface_name_;
105 handle_name_ = other.handle_name_;
106 value_ = other.value_;
107 value_ptr_ = other.value_ptr_;
108 }
109 return *this;
110 }
111
112 Handle & operator=(Handle && other)
113 {
114 if (this != &other)
115 {
116 std::unique_lock<std::shared_mutex> lock(other.handle_mutex_);
117 std::unique_lock<std::shared_mutex> lock_this(handle_mutex_);
118 prefix_name_ = std::move(other.prefix_name_);
119 interface_name_ = std::move(other.interface_name_);
120 handle_name_ = std::move(other.handle_name_);
121 value_ = std::move(other.value_);
122 value_ptr_ = std::move(other.value_ptr_);
123 }
124 return *this;
125 }
126
127 virtual ~Handle() = default;
128
130 inline operator bool() const { return value_ptr_ != nullptr; }
131
132 const std::string & get_name() const { return handle_name_; }
133
134 const std::string & get_interface_name() const { return interface_name_; }
135
136 [[deprecated(
137 "Replaced by get_name method, which is semantically more correct")]] const std::string &
138 get_full_name() const
139 {
140 return get_name();
141 }
142
143 const std::string & get_prefix_name() const { return prefix_name_; }
144
145 [[deprecated("Use bool get_value(double & value) instead to retrieve the value.")]]
146 double get_value() const
147 {
148 std::shared_lock<std::shared_mutex> lock(handle_mutex_, std::try_to_lock);
149 if (!lock.owns_lock())
150 {
151 return std::numeric_limits<double>::quiet_NaN();
152 }
153 // BEGIN (Handle export change): for backward compatibility
154 // TODO(Manuel) return value_ if old functionality is removed
155 THROW_ON_NULLPTR(value_ptr_);
156 return *value_ptr_;
157 // END
158 }
159
160 [[nodiscard]] bool get_value(double & value) const
161 {
162 std::shared_lock<std::shared_mutex> lock(handle_mutex_, std::try_to_lock);
163 if (!lock.owns_lock())
164 {
165 return false;
166 }
167 // BEGIN (Handle export change): for backward compatibility
168 // TODO(Manuel) set value directly if old functionality is removed
169 THROW_ON_NULLPTR(value_ptr_);
170 value = *value_ptr_;
171 return true;
172 // END
173 }
174
175 [[nodiscard]] bool set_value(double value)
176 {
177 std::unique_lock<std::shared_mutex> lock(handle_mutex_, std::try_to_lock);
178 if (!lock.owns_lock())
179 {
180 return false;
181 }
182 // BEGIN (Handle export change): for backward compatibility
183 // TODO(Manuel) set value_ directly if old functionality is removed
184 THROW_ON_NULLPTR(this->value_ptr_);
185 *this->value_ptr_ = value;
186 return true;
187 // END
188 }
189
190protected:
191 std::string prefix_name_;
192 std::string interface_name_;
193 std::string handle_name_;
194 HANDLE_DATATYPE value_;
195 // BEGIN (Handle export change): for backward compatibility
196 // TODO(Manuel) redeclare as HANDLE_DATATYPE * value_ptr_ if old functionality is removed
197 double * value_ptr_;
198 // END
199 mutable std::shared_mutex handle_mutex_;
200};
201
202class StateInterface : public Handle
203{
204public:
205 explicit StateInterface(const InterfaceDescription & interface_description)
206 : Handle(interface_description)
207 {
208 }
209
210 StateInterface(const StateInterface & other) = default;
211
212 StateInterface(StateInterface && other) = default;
213
214 using Handle::Handle;
215
216 using SharedPtr = std::shared_ptr<StateInterface>;
217 using ConstSharedPtr = std::shared_ptr<const StateInterface>;
218};
219
221{
222public:
223 explicit CommandInterface(const InterfaceDescription & interface_description)
224 : Handle(interface_description)
225 {
226 }
228
233 CommandInterface(const CommandInterface & other) = delete;
234
235 CommandInterface(CommandInterface && other) = default;
236
237 using Handle::Handle;
238
239 using SharedPtr = std::shared_ptr<CommandInterface>;
240};
241
242} // namespace hardware_interface
243
244#endif // HARDWARE_INTERFACE__HANDLE_HPP_
Definition handle.hpp:221
CommandInterface(const CommandInterface &other)=delete
CommandInterface copy constructor is actively deleted.
A handle used to get and set a value on a given interface.
Definition handle.hpp:36
Definition handle.hpp:203
Definition actuator.hpp:33
Definition hardware_info.hpp:138