Plugin.hh
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 Open Source Robotics Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 #ifndef _GZ_PLUGIN_HH_
18 #define _GZ_PLUGIN_HH_
19 
20 #ifdef _WIN32
21  // Ensure that Winsock2.h is included before Windows.h, which can get
22  // pulled in by anybody (e.g., Boost).
23  // This was put here because all the plugins are going to use it
24  // This doesn't guarantee something else won't cause it,
25  // but this saves putting this in every plugin
26 #include <Winsock2.h>
27 #endif
28 
29 #ifndef _WIN32
30  #include <unistd.h>
31 #endif
32 
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 
36 #include <gazebo/gazebo_config.h>
37 #include <dlfcn.h>
38 
39 #include <list>
40 #include <string>
41 
42 #include <sdf/sdf.hh>
43 #include <boost/filesystem.hpp>
44 
47 #include "gazebo/common/Console.hh"
49 
53 #include "gazebo/util/system.hh"
54 
55 namespace gazebo
56 {
57  class Event;
58 
61 
65  {
78  };
79 
80 
83  template<class T>
84  class PluginT
85  {
87  public: typedef boost::shared_ptr<T> TPtr;
88 
90  public: PluginT()
91  {
92  this->dlHandle = nullptr;
93  }
94 
96  public: virtual ~PluginT()
97  {
98  // dlclose has been disabled due to segfaults in the test suite
99  // This workaround is detailed in #1026 and #1066. After the test
100  // or gazebo execution the plugin is not loaded in memory anymore
101  // \todo Figure out the right thing to do.
102 
103  // dlclose(this->dlHandle);
104  }
105 
107  public: std::string GetFilename() const
108  {
109  return this->filename;
110  }
111 
113  public: std::string GetHandle() const
114  {
115  return this->handleName;
116  }
117 
123  public: static TPtr Create(const std::string &_filename,
124  const std::string &_name)
125  {
126  TPtr result;
127  // PluginPtr result;
128  struct stat st;
129  bool found = false;
130  std::string fullname, filename(_filename);
131  std::list<std::string>::iterator iter;
132  std::list<std::string> pluginPaths =
133  common::SystemPaths::Instance()->GetPluginPaths();
134 
135 #ifdef __APPLE__
136  // This is a hack to work around issue #800,
137  // error loading plugin libraries with different extensions
138  {
139  size_t soSuffix = filename.rfind(".so");
140  if (soSuffix != std::string::npos)
141  {
142  const std::string macSuffix(".dylib");
143  filename.replace(soSuffix, macSuffix.length(), macSuffix);
144  }
145  }
146 #elif _WIN32
147  // Corresponding windows hack
148  {
149  // replace .so with .dll
150  size_t soSuffix = filename.rfind(".so");
151  if (soSuffix != std::string::npos)
152  {
153  const std::string winSuffix(".dll");
154  filename.replace(soSuffix, winSuffix.length(), winSuffix);
155  }
156  size_t libPrefix = filename.find("lib");
157  if (libPrefix == 0)
158  {
159  // remove the lib prefix
160  filename.erase(0, 3);
161  }
162  }
163 #endif // ifdef __APPLE__
164 
165  for (iter = pluginPaths.begin();
166  iter!= pluginPaths.end(); ++iter)
167  {
168  fullname = (*iter)+std::string("/")+filename;
169  fullname = boost::filesystem::path(fullname)
170  .make_preferred().string();
171  if (stat(fullname.c_str(), &st) == 0)
172  {
173  found = true;
174  break;
175  }
176  }
177 
178  if (!found)
179  fullname = filename;
180 
181  fptr_union_t registerFunc;
182  std::string registerName = "RegisterPlugin";
183 
184  void *dlHandle = dlopen(fullname.c_str(), RTLD_LAZY|RTLD_GLOBAL);
185  if (!dlHandle)
186  {
187  gzerr << "Failed to load plugin " << fullname << ": "
188  << dlerror() << "\n";
189  return result;
190  }
191 
192  registerFunc.ptr = dlsym(dlHandle, registerName.c_str());
193 
194  if (!registerFunc.ptr)
195  {
196  gzerr << "Failed to resolve " << registerName
197  << ": " << dlerror();
198  return result;
199  }
200 
201  // Register the new controller.
202  result.reset(registerFunc.func());
203  result->dlHandle = dlHandle;
204 
205  result->handleName = _name;
206  result->filename = filename;
207 
208  return result;
209  }
210 
213  public: PluginType GetType() const
214  {
215  return this->type;
216  }
217 
226  protected: template <typename V> void LoadParam(const sdf::ElementPtr &_sdf,
227  const std::string &_name, V &_target,
228  V _defaultValue = V()) const
229  {
230  auto result = _sdf->Get<V>(_name, _defaultValue);
231 
232  if (!result.second)
233  {
234  gzmsg << this->handleName.c_str() << " Plugin missing <"
235  << _name.c_str() << ">, defaults to "
236  << result.first << std::endl;
237  }
238  else
239  {
240  gzmsg << this->handleName.c_str() << " Plugin <"
241  << _name.c_str() << "> set to "
242  << result.first << std::endl;
243  }
244  _target = result.first;
245  }
246 
256  protected: void LoadParam(sdf::ElementPtr &_sdf,
257  const std::string &_name, std::string &_target,
258  const char* _defaultValue) const
259  {
260  this->LoadParam<std::string>(_sdf, _name, _target, _defaultValue);
261  }
262 
264  protected: PluginType type;
265 
267  protected: std::string filename;
268 
270  protected: std::string handleName;
271 
273  private: typedef union
274  {
275  T *(*func)();
276  void *ptr;
277  } fptr_union_t;
278 
280  private: void *dlHandle;
281  };
282 
287  class WorldPlugin : public PluginT<WorldPlugin>
288  {
290  public: WorldPlugin()
291  {this->type = WORLD_PLUGIN;}
292 
294  public: virtual ~WorldPlugin() {}
295 
302  public: virtual void Load(physics::WorldPtr _world,
303  sdf::ElementPtr _sdf) = 0;
304 
305  public: virtual void Init() {}
306  public: virtual void Reset() {}
307  };
308 
312  class ModelPlugin : public PluginT<ModelPlugin>
313  {
315  public: ModelPlugin()
316  {this->type = MODEL_PLUGIN;}
317 
319  public: virtual ~ModelPlugin() {}
320 
327  public: virtual void Load(physics::ModelPtr _model,
328  sdf::ElementPtr _sdf) = 0;
329 
331  public: virtual void Init() {}
332 
334  public: virtual void Reset() {}
335  };
336 
341  class SensorPlugin : public PluginT<SensorPlugin>
342  {
344  public: SensorPlugin()
345  {this->type = SENSOR_PLUGIN;}
346 
348  public: virtual ~SensorPlugin() {}
349 
356  public: virtual void Load(sensors::SensorPtr _sensor,
357  sdf::ElementPtr _sdf) = 0;
358 
360  public: virtual void Init() {}
361 
363  public: virtual void Reset() {}
364  };
365 
370  class SystemPlugin : public PluginT<SystemPlugin>
371  {
373  public: SystemPlugin()
374  {this->type = SYSTEM_PLUGIN;}
375 
377  public: virtual ~SystemPlugin() {}
378 
384  public: virtual void Load(int _argc = 0, char **_argv = nullptr) = 0;
385 
389  public: virtual void Init() {}
390 
392  public: virtual void Reset() {}
393  };
394 
398  class VisualPlugin : public PluginT<VisualPlugin>
399  {
400  public: VisualPlugin()
401  {this->type = VISUAL_PLUGIN;}
402 
409  public: virtual void Load(rendering::VisualPtr _visual,
410  sdf::ElementPtr _sdf) = 0;
411 
415  public: virtual void Init() {}
416 
418  public: virtual void Reset() {}
419  };
420 
421 
423 
428 #define GZ_REGISTER_MODEL_PLUGIN(classname) \
429  extern "C" GZ_PLUGIN_VISIBLE gazebo::ModelPlugin *RegisterPlugin(); \
430  gazebo::ModelPlugin *RegisterPlugin() \
431  {\
432  return new classname();\
433  }
434 
439 #define GZ_REGISTER_WORLD_PLUGIN(classname) \
440  extern "C" GZ_PLUGIN_VISIBLE gazebo::WorldPlugin *RegisterPlugin(); \
441  gazebo::WorldPlugin *RegisterPlugin() \
442  {\
443  return new classname();\
444  }
445 
450 #define GZ_REGISTER_SENSOR_PLUGIN(classname) \
451  extern "C" GZ_PLUGIN_VISIBLE gazebo::SensorPlugin *RegisterPlugin(); \
452  gazebo::SensorPlugin *RegisterPlugin() \
453  {\
454  return new classname();\
455  }
456 
461 #define GZ_REGISTER_SYSTEM_PLUGIN(classname) \
462  extern "C" GZ_PLUGIN_VISIBLE gazebo::SystemPlugin *RegisterPlugin(); \
463  gazebo::SystemPlugin *RegisterPlugin() \
464  {\
465  return new classname();\
466  }
467 
472 #define GZ_REGISTER_VISUAL_PLUGIN(classname) \
473  extern "C" GZ_PLUGIN_VISIBLE gazebo::VisualPlugin *RegisterPlugin(); \
474  gazebo::VisualPlugin *RegisterPlugin() \
475  {\
476  return new classname();\
477  }
478 }
479 
480 #endif
default namespace for gazebo
Forward declarations and typedefs for sensors.
static SystemPaths * Instance()
Get an instance of the singleton.
Definition: SingletonT.hh:36
A plugin with access to physics::Model.
Definition: Plugin.hh:313
virtual void Load(physics::ModelPtr _model, sdf::ElementPtr _sdf)=0
Load function.
virtual void Init()
Override this method for custom plugin initialization behavior.
Definition: Plugin.hh:331
virtual void Reset()
Override this method for custom plugin reset behavior.
Definition: Plugin.hh:334
virtual ~ModelPlugin()
Destructor.
Definition: Plugin.hh:319
ModelPlugin()
Constructor.
Definition: Plugin.hh:315
A class which all plugins must inherit from.
Definition: Plugin.hh:85
std::string GetFilename() const
Get the name of the handler.
Definition: Plugin.hh:107
std::string handleName
Short name.
Definition: Plugin.hh:270
PluginType type
Type of plugin.
Definition: Plugin.hh:264
boost::shared_ptr< T > TPtr
plugin pointer type definition
Definition: Plugin.hh:87
void LoadParam(const sdf::ElementPtr &_sdf, const std::string &_name, V &_target, V _defaultValue=V()) const
Load parameter value from _sdf and store it to the given reference, using the supplied default value ...
Definition: Plugin.hh:226
PluginType GetType() const
Returns the type of the plugin.
Definition: Plugin.hh:213
static TPtr Create(const std::string &_filename, const std::string &_name)
a class method that creates a plugin from a file name.
Definition: Plugin.hh:123
PluginT()
Constructor.
Definition: Plugin.hh:90
std::string GetHandle() const
Get the short name of the handler.
Definition: Plugin.hh:113
void LoadParam(sdf::ElementPtr &_sdf, const std::string &_name, std::string &_target, const char *_defaultValue) const
Load parameter value from _sdf and store it to the given reference, using the supplied default value ...
Definition: Plugin.hh:256
std::string filename
Path to the shared library file.
Definition: Plugin.hh:267
virtual ~PluginT()
Destructor.
Definition: Plugin.hh:96
A plugin with access to physics::Sensor.
Definition: Plugin.hh:342
SensorPlugin()
Constructor.
Definition: Plugin.hh:344
virtual void Init()
Override this method for custom plugin initialization behavior.
Definition: Plugin.hh:360
virtual void Reset()
Override this method for custom plugin reset behavior.
Definition: Plugin.hh:363
virtual void Load(sensors::SensorPtr _sensor, sdf::ElementPtr _sdf)=0
Load function.
virtual ~SensorPlugin()
Destructor.
Definition: Plugin.hh:348
A plugin loaded within the gzserver on startup.
Definition: Plugin.hh:371
SystemPlugin()
Constructor.
Definition: Plugin.hh:373
virtual void Init()
Initialize the plugin.
Definition: Plugin.hh:389
virtual ~SystemPlugin()
Destructor.
Definition: Plugin.hh:377
virtual void Reset()
Override this method for custom plugin reset behavior.
Definition: Plugin.hh:392
virtual void Load(int _argc=0, char **_argv=nullptr)=0
Load function.
A plugin with access to rendering::Visual.
Definition: Plugin.hh:399
virtual void Load(rendering::VisualPtr _visual, sdf::ElementPtr _sdf)=0
Load function.
virtual void Init()
Initialize the plugin.
Definition: Plugin.hh:415
virtual void Reset()
Override this method for custom plugin reset behavior.
Definition: Plugin.hh:418
VisualPlugin()
Definition: Plugin.hh:400
A plugin with access to physics::World.
Definition: Plugin.hh:288
virtual ~WorldPlugin()
Destructor.
Definition: Plugin.hh:294
virtual void Init()
Definition: Plugin.hh:305
virtual void Load(physics::WorldPtr _world, sdf::ElementPtr _sdf)=0
Load function.
WorldPlugin()
Constructor.
Definition: Plugin.hh:290
virtual void Reset()
Definition: Plugin.hh:306
#define gzmsg
Output a message.
Definition: Console.hh:41
PluginType
Used to specify the type of plugin.
Definition: Plugin.hh:65
#define gzerr
Output an error message.
Definition: Console.hh:50
@ SYSTEM_PLUGIN
A System plugin.
Definition: Plugin.hh:73
@ GUI_PLUGIN
A GUI plugin.
Definition: Plugin.hh:77
@ VISUAL_PLUGIN
A Visual plugin.
Definition: Plugin.hh:75
@ SENSOR_PLUGIN
A Sensor plugin.
Definition: Plugin.hh:71
@ MODEL_PLUGIN
A Model plugin.
Definition: Plugin.hh:69
@ WORLD_PLUGIN
A World plugin.
Definition: Plugin.hh:67
boost::shared_ptr< World > WorldPtr
Definition: PhysicsTypes.hh:89
boost::shared_ptr< Model > ModelPtr
Definition: PhysicsTypes.hh:93
std::shared_ptr< Visual > VisualPtr
Definition: RenderTypes.hh:114
std::shared_ptr< Sensor > SensorPtr
Definition: SensorTypes.hh:64
Forward declarations for the common classes.
Definition: Animation.hh:27