- Combining existing manifolds
- The simplest way to obtain new manifolds is to combine existing ones. For example, to get the manifold of a manipulator arm one could combine R5 (ompl::base::RealVectorStateManifold) and SO2 (ompl::base::SO2StateManifold) to represent 5 joints that have bounds and one joint that can rotate continuously: Alternatively to using the "+" operator on manifolds (see working with states and manifolds), one could directly create an instance of ompl::base::CompoundStateManifold and call ompl::base::CompoundStateManifold::addSubManifold() on it. This approach allows setting the weights of each added manifold for computing distances bewteen states in the compound manifold. When using the "+" operator these weights are assumed to be 1.0.
- Inheriting from existing manifolds
- In order to implement a new state manifold it is necessary to define a class that inherits from an existing manifold class. All manifold specific functions (pure virtual in the ompl::base::StateManifold class) need to be implemented accordingly. If the implementation of the new manifold defines a ompl::base::StateManifold::allocState() function, it should also provide a ompl::base::StateManifold::freeState() function and define (or typedef) StateType to the type of the state that is allocated/freed. In such cases it will often be necessary to also implement ompl::base::StateManifold::copyState().
- Inheriting from ompl::base::CompoundStateManifold
- Another option is to inherit from a ompl::base::CompoundStateManifold and call ompl::base::CompoundStateManifold::addSubManifold() in the constructor of the new class for other existing manifolds. This is the easiest way to create new manifolds -- only the constructor needs to be provided. For example, see ompl::base::SE2StateManifold. Optionally, the ompl::base::CompoundStateManifold::lock() function can be called after the components have been set in order to prevent the user of the manifold from adding further components.
Optionally, if there exist projections to Euclidean spaces (ompl::base::ProjectionEvaluator) for the defined manifold, these can be registered by the ompl::base::StateManifold::registerProjections() function (by calling ompl::base::StateManifold::registerProjection() or ompl::base::StateManifold::registerDefaultProjection()). Planners that need a projection but do not have one defined will attempt using this default projection during planning.