Gazebo Physics

API Reference

7.4.0
Implement physics feature

This tutorial shows how to develop a simple plugin that implements a 3D policy and includes a sample list of Feature Features.

Prerequisites

Write a simple physics plugin

First we need to create a workspace

cd ~
mkdir -p ~/hello_world_plugin/build
cd hello_world_plugin

Examine the code

To set up all libraries needed to implement physics feature, we need to include the following:

  • FeatureList header: to define a list of Feature that will be implemented for the plugin, e.g. GetEngineInfo.
  • FeaturePolicy header: to specify the metadata about the coordinate system (e.g. 2 or 3 dimensions) and numeric system (e.g. float, int) that the Features will be implemented accordingly.
  • GetEntities.hh header: to retrieve the pre-defined list of features in Gazebo Physics. Please refer to this API Reference for a list of features defined in GetEntities.hh and Understanding the Physics Plugin tutorial for an example list of common features implemented with a plugin.
  • Register.hh header: to register a plugin to Gazebo Physics.

Next, we use a dummy namespace mock and list all the features we would like to implement.

// List of all features that this plugin will implement
struct HelloWorldFeatureList : gz::physics::FeatureList<
gz::physics::GetEngineInfo
> { };

The plugin will be able to return its physics engine metadata. We will now implement our plugin class named HelloWorldPlugin using the defined FeatureList above. The class is inherited from Implements3d to declare that the plugin's HelloWorldFeatureList will be in the 3D coordinate system.

// The plugin class, which implements a 3D policy
class HelloWorldPlugin
: public gz::physics::Implements3d<HelloWorldFeatureList>
{
using Identity = gz::physics::Identity;
public: Identity InitiateEngine(std::size_t /*_engineID*/) override
{
this->engineName = "HelloWorld";
return this->GenerateIdentity(0);
}
public: std::size_t GetEngineIndex(const Identity &/*_id*/) const override
{
return 0;
}
public: const std::string &GetEngineName(const Identity &/*_id*/) const override
{
return this->engineName;
}
std::string engineName;
};

Because we are not using a real physics engines, a dummy physics engines is defined inside member function InitiateEngine by simply setting the engineName to HelloWorld, and returning the engine object using Identity. Then, we define the metadata getters GetEngineIndex and GetEngineName for the feature GetEngineInfo (please look into corresponding public member functions defined in the subclasses). A list of other pre-defined features can be found in the GetEntities FeatureList.

Finally, we only have to register our plugin in Gazebo Physics as a physics engine by:

// Register plugin
HelloWorldPlugin,
HelloWorldFeatureList)

Note that:

  • The first argument is the name of the class that wraps the physics engine into a plugin.
  • The second argument is the FeaturePolicy for this plugin, i.e. FeaturePolicy3d
  • The third argument is the FeatureList, specifying all the features that this plugin provides, i.e. HelloWorldFeatureList

Setup CMakeLists.txt for building (Version: gz-physics7)

Now create a file named CMakeLists.txt with your favorite editor and add these lines for finding gz-plugin and gz-physics dependencies for the Fortress release:

cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
project(gz-physics-hello-world-plugin)
find_package(gz-plugin2 REQUIRED COMPONENTS all)
set(GZ_PLUGIN_VER ${gz-plugin2_VERSION_MAJOR})
find_package(gz-physics7 REQUIRED)
set(GZ_PHYSICS_VER ${gz-physics7_VERSION_MAJOR})
add_library(HelloWorldPlugin SHARED HelloWorldPlugin.cc)
target_link_libraries(HelloWorldPlugin
PRIVATE
gz-physics${GZ_PHYSICS_VER}::gz-physics${GZ_PHYSICS_VER})

Build and run

Compile the plugin

Your current plugin folder should look like this:

$ ls ~/hello_world_plugin
CMakeLists.txt HelloWorldPlugin.cc build

Now you can build the plugin by:

cd ~/hello_world_plugin/build
cmake ..
make

This will generate the HelloWorldPlugin library under build. The exact name of the library file depends on the operating system such as libHelloWorldPlugin.so on Linux, libHelloWorldPlugin.dylib on MacOS, and HelloWorldPlugin.dll on Windows.

Test loading the plugin on Linux

Please first follow the Loading physics plugins tutorial to create a simple loader. Then we test our plugin using the loader as follow:

cd ~
./hello_world_loader/build/hello_world_loader simple_plugin/build/libHelloWorldPlugin.so

And you will see the engine info of our plugin:

Testing plugin: mock::HelloWorldPlugin
engine name: HelloWorld