Plugins
Using Model Plugins
The Syskit integration for Gazebo offers extension points to allow integrating plugins within the Syskit system. Plugins that are meant to be gazebo-only - i.e. that don't have the need to interface with Rock are transparent. This guide is for model plugins that are getting exposed through a Rock interface.
As good Rock citizens, these plugins should come in two packages:
- a
simulation/$NAME
package that contains the gazebo plugin itself - a
simulation/orogen/$NAME
package that contains the orogen components that will interface with the plugin
The plugin's documentation, apart from information on how to set itself up,
should say what task and device model to use for the interface. Then, if you
with to use the plugins' Rock interface, you must add a <task ...>
element
to the plugin
element like this:
<plugin name="direct_force" filename="libgazebo_usv.so">
<task model="gazebo_usv::DirectForceApplicationTask" />
<!-- other elements that configure the plugin and/or the task -->
</plugin>
In your Syskit app, you also have to map the task model to the device model that should be used to expose it on profiles. Do so in the orogen package's extension file Note that this device model does not necessarily have to be provided by the plugin developer. It is usually designed and added for your application specifically.
The gazebo_usv
example above would be declared in models/orogen/gazebo_usv.rb
with:
RockGazebo::Syskit::RobotDefinitionExtension.register_device_by_plugin_task_model(
OroGen.gazebo_usv.DirectForceApplicationTask,
Seabots::Devices::Gazebo::DirectForceApplication
)
Implementing an oroGen Plugin Interface
To ensure that the gazebo plugin and the orogen component can use a common
configuration, the orogen component must implement the
ModelTaskI
.
interface. In most cases, just subclass the rock_gazebo::ModelPluginTask
task context.
Doing so will ensure that the interface's setGazeboModel
method gets called at
component creation. This method must be overloaded. In particular, it sets the
task name, which to allow syskit to pick up the plugin must be
string worldName = model->GetWorld()->Name();
string taskName = "gazebo::" + worldName + "::" + model->GetName() + "::" + pluginName;
provides()->setName(taskName);
At runtime, the preferred mechanism to allow communication between the gazebo plugin itself and its associated orogen component is to use Gazebo's own publish/subscribe system. One essentially has to choose a topic name that is unique, and that only depend on the plugin configuration in the SDF. This way, both the plugin and the orogen component can infer the same topic name(s) and successfully manage to communicate. Note that the orogen component runs within the Gazebo event loop itself.
The gazebo_usv and associated components are a good example of these mechanisms