diff --git a/moveit_core/collision_detection/include/moveit/collision_detection/collision_common.h b/moveit_core/collision_detection/include/moveit/collision_detection/collision_common.h index db246518fd..2c1805015a 100644 --- a/moveit_core/collision_detection/include/moveit/collision_detection/collision_common.h +++ b/moveit_core/collision_detection/include/moveit/collision_detection/collision_common.h @@ -150,6 +150,12 @@ struct CollisionRequest * are included. */ std::string group_name = ""; + /** \brief If true, use padded collision environment */ + bool use_padded_collision_environment = true; + + /** \brief If true, do self collision check with padded robot links */ + bool use_padded_self_collision = false; + /** \brief If true, compute proximity distance */ bool distance = false; diff --git a/moveit_core/planning_scene/include/moveit/planning_scene/planning_scene.h b/moveit_core/planning_scene/include/moveit/planning_scene/planning_scene.h index 3d71a117e7..7ee02aa045 100644 --- a/moveit_core/planning_scene/include/moveit/planning_scene/planning_scene.h +++ b/moveit_core/planning_scene/include/moveit/planning_scene/planning_scene.h @@ -347,19 +347,12 @@ class MOVEIT_PLANNING_SCENE_EXPORT PlanningScene : public std::enable_shared_fro void checkCollision(const collision_detection::CollisionRequest& req, collision_detection::CollisionResult& res); /** \brief Check whether the current state is in collision. The current state is expected to be updated. */ - void checkCollision(const collision_detection::CollisionRequest& req, collision_detection::CollisionResult& res) const - { - checkCollision(req, res, getCurrentState()); - } + void checkCollision(const collision_detection::CollisionRequest& req, collision_detection::CollisionResult& res) const; /** \brief Check whether a specified state (\e robot_state) is in collision. This variant of the function takes a non-const \e robot_state and calls updateCollisionBodyTransforms() on it. */ void checkCollision(const collision_detection::CollisionRequest& req, collision_detection::CollisionResult& res, - moveit::core::RobotState& robot_state) const - { - robot_state.updateCollisionBodyTransforms(); - checkCollision(req, res, static_cast(robot_state)); - } + moveit::core::RobotState& robot_state) const; /** \brief Check whether a specified state (\e robot_state) is in collision. The collision transforms of \e * robot_state are @@ -372,114 +365,80 @@ class MOVEIT_PLANNING_SCENE_EXPORT PlanningScene : public std::enable_shared_fro a non-const \e robot_state and updates its link transforms if needed. */ void checkCollision(const collision_detection::CollisionRequest& req, collision_detection::CollisionResult& res, moveit::core::RobotState& robot_state, - const collision_detection::AllowedCollisionMatrix& acm) const - { - robot_state.updateCollisionBodyTransforms(); - checkCollision(req, res, static_cast(robot_state), acm); - } + const collision_detection::AllowedCollisionMatrix& acm) const; /** \brief Check whether a specified state (\e robot_state) is in collision, with respect to a given allowed collision matrix (\e acm). */ void checkCollision(const collision_detection::CollisionRequest& req, collision_detection::CollisionResult& res, const moveit::core::RobotState& robot_state, - const collision_detection::AllowedCollisionMatrix& acm) const; + const collision_detection::AllowedCollisionMatrix& acm, bool validate_transforms = true) const; /** \brief Check whether the current state is in collision, but use a collision_detection::CollisionRobot instance that has no padding. Since the function is non-const, the current state transforms are also updated if needed. */ - void checkCollisionUnpadded(const collision_detection::CollisionRequest& req, - collision_detection::CollisionResult& res); + [[deprecated("Use new CollisionRequest flags to enable/ disable padding instead.")]] void + checkCollisionUnpadded(const collision_detection::CollisionRequest& req, collision_detection::CollisionResult& res); /** \brief Check whether the current state is in collision, but use a collision_detection::CollisionRobot instance that has no padding. */ - void checkCollisionUnpadded(const collision_detection::CollisionRequest& req, - collision_detection::CollisionResult& res) const - { - checkCollisionUnpadded(req, res, getCurrentState(), getAllowedCollisionMatrix()); - } + [[deprecated("Use new CollisionRequest flags to enable/ disable padding instead.")]] void + checkCollisionUnpadded(const collision_detection::CollisionRequest& req, + collision_detection::CollisionResult& res) const; /** \brief Check whether a specified state (\e robot_state) is in collision, but use a collision_detection::CollisionRobot instance that has no padding. */ - void checkCollisionUnpadded(const collision_detection::CollisionRequest& req, - collision_detection::CollisionResult& res, - const moveit::core::RobotState& robot_state) const - { - checkCollisionUnpadded(req, res, robot_state, getAllowedCollisionMatrix()); - } + [[deprecated("Use new CollisionRequest flags to enable/ disable padding instead.")]] void + checkCollisionUnpadded(const collision_detection::CollisionRequest& req, collision_detection::CollisionResult& res, + const moveit::core::RobotState& robot_state) const; /** \brief Check whether a specified state (\e robot_state) is in collision, but use a collision_detection::CollisionRobot instance that has no padding. Update the link transforms of \e robot_state if needed. */ - void checkCollisionUnpadded(const collision_detection::CollisionRequest& req, - collision_detection::CollisionResult& res, moveit::core::RobotState& robot_state) const - { - robot_state.updateCollisionBodyTransforms(); - checkCollisionUnpadded(req, res, static_cast(robot_state), - getAllowedCollisionMatrix()); - } + [[deprecated("Use new CollisionRequest flags to enable/ disable padding instead.")]] void + checkCollisionUnpadded(const collision_detection::CollisionRequest& req, collision_detection::CollisionResult& res, + moveit::core::RobotState& robot_state) const; /** \brief Check whether a specified state (\e robot_state) is in collision, with respect to a given allowed collision matrix (\e acm), but use a collision_detection::CollisionRobot instance that has no padding. This variant of the function takes a non-const \e robot_state and calls updates the link transforms if needed. */ - void checkCollisionUnpadded(const collision_detection::CollisionRequest& req, - collision_detection::CollisionResult& res, moveit::core::RobotState& robot_state, - const collision_detection::AllowedCollisionMatrix& acm) const - { - robot_state.updateCollisionBodyTransforms(); - checkCollisionUnpadded(req, res, static_cast(robot_state), acm); - } + [[deprecated("Use new CollisionRequest flags to enable/ disable padding instead.")]] void + checkCollisionUnpadded(const collision_detection::CollisionRequest& req, collision_detection::CollisionResult& res, + moveit::core::RobotState& robot_state, + const collision_detection::AllowedCollisionMatrix& acm) const; /** \brief Check whether a specified state (\e robot_state) is in collision, with respect to a given allowed collision matrix (\e acm), but use a collision_detection::CollisionRobot instance that has no padding. */ - void checkCollisionUnpadded(const collision_detection::CollisionRequest& req, - collision_detection::CollisionResult& res, const moveit::core::RobotState& robot_state, - const collision_detection::AllowedCollisionMatrix& acm) const; + [[deprecated("Use new CollisionRequest flags to enable/ disable padding instead.")]] void + checkCollisionUnpadded(const collision_detection::CollisionRequest& req, collision_detection::CollisionResult& res, + const moveit::core::RobotState& robot_state, + const collision_detection::AllowedCollisionMatrix& acm) const; /** \brief Check whether the current state is in self collision */ void checkSelfCollision(const collision_detection::CollisionRequest& req, collision_detection::CollisionResult& res); /** \brief Check whether the current state is in self collision */ void checkSelfCollision(const collision_detection::CollisionRequest& req, - collision_detection::CollisionResult& res) const - { - checkSelfCollision(req, res, getCurrentState()); - } + collision_detection::CollisionResult& res) const; /** \brief Check whether a specified state (\e robot_state) is in self collision */ void checkSelfCollision(const collision_detection::CollisionRequest& req, collision_detection::CollisionResult& res, - moveit::core::RobotState& robot_state) const - { - robot_state.updateCollisionBodyTransforms(); - checkSelfCollision(req, res, static_cast(robot_state), getAllowedCollisionMatrix()); - } + moveit::core::RobotState& robot_state) const; /** \brief Check whether a specified state (\e robot_state) is in self collision */ void checkSelfCollision(const collision_detection::CollisionRequest& req, collision_detection::CollisionResult& res, - const moveit::core::RobotState& robot_state) const - { - // do self-collision checking with the unpadded version of the robot - getCollisionEnvUnpadded()->checkSelfCollision(req, res, robot_state, getAllowedCollisionMatrix()); - } + const moveit::core::RobotState& robot_state) const; /** \brief Check whether a specified state (\e robot_state) is in self collision, with respect to a given allowed collision matrix (\e acm). The link transforms of \e robot_state are updated if needed. */ void checkSelfCollision(const collision_detection::CollisionRequest& req, collision_detection::CollisionResult& res, moveit::core::RobotState& robot_state, - const collision_detection::AllowedCollisionMatrix& acm) const - { - robot_state.updateCollisionBodyTransforms(); - checkSelfCollision(req, res, static_cast(robot_state), acm); - } + const collision_detection::AllowedCollisionMatrix& acm) const; /** \brief Check whether a specified state (\e robot_state) is in self collision, with respect to a given allowed collision matrix (\e acm) */ void checkSelfCollision(const collision_detection::CollisionRequest& req, collision_detection::CollisionResult& res, const moveit::core::RobotState& robot_state, - const collision_detection::AllowedCollisionMatrix& acm) const - { - // do self-collision checking with the unpadded version of the robot - getCollisionEnvUnpadded()->checkSelfCollision(req, res, robot_state, acm); - } + const collision_detection::AllowedCollisionMatrix& acm) const; /** \brief Get the names of the links that are involved in collisions for the current state */ void getCollidingLinks(std::vector& links); diff --git a/moveit_core/planning_scene/src/planning_scene.cpp b/moveit_core/planning_scene/src/planning_scene.cpp index 8655117fb8..1015d50cbf 100644 --- a/moveit_core/planning_scene/src/planning_scene.cpp +++ b/moveit_core/planning_scene/src/planning_scene.cpp @@ -394,14 +394,20 @@ void PlanningScene::pushDiffs(const PlanningScenePtr& scene) void PlanningScene::checkCollision(const collision_detection::CollisionRequest& req, collision_detection::CollisionResult& res) { - if (getCurrentState().dirtyCollisionBodyTransforms()) - { - checkCollision(req, res, getCurrentStateNonConst()); - } - else - { - checkCollision(req, res, getCurrentState()); - } + checkCollision(req, res, getCurrentStateNonConst()); +} + +void PlanningScene::checkCollision(const collision_detection::CollisionRequest& req, + collision_detection::CollisionResult& res) const +{ + checkCollision(req, res, getCurrentState(), getAllowedCollisionMatrix()); +} + +void PlanningScene::checkCollision(const collision_detection::CollisionRequest& req, + collision_detection::CollisionResult& res, + moveit::core::RobotState& robot_state) const +{ + checkCollision(req, res, robot_state, getAllowedCollisionMatrix()); } void PlanningScene::checkCollision(const collision_detection::CollisionRequest& req, @@ -411,43 +417,86 @@ void PlanningScene::checkCollision(const collision_detection::CollisionRequest& checkCollision(req, res, robot_state, getAllowedCollisionMatrix()); } -void PlanningScene::checkSelfCollision(const collision_detection::CollisionRequest& req, - collision_detection::CollisionResult& res) +void PlanningScene::checkCollision(const collision_detection::CollisionRequest& req, + collision_detection::CollisionResult& res, moveit::core::RobotState& robot_state, + const collision_detection::AllowedCollisionMatrix& acm) const { - if (getCurrentState().dirtyCollisionBodyTransforms()) + if (robot_state.dirtyCollisionBodyTransforms()) { - checkSelfCollision(req, res, getCurrentStateNonConst()); - } - else - { - checkSelfCollision(req, res, getCurrentState()); + robot_state.updateCollisionBodyTransforms(); } + checkCollision(req, res, robot_state, acm); } void PlanningScene::checkCollision(const collision_detection::CollisionRequest& req, collision_detection::CollisionResult& res, const moveit::core::RobotState& robot_state, - const collision_detection::AllowedCollisionMatrix& acm) const + const collision_detection::AllowedCollisionMatrix& acm, + bool validate_transforms) const { + if (validate_transforms && robot_state.dirtyCollisionBodyTransforms()) + { + RCLCPP_WARN(getLogger(), "Robot state has dirty collision body transforms. Please update the collision body " + "transforms before checking collision."); + } // check collision with the world using the padded version - getCollisionEnv()->checkRobotCollision(req, res, robot_state, acm); + req.use_padded_collision_environment ? getCollisionEnv()->checkRobotCollision(req, res, robot_state, acm) : + getCollisionEnvUnpadded()->checkRobotCollision(req, res, robot_state, acm); + + // Return early if a collision was found or the maximum number of allowed contacts is exceeded + if (res.collision || (req.contacts && res.contacts.size() >= req.max_contacts)) + { + return; + } // do self-collision checking with the unpadded version of the robot - if (!res.collision || (req.contacts && res.contacts.size() < req.max_contacts)) - getCollisionEnvUnpadded()->checkSelfCollision(req, res, robot_state, acm); + req.use_padded_self_collision ? getCollisionEnv()->checkSelfCollision(req, res, robot_state, acm) : + getCollisionEnvUnpadded()->checkSelfCollision(req, res, robot_state, acm); } void PlanningScene::checkCollisionUnpadded(const collision_detection::CollisionRequest& req, collision_detection::CollisionResult& res) { - if (getCurrentState().dirtyCollisionBodyTransforms()) - { - checkCollisionUnpadded(req, res, getCurrentStateNonConst(), getAllowedCollisionMatrix()); - } - else - { - checkCollisionUnpadded(req, res, getCurrentState(), getAllowedCollisionMatrix()); - } + collision_detection::CollisionRequest new_req = req; + new_req.use_padded_collision_environment = false; + checkCollision(req, res, getCurrentStateNonConst(), getAllowedCollisionMatrix()); +} + +void PlanningScene::checkCollisionUnpadded(const collision_detection::CollisionRequest& req, + collision_detection::CollisionResult& res) const +{ + collision_detection::CollisionRequest new_req = req; + new_req.use_padded_collision_environment = false; + checkCollision(new_req, res, getCurrentState(), getAllowedCollisionMatrix()); +} + +void PlanningScene::checkCollisionUnpadded(const collision_detection::CollisionRequest& req, + collision_detection::CollisionResult& res, + const moveit::core::RobotState& robot_state) const +{ + collision_detection::CollisionRequest new_req = req; + new_req.use_padded_collision_environment = false; + checkCollision(new_req, res, robot_state, getAllowedCollisionMatrix()); +} + +void PlanningScene::checkCollisionUnpadded(const collision_detection::CollisionRequest& req, + collision_detection::CollisionResult& res, + moveit::core::RobotState& robot_state) const +{ + collision_detection::CollisionRequest new_req = req; + new_req.use_padded_collision_environment = false; + checkCollision(new_req, res, static_cast(robot_state), getAllowedCollisionMatrix()); +} + +void PlanningScene::checkCollisionUnpadded(const collision_detection::CollisionRequest& req, + collision_detection::CollisionResult& res, + moveit::core::RobotState& robot_state, + const collision_detection::AllowedCollisionMatrix& acm) const +{ + robot_state.updateCollisionBodyTransforms(); + collision_detection::CollisionRequest new_req = req; + new_req.use_padded_collision_environment = false; + checkCollision(new_req, res, static_cast(robot_state), acm); } void PlanningScene::checkCollisionUnpadded(const collision_detection::CollisionRequest& req, @@ -455,14 +504,60 @@ void PlanningScene::checkCollisionUnpadded(const collision_detection::CollisionR const moveit::core::RobotState& robot_state, const collision_detection::AllowedCollisionMatrix& acm) const { - // check collision with the world using the unpadded version - getCollisionEnvUnpadded()->checkRobotCollision(req, res, robot_state, acm); + collision_detection::CollisionRequest new_req = req; + new_req.use_padded_collision_environment = false; + checkCollision(req, res, robot_state, acm); +} - // do self-collision checking with the unpadded version of the robot - if (!res.collision || (req.contacts && res.contacts.size() < req.max_contacts)) +void PlanningScene::checkSelfCollision(const collision_detection::CollisionRequest& req, + collision_detection::CollisionResult& res) +{ + checkSelfCollision(req, res, getCurrentStateNonConst()); +} + +/** \brief Check whether the current state is in self collision */ +void PlanningScene::checkSelfCollision(const collision_detection::CollisionRequest& req, + collision_detection::CollisionResult& res) const +{ + checkSelfCollision(req, res, getCurrentState()); +} + +void PlanningScene::checkSelfCollision(const collision_detection::CollisionRequest& req, + collision_detection::CollisionResult& res, + moveit::core::RobotState& robot_state) const +{ + if (robot_state.dirtyCollisionBodyTransforms()) { - getCollisionEnvUnpadded()->checkSelfCollision(req, res, robot_state, acm); + robot_state.updateCollisionBodyTransforms(); } + checkSelfCollision(req, res, static_cast(robot_state), getAllowedCollisionMatrix()); +} + +void PlanningScene::checkSelfCollision(const collision_detection::CollisionRequest& req, + collision_detection::CollisionResult& res, + const moveit::core::RobotState& robot_state) const +{ + checkSelfCollision(req, res, robot_state, getAllowedCollisionMatrix()); +} + +void PlanningScene::checkSelfCollision(const collision_detection::CollisionRequest& req, + collision_detection::CollisionResult& res, moveit::core::RobotState& robot_state, + const collision_detection::AllowedCollisionMatrix& acm) const +{ + if (robot_state.dirtyCollisionBodyTransforms()) + { + robot_state.updateCollisionBodyTransforms(); + } + checkSelfCollision(req, res, static_cast(robot_state), acm); +} + +void PlanningScene::checkSelfCollision(const collision_detection::CollisionRequest& req, + collision_detection::CollisionResult& res, + const moveit::core::RobotState& robot_state, + const collision_detection::AllowedCollisionMatrix& acm) const +{ + req.use_padded_self_collision ? getCollisionEnv()->checkSelfCollision(req, res, robot_state, acm) : + getCollisionEnvUnpadded()->checkSelfCollision(req, res, robot_state, acm); } void PlanningScene::getCollidingPairs(collision_detection::CollisionResult::ContactMap& contacts) diff --git a/moveit_ros/benchmarks/src/BenchmarkExecutor.cpp b/moveit_ros/benchmarks/src/BenchmarkExecutor.cpp index 252d2a98d6..be47a121a7 100644 --- a/moveit_ros/benchmarks/src/BenchmarkExecutor.cpp +++ b/moveit_ros/benchmarks/src/BenchmarkExecutor.cpp @@ -1010,10 +1010,11 @@ void BenchmarkExecutor::collectMetrics(PlannerRunData& metrics, // compute correctness and clearance collision_detection::CollisionRequest req; + req.use_padded_collision_environment = false; for (std::size_t k = 0; k < p.getWayPointCount(); ++k) { collision_detection::CollisionResult res; - planning_scene_->checkCollisionUnpadded(req, res, p.getWayPoint(k)); + planning_scene_->checkCollision(req, res, p.getWayPoint(k)); if (res.collision) correct = false; if (!p.getWayPoint(k).satisfiesBounds()) diff --git a/moveit_ros/planning/plan_execution/src/plan_execution.cpp b/moveit_ros/planning/plan_execution/src/plan_execution.cpp index 6e0452f410..7c51894a0f 100644 --- a/moveit_ros/planning/plan_execution/src/plan_execution.cpp +++ b/moveit_ros/planning/plan_execution/src/plan_execution.cpp @@ -282,16 +282,17 @@ bool plan_execution::PlanExecution::isRemainingPathValid(const ExecutableMotionP std::size_t wpc = t.getWayPointCount(); collision_detection::CollisionRequest req; req.group_name = t.getGroupName(); + req.use_padded_collision_environment = false; for (std::size_t i = std::max(path_segment.second - 1, 0); i < wpc; ++i) { collision_detection::CollisionResult res; if (acm) { - plan.planning_scene->checkCollisionUnpadded(req, res, t.getWayPoint(i), *acm); + plan.planning_scene->checkCollision(req, res, t.getWayPoint(i), *acm); } else { - plan.planning_scene->checkCollisionUnpadded(req, res, t.getWayPoint(i)); + plan.planning_scene->checkCollision(req, res, t.getWayPoint(i)); } if (res.collision || !plan.planning_scene->isStateFeasible(t.getWayPoint(i), false)) @@ -306,11 +307,11 @@ bool plan_execution::PlanExecution::isRemainingPathValid(const ExecutableMotionP res.clear(); if (acm) { - plan.planning_scene->checkCollisionUnpadded(req, res, t.getWayPoint(i), *acm); + plan.planning_scene->checkCollision(req, res, t.getWayPoint(i), *acm); } else { - plan.planning_scene->checkCollisionUnpadded(req, res, t.getWayPoint(i)); + plan.planning_scene->checkCollision(req, res, t.getWayPoint(i)); } return false; }