interface_manager.h
Go to the documentation of this file.
1 // Copyright (C) 2013, PAL Robotics S.L.
3 // Copyright (C) 2012, hiDOF INC.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are met:
7 // * Redistributions of source code must retain the above copyright notice,
8 // this list of conditions and the following disclaimer.
9 // * Redistributions in binary form must reproduce the above copyright
10 // notice, this list of conditions and the following disclaimer in the
11 // documentation and/or other materials provided with the distribution.
12 // * Neither the name of hiDOF, Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived from
14 // this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 // POSSIBILITY OF SUCH DAMAGE.
28 
30 
31 #pragma once
32 
33 
34 #include <map>
35 #include <string>
36 #include <vector>
37 
38 #include <ros/console.h>
39 
42 
43 namespace hardware_interface
44 {
45 
46 namespace internal
47 {
48 
49 // SFINAE workaround, so that we have reflection inside the template functions
50 template <typename T>
52  // method called if C is a ResourceManager
53  template <typename C>
54  static void callCM(typename std::vector<C*>& managers, C* result, typename C::ResourceManagerType*)
55  {
56  // We have to typecast back to base class
57  std::vector<typename C::ResourceManagerType*> managers_in(managers.begin(), managers.end());
58  C::concatManagers(managers_in, result);
59  }
60 
61  // method called if C is not a ResourceManager
62  template <typename C>
63  static void callCM(typename std::vector<C*>& /*managers*/, C* /*result*/, ...) {}
64 
65  // calls ResourceManager::concatManagers if C is a ResourceManager
66  static void callConcatManagers(typename std::vector<T*>& managers, T* result)
67  { callCM<T>(managers, result, nullptr); }
68 
69 
70  // method called if C is a ResourceManager
71  template <typename C>
72  static void callGR(std::vector<std::string> &resources, C* iface, typename C::ResourceManagerType*)
73  {
74  resources = iface->getNames();
75  }
76 
77  // method called if C is not a ResourceManager
78  template <typename C>
79  static void callGR(std::vector<std::string> &/*resources*/, T* /*iface*/, ...) { }
80 
81  // calls ResourceManager::concatManagers if C is a ResourceManager
82  static void callGetResources(std::vector<std::string> &resources, T* iface)
83  { return callGR<T>(resources, iface, nullptr); }
84 
85  template <typename C>
86  static T* newCI(std::vector<ResourceManagerBase*> &guards, typename C::ResourceManagerType*)
87  {
88  T* iface_combo = new T;
89  // save the new interface pointer to allow for its correct destruction
90  guards.push_back(static_cast<ResourceManagerBase*>(iface_combo));
91  return iface_combo;
92  }
93 
94  // method called if C is not a ResourceManager
95  template <typename C>
96  static T* newCI(std::vector<ResourceManagerBase*> &/*guards*/, ...) {
97  // it is not a ResourceManager
98  ROS_ERROR("You cannot register multiple interfaces of the same type which are "
99  "not of type ResourceManager. There is no established protocol "
100  "for combining them.");
101  return nullptr;
102  }
103 
104  static T* newCombinedInterface(std::vector<ResourceManagerBase*> &guards)
105  {
106  return newCI<T>(guards, nullptr);
107  }
108 
109 };
110 
111 } // namespace internal
112 
123 {
124 public:
137  template<class T>
138  void registerInterface(T* iface)
139  {
140  const std::string iface_name = internal::demangledTypeName<T>();
141  if (interfaces_.find(iface_name) != interfaces_.end())
142  {
143  ROS_WARN_STREAM("Replacing previously registered interface '" << iface_name << "'.");
144  }
145  interfaces_[iface_name] = iface;
147  }
148 
158  {
159  interface_managers_.push_back(iface_man);
160  }
161 
182  template<class T>
183  T* get()
184  {
185  std::string type_name = internal::demangledTypeName<T>();
186  std::vector<T*> iface_list;
187 
188  // look for interfaces registered here
189  InterfaceMap::iterator it = interfaces_.find(type_name);
190  if (it != interfaces_.end()) {
191  T* iface = static_cast<T*>(it->second);
192  if (!iface) {
193  ROS_ERROR_STREAM("Failed reconstructing type T = '" << type_name.c_str() <<
194  "'. This should never happen");
195  return nullptr;
196  }
197  iface_list.push_back(iface);
198  }
199 
200  // look for interfaces registered in the registered hardware
201  for (const auto& interface_manager : interface_managers_) {
202  T* iface = interface_manager->get<T>();
203  if (iface)
204  iface_list.push_back(iface);
205  }
206 
207  if(iface_list.size() == 0)
208  return nullptr;
209 
210  if(iface_list.size() == 1)
211  return iface_list.front();
212 
213  // if we're here, we have multiple interfaces, and thus we must construct a new
214  // combined interface, or return one already constructed
215  T* iface_combo;
216  InterfaceMap::iterator it_combo = interfaces_combo_.find(type_name);
217  if(it_combo != interfaces_combo_.end() &&
218  num_ifaces_registered_[type_name] == iface_list.size()) {
219  // there exists a combined interface with the same number of interfaces combined
220  // (since you cannot unregister interfaces, this will be guaranteed to be the
221  // same interfaces from previous calls)
222  iface_combo = static_cast<T*>(it_combo->second);
223  } else {
224  // no existing combined interface
226  if(iface_combo) {
227  // concat all of the resource managers together
229  // save the combined interface for if this is called again
230  interfaces_combo_[type_name] = iface_combo;
231  num_ifaces_registered_[type_name] = iface_list.size();
232  } else {
233  // Multiple interfaces of the same type which are not ResourceManager cannot be combined, so return
234  // nullptr
235  iface_combo = nullptr;
236  }
237  }
238  return iface_combo;
239  }
240 
250  std::vector<std::string> getNames() const
251  {
252  std::vector<std::string> out;
253  out.reserve(interfaces_.size());
254  for (const auto& interface : interfaces_)
255  {
256  out.push_back(interface.first);
257  }
258 
259  for (const auto& interface_manager : interface_managers_)
260  {
261  // Make sure interfaces appear only once, as they may have been combined
262  for (const auto& interface_name : interface_manager->getNames())
263  {
264  if (std::find(out.begin(), out.end(), interface_name) == out.end())
265  {
266  out.push_back(interface_name);
267  }
268  }
269  }
270 
271  return out;
272  }
273 
283  std::vector<std::string> getInterfaceResources(std::string iface_type) const
284  {
285  std::vector<std::string> out;
286  ResourceMap::const_iterator it = resources_.find(iface_type);
287  if(it != resources_.end())
288  {
289  out = it->second;
290  }
291 
292  for (const auto& interface_manager : interface_managers_)
293  {
294  std::vector<std::string> resources = interface_manager->getInterfaceResources(iface_type);
295  out.insert(out.end(), resources.begin(), resources.end());
296  }
297 
298  return out;
299  }
300 
301 protected:
302  typedef std::map<std::string, void*> InterfaceMap;
303  typedef std::vector<InterfaceManager*> InterfaceManagerVector;
304  typedef std::map<std::string, size_t> SizeMap;
305  typedef std::map<std::string, std::vector<std::string> > ResourceMap;
306 
311  std::vector<ResourceManagerBase*> interface_destruction_list_;
314 };
315 
316 } // namespace
hardware_interface::InterfaceManager
Manager for hardware interface registrations.
Definition: interface_manager.h:122
ROS_ERROR_STREAM
#define ROS_ERROR_STREAM(args)
hardware_interface::internal::CheckIsResourceManager::callConcatManagers
static void callConcatManagers(typename std::vector< T * > &managers, T *result)
Definition: interface_manager.h:66
hardware_interface::internal::CheckIsResourceManager::callCM
static void callCM(typename std::vector< C * > &managers, C *result, typename C::ResourceManagerType *)
Definition: interface_manager.h:54
hardware_interface::internal::CheckIsResourceManager::callCM
static void callCM(typename std::vector< C * > &, C *,...)
Definition: interface_manager.h:63
hardware_interface::InterfaceManager::get
T * get()
Get an interface.
Definition: interface_manager.h:183
hardware_interface::InterfaceManager::registerInterface
void registerInterface(T *iface)
Register an interface.
Definition: interface_manager.h:138
hardware_interface::internal::CheckIsResourceManager::newCI
static T * newCI(std::vector< ResourceManagerBase * > &,...)
Definition: interface_manager.h:96
hardware_interface::InterfaceManager::interface_managers_
InterfaceManagerVector interface_managers_
Definition: interface_manager.h:309
hardware_interface::internal::CheckIsResourceManager::newCombinedInterface
static T * newCombinedInterface(std::vector< ResourceManagerBase * > &guards)
Definition: interface_manager.h:104
hardware_interface::InterfaceManager::registerInterfaceManager
void registerInterfaceManager(InterfaceManager *iface_man)
Register another interface manager.
Definition: interface_manager.h:157
console.h
ROS_WARN_STREAM
#define ROS_WARN_STREAM(args)
hardware_interface::InterfaceManager::interface_destruction_list_
std::vector< ResourceManagerBase * > interface_destruction_list_
Definition: interface_manager.h:311
hardware_interface::internal::CheckIsResourceManager::callGetResources
static void callGetResources(std::vector< std::string > &resources, T *iface)
Definition: interface_manager.h:82
hardware_interface
Definition: actuator_command_interface.h:36
hardware_interface::ResourceManagerBase
Non-templated Base Class that contains a virtual destructor.
Definition: resource_manager.h:52
hardware_interface::InterfaceManager::getNames
std::vector< std::string > getNames() const
Lists the demangled names of all registered interfaces.
Definition: interface_manager.h:250
hardware_interface::InterfaceManager::getInterfaceResources
std::vector< std::string > getInterfaceResources(std::string iface_type) const
Get the resource names registered to an interface, specified by type.
Definition: interface_manager.h:283
hardware_interface::InterfaceManager::SizeMap
std::map< std::string, size_t > SizeMap
Definition: interface_manager.h:304
demangle_symbol.h
hardware_interface::InterfaceManager::interfaces_
InterfaceMap interfaces_
Definition: interface_manager.h:307
hardware_interface::InterfaceManager::ResourceMap
std::map< std::string, std::vector< std::string > > ResourceMap
Definition: interface_manager.h:305
hardware_interface::internal::CheckIsResourceManager
Definition: interface_manager.h:51
hardware_interface::InterfaceManager::InterfaceMap
std::map< std::string, void * > InterfaceMap
Definition: interface_manager.h:302
hardware_interface::internal::CheckIsResourceManager::newCI
static T * newCI(std::vector< ResourceManagerBase * > &guards, typename C::ResourceManagerType *)
Definition: interface_manager.h:86
hardware_interface::InterfaceManager::InterfaceManagerVector
std::vector< InterfaceManager * > InterfaceManagerVector
Definition: interface_manager.h:303
ROS_ERROR
#define ROS_ERROR(...)
hardware_interface::internal::CheckIsResourceManager::callGR
static void callGR(std::vector< std::string > &, T *,...)
Definition: interface_manager.h:79
hardware_interface::InterfaceManager::resources_
ResourceMap resources_
This will allow us to check the resources based on the demangled type name of the interface.
Definition: interface_manager.h:313
hardware_interface::InterfaceManager::num_ifaces_registered_
SizeMap num_ifaces_registered_
Definition: interface_manager.h:310
resource_manager.h
hardware_interface::internal::CheckIsResourceManager::callGR
static void callGR(std::vector< std::string > &resources, C *iface, typename C::ResourceManagerType *)
Definition: interface_manager.h:72
hardware_interface::InterfaceManager::interfaces_combo_
InterfaceMap interfaces_combo_
Definition: interface_manager.h:308


hardware_interface
Author(s): Wim Meeussen, Adolfo Rodriguez Tsouroukdissian
autogenerated on Fri Nov 3 2023 02:07:57