Get the underlying dartsim world for this World object. public: dart::simulation::WorldPtr GetDartsimWorld(); };
Prerequisites
In the previous tutorial Installation, you have installed the Ignition Physics corresponding to the desired Ignition release.
Implement a custom feature in DART plugin
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 this tutorial, we will look deeper into the structure of a physics engine plugin, for example, the available DART physics engine in ign-physics
repository and how to define a custom Feature for the plugin.
Folder structure of the plugins
Below is the general structure of the ign-physics
repository:
As shown above, there are two physics engines available (more detail in Physics plugin tutorial):
- DART:
ignition-physics-dartsim-plugin
. - TPE:
ignition-physics-tpe-plugin
.
and their plugin folders are placed just below the top level of ign-physics
.
Looking closer to a plugin folder, for example, the dartsim
(DART) plugin:
Basically, new implementation of Feature or FeatureList, which is corresponded to a functionality of the external physics engine can be defined as a header in include/ignition/physics/<plugin_name>
folder. The custom feature could be added in a FeatureList and implemented its functionalities in src
folder.
The dartsim
plugin's FeatureList could be found in Understanding the Physics Plugin tutorial.
Plugin and feature requirements
In general, the minimum set of features that any physics engine plugin must implement to be supported by Ignition Gazebo is as below:
- FindFreeGroupFeature
- SetFreeGroupWorldPose
- FreeGroupFrameSemantics
- LinkFrameSemantics
- ForwardStep
- RemoveEntities
- ConstructSdfLink
- ConstructSdfModel
- ConstructSdfWorld
This list defines the minimum requirements for the simulation capability of a physics engine plugin and also maintains backward compatibility with downstream physics plugins.
For custom feature requirements, there are two main component classes in the general structure of a custom feature:
Entity corresponds to the "proxy object" that the Feature is implemented. These are the most common "proxy objects" that are inherited from
Entity
class:- Engine: Placeholder class for the Engine API. This class serves metadata for the physics engine (for example the GetEngineInfo feature). Every Engine feature must inherit this class.
- Joint: defines physics concept
Joint
behaviors (for example the GetBasicJointState feature). - Link: defines physics concept
Link
structure. - Model: defines physics concept
Model
structure (for example the GetLinkFromModel feature including bothLink
andModel
objects). - Shape: defines physics concept
Shape
structure (for example the GetShapeKinematicProperties feature). - World: defines physics concept
Shape
structure (for example the RetrieveWorld feature indartsim
plugin).
Note that these object classes are not mutually exclusive and could be defined in conjunction together to describe the
Feature
. There are also other uncommon objects defined depending on feature functionality, for example, the FreeGroup object inSetFreeGroupWorldPose
feature. For more information about the physics concepts, please refer to Ignition Physics simulation concepts tutorial.- Implementation interfaces the actual physics engines API for the custom feature. It has InitiateEngine to trigger physics engine initiation to provide the required functionalities.
Moreover, we can define dependencies between custom Features
:
- By default, a blank feature will not require any other features. If the custom feature does require some other set of features, then it should be inherited from FeatureWithRequirements class, and provided a list of the
Features
required. - By default, a blank feature will not conflict with any other features. If the custom feature does conflict with some other set of features, then it should be inherited from FeatureWithConflicts class, and provided a list of the conflicting
Features
. The conflictingFeatures
will not run at the same time when requested.
Define the custom feature
With the requirements and restrictions above, we will implement an example custom Feature
that retrieves a simulation world from dartsim
physics engine. For example, we name it as World.hh and the its content is as follow:
The new defined feature file is placed in dartsim/include/ignition/physics/dartsim
:
As seen above, after including the necessary library of dartsim
and ign-physics
, we define the RetrieveWorld
custom feature inherited from the base Feature.
As defined, the RetrieveWorld
feature retrieves world pointer from physics engine, so it is natural to define World
entity inherited from Feature::World and declare the necessary member function GetDartsimWorld
. Then we define the Implementation
class having virtual member function for overriding in the actual implementation of the custom feature RetrieveWorld
later.
Finally, we implement the World
entity's member function GetDartsimWorld
to call the Implementation
class's member function GetDartsimWorld
via Entity::Interface convenience function for querying the feature Implementation
object.
Implement the custom feature
After defining the custom feature, please look into where it is added to a FeatureList in CustomFeatures.hh and implemented in CustomFeatures.cc. These files are place as follows:
We display them here for convenience:
CustomFeatures.hh
:
The custom feature RetrieveWorld
is added to CustomFeatureList
, other custom features could also be added here. The CustomFeatures
"FeatureList" here inherits from:
- Base class for foundation definitions of Models, Joints, Links, and Shapes objects of
dartsim
interfacing to Ignition Physics API. - Implements3d for implementing the custom feature with FeaturePolicy3d ("FeaturePolicy" of 3 dimensions and scalar type
double
).
Based on the CustomFeatureList
, we will override the corresponding member functions declared in each of the custom features. In this case, we have only the custom feature RetrieveWorld
and its corresponding Implementation::GetDartsimWorld
member function.
CustomFeatures.cc
:
Here we simply implement the actual behavior of GetDartsimWorld
to return the world pointer from EntityStorage
object storing world pointers of dartsim
in Base class.
Finally, we add the implemented CustomFeatures
"FeatureList" together with other FeatureList to final DartsimFeatures
"FeatureList" as in dartsim/src/plugin.cc (please see Implement a physics plugin for registering the plugin to Ignition Physics).