state_validity_checker.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002 * Software License Agreement (BSD License)
00003 *
00004 *  Copyright (c) 2011, Willow Garage, Inc.
00005 *  All rights reserved.
00006 *
00007 *  Redistribution and use in source and binary forms, with or without
00008 *  modification, are permitted provided that the following conditions
00009 *  are met:
00010 *
00011 *   * Redistributions of source code must retain the above copyright
00012 *     notice, this list of conditions and the following disclaimer.
00013 *   * Redistributions in binary form must reproduce the above
00014 *     copyright notice, this list of conditions and the following
00015 *     disclaimer in the documentation and/or other materials provided
00016 *     with the distribution.
00017 *   * Neither the name of Willow Garage nor the names of its
00018 *     contributors may be used to endorse or promote products derived
00019 *     from this software without specific prior written permission.
00020 *
00021 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032 *  POSSIBILITY OF SUCH DAMAGE.
00033 *********************************************************************/
00034 
00035 /* Author: Ioan Sucan */
00036 
00037 #include <moveit/ompl_interface/detail/state_validity_checker.h>
00038 #include <moveit/ompl_interface/model_based_planning_context.h>
00039 #include <moveit/profiler/profiler.h>
00040 #include <ros/ros.h>
00041 
00042 ompl_interface::StateValidityChecker::StateValidityChecker(const ModelBasedPlanningContext *pc)
00043   : ompl::base::StateValidityChecker(pc->getOMPLSimpleSetup()->getSpaceInformation())
00044   , planning_context_(pc)
00045   , group_name_(pc->getGroupName())
00046   , tss_(pc->getCompleteInitialRobotState())
00047   , verbose_(false)
00048 {
00049   specs_.clearanceComputationType = ompl::base::StateValidityCheckerSpecs::APPROXIMATE;
00050   specs_.hasValidDirectionComputation = false;
00051   
00052   collision_request_with_distance_.distance = true;
00053   collision_request_with_cost_.cost = true;
00054 
00055   collision_request_simple_.group_name = planning_context_->getGroupName();
00056   collision_request_with_distance_.group_name = planning_context_->getGroupName();
00057   collision_request_with_cost_.group_name = planning_context_->getGroupName();
00058 
00059   collision_request_simple_verbose_ = collision_request_simple_;
00060   collision_request_simple_verbose_.verbose = true;
00061 
00062   collision_request_with_distance_verbose_ = collision_request_with_distance_;
00063   collision_request_with_distance_verbose_.verbose = true;
00064 }
00065 
00066 void ompl_interface::StateValidityChecker::setVerbose(bool flag)
00067 {
00068   verbose_ = flag;
00069 }
00070 
00071 bool ompl_interface::StateValidityChecker::isValid(const ompl::base::State *state, bool verbose) const
00072 {
00073   //  moveit::Profiler::ScopedBlock sblock("isValid");
00074   return planning_context_->useStateValidityCache() ? isValidWithCache(state, verbose) : isValidWithoutCache(state, verbose);
00075 }
00076 
00077 bool ompl_interface::StateValidityChecker::isValid(const ompl::base::State *state, double &dist, bool verbose) const
00078 {
00079   //  moveit::Profiler::ScopedBlock sblock("isValid");
00080   return planning_context_->useStateValidityCache() ? isValidWithCache(state, dist, verbose) : isValidWithoutCache(state, dist, verbose);
00081 }
00082 
00083 double ompl_interface::StateValidityChecker::cost(const ompl::base::State *state) const
00084 {
00085   double cost = 0.0;
00086   
00087   robot_state::RobotState *kstate = tss_.getStateStorage();
00088   planning_context_->getOMPLStateSpace()->copyToRobotState(*kstate, state);
00089 
00090   // Calculates cost from a summation of distance to obstacles times the size of the obstacle
00091   collision_detection::CollisionResult res;
00092   planning_context_->getPlanningScene()->checkCollision(collision_request_with_cost_, res, *kstate);
00093   
00094   for (std::set<collision_detection::CostSource>::const_iterator it = res.cost_sources.begin() ; it != res.cost_sources.end() ; ++it)
00095     cost += it->cost * it->getVolume();
00096 
00097   return cost;
00098 }
00099 
00100 double ompl_interface::StateValidityChecker::clearance(const ompl::base::State *state) const
00101 {
00102   robot_state::RobotState *kstate = tss_.getStateStorage();
00103   planning_context_->getOMPLStateSpace()->copyToRobotState(*kstate, state);
00104 
00105   collision_detection::CollisionResult res;
00106   planning_context_->getPlanningScene()->checkCollision(collision_request_with_distance_, res, *kstate);
00107   return res.collision ? 0.0 : (res.distance < 0.0 ? std::numeric_limits<double>::infinity() : res.distance);
00108 }
00109 
00110 bool ompl_interface::StateValidityChecker::isValidWithoutCache(const ompl::base::State *state, bool verbose) const
00111 {
00112   // check bounds
00113   if (!si_->satisfiesBounds(state))
00114   {
00115     if (verbose)
00116       logInform("State outside bounds");
00117     return false;
00118   }
00119 
00120   // convert ompl state to moveit robot state
00121   robot_state::RobotState *kstate = tss_.getStateStorage();
00122   planning_context_->getOMPLStateSpace()->copyToRobotState(*kstate, state);
00123 
00124   // check path constraints
00125   const kinematic_constraints::KinematicConstraintSetPtr &kset = planning_context_->getPathConstraints();
00126   if (kset && !kset->decide(*kstate, verbose).satisfied)
00127     return false;
00128 
00129   // check feasibility
00130   if (!planning_context_->getPlanningScene()->isStateFeasible(*kstate, verbose))
00131     return false;
00132 
00133   // check collision avoidance
00134   collision_detection::CollisionResult res;
00135   planning_context_->getPlanningScene()->checkCollision(verbose ? collision_request_simple_verbose_ : collision_request_simple_, res, *kstate);
00136   return res.collision == false;
00137 }
00138 
00139 bool ompl_interface::StateValidityChecker::isValidWithoutCache(const ompl::base::State *state, double &dist, bool verbose) const
00140 {
00141   if (!si_->satisfiesBounds(state))
00142   {
00143     if (verbose)
00144       logInform("State outside bounds");
00145     return false;
00146   }
00147 
00148   robot_state::RobotState *kstate = tss_.getStateStorage();
00149   planning_context_->getOMPLStateSpace()->copyToRobotState(*kstate, state);
00150 
00151   // check path constraints
00152   const kinematic_constraints::KinematicConstraintSetPtr &kset = planning_context_->getPathConstraints();
00153   if (kset)
00154   {
00155     kinematic_constraints::ConstraintEvaluationResult cer = kset->decide(*kstate, verbose);
00156     if (!cer.satisfied)
00157     {
00158       dist = cer.distance;
00159       return false;
00160     }
00161   }
00162 
00163   // check feasibility
00164   if (!planning_context_->getPlanningScene()->isStateFeasible(*kstate, verbose))
00165   {
00166     dist = 0.0;
00167     return false;
00168   }
00169 
00170   // check collision avoidance
00171   collision_detection::CollisionResult res;
00172   planning_context_->getPlanningScene()->checkCollision(verbose ? collision_request_with_distance_verbose_ : collision_request_with_distance_, res, *kstate);
00173   dist = res.distance;
00174   return res.collision == false;
00175 }
00176 
00177 bool ompl_interface::StateValidityChecker::isValidWithCache(const ompl::base::State *state, bool verbose) const
00178 {
00179   if (state->as<ModelBasedStateSpace::StateType>()->isValidityKnown())
00180     return state->as<ModelBasedStateSpace::StateType>()->isMarkedValid();
00181 
00182   if (!si_->satisfiesBounds(state))
00183   {
00184     if (verbose)
00185       logInform("State outside bounds");
00186     const_cast<ob::State*>(state)->as<ModelBasedStateSpace::StateType>()->markInvalid();
00187     return false;
00188   }
00189 
00190   robot_state::RobotState *kstate = tss_.getStateStorage();
00191   planning_context_->getOMPLStateSpace()->copyToRobotState(*kstate, state);
00192 
00193   // check path constraints
00194   const kinematic_constraints::KinematicConstraintSetPtr &kset = planning_context_->getPathConstraints();
00195   if (kset && !kset->decide(*kstate, verbose).satisfied)
00196   {
00197     const_cast<ob::State*>(state)->as<ModelBasedStateSpace::StateType>()->markInvalid();
00198     return false;
00199   }
00200 
00201   // check feasibility
00202   if (!planning_context_->getPlanningScene()->isStateFeasible(*kstate, verbose))
00203   {
00204     const_cast<ob::State*>(state)->as<ModelBasedStateSpace::StateType>()->markInvalid();
00205     return false;
00206   }
00207 
00208   // check collision avoidance
00209   collision_detection::CollisionResult res;
00210   planning_context_->getPlanningScene()->checkCollision(verbose ? collision_request_simple_verbose_ : collision_request_simple_, res, *kstate);
00211   if (res.collision == false)
00212   {
00213     const_cast<ob::State*>(state)->as<ModelBasedStateSpace::StateType>()->markValid();
00214     return true;
00215   }
00216   else
00217   {
00218     const_cast<ob::State*>(state)->as<ModelBasedStateSpace::StateType>()->markInvalid();
00219     return false;
00220   }
00221 }
00222 
00223 bool ompl_interface::StateValidityChecker::isValidWithCache(const ompl::base::State *state, double &dist, bool verbose) const
00224 {
00225   if (state->as<ModelBasedStateSpace::StateType>()->isValidityKnown() && state->as<ModelBasedStateSpace::StateType>()->isGoalDistanceKnown())
00226   {
00227     dist = state->as<ModelBasedStateSpace::StateType>()->distance;
00228     return state->as<ModelBasedStateSpace::StateType>()->isMarkedValid();
00229   }
00230 
00231   if (!si_->satisfiesBounds(state))
00232   {
00233     if (verbose)
00234       logInform("State outside bounds");
00235     const_cast<ob::State*>(state)->as<ModelBasedStateSpace::StateType>()->markInvalid(0.0);
00236     return false;
00237   }
00238 
00239   robot_state::RobotState *kstate = tss_.getStateStorage();
00240   planning_context_->getOMPLStateSpace()->copyToRobotState(*kstate, state);
00241 
00242   // check path constraints
00243   const kinematic_constraints::KinematicConstraintSetPtr &kset = planning_context_->getPathConstraints();
00244   if (kset)
00245   {
00246     kinematic_constraints::ConstraintEvaluationResult cer = kset->decide(*kstate, verbose);
00247     if (!cer.satisfied)
00248     {
00249       dist = cer.distance;
00250       const_cast<ob::State*>(state)->as<ModelBasedStateSpace::StateType>()->markInvalid(dist);
00251       return false;
00252     }
00253   }
00254 
00255   // check feasibility
00256   if (!planning_context_->getPlanningScene()->isStateFeasible(*kstate, verbose))
00257   {
00258     dist = 0.0;
00259     return false;
00260   }
00261 
00262   // check collision avoidance
00263   collision_detection::CollisionResult res;
00264   planning_context_->getPlanningScene()->checkCollision(verbose ? collision_request_with_distance_verbose_ : collision_request_with_distance_, res, *kstate);
00265   dist = res.distance;
00266   return res.collision == false;
00267 }


ompl
Author(s): Ioan Sucan
autogenerated on Wed Sep 16 2015 04:42:27