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 
46 #include "gazebo/common/Console.hh"
48 
52 #include "gazebo/util/system.hh"
53 
54 namespace gazebo
55 {
56  class Event;
57 
60 
64  {
77  };
78 
79 
82  template<class T>
83  class PluginT
84  {
86  public: typedef boost::shared_ptr<T> TPtr;
87 
89  public: PluginT()
90  {
91  this->dlHandle = nullptr;
92  }
93 
95  public: virtual ~PluginT()
96  {
97  // dlclose has been disabled due to segfaults in the test suite
98  // This workaround is detailed in #1026 and #1066. After the test
99  // or gazebo execution the plugin is not loaded in memory anymore
100  // \todo Figure out the right thing to do.
101 
102  // dlclose(this->dlHandle);
103  }
104 
106  public: std::string GetFilename() const
107  {
108  return this->filename;
109  }
110 
112  public: std::string GetHandle() const
113  {
114  return this->handleName;
115  }
116 
122  public: static TPtr Create(const std::string &_filename,
123  const std::string &_name)
124  {
125  TPtr result;
126  // PluginPtr result;
127  struct stat st;
128  bool found = false;
129  std::string fullname, filename(_filename);
130  std::list<std::string>::iterator iter;
131  std::list<std::string> pluginPaths =
132  common::SystemPaths::Instance()->GetPluginPaths();
133 
134 #ifdef __APPLE__
135  // This is a hack to work around issue #800,
136  // error loading plugin libraries with different extensions
137  {
138  size_t soSuffix = filename.rfind(".so");
139  if (soSuffix != std::string::npos)
140  {
141  const std::string macSuffix(".dylib");
142  filename.replace(soSuffix, macSuffix.length(), macSuffix);
143  }
144  }
145 #elif _WIN32
146  // Corresponding windows hack
147  {
148  // replace .so with .dll
149  size_t soSuffix = filename.rfind(".so");
150  if (soSuffix != std::string::npos)
151  {
152  const std::string winSuffix(".dll");
153  filename.replace(soSuffix, winSuffix.length(), winSuffix);
154  }
155  // remove the lib prefix
156  filename.erase(0, 3);
157  }
158 #endif // ifdef __APPLE__
159 
160  for (iter = pluginPaths.begin();
161  iter!= pluginPaths.end(); ++iter)
162  {
163  fullname = (*iter)+std::string("/")+filename;
164  if (stat(fullname.c_str(), &st) == 0)
165  {
166  found = true;
167  break;
168  }
169  }
170 
171  if (!found)
172  fullname = filename;
173 
174  fptr_union_t registerFunc;
175  std::string registerName = "RegisterPlugin";
176 
177  void *dlHandle = dlopen(fullname.c_str(), RTLD_LAZY|RTLD_GLOBAL);
178  if (!dlHandle)
179  {
180  gzerr << "Failed to load plugin " << fullname << ": "
181  << dlerror() << "\n";
182  return result;
183  }
184 
185  registerFunc.ptr = dlsym(dlHandle, registerName.c_str());
186 
187  if (!registerFunc.ptr)
188  {
189  gzerr << "Failed to resolve " << registerName
190  << ": " << dlerror();
191  return result;
192  }
193 
194  // Register the new controller.
195  result.reset(registerFunc.func());
196  result->dlHandle = dlHandle;
197 
198  result->handleName = _name;
199  result->filename = filename;
200 
201  return result;
202  }
203 
206  public: PluginType GetType() const
207  {
208  return this->type;
209  }
210 
219  protected: template <typename V> void LoadParam(const sdf::ElementPtr &_sdf,
220  const std::string &_name, V &_target,
221  V _defaultValue = V()) const
222  {
223  auto result = _sdf->Get<V>(_name, _defaultValue);
224 
225  if (!result.second)
226  {
227  gzmsg << this->handleName.c_str() << " Plugin missing <"
228  << _name.c_str() << ">, defaults to "
229  << result.first << std::endl;
230  }
231  else
232  {
233  gzmsg << this->handleName.c_str() << " Plugin <"
234  << _name.c_str() << "> set to "
235  << result.first << std::endl;
236  }
237  _target = result.first;
238  }
239 
249  protected: void LoadParam(sdf::ElementPtr &_sdf,
250  const std::string &_name, std::string &_target,
251  const char* _defaultValue) const
252  {
253  this->LoadParam<std::string>(_sdf, _name, _target, _defaultValue);
254  }
255 
257  protected: PluginType type;
258 
260  protected: std::string filename;
261 
263  protected: std::string handleName;
264 
266  private: typedef union
267  {
268  T *(*func)();
269  void *ptr;
270  } fptr_union_t;
271 
273  private: void *dlHandle;
274  };
275 
280  class WorldPlugin : public PluginT<WorldPlugin>
281  {
283  public: WorldPlugin()
284  {this->type = WORLD_PLUGIN;}
285 
287  public: virtual ~WorldPlugin() {}
288 
295  public: virtual void Load(physics::WorldPtr _world,
296  sdf::ElementPtr _sdf) = 0;
297 
298  public: virtual void Init() {}
299  public: virtual void Reset() {}
300  };
301 
305  class ModelPlugin : public PluginT<ModelPlugin>
306  {
308  public: ModelPlugin()
309  {this->type = MODEL_PLUGIN;}
310 
312  public: virtual ~ModelPlugin() {}
313 
320  public: virtual void Load(physics::ModelPtr _model,
321  sdf::ElementPtr _sdf) = 0;
322 
324  public: virtual void Init() {}
325 
327  public: virtual void Reset() {}
328  };
329 
334  class SensorPlugin : public PluginT<SensorPlugin>
335  {
337  public: SensorPlugin()
338  {this->type = SENSOR_PLUGIN;}
339 
341  public: virtual ~SensorPlugin() {}
342 
349  public: virtual void Load(sensors::SensorPtr _sensor,
350  sdf::ElementPtr _sdf) = 0;
351 
353  public: virtual void Init() {}
354 
356  public: virtual void Reset() {}
357  };
358 
363  class SystemPlugin : public PluginT<SystemPlugin>
364  {
366  public: SystemPlugin()
367  {this->type = SYSTEM_PLUGIN;}
368 
370  public: virtual ~SystemPlugin() {}
371 
377  public: virtual void Load(int _argc = 0, char **_argv = nullptr) = 0;
378 
382  public: virtual void Init() {}
383 
385  public: virtual void Reset() {}
386  };
387 
391  class VisualPlugin : public PluginT<VisualPlugin>
392  {
393  public: VisualPlugin()
394  {this->type = VISUAL_PLUGIN;}
395 
402  public: virtual void Load(rendering::VisualPtr _visual,
403  sdf::ElementPtr _sdf) = 0;
404 
408  public: virtual void Init() {}
409 
411  public: virtual void Reset() {}
412  };
413 
414 
416 
421 #define GZ_REGISTER_MODEL_PLUGIN(classname) \
422  extern "C" GZ_PLUGIN_VISIBLE gazebo::ModelPlugin *RegisterPlugin(); \
423  gazebo::ModelPlugin *RegisterPlugin() \
424  {\
425  return new classname();\
426  }
427 
432 #define GZ_REGISTER_WORLD_PLUGIN(classname) \
433  extern "C" GZ_PLUGIN_VISIBLE gazebo::WorldPlugin *RegisterPlugin(); \
434  gazebo::WorldPlugin *RegisterPlugin() \
435  {\
436  return new classname();\
437  }
438 
443 #define GZ_REGISTER_SENSOR_PLUGIN(classname) \
444  extern "C" GZ_PLUGIN_VISIBLE gazebo::SensorPlugin *RegisterPlugin(); \
445  gazebo::SensorPlugin *RegisterPlugin() \
446  {\
447  return new classname();\
448  }
449 
454 #define GZ_REGISTER_SYSTEM_PLUGIN(classname) \
455  extern "C" GZ_PLUGIN_VISIBLE gazebo::SystemPlugin *RegisterPlugin(); \
456  gazebo::SystemPlugin *RegisterPlugin() \
457  {\
458  return new classname();\
459  }
460 
465 #define GZ_REGISTER_VISUAL_PLUGIN(classname) \
466  extern "C" GZ_PLUGIN_VISIBLE gazebo::VisualPlugin *RegisterPlugin(); \
467  gazebo::VisualPlugin *RegisterPlugin() \
468  {\
469  return new classname();\
470  }
471 }
472 
473 #endif
#define gzmsg
Output a message.
Definition: Console.hh:41
std::shared_ptr< Sensor > SensorPtr
Definition: SensorTypes.hh:64
std::string handleName
Short name.
Definition: Plugin.hh:263
boost::shared_ptr< World > WorldPtr
Definition: PhysicsTypes.hh:89
Forward declarations for the common classes.
Definition: Animation.hh:26
std::string filename
Path to the shared library file.
Definition: Plugin.hh:260
std::string GetFilename() const
Get the name of the handler.
Definition: Plugin.hh:106
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:122
virtual void Reset()
Definition: Plugin.hh:299
std::string GetHandle() const
Get the short name of the handler.
Definition: Plugin.hh:112
PluginType type
Type of plugin.
Definition: Plugin.hh:257
A plugin with access to physics::World.
Definition: Plugin.hh:280
A plugin with access to rendering::Visual.
Definition: Plugin.hh:391
virtual void Init()
Override this method for custom plugin initialization behavior.
Definition: Plugin.hh:353
#define gzerr
Output an error message.
Definition: Console.hh:50
A World plugin.
Definition: Plugin.hh:66
virtual void Reset()
Override this method for custom plugin reset behavior.
Definition: Plugin.hh:385
default namespace for gazebo
virtual void Reset()
Override this method for custom plugin reset behavior.
Definition: Plugin.hh:411
A plugin loaded within the gzserver on startup.
Definition: Plugin.hh:363
A GUI plugin.
Definition: Plugin.hh:76
PluginType
Used to specify the type of plugin.
Definition: Plugin.hh:63
A Sensor plugin.
Definition: Plugin.hh:70
virtual void Reset()
Override this method for custom plugin reset behavior.
Definition: Plugin.hh:327
virtual void Reset()
Override this method for custom plugin reset behavior.
Definition: Plugin.hh:356
virtual void Init()
Definition: Plugin.hh:298
virtual ~PluginT()
Destructor.
Definition: Plugin.hh:95
virtual ~SystemPlugin()
Destructor.
Definition: Plugin.hh:370
boost::shared_ptr< T > TPtr
plugin pointer type definition
Definition: Plugin.hh:86
VisualPlugin()
Definition: Plugin.hh:393
virtual void Init()
Initialize the plugin.
Definition: Plugin.hh:408
PluginType GetType() const
Returns the type of the plugin.
Definition: Plugin.hh:206
A class which all plugins must inherit from.
Definition: Plugin.hh:83
SystemPlugin()
Constructor.
Definition: Plugin.hh:366
A Model plugin.
Definition: Plugin.hh:68
ModelPlugin()
Constructor.
Definition: Plugin.hh:308
virtual ~WorldPlugin()
Destructor.
Definition: Plugin.hh:287
std::shared_ptr< Visual > VisualPtr
Definition: RenderTypes.hh:114
boost::shared_ptr< Model > ModelPtr
Definition: PhysicsTypes.hh:93
SensorPlugin()
Constructor.
Definition: Plugin.hh:337
Forward declarations and typedefs for sensors.
WorldPlugin()
Constructor.
Definition: Plugin.hh:283
virtual void Init()
Initialize the plugin.
Definition: Plugin.hh:382
virtual ~SensorPlugin()
Destructor.
Definition: Plugin.hh:341
A Visual plugin.
Definition: Plugin.hh:74
PluginT()
Constructor.
Definition: Plugin.hh:89
A plugin with access to physics::Sensor.
Definition: Plugin.hh:334
A plugin with access to physics::Model.
Definition: Plugin.hh:305
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:219
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:249
virtual ~ModelPlugin()
Destructor.
Definition: Plugin.hh:312
virtual void Init()
Override this method for custom plugin initialization behavior.
Definition: Plugin.hh:324
static SystemPaths * Instance()
Get an instance of the singleton.
Definition: SingletonT.hh:36
A System plugin.
Definition: Plugin.hh:72