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 the 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, Dave Coleman */
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()), planning_context_(pc),
00044   group_name_(pc->getGroupName()), tss_(pc->getCompleteInitialRobotState()), verbose_(false)
00045 {
00046   specs_.clearanceComputationType = ompl::base::StateValidityCheckerSpecs::APPROXIMATE;
00047   specs_.hasValidDirectionComputation = false;
00048 
00049   collision_request_with_distance_.distance = true;
00050   collision_request_with_cost_.cost = true;
00051 
00052   collision_request_simple_.group_name = planning_context_->getGroupName();
00053   collision_request_with_distance_.group_name = planning_context_->getGroupName();
00054   collision_request_with_cost_.group_name = planning_context_->getGroupName();
00055 
00056   collision_request_simple_verbose_ = collision_request_simple_;
00057   collision_request_simple_verbose_.verbose = true;
00058 
00059   collision_request_with_distance_verbose_ = collision_request_with_distance_;
00060   collision_request_with_distance_verbose_.verbose = true;
00061 }
00062 
00063 void ompl_interface::StateValidityChecker::setVerbose(bool flag)
00064 {
00065   verbose_ = flag;
00066 }
00067 
00068 bool ompl_interface::StateValidityChecker::isValid(const ompl::base::State *state, bool verbose) const
00069 {
00070   //  moveit::Profiler::ScopedBlock sblock("isValid");
00071   return planning_context_->useStateValidityCache() ? isValidWithCache(state, verbose) : isValidWithoutCache(state, verbose);
00072 }
00073 
00074 bool ompl_interface::StateValidityChecker::isValid(const ompl::base::State *state, double &dist, bool verbose) const
00075 {
00076   //  moveit::Profiler::ScopedBlock sblock("isValid");
00077   return planning_context_->useStateValidityCache() ? isValidWithCache(state, dist, verbose) : isValidWithoutCache(state, dist, verbose);
00078 }
00079 
00080 double ompl_interface::StateValidityChecker::cost(const ompl::base::State *state) const
00081 {
00082   bool useCollisionDistanceCost = false; // TODO - set this somewhere else
00083   double cost = 0.0;
00084 
00085   if( useCollisionDistanceCost ) // proximity to collisions cost
00086   {
00087     robot_state::RobotState *kstate = tss_.getStateStorage();
00088     planning_context_->getOMPLStateSpace()->copyToRobotState(*kstate, state);
00089 
00090     collision_detection::CollisionResult res;
00091     planning_context_->getPlanningScene()->checkCollision(collision_request_with_cost_, res, *kstate);
00092 
00093     for (std::set<collision_detection::CostSource>::const_iterator it = res.cost_sources.begin() ; it != res.cost_sources.end() ; ++it)
00094       cost += it->cost * it->getVolume();
00095   }
00096   else // use distance between joints cost
00097   {
00098     static std::vector<double> prev_joint_values;
00099     static bool first_time = true;
00100     static boost::thread::id thread_id = boost::this_thread::get_id();
00101 
00102     // Check that we are still on same thread
00103     if( thread_id != boost::this_thread::get_id() )
00104       ROS_ERROR_STREAM("Multiple threads are not implemented here...");
00105 
00106     // Get current robot state
00107     robot_state::RobotState *kstate = tss_.getStateStorage();
00108     planning_context_->getOMPLStateSpace()->copyToRobotState(*kstate, state);
00109 
00110     std::vector<double> new_joint_values;
00111 
00112     // get joint state values
00113     kstate->getStateValues(new_joint_values);
00114 
00115     // calculate cost
00116     for (std::size_t i = 0; i < new_joint_values.size(); ++i)
00117     {
00118       double value = 0;
00119       // Check if first time
00120       if (first_time)
00121       {
00122         first_time = false;
00123         prev_joint_values.resize(new_joint_values.size());
00124       }
00125       else
00126       {
00127         // get abs of difference in each joint value
00128         value = fabs(prev_joint_values[i] - new_joint_values[i]);
00129       }
00130 
00131       cost += value;
00132 
00133       // copy new value to old vector
00134       prev_joint_values[i] = new_joint_values[i];
00135     }
00136   }
00137 
00138   return cost;
00139 }
00140 
00141 double ompl_interface::StateValidityChecker::clearance(const ompl::base::State *state) const
00142 {
00143   robot_state::RobotState *kstate = tss_.getStateStorage();
00144   planning_context_->getOMPLStateSpace()->copyToRobotState(*kstate, state);
00145 
00146   collision_detection::CollisionResult res;
00147   planning_context_->getPlanningScene()->checkCollision(collision_request_with_distance_, res, *kstate);
00148   return res.collision ? 0.0 : (res.distance < 0.0 ? std::numeric_limits<double>::infinity() : res.distance);
00149 }
00150 
00151 bool ompl_interface::StateValidityChecker::isValidWithoutCache(const ompl::base::State *state, bool verbose) const
00152 {
00153   if (!si_->satisfiesBounds(state))
00154   {
00155     if (verbose)
00156       logInform("State outside bounds");
00157     return false;
00158   }
00159 
00160   robot_state::RobotState *kstate = tss_.getStateStorage();
00161   planning_context_->getOMPLStateSpace()->copyToRobotState(*kstate, state);
00162 
00163   // check path constraints
00164   const kinematic_constraints::KinematicConstraintSetPtr &kset = planning_context_->getPathConstraints();
00165   if (kset && !kset->decide(*kstate, verbose).satisfied)
00166     return false;
00167 
00168   // check feasibility
00169   if (!planning_context_->getPlanningScene()->isStateFeasible(*kstate, verbose))
00170     return false;
00171 
00172   // check collision avoidance
00173   collision_detection::CollisionResult res;
00174   planning_context_->getPlanningScene()->checkCollision(verbose ? collision_request_simple_verbose_ : collision_request_simple_, res, *kstate);
00175   return res.collision == false;
00176 }
00177 
00178 bool ompl_interface::StateValidityChecker::isValidWithoutCache(const ompl::base::State *state, double &dist, bool verbose) const
00179 {
00180   if (!si_->satisfiesBounds(state))
00181   {
00182     if (verbose)
00183       logInform("State outside bounds");
00184     return false;
00185   }
00186 
00187   robot_state::RobotState *kstate = tss_.getStateStorage();
00188   planning_context_->getOMPLStateSpace()->copyToRobotState(*kstate, state);
00189 
00190   // check path constraints
00191   const kinematic_constraints::KinematicConstraintSetPtr &kset = planning_context_->getPathConstraints();
00192   if (kset)
00193   {
00194     kinematic_constraints::ConstraintEvaluationResult cer = kset->decide(*kstate, verbose);
00195     if (!cer.satisfied)
00196     {
00197       dist = cer.distance;
00198       return false;
00199     }
00200   }
00201 
00202   // check feasibility
00203   if (!planning_context_->getPlanningScene()->isStateFeasible(*kstate, verbose))
00204   {
00205     dist = 0.0;
00206     return false;
00207   }
00208 
00209   // check collision avoidance
00210   collision_detection::CollisionResult res;
00211   planning_context_->getPlanningScene()->checkCollision(verbose ? collision_request_with_distance_verbose_ : collision_request_with_distance_, res, *kstate);
00212   dist = res.distance;
00213   return res.collision == false;
00214 }
00215 
00216 bool ompl_interface::StateValidityChecker::isValidWithCache(const ompl::base::State *state, bool verbose) const
00217 {
00218   if (state->as<ModelBasedStateSpace::StateType>()->isValidityKnown())
00219     return state->as<ModelBasedStateSpace::StateType>()->isMarkedValid();
00220 
00221   if (!si_->satisfiesBounds(state))
00222   {
00223     if (verbose)
00224       logInform("State outside bounds");
00225     const_cast<ob::State*>(state)->as<ModelBasedStateSpace::StateType>()->markInvalid();
00226     return false;
00227   }
00228 
00229   robot_state::RobotState *kstate = tss_.getStateStorage();
00230   planning_context_->getOMPLStateSpace()->copyToRobotState(*kstate, state);
00231 
00232   // check path constraints
00233   const kinematic_constraints::KinematicConstraintSetPtr &kset = planning_context_->getPathConstraints();
00234   if (kset && !kset->decide(*kstate, verbose).satisfied)
00235   {
00236     const_cast<ob::State*>(state)->as<ModelBasedStateSpace::StateType>()->markInvalid();
00237     return false;
00238   }
00239 
00240   // check feasibility
00241   if (!planning_context_->getPlanningScene()->isStateFeasible(*kstate, verbose))
00242   {
00243     const_cast<ob::State*>(state)->as<ModelBasedStateSpace::StateType>()->markInvalid();
00244     return false;
00245   }
00246 
00247   // check collision avoidance
00248   collision_detection::CollisionResult res;
00249   planning_context_->getPlanningScene()->checkCollision(verbose ? collision_request_simple_verbose_ : collision_request_simple_, res, *kstate);
00250   if (res.collision == false)
00251   {
00252     const_cast<ob::State*>(state)->as<ModelBasedStateSpace::StateType>()->markValid();
00253     return true;
00254   }
00255   else
00256   {
00257     const_cast<ob::State*>(state)->as<ModelBasedStateSpace::StateType>()->markInvalid();
00258     return false;
00259   }
00260 }
00261 
00262 bool ompl_interface::StateValidityChecker::isValidWithCache(const ompl::base::State *state, double &dist, bool verbose) const
00263 {
00264   if (state->as<ModelBasedStateSpace::StateType>()->isValidityKnown() && state->as<ModelBasedStateSpace::StateType>()->isGoalDistanceKnown())
00265   {
00266     dist = state->as<ModelBasedStateSpace::StateType>()->distance;
00267     return state->as<ModelBasedStateSpace::StateType>()->isMarkedValid();
00268   }
00269 
00270   if (!si_->satisfiesBounds(state))
00271   {
00272     if (verbose)
00273       logInform("State outside bounds");
00274     const_cast<ob::State*>(state)->as<ModelBasedStateSpace::StateType>()->markInvalid(0.0);
00275     return false;
00276   }
00277 
00278   robot_state::RobotState *kstate = tss_.getStateStorage();
00279   planning_context_->getOMPLStateSpace()->copyToRobotState(*kstate, state);
00280 
00281   // check path constraints
00282   const kinematic_constraints::KinematicConstraintSetPtr &kset = planning_context_->getPathConstraints();
00283   if (kset)
00284   {
00285     kinematic_constraints::ConstraintEvaluationResult cer = kset->decide(*kstate, verbose);
00286     if (!cer.satisfied)
00287     {
00288       dist = cer.distance;
00289       const_cast<ob::State*>(state)->as<ModelBasedStateSpace::StateType>()->markInvalid(dist);
00290       return false;
00291     }
00292   }
00293 
00294   // check feasibility
00295   if (!planning_context_->getPlanningScene()->isStateFeasible(*kstate, verbose))
00296   {
00297     dist = 0.0;
00298     return false;
00299   }
00300 
00301   // check collision avoidance
00302   collision_detection::CollisionResult res;
00303   planning_context_->getPlanningScene()->checkCollision(verbose ? collision_request_with_distance_verbose_ : collision_request_with_distance_, res, *kstate);
00304   dist = res.distance;
00305   return res.collision == false;
00306 }


ompl
Author(s): Ioan Sucan
autogenerated on Mon Oct 6 2014 11:12:03