00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
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
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
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
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
00113 if (!si_->satisfiesBounds(state))
00114 {
00115 if (verbose)
00116 logInform("State outside bounds");
00117 return false;
00118 }
00119
00120
00121 robot_state::RobotState *kstate = tss_.getStateStorage();
00122 planning_context_->getOMPLStateSpace()->copyToRobotState(*kstate, state);
00123
00124
00125 const kinematic_constraints::KinematicConstraintSetPtr &kset = planning_context_->getPathConstraints();
00126 if (kset && !kset->decide(*kstate, verbose).satisfied)
00127 return false;
00128
00129
00130 if (!planning_context_->getPlanningScene()->isStateFeasible(*kstate, verbose))
00131 return false;
00132
00133
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
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
00164 if (!planning_context_->getPlanningScene()->isStateFeasible(*kstate, verbose))
00165 {
00166 dist = 0.0;
00167 return false;
00168 }
00169
00170
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
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
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
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
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
00256 if (!planning_context_->getPlanningScene()->isStateFeasible(*kstate, verbose))
00257 {
00258 dist = 0.0;
00259 return false;
00260 }
00261
00262
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 }