Representing Goals in OMPL

Setting the Goal

The most general representation of a goal is ompl::base::Goal. This class contains a pure virtual method, ompl::base::Goal::isSatisfied(), which takes a state as argument and returns a boolean indicating whether that state is a goal or not. No other information about the goal is given. This function can include arbitrary code deciding what is in the goal region and what is not.

class MyArbitraryGoal : public ompl::base::Goal
{
public:
MyArbitraryGoal(const SpaceInformationPtr &si) : ompl::base::Goal(si)
{
}
virtual bool isSatisfied(const State *st) const
{
// perform any operations and return a truth value
}
};

While this is a very general definition, it is often the case more information is known about the goal. This information is helpful for planners and the user should specify this information when available. Here are types of information planners can use:

  • If an approximation of distance to the goal is available, not necessarily a metric, this information can be given to the planner by also providing an implementation of ompl::base::Goal::isSatisfied() (the version that takes a ompl::base::State* and a double* as arguments). By default, the implementation of this function simply sets the distance to the maximum value a double can hold.
class MyArbitraryGoal : public ompl::base::Goal
{
public:
MyArbitraryGoal(const SpaceInformationPtr &si) : ompl::base::Goal(si)
{
}
virtual bool isSatisfied(const State *st) const
{
perform_any_operations();
return truth value;
}
virtual bool isSatisfied(const State *st, double *distance) const
{
bool result = isSatisfied(st);
if (distance != NULL)
{
if (state_clearly_out_of_goal_region(st))
{
*distance = std::numeric_limits<double>::max();
}
else
{
if (state_near_goal(st))
*distance = 1;
else
*distance = 100;
}
}
return result;
}
};
  • It is often the case that when distance to goal approximations are available, the condition for a state being in the goal region is that that distance is less than a specified threshold. If this is indeed the case, ompl::base::GoalRegion (which inherits from ompl::base::Goal) should be used. The additional function ompl::base::GoalRegion::distanceGoal() needs to be implemented. However, all the versions of ompl::base::Goal::isSatisfied() are implemented in terms of this new function and a specified threshold (which is equal to the machine epsilon, by default).
class MyGoalRegion : public ompl::base::GoalRegion
{
public:
MyGoalRegion(const SpaceInformationPtr &si) : ompl::base::GoalRegion(si)
{
}
virtual double distanceGoal(const State *st) const
{
// perform any operations and return a double indicating the distance to the goal
}
};

Using the Goal Region

Planners cast the specified goal representation into the minimal representation they can use. For uni-directional planners, ompl::base::Goal is fine. For bi-directional planners however, this needs to be ompl::base::GoalSampleableRegion.

If the planner can use the goal specification, it will compute a motion plan. If successful, the found path is stored in the goal region. Flags indicating whether the solution was approximate are also set. The user can query all the information the planner has set using accessors from ompl::base::Goal.

Planners that include the notion of path length, and attempt to find solution paths that are shorter, also make use of a third version of ompl::base::Goal::isSatisfied(), the one that takes a path length as argument as well. This version decides whether a maximum path length is met. The user can set this maximum length by calling ompl::base::Goal::setMaximumPathLength().