Note: This tutorial assumes that you have completed the previous tutorials: Create and Export new Plugin, How to use Dynamic Parameters in Plugins.
(!) Please ask about problems and questions regarding this tutorial on answers.ros.org. Don't forget to include in your question the link to this page, the versions of your OS & ROS, and also add appropriate tags.

Working with the Plugin Manager

Description: In this tutorial the basic capabilities of the Plugin Manager are introduced and basic explanations are given how to use them. This also includes how to query plugins from the manager.

Keywords: plugin, manager, create plugins, get plugins

Tutorial Level: INTERMEDIATE

The plugin manager is the core of the vigir_pluginlib that manages a heterogeneous plugin database. The application can request for any plugin that implements the requested interface.

Setup of Plugin Manager

The plugin manager should be initialized at the very first possible moment, e.g. in the constructor of the node using the code snippet below.

   1 #include <vigir_pluginlib/plugin_manager.h>
   2 
   3 ...
   4 
   5 ros::NodeHandle nh;
   6 vigir_pluginlib::PluginManager::initialize(nh);

For each plugin interface the plugin manager should handle, the appropriate class loader must be added. According to previous example this will look like:

   1 vigir_pluginlib::PluginManager::addPluginClassLoader<my_interface_plugins_ns::MyInterfacePlugin>("my_interface_plugins_pkg", "my_interface_plugins_ns::MyInterfacePlugin");

That is it! From now you can work using the convenient plugin library.

ROS API

The plugin manager provides out of the box multiple services as well action server.

Action Goal

plugin_manager/get_plugin_descriptions (vigir_pluginlib_msgs/GetPluginDescriptionsGoal)
  • Retrieves list of all known plugins
plugin_manager/get_plugin_states (vigir_pluginlib_msgs/GetPluginStatesGoal)
  • Retrieves list of all instantiated plugins
plugin_manager/add_plugin (vigir_pluginlib_msgs/PluginManagementGoal)
  • Instantiate plugin based on given plugin description
plugin_manager/remove_plugin (vigir_pluginlib_msgs/PluginManagementGoal)
  • Deletes plugin based on given plugin description
plugin_manager/load_plugin_set (vigir_pluginlib_msgs/PluginManagementGoal)
  • Loads the plugin set according to the request

Subscribed Topics

plugin_manager/add_plugin (vigir_pluginlib_msgs/PluginDescription)
  • Instantiate plugin based on given plugin description
plugin_manager/load_plugin_set (std_msgs/String)
  • Loads plugin set with given name
plugin_manager/remove_plugin (vigir_pluginlib_msgs/PluginDescription)
  • Deletes plugin based on given plugin description

Services

plugin_manager/get_plugin_descriptions (vigir_pluginlib_msgs/GetPluginDescriptionsService)
  • Retrieves list of all known plugins
plugin_manager/get_plugin_states (vigir_pluginlib_msgs/GetPluginStatesService)
  • Retrieves list of all instantiated plugins
plugin_manager/add_plugin (vigir_pluginlib_msgs/PluginManagementService)
  • Instantiate plugin based on given plugin description
plugin_manager/remove_plugin (vigir_pluginlib_msgs/PluginManagementService)
  • Deletes plugin based on given plugin description
plugin_manager/load_plugin_set (vigir_pluginlib_msgs/PluginManagementService)
  • Loads the plugin set according to the request

Obtain Plugins from the Plugin Manager

There are very many convenient ways to get plugins. In every case you will get the boost::shared_pointer object to the plugin. The best practice is to store this pointer once (e.g. during initialization code) instead of requesting it every time from the plugin manager to reduce computational overhead.

Loading/Instantiation of Plugins

During plugin instantiation the plugin manager needs either the unique name or the type_class_package and type_class of the plugin. When only the name was given, then the a corresponding plugin description config must have been uploaded first to the rosparam server (see above) providing the missing type_class_package and type_class information.

Plugins can be instantiated manually by calling:

   1 bool vigir_pluginlib::PluginManager::addPluginByName(const std::string& name);

The name must match one plugin in the plugin description config. The method returns true on success, otherwise false when an error has occurred.

An individual plugin can be spawned by using the generic method:

   1 bool vigir_pluginlib::PluginManager::addPlugin(const msgs::PluginDescription& plugin_description);

where the first parameter must be a plugin description sufficient for the instantiation process. The method returns true on success, otherwise false when an error has occurred.

Alternatively you can use the ros topic, service or action server providing the same functionality as described previously.

Query by Name

If you do not care about the concrete plugin type and want only a specific plugin identified by its name, then you can obtain it by calling

   1 bool vigir_pluginlib::PluginManager::getPluginByName(const std::string& name, Plugin::Ptr& plugin);

The second parameter plugin is the return variable in which the corresponding pointer to the plugin is stored if available. You can upcast this pointer to another type T by using the boost::dynamic_pointer_cast:

   1 boost::dynamic_pointer_cast<T>(my_plugin);

Query by Type

The most versatile way to obtain plugins from the manager is using the generic getter:

   1 boost::shared_ptr<T> vigir_pluginlib::PluginManager::getPlugin<T>(const std::string& name = std::string());

where the template parameter T has to be substituted by the requested plugin type or implementation (e.g. the abstract my_interface_plugins_ns::MyInterfacePlugin or even concrete my_concrete_plugins_ns::MyConcretePlugin). As all plugins derived from T are considered, the optional parameter name can be used to resolve disambiguity.

Note

Giving a name equals to Query by Name with upcast as described above.

If a plugin type is not declared as unique (see here), then multiple instances may exists in the system. The following method allows to obtain all of them given in a list:

   1 boost::shared_ptr<T> vigir_pluginlib::PluginManager::getPlugins<T>(std::vector<boost::shared_ptr<T> >& plugins);

where the template parameter T has to be substituted analogously by the requested plugin abstract type or concrete implementation.

Important

Please check also the API for all available functions here.

Wiki: vigir_pluginlib/Tutorials/WorkingWithPluginManager (last edited 2017-04-03 19:11:43 by AlexanderStumpf)