3232 * POSSIBILITY OF SUCH DAMAGE.
3333 *********************************************************************/
3434
35- /* Author : Ioan Sucan */
35+ /* Authors : Ioan Sucan, Jeroen De Maeyer */
3636
3737#include < moveit/ompl_interface/detail/state_validity_checker.h>
3838#include < moveit/ompl_interface/model_based_planning_context.h>
3939#include < moveit/profiler/profiler.h>
4040#include < ros/ros.h>
4141
42+ #include < ompl/base/spaces/constraint/ConstrainedStateSpace.h>
43+
4244namespace ompl_interface
4345{
4446constexpr char LOGNAME [] = " state_validity_checker" ;
@@ -194,4 +196,112 @@ double ompl_interface::StateValidityChecker::clearance(const ompl::base::State*
194196 collision_detection::CollisionResult res;
195197 planning_context_->getPlanningScene ()->checkCollision (collision_request_with_distance_, res, *robot_state);
196198 return res.collision ? 0.0 : (res.distance < 0.0 ? std::numeric_limits<double >::infinity () : res.distance );
199+ }
200+
201+ /* ******************************************
202+ * Constrained Planning StateValidityChecker
203+ * *****************************************/
204+
205+ bool ompl_interface::ConstrainedPlanningStateValidityChecker::isValid (const ompl::base::State* wrapped_state,
206+ bool verbose) const
207+ {
208+ // Unwrap the state from a ConstrainedStateSpace::StateType
209+ auto state = wrapped_state->as <ompl::base::ConstrainedStateSpace::StateType>()->getState ();
210+
211+ // Use cached validity if it is available
212+ if (state->as <ModelBasedStateSpace::StateType>()->isValidityKnown ())
213+ return state->as <ModelBasedStateSpace::StateType>()->isMarkedValid ();
214+
215+ // do not use the unwrapped state here, as satisfiesBounds expects a state of type ConstrainedStateSpace::StateType
216+ if (!si_->satisfiesBounds (wrapped_state))
217+ {
218+ if (verbose)
219+ ROS_INFO_NAMED (LOGNAME , " State outside bounds" );
220+ const_cast <ob::State*>(state)->as <ModelBasedStateSpace::StateType>()->markInvalid ();
221+ return false ;
222+ }
223+
224+ moveit::core::RobotState* robot_state = tss_.getStateStorage ();
225+ // do not use the unwrapped state here, as copyToRobotState expects a state of type ConstrainedStateSpace::StateType
226+ planning_context_->getOMPLStateSpace ()->copyToRobotState (*robot_state, wrapped_state);
227+
228+ // check path constraints
229+ const kinematic_constraints::KinematicConstraintSetPtr& kset = planning_context_->getPathConstraints ();
230+ if (kset && !kset->decide (*robot_state, verbose).satisfied )
231+ {
232+ const_cast <ob::State*>(state)->as <ModelBasedStateSpace::StateType>()->markInvalid ();
233+ return false ;
234+ }
235+
236+ // check feasibility
237+ if (!planning_context_->getPlanningScene ()->isStateFeasible (*robot_state, verbose))
238+ {
239+ const_cast <ob::State*>(state)->as <ModelBasedStateSpace::StateType>()->markInvalid ();
240+ return false ;
241+ }
242+
243+ // check collision avoidance
244+ collision_detection::CollisionResult res;
245+ planning_context_->getPlanningScene ()->checkCollision (
246+ verbose ? collision_request_simple_verbose_ : collision_request_simple_, res, *robot_state);
247+ if (!res.collision )
248+ {
249+ const_cast <ob::State*>(state)->as <ModelBasedStateSpace::StateType>()->markValid ();
250+ }
251+ else
252+ {
253+ const_cast <ob::State*>(state)->as <ModelBasedStateSpace::StateType>()->markInvalid ();
254+ }
255+ return !res.collision ;
256+ }
257+
258+ bool ompl_interface::ConstrainedPlanningStateValidityChecker::isValid (const ompl::base::State* wrapped_state,
259+ double & dist, bool verbose) const
260+ {
261+ // Unwrap the state from a ConstrainedStateSpace::StateType
262+ auto state = wrapped_state->as <ompl::base::ConstrainedStateSpace::StateType>()->getState ();
263+
264+ // Use cached validity and distance if they are available
265+ if (state->as <ModelBasedStateSpace::StateType>()->isValidityKnown () &&
266+ state->as <ModelBasedStateSpace::StateType>()->isGoalDistanceKnown ())
267+ {
268+ dist = state->as <ModelBasedStateSpace::StateType>()->distance ;
269+ return state->as <ModelBasedStateSpace::StateType>()->isMarkedValid ();
270+ }
271+
272+ // do not use the unwrapped state here, as satisfiesBounds expects a state of type ConstrainedStateSpace::StateType
273+ if (!si_->satisfiesBounds (wrapped_state))
274+ {
275+ if (verbose)
276+ ROS_INFO_NAMED (LOGNAME , " State outside bounds" );
277+ const_cast <ob::State*>(state)->as <ModelBasedStateSpace::StateType>()->markInvalid (0.0 );
278+ return false ;
279+ }
280+
281+ moveit::core::RobotState* robot_state = tss_.getStateStorage ();
282+
283+ // do not use the unwrapped state here, as copyToRobotState expects a state of type ConstrainedStateSpace::StateType
284+ planning_context_->getOMPLStateSpace ()->copyToRobotState (*robot_state, wrapped_state);
285+
286+ // check path constraints
287+ const kinematic_constraints::KinematicConstraintSetPtr& kset = planning_context_->getPathConstraints ();
288+ if (kset && !kset->decide (*robot_state, verbose).satisfied )
289+ {
290+ const_cast <ob::State*>(state)->as <ModelBasedStateSpace::StateType>()->markInvalid ();
291+ return false ;
292+ }
293+
294+ // check feasibility
295+ if (!planning_context_->getPlanningScene ()->isStateFeasible (*robot_state, verbose))
296+ {
297+ dist = 0.0 ;
298+ return false ;
299+ }
300+
301+ // check collision avoidance
302+ collision_detection::CollisionResult res;
303+ planning_context_->getPlanningScene ()->checkCollision (
304+ verbose ? collision_request_with_distance_verbose_ : collision_request_with_distance_, res, *robot_state);
305+ dist = res.distance ;
306+ return !res.collision ;
197307}
0 commit comments