以下内容为OMPL官方Tutorial Setting up state validity checking的翻译
OMPL本身并不包括可行状态检查的代码。这样的设置是取决于所要求解的问题的。比如,OMPL.app定义可行状态检测为检查加载的CAD模型的碰撞关系。MoveIt中的ROS OMPL接口定义可行状态检查为机器人模型与感知到的环境物体之间的碰撞检测。如果为蛋白质折叠做规划,那么可行状态检查就与能量函数有关了。
为了让用户定义可行状态,OMPL定义了两个抽象类
- ompl::base::StateValidityChecker
- ompl::base::MotionValidator
这些类将我们所规划的系统的性质抽象化了。例如,OMPL不需要表示机器人或者障碍物的几何关系。用户在配置ompl::base::SpaceInformation的时候可以设定具体用哪一种实现方式。注意,ompl::base::StateValidityChecker和ompl::base::MotionValidator类的实例化需要时线程安全的。
ompl::base::StateValidityChecker定义了ompl::base::StateValidityChecker::isValid()函数,规划器(planner)通过这个函数来评估一个状态是否是可行的。如果用户没有设置这个类的话,则会假设ompl::base::AllValidStateValidityChecker,也就是说所有的状态都是可行的。
// 定义类
class myStateValidityCheckerClass : public base::StateValidityChecker
{
public:
myStateValidityCheckerClass(const base::SpaceInformationPtr &si) :
base::StateValidityChecker(si)
{
}
virtual bool isValid(const base::State *state) const
{
return ...;
}
};
// 或者用这个函数来check:
bool myStateValidityCheckerFunction(const base::State *state)
{
return ...;
}
base::SpaceInformationPtr si(space);
// 如果定义类则通过这一种方式来做可行状态检查
si->setStateValidityChecker(std::make_shared<myStateValidityCheckerClass>(si));
// 如果只定义了上述函数就用这个做可行状态检查
si->setStateValidityChecker(myStateValidityCheckerFunction);
si->setStateValidityCheckingResolution(0.03); // 3%
si->setup();
ompl::base::MotionValidator 类定义了 ompl::base::MotionValidator::checkMotion() 方法来评估两个状态之间运动的可行性。默认情况下,这个类的是现实ompl::base::DiscreteMotionValidator,它的优点是可以通过ompl::base::StateValidityChecker中的函数单独实现。缺点是整个motion被离散化为特定的分辨率,然后以这个分辨率做可行状态检测。如果分辨率太大,则可能会有一些不可行的状态检测不到;如果分辨率太小的话,又可能会检测太多的状态,从而影响求解速度。运动离散的分辨率是通过ompl::base::StateSpace::validSegmentCount()计算的:每个状态空间可以计算运动应该被分割为多少段(segment)从而能满足可行状态检测的数量要求。用户可以定义通过调用 ompl::base::SpaceInformation::setStateValidityCheckingResolution(),定义“空间最大范围(ompl::base::StateSpace::getMaximumExtent())的百分比”来定义分辨率;或者通过调用ompl::base::StateSpace::setLongestValidSegmentFraction() 来针对单个的状态空间定义。如果用四大ompl::base::CompoundStateSpace的话,每个子空间可以定义不同的分辨率。如果连续碰撞检测可行,则推荐使用另一个ompl::base::MotionValidator提供的实现方案,这种方案不依赖于按照一定分辨率离散运动。
// define this class:
class myMotionValidator : public base::MotionValidator
{
public:
// implement checkMotion()
};
base::SpaceInformationPtr si(space);
si->setMotionValidator(std::make_shared<myMotionValidator>(si));
si->setup();