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
49
53#include "gazebo/util/system.hh"
54
55namespace 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