Ignition Physics

API Reference

3.1.0
"Use custom engine with Ignition Physics"

Prerequisites

In the previous tutorial Installation, you have installed the Ignition Physics corresponding to the desired Ignition release.

How to adapt a physics engine as a plugin in Ignition Physics

In the last Implement a physics plugin tutorial, we know how to implement a dummy physics engine as a plugin and load it using Ignition Physics API. In Implement a custom feature tutorial, we know how to define and implement a custom feature in an existing DART physics plugin. This tutorial will explain step-by-step how to use any physics engine with Ignition Physics. We will use TPE as an example for this tutorial.

General structure of a physics plugin

As described in Implement a custom feature tutorial, the plugin folder is placed just below the top-level folder of ign-physics. In general, any physics plugin folder will have the following structure, which is commented in detail:

tpe
├── lib Main physics engine implementation.
│ ├── src
│ ├── CMakeLists.txt CMake build script for physics engine implementation.
├── plugin Main implementation of the plugin features interfacing the physics engines API
│ ├── src
│ | ├── plugin.cc Main file for the plugin declaration and plugin registering.
│ | ├── <FEATURES>.hh The FeatureList header file.
│ | ├── <FEATURES>.cc Implementation of the FeatureList, which adapts to functions implemented in lib used in the FeatureList.
│ | ├── <FEATURES_TEST>.cc Test cases for the FeatureList.
│ ├── worlds Example SDF files for testing plugin functionalities.
│ ├── CMakeLists.txt CMake build script for the plugin features.
└── CMakeLists.txt CMake build script for the plugin.

Note that the lib folder is optionally placed inside the physics plugin folder depending on the design target, we can link the external physics engine library in CMakeLists.txt of the plugin, assuming the physics engine library is already installed. In our case, TPE is natively developed inside Ignition Physics and hence the lib folder.

We declare and implement the FeatureList interfacing with the physics engine API inside plugin\src folder (please see Implement a custom feature for the plugin feature requirements). Depending on design target, a FeatureList is generally a packing of related Features. For example in TPE's EntityManagementFeatures , there are GetEngineInfo, GetWorldFromEngine, etc. features defined in the "FeatureList" structure for entity management purpose.

Conventionally, a FeatureList can be implemented as:

  • <FEATURES>.hh for the "FeatureList" declaration.
  • <FEATURES>.cc for the "FeatureList" implementation corresponding to each of the Features member functions, using the physics engine API to realize the feature behavior. For a list of common pre-defined features in Ignition Physics, please refer to Understanding the Physics Plugin tutorial.
  • <FEATURES_TEST>.cc for unit tests of the "FeatureList".

Main plugin.cc file

In this tutorial, we will show how to construct a simple simulation world using TPE physics engine. For this purpose, we will implement the pre-defined ConstructEmptyWorldFeature and include this feature into an empty FeatureList named EntityManagementFeatureList defined in EntityManagementFeatures.hh. We first include the EntityManagementFeatureList in plugin.cc main file and register the example TPE physics plugin as follow:

#include "Base.hh"
#include "EntityManagementFeatures.hh"
namespace ignition {
namespace physics {
namespace tpeplugin {
struct TpePluginFeatures : FeatureList<
EntityManagementFeatureList
> { };
class Plugin :
public virtual Implements3d<TpePluginFeatures>,
public virtual Base,
public virtual EntityManagementFeatures { };
IGN_PHYSICS_ADD_PLUGIN(Plugin, FeaturePolicy3d, TpePluginFeatures)
}
}
}

In general, there are 3 steps for plugin.cc:

  • Define the final FeatureList including all required "FeatureLists". In TPE case, it is TpePluginFeatures.
  • Define an empty class inherited all "FeatureLists" class, Base class (optionally depending on software design) and Implements class implementing FeaturePolicy 2D or 3D and different scalar type.
  • Register the physics plugin using IGN_PHYSICS_ADD_PLUGIN macro (See Implement a physics plugin for more detail).

Implement a feature using TPE's API

Now we assume that we have not implemented any Feature for TPE. In the plugin folder, we will create two files EntityManagementFeatures.hh and EntityManagementFeatures.cc to implement ConstructEmptyWorldFeature in EntityManagementFeatures "FeatureList". The unit test for this feature is also worth implemented in EntityManagement_TEST.cc. Please download the example CMakeLists.txt and Base.hh into plugin folder by:

wget https://raw.githubusercontent.com/ignitionrobotics/ign-physics/main/tpe/plugin/CMakeLists.txt -P <path-to-ign-physics>/tpe/plugin/
wget https://raw.githubusercontent.com/ignitionrobotics/ign-physics/main/tpe/plugin/src/Base.hh -P <path-to-ign-physics>/tpe/plugin/src

Now the folder structure looks like this:

tpe
├── lib
├── plugin
│ ├── src
│ | ├── plugin.cc
│ | ├── Base.hh
│ | ├── EntityManagementFeatures.hh
│ | ├── EntityManagementFeatures.cc
│ | ├── EntityManagement_TEST.cc
│ ├── CMakeLists.txt
└── CMakeLists.txt

Basically, ConstructEmptyWorldFeature has a subclass Engine defining ConstructEmptyWorld member function. The feature implementation is shown as below:

EntityManagementFeatures.hh:
#ifndef IGNITION_PHYSICS_TPE_PLUGIN_SRC_GETENTITIESFEATURE_HH_
#define IGNITION_PHYSICS_TPE_PLUGIN_SRC_GETENTITIESFEATURE_HH_
#include <string>
#include "Base.hh" // optionally depending on software design
namespace ignition {
namespace physics {
namespace tpeplugin {
struct EntityManagementFeatureList : FeatureList<
ConstructEmptyWorldFeature
> { };
class EntityManagementFeatures :
public virtual Base,
public virtual Implements3d<EntityManagementFeatureList>
{
// ----- Construct empty entities -----
public: Identity ConstructEmptyWorld(
const Identity &_engineID, const std::string &_name) override;
};
}
}
}
#endif

Together with other (if existing) Features, the ConstructEmptyWorldFeature is included in EntityManagementFeatureList "FeatureList" to declare the related features for entity management purpose.

The EntityManagementFeatures "FeatureList" here inherits from:

  • (optionally) Base class for foundation metadata definitions of Models, Joints, Links, and Shapes objects of TPE to provide easy access to tpelib structures in the TPE library. Note that we mention Base class here for completeness, Base class is not necessarily needed if there is a straightforward way to interface external physics engine class objects with ign-physics class objects.
  • Implements3d for implementing the custom feature with FeaturePolicy3d ("FeaturePolicy" of 3 dimensions and scalar type double).
EntityManagementFeatures.cc:
#include <string>
#include "EntityManagementFeatures.hh"
using namespace ignition;
using namespace physics;
using namespace tpeplugin;
Identity EntityManagementFeatures::ConstructEmptyWorld(
const Identity &, const std::string &_name)
{
auto world = std::make_shared<tpelib::World>();
world->SetName(_name);
return this->AddWorld(world);
}

Here we show the overriding of ConstructEmptyWorld member function of ConstructEmptyWorldFeature, this is where we use the physics engine API to implement this member function. We simply instantiate World object, set the world name and call AddWorld function which was defined in Base.hh.

EntityManagement_TEST.cc:

Simple unit tests are good practice for sanity checks. While we won't go into detail, here is an example to test our new ConstructEmptyWorldFeature:

#include <gtest/gtest.h>
#include "EntityManagementFeatures.hh"
struct TestFeatureList : ignition::physics::FeatureList<
ignition::physics::tpeplugin::EntityManagementFeatureList
> { };
TEST(EntityManagement_TEST, ConstructEmptyWorld)
{
loader.LoadLib(tpe_plugin_LIB);
loader.Instantiate("ignition::physics::tpeplugin::Plugin");
auto engine =
auto world = engine->ConstructEmptyWorld("empty world");
ASSERT_NE(nullptr, world);
}
int main(int argc, char *argv[])
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

Please take a look at EntityManagement_TEST.cc for more comprehensive unit tests.

Build the custom physics plugin

Please follow the previous tutorial Installation to build ign-physics from source again for our new feature to be compiled.

Now we can load the new physics plugin named ignition-physics-tpe-plugin to test it on Ignition Gazebo by following this Switching physics engines tutorial.