Documentation Status

pluginlib

Package Summary

Documented

The pluginlib package provides tools for writing and dynamically loading plugins using the ROS build infrastructure. To work, these tools require plugin providers to register their plugins in the manifest.xml of their package. Pluginlib includes parts of Poco from pocoproject.org

Package Summary

Released Continuous integration Documented

The pluginlib package provides tools for writing and dynamically loading plugins using the ROS build infrastructure. To work, these tools require plugin providers to register their plugins in the package.xml of their package.

  • Maintainer: Esteve Fernandez <esteve AT osrfoundation DOT org>
  • Author: Eitan Marder-Eppstein, Tully Foote, Dirk Thomas, Mirza Shah
  • License: BSD, Boost Software License
  • Source: git https://github.com/ros/pluginlib.git (branch: groovy-devel)

Package Summary

Released Continuous integration Documented

The pluginlib package provides tools for writing and dynamically loading plugins using the ROS build infrastructure. To work, these tools require plugin providers to register their plugins in the package.xml of their package.

  • Maintainer status: maintained
  • Maintainer: Esteve Fernandez <esteve AT osrfoundation DOT org>
  • Author: Eitan Marder-Eppstein, Tully Foote, Dirk Thomas, Mirza Shah
  • License: BSD, Boost Software License
  • Source: git https://github.com/ros/pluginlib.git (branch: groovy-devel)

Package Summary

Released Continuous integration Documented

The pluginlib package provides tools for writing and dynamically loading plugins using the ROS build infrastructure. To work, these tools require plugin providers to register their plugins in the package.xml of their package.

  • Maintainer status: maintained
  • Maintainer: Esteve Fernandez <esteve AT osrfoundation DOT org>
  • Author: Eitan Marder-Eppstein, Tully Foote, Dirk Thomas, Mirza Shah
  • License: BSD, Boost Software License
  • Source: git https://github.com/ros/pluginlib.git (branch: indigo-devel)
Cannot load information on name: pluginlib, distro: jade, which means that it is not yet in our index. Please see this page for information on how to submit your repository to our index.

Contents

New in Electric: pluginlib is now a separate stack. In previous releases, it was part of common.

Example

To understand how pluginlib works, let's consider a small example. First, suppose that a ROS package exists containing a polygon base class ("polygon_interface_package"). Let's also say that there are two different kinds of polygons supported in the system: a rectangle which lives in the "rectangle_plugin" package and a triangle that lives in the "triangle_plugin" package. The implementers of both the rectangle_plugin and triangle_plugin packages would include special export lines in their manifest.xml file telling the rosbuild system that they intend to provide plugins for the polygon class in the polygon_interface_package package. These export lines, in effect, register the classes with the rosbuild system. This means that someone wishing to see all polygon classes available in the system can run a simple rospack query which will return a list of available classes, in this case, rectangle and triangle.

pluginlib/plugin_model.png

Providing a Plugin

Adding a Plugin to the Plugin List

In order to allow a class to be dynamically loaded, it must be added to a class list for the relevant class type. This list can be defined in any .cpp file that is compiled in the library containing a class. To help with this process, pluginlib defines three macros in the class_list_macros.h file. For the example above, we might create a class_list.cpp file in package 'example_pkg' that looks as follows and compile it into the librectangle library:

   1 #include <pluginlib/class_list_macros.h>
   2 #include <polygon_interface_package/polygon.h>
   3 #include <rectangle_package/rectangle.h>
   4 
   5 //Declare the Rectangle as a Polygon class
   6 PLUGINLIB_DECLARE_CLASS(example_pkg, Rectangle, rectangle_namespace::Rectangle, polygon_namespace::Polygon)

The Plugin Description File

The plugin description file is an XML file that serves to store all the important information about a plugin in a machine readable format. It contains information about the library the plugin is in, the name of the plugin, the type of the plugin, etc. If we consider the rectangle_plugin package discussed above, the plugin description file (e.g. rectangle_plugin.xml), would look something like this:

<library path="lib/librectangle">
  <class name="example_pkg/Rectangle" type="rectangle_namespace::Rectangle" base_class_type="polygon_namespace::Polygon">
  <description>
  This is a rectangle plugin
  </description>
  </class>
</library>

For a detailed description of plugin description files and their associated tags/attributes please see the following documentation.

Why Do We Need This File

We need this file in addition to the code macro to allow the ROS system to automatically discover, load, and reason about plugins. The plugin description file also holds important information, like a description of the plugin, that doesn't fit well in the macro.

Exporting a Plugin

In order to allow plugin users to access information, a plugin provider must point to its plugin description file in its manifest.xml inside the export tag block. Note, if you have other exports they all must go in the same export field.

Considering the rectangle_plugin package again, the relevant lines would look as follows:

<export>
  <polygon_interface_package plugin="${prefix}/rectangle_plugin.xml" />
</export>

For a detailed discussion of exporting a plugin, please see the following documentation.

Important Note: In order for the above export command to work properly, the providing package must depend directly on the package containing the plugin interface. For example, the rectangle_plugin must have the line below in its manifest.xml:

  <depend package="polygon_interface_package" />

Check exports

To check an export has been successfully exported use the following:

rospack plugins --attrib=plugin nav_core

This will return all "plugins" exported into the nav_core package.

Using a Plugin

pluginlib provides a ClassLoader tool available in the class_loader.h header that makes it quick and easy to use provided classes. For detailed documentation of the code-level API for this tool please see pluginlib::ClassLoader documentation. Below, we'll show a simple example of using the ClassLoader to create an instance of a rectangle in some code that uses a polygon:

   1 #include <pluginlib/class_loader.h>
   2 #include <polygon_interface_package/polygon.h>
   3 
   4 //... some code ...
   5 
   6 pluginlib::ClassLoader<polygon_namespace::Polygon> poly_loader("polygon_interface_package", "polygon_namespace::Polygon");
   7 polygon_namespace::Polygon* poly = NULL;
   8 
   9 try{
  10   poly = poly_loader.createClassInstance("example_pkg/Rectangle");
  11 
  12   //... use the polygon
  13 }
  14 catch(pluginlib::PluginlibException& ex){
  15   //handle the class failing to load
  16   ROS_ERROR("The plugin failed to load for some reason. Error: %s", ex.what());
  17 }

Important Note: The classloader must not go out scope while you are using the plugin. So, if you are loading a plugin object inside a class, make sure that the class loader is a member variable of that class.

Report a Bug

Use trac to report bugs or request features. [View active tickets]

Overview

pluginlib is a C++ library for loading and unloading plugins from within a ROS package. Plugins are dynamically loadable classes that are loaded from a runtime library (i.e. shared object, dynamically linked library). With pluginlib, one does not have to explicitly link their application against the library containing the classes -- instead pluginlib can open a library containing exported classes at any point without the application having any prior awareness of the library or the header file containing the class definition. Plugins are useful for extending/modifying application behavior without needing the application source code.

Example

To understand how pluginlib works, let's consider a small example. First, suppose that a ROS package exists containing a polygon base class ("polygon_interface_package"). Let's also say that there are two different kinds of polygons supported in the system: a rectangle which lives in the "rectangle_plugin" package and a triangle that lives in the "triangle_plugin" package. The implementers of both the rectangle_plugin and triangle_plugin packages would include special export lines in their package.xml file telling the rosbuild system that they intend to provide plugins for the polygon class in the polygon_interface_package package. These export lines, in effect, register the classes with the ROS build/packaging system. This means that someone wishing to see all polygon classes available in the system can run a simple rospack query which will return a list of available classes, in this case, rectangle and triangle.

pluginlib/plugin_model.png

Providing a Plugin

Registering/Exporting a Plugin

In order to allow a class to be dynamically loaded, it must be marked as an exported class. This is done through the special macro PLUGINLIB_EXPORT_CLASS. This macro can be put into any source (.cpp) file that composes the plugin library, but is usually put at the end of the .cpp file for the exported class. For the example above, we might create a class_list.cpp file in package 'example_pkg' that looks as follows and compile it into the librectangle library:

   1 #include <pluginlib/class_list_macros.h>
   2 #include <polygon_interface_package/polygon.h>
   3 #include <rectangle_package/rectangle.h>
   4 
   5 //Declare the Rectangle as a Polygon class
   6 PLUGINLIB_EXPORT_CLASS(rectangle_namespace::Rectangle, polygon_namespace::Polygon)

The Plugin Description File

The plugin description file is an XML file that serves to store all the important information about a plugin in a machine readable format. It contains information about the library the plugin is in, the name of the plugin, the type of the plugin, etc. If we consider the rectangle_plugin package discussed above, the plugin description file (e.g. rectangle_plugin.xml), would look something like this:

<library path="lib/librectangle">
  <class type="rectangle_namespace::Rectangle" base_class_type="polygon_namespace::Polygon">
  <description>
  This is a rectangle plugin
  </description>
  </class>
</library>

For a detailed description of plugin description files and their associated tags/attributes please see the following documentation.

Why Do We Need This File

We need this file in addition to the code macro to allow the ROS system to automatically discover, load, and reason about plugins. The plugin description file also holds important information, like a description of the plugin, that doesn't fit well in the macro.

Registering Plugin with ROS Package System

In order for pluginlib to query all available plugins on a system across all ROS packages, each package must explicitly specify the plugins it exports and which package libraries contain those plugins. A plugin provider must point to its plugin description file in its package.xml inside the export tag block. Note, if you have other exports they all must go in the same export field.

Considering the rectangle_plugin package again, the relevant lines would look as follows:

<export>
  <polygon_interface_package plugin="${prefix}/rectangle_plugin.xml" />
</export>

For a detailed discussion of exporting a plugin, please see the following documentation.

Important Note: In order for the above export command to work properly, the providing package must depend directly on the package containing the plugin interface. For example, the rectangle_plugin must have the line below in its catkin/package.xml:

  <build_depend>polygon_interface_package</build_depend>
  <run_depend>polygon_interface_package</run_depend>

Querying ROS Package System For Available Plugins

One can query the ROS package system via rospack to see which plugins are available by any given package. For example:

rospack plugins --attrib=plugin nav_core

This will return all plugins exported from the nav_core package.

Using a Plugin

pluginlib provides a ClassLoader class available in the class_loader.h header that makes it quick and easy to use provided classes. For detailed documentation of the code-level API for this tool please see pluginlib::ClassLoader documentation. Below, we'll show a simple example of using the ClassLoader to create an instance of a rectangle in some code that uses a polygon:

   1 #include <pluginlib/class_loader.h>
   2 #include <polygon_interface_package/polygon.h>
   3 
   4 //... some code ...
   5 
   6 pluginlib::ClassLoader<polygon_namespace::Polygon> poly_loader("polygon_interface_package", "polygon_namespace::Polygon");
   7 
   8 try
   9 {
  10   boost::shared_ptr<polygon_namespace::Polygon> poly = poly_loader.createInstance("rectangle_namespace::Rectangle");
  11 
  12   //... use the polygon, boost::shared_ptr will automatically delete memory when it goes out of scope
  13 }
  14 catch(pluginlib::PluginlibException& ex)
  15 {
  16   //handle the class failing to load
  17   ROS_ERROR("The plugin failed to load for some reason. Error: %s", ex.what());
  18 }

Important Note: The ClassLoader must not go out scope while you are using the plugin. So, if you are loading a plugin object inside a class, make sure that the class loader is a member variable of that class.

Changes from Pre-Groovy pluginlib

Simplified Export Macro

Prior to pluginlib 1.9 (Groovy), the macros PLUGINLIB_REGISTER_CLASS and PLUGINLIB_DECLARE_CLASS were used to register exported classes. These have been deprecated in favor of the new PLUGINLIB_EXPORT_CLASS. The new macro is simpler as it only takes two arguments.

A script has been provided with pluginlib which can be run in the root of your source folder to automatically update the legacy macros to utilize the new one:

 plugin_macro_update

Legacy "Lookup Name"

Pre-Groovy versions of pluginlib required specifying a "lookup name" for exported classes in both the plugin description file and export macro. This lookup name acted as an alias for the true class name -- the true class name was not used in the user facing interface. The reason why this lookup alias was used instead of the real name was due to a technical limitation in older versions.

One can now use the real name of a class instead of the lookup name. However, if users want to still use the lookup name, they can add it in their plugin description file. For example:

<library path="lib/librectangle">
  <class name="rviz/Rectangle" type="rectangle_namespace::Rectangle" base_class_type="polygon_namespace::Polygon">
  <description>
  This is a rectangle plugin
  </description>
  </class>
</library>

pluginlib will now utilize "rviz/Rectangle" instead of "rectangle_namespace::Rectangle" to refer to the class. The real class name cannot be used to refer to the class if a lookup name alias is used. If no lookup name is provided, the lookup name and true class name are equivalent.

Report a Bug

Wiki: pluginlib (last edited 2014-07-30 01:48:44 by AustinHendrix)