A plugin is a chunk of code that is compiled as a shared library and inserted into the simulation. The plugin has direct access to all the functionality of Gazebo through the standard C++ classes.
Plugins are useful because they:
Previous versions of Gazebo utilized controllers. These behaved in much the same way as plugins, but were statically compiled into Gazebo. Plugins are more flexible, and allow users to pick and choose what functionality to include in their simulations.
You should use a plugin when:
Ex: move models, respond to events, insert new models given a set of preconditions
Ex: No serialization and deserialization of messages.
There are currently 6 types of plugins
Each plugin type is managed by a different component of Gazebo. For example, a Model plugin is attached to and controls a specific model in Gazebo. Similarly, a World plugin is attached to a world, and a Sensor plugin to a specific sensor. The System plugin is specified on the command line, and loads first during a Gazebo startup. This plugin gives the user control over the startup process.
A plugin type should be chosen based on the desired functionality. Use a World plugin to control world properties, such as the physics engine, ambient lighting, etc. Use a Model plugin to control joints, and state of a model. Use a Sensor plugin to acquire sensor information and control sensor properties.
Plugins are designed to be simple. A bare bones world plugin contains a class with a few member functions.
First, if you installed Gazebo from debians, make sure you've installed the Gazebo development files. If you installed Gazebo from source, you can ignore this step. If you have a release other than gazebo6, replace 6 with whatever version number you have.
sudo apt-get install libgazebo6-dev
Next, make a directory and a .cc file for the new plugin:
$ mkdir ~/gazebo_plugin_tutorial
$ cd ~/gazebo_plugin_tutorial
$ gedit hello_world.cc
Copy the following into hello_world.cc:
#include <gazebo/gazebo.hh>
namespace gazebo
{
class WorldPluginTutorial : public WorldPlugin
{
public: WorldPluginTutorial() : WorldPlugin()
{
printf("Hello World!\n");
}
public: void Load(physics::WorldPtr _world, sdf::ElementPtr _sdf)
{
}
};
GZ_REGISTER_WORLD_PLUGIN(WorldPluginTutorial)
}
The above code is also located in the Gazebo sources: examples/plugins/hello_world/hello_world.cc, along with an appropriate CMakeLists.txt file.
#include <gazebo/gazebo.hh>
namespace gazebo
{
The gazebo/gazebo.hh
file includes a core set of basic gazebo functions.
It doesn't include gazebo/physics/physics.hh
, gazebo/rendering/rendering.hh
,
or gazebo/sensors/sensors.hh
as those should be included on a case by case basis.
All plugins must be in the gazebo
namespace.
class WorldPluginTutorial : public WorldPlugin
{
public: WorldPluginTutorial() : WorldPlugin()
{
printf("Hello World!\n");
}
Each plugin must inherit from a plugin type, which in this case is the WorldPlugin
class.
public: void Load(physics::WorldPtr _world, sdf::ElementPtr _sdf)
{
}
The only other mandatory function is Load
which receives an SDF element that
contains the elements and attributes specified in loaded SDF file.
GZ_REGISTER_WORLD_PLUGIN(WorldPluginTutorial)
Finally, the plugin must be registered with the simulator using the
GZ_REGISTER_WORLD_PLUGIN
macro.
The only parameter to this macro is the name of the plugin class.
There are matching register macros for each plugin type:
GZ_REGISTER_MODEL_PLUGIN
, GZ_REGISTER_SENSOR_PLUGIN
,
GZ_REGISTER_GUI_PLUGIN
,
GZ_REGISTER_SYSTEM_PLUGIN
and GZ_REGISTER_VISUAL_PLUGIN
.
The following section contains instructions on how to compile this plugin.
Please make sure that gazebo has been properly installed.
To compile the above plugin, create ~/gazebo_plugin_tutorial/CMakeLists.txt
:
$ gedit ~/gazebo_plugin_tutorial/CMakeLists.txt
Copy the following in CMakeLists.txt:
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
find_package(gazebo REQUIRED)
include_directories(${GAZEBO_INCLUDE_DIRS})
link_directories(${GAZEBO_LIBRARY_DIRS})
list(APPEND CMAKE_CXX_FLAGS "${GAZEBO_CXX_FLAGS}")
add_library(hello_world SHARED hello_world.cc)
target_link_libraries(hello_world ${GAZEBO_LIBRARIES})
New in gazebo6
: c++11 flags are now required for all downstream software to compile against gazebo.
This is done with the following line:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GAZEBO_CXX_FLAGS}")
Create the build directory
$ mkdir ~/gazebo_plugin_tutorial/build
$ cd ~/gazebo_plugin_tutorial/build
Compile the code.
$ cmake ../
$ make
Compiling will result in a shared library,
~/gazebo_plugin_tutorial/build/libhello_world.so
,
that can be inserted in a Gazebo simulation.
Lastly, add your library path to the GAZEBO_PLUGIN_PATH
:
$ export GAZEBO_PLUGIN_PATH=${GAZEBO_PLUGIN_PATH}:~/gazebo_plugin_tutorial/build
Note: This changes the path only for the current shell. If you want to use your plugin for every new temrinal you open, append the line above to the
~/.bashrc
file.
Once you have a plugin compiled as a shared library (see above),
you can attach it to a world or model in an SDF file
(see SDF documentation for more info).
On startup, Gazebo parses the SDF file, locates the plugin, and loads the code.
It is important that Gazebo is capable of finding the plugin.
Either the full path to the plugin is specified, or the plugin exists in
one of the paths in the GAZEBO_PLUGIN_PATH
environment variable.
Create a world file and copy the code below into it. The example world file can also be found in examples/plugins/hello_world/hello.world.
$ gedit ~/gazebo_plugin_tutorial/hello.world
<?xml version="1.0"?>
<sdf version="1.4">
<world name="default">
<plugin name="hello_world" filename="libhello_world.so"/>
</world>
</sdf>
Now open it with gzserver
:
$ gzserver ~/gazebo_plugin_tutorial/hello.world --verbose
You should see output similar to:
Gazebo multi-robot simulator, version 6.1.0
Copyright (C) 2012-2015 Open Source Robotics Foundation.
Released under the Apache 2 License.
http://gazebosim.org
[Msg] Waiting for master.
[Msg] Connected to gazebo master @ http://127.0.0.1:11345
[Msg] Publicized address: 172.23.1.52
Hello World!