The vigir_pluginlib package
- Maintainer status: maintained
- Maintainer: Alexander Stumpf <stumpf AT sim.tu-darmstadt DOT de>
- Author: Alexander Stumpf <stumpf AT sim.tu-darmstadt DOT de>
- License: BSD
- Source: git https://github.com/team-vigir/vigir_pluginlib.git (branch: master)
The vigir_pluginlib is based on the exisiting pluginlib system. It extends the basic plugin system by a convenient plugin management tool which enables to gather specific plugins based on their provided functionality from a heterogeneous plugin database.
Hereby the basic infrastructure remains identically to the original pluginlib system as the vigir_pluginlib is built on top. Using the vigir_pluginlib allows analogously to load classes from a runtime library (i.e. shared object, dynamically linked library) without the application having any prior awareness of the library or the header file containing the class definition (for details see the pluginlib documentation).
The vigir_pluginlib uses the C++ RTTI mechanism to determine the functionality of each instantiated plugin based on implemented parent classes. This information helps the plugin manager to resolve any kind of plugin request done by the application during runtime and allows to manage a heterogeneous plugin database. For clarification, heterogeneous denotes indeed that you can load plugins of different type in one single manager and therefore have convenient centralized access to all your plugins no matter which interface they actually implement. If you need a plugin implementing a specific interface, then the plugin manager tries best effort to deliver them. Polymorphic plugins are indeed allowed, thus a single plugin may implement the interfaces of multiple interface plugins and still will be retrieved correctly.
Furthermore the plugin manager comes with full service and action interfaces, thus the plugin composition used by your application can be remotely reconfigured during runtime using the provided rqt widget or external nodes.
As an example use case for such kind of plugin system, please take a look at the vigir_footstep_planning stack.
The vigir_pluginlib::Plugin class provides the low level basic functionality needed by the plugin manager. Therefore each new interface plugin must be derived from this class.
Each plugin is characterized by its plugin description. While the name must be unique in the entire database, the other attributes specify the implemented interface and runtime library.
- Name of the plugin that must exist only once
- Package that exports this plugin implementing the interface plugin
- Class name of plugin implementing the interface plugin; Must be given in global context, thus with namespaces (e.g. my_namespace::MyPlugin)
- (Optional) Package that exports the interface plugin
- (Optional) Name of interface plugin class; Must be given in global context as well (e.g. my_other_namespace::MyBasePlugin)
Usage of Plugins
See tutorials page.
Working with the Plugin Manager
Please take also a look at the tutorials page.
A Plugin Aggregator is a collector for a set of plugins implementing a specified interface and simplifies handling of such sets. It obtains automatically all plugins from the plugin manager and provides the option to update parameters of those plugins. The plain plugin_aggregator class is ready for use, but may be extended as demonstrated here to perform accumulative operations using the plugins.
Plugin Manager Widget
The vigir_pluginlib comes with a rqt widget providing full access to all running plugin manager instance. The widget allows to monitor the current state of all plugins and even to add and remove plugins during runtime. In rqt this widget is located in the plugins->vigir_pluginlib menu. Alternatively you can launch the standalone version:
roslaunch vigir_pluginlib_manager plugin_mananger_rqt.launch
An example why we need such a complex plugin management can be seen at the vigir_footstep_planning stack.
A full example how to use the the plugin management can be found at https://github.com/thor-mang/thor_mang_footstep_planning_plugins.
- When calling plugin methods frequently, it is highly recommended to request and store all required plugins into a (temporary) list (of shared pointers) as the plugin retrieval works via RTTI causing a overhead for each call.
The vigir_pluginlib uses pluginlib under the hood where many magic is happening. This can cause many unforeseen issues.
MultiLibraryClassLoader blames about not existing library
[PluginManager] Plugin (thor_mang_step_plan_msg_plugin) of type_class 'thor_mang_footstep_planning::ThorMangStepPlanMsgPlugin' failed to load for some reason. Error: MultiLibraryClassLoader: Could not create object of class type thor_mang_footstep_planning::ThorMangStepPlanMsgPlugin as no factory exists for it. Make sure that the library exists and was explicitly loaded through MultiLibraryClassLoader::loadLibrary()
Solution: Ensure all above steps have been done right. Another very weird issue may arise if you try to load plugins from a package A which have been depended from another package B which exports plugins too. NEVER DO THAT!!! As the library from A may be linked into B, while loading library B the MultiLibraryClassLoader may invoke all PLUGINLIB_EXPORT_CLASS macros from A too while being under the namespace of package B. This confuses the class_loaders as all plugins from A seems now to be part of package B.