37#include <boost/algorithm/string.hpp>
41#include <geometric_shapes/shape_operations.h>
48#include <octomap_msgs/conversions.h>
49#include <rclcpp/logger.hpp>
50#include <rclcpp/logging.hpp>
51#include <tf2_eigen/tf2_eigen.hpp>
76void poseMsgToEigen(
const geometry_msgs::msg::Pose& msg, Eigen::Isometry3d& out)
78 Eigen::Translation3d translation(msg.position.x, msg.position.y, msg.position.z);
79 Eigen::Quaterniond quaternion(msg.orientation.w, msg.orientation.x, msg.orientation.y, msg.orientation.z);
80 quaternion.normalize();
81 out = translation * quaternion;
87 double x, y, z, rx, ry, rz, rw;
88 if (!(in >> x >> y >> z))
90 RCLCPP_ERROR(getLogger(),
"Improperly formatted translation in scene geometry file");
93 if (!(in >> rx >> ry >> rz >> rw))
95 RCLCPP_ERROR(getLogger(),
"Improperly formatted rotation in scene geometry file");
98 pose = Eigen::Translation3d(x, y, z) * Eigen::Quaterniond(rw, rx, ry, rz);
105 out << pose.translation().x() <<
' ' << pose.translation().y() <<
' ' << pose.translation().z() <<
'\n';
106 Eigen::Quaterniond r(pose.linear());
107 out << r.x() <<
' ' << r.y() <<
' ' << r.z() <<
' ' << r.w() <<
'\n';
127 if (Transforms::isFixedFrame(frame))
131 return knowsObjectFrame(frame.substr(1));
135 return knowsObjectFrame(frame);
139 const Eigen::Isometry3d&
getTransform(
const std::string& from_frame)
const override
146 bool knowsObjectFrame(
const std::string& frame_id)
const
148 return scene_->
getWorld()->knowsTransform(frame_id);
151 const PlanningScene* scene_;
155 const collision_detection::WorldPtr& world)
157 : robot_model_(robot_model), world_(world), world_const_(world)
163 const srdf::ModelConstSharedPtr& srdf_model,
const collision_detection::WorldPtr& world)
164 : world_(world), world_const_(world)
172 robot_model_ = std::make_shared<moveit::core::RobotModel>(urdf_model, srdf_model);
173 if (!robot_model_ || !robot_model_->getRootJoint())
175 robot_model_ =
nullptr;
184 if (current_world_object_update_callback_)
185 world_->removeObserver(current_world_object_update_observer_handle_);
188void PlanningScene::initialize()
192 scene_transforms_.emplace(std::make_shared<SceneTransforms>(
this));
195 robot_state_.value().setToDefaultValues();
196 robot_state_.value().update();
208 if (!parent_->getName().empty())
209 name_ = parent_->getName() +
"+";
211 robot_model_ = parent_->robot_model_;
218 world_ = std::make_shared<collision_detection::World>(*parent_->world_);
219 world_const_ = world_;
223 world_diff_ = std::make_shared<collision_detection::WorldDiff>(world_);
226 collision_detector_->copyPadding(*parent_->collision_detector_);
231 PlanningScenePtr result = scene->diff();
232 result->decoupleParent();
233 result->setName(scene->getName());
239 return PlanningScenePtr(
new PlanningScene(shared_from_this()));
244 PlanningScenePtr result =
diff();
245 result->setPlanningSceneDiffMsg(msg);
249void PlanningScene::CollisionDetector::copyPadding(
const PlanningScene::CollisionDetector& src)
251 cenv_->setLinkPadding(src.getCollisionEnv()->getLinkPadding());
252 cenv_->setLinkScale(src.getCollisionEnv()->getLinkScale());
256 const CollisionDetectorPtr& parent_detector)
259 CollisionDetectorPtr prev_coll_detector = collision_detector_;
262 collision_detector_ = std::make_shared<CollisionDetector>();
263 collision_detector_->alloc_ = allocator;
269 collision_detector_->cenv_ = collision_detector_->alloc_->allocateEnv(parent_detector->cenv_, world_);
270 collision_detector_->cenv_unpadded_ =
271 collision_detector_->alloc_->allocateEnv(parent_detector->cenv_unpadded_, world_);
275 collision_detector_->cenv_ = collision_detector_->alloc_->allocateEnv(world_,
getRobotModel());
276 collision_detector_->cenv_unpadded_ = collision_detector_->alloc_->allocateEnv(world_,
getRobotModel());
279 if (prev_coll_detector)
280 collision_detector_->copyPadding(*prev_coll_detector);
284 collision_detector_->cenv_const_ = collision_detector_->cenv_;
285 collision_detector_->cenv_unpadded_const_ = collision_detector_->cenv_unpadded_;
288const collision_detection::CollisionEnvConstPtr&
293 RCLCPP_ERROR(getLogger(),
"Could not get CollisionRobot named '%s'. Returning active CollisionRobot '%s' instead",
294 collision_detector_name.c_str(), collision_detector_->alloc_->getName().c_str());
295 return collision_detector_->getCollisionEnv();
298 return collision_detector_->getCollisionEnv();
301const collision_detection::CollisionEnvConstPtr&
306 RCLCPP_ERROR(getLogger(),
307 "Could not get CollisionRobotUnpadded named '%s'. "
308 "Returning active CollisionRobotUnpadded '%s' instead",
309 collision_detector_name.c_str(), collision_detector_->alloc_->getName().c_str());
310 return collision_detector_->getCollisionEnvUnpadded();
313 return collision_detector_->getCollisionEnvUnpadded();
322 world_ = std::make_shared<collision_detection::World>(*parent_->world_);
323 world_const_ = world_;
324 world_diff_ = std::make_shared<collision_detection::WorldDiff>(world_);
325 if (current_world_object_update_callback_)
326 current_world_object_update_observer_handle_ = world_->addObserver(current_world_object_update_callback_);
331 scene_transforms_.reset();
332 robot_state_.reset();
334 object_colors_.reset();
335 object_types_.reset();
343 if (scene_transforms_.has_value())
344 scene->getTransformsNonConst().setAllTransforms(scene_transforms_.value()->getAllTransforms());
346 if (robot_state_.has_value())
348 scene->getCurrentStateNonConst() = robot_state_.value();
350 std::vector<const moveit::core::AttachedBody*> attached_objs;
351 robot_state_.value().getAttachedBodies(attached_objs);
355 scene->setObjectType(attached_obj->getName(),
getObjectType(attached_obj->getName()));
357 scene->setObjectColor(attached_obj->getName(),
getObjectColor(attached_obj->getName()));
361 if (acm_.has_value())
362 scene->getAllowedCollisionMatrixNonConst() = acm_.value();
364 collision_detection::CollisionEnvPtr active_cenv = scene->getCollisionEnvNonConst();
365 active_cenv->setLinkPadding(collision_detector_->cenv_->getLinkPadding());
366 active_cenv->setLinkScale(collision_detector_->cenv_->getLinkScale());
370 for (
const std::pair<const std::string, collision_detection::World::Action>& it : *world_diff_)
374 scene->world_->removeObject(it.first);
375 scene->removeObjectColor(it.first);
376 scene->removeObjectType(it.first);
378 if (!scene->getCurrentState().hasAttachedBody(it.first))
380 scene->getAllowedCollisionMatrixNonConst().removeEntry(it.first);
386 scene->world_->removeObject(obj.
id_);
577 const std::string& group_name)
const
607 for (collision_detection::CollisionResult::ContactMap::const_iterator it = contacts.begin(); it != contacts.end();
613 links.push_back(contact.body_name_1);
615 links.push_back(contact.body_name_2);
622 return collision_detector_->cenv_;
627 if (!robot_state_.has_value())
630 robot_state_.value().setAttachedBodyUpdateCallback(current_state_attached_body_callback_);
632 robot_state_.value().update();
633 return robot_state_.value();
638 auto state = std::make_shared<moveit::core::RobotState>(
getCurrentState());
645 current_state_attached_body_callback_ = callback;
646 if (robot_state_.has_value())
647 robot_state_.value().setAttachedBodyUpdateCallback(callback);
652 if (current_world_object_update_callback_)
653 world_->removeObserver(current_world_object_update_observer_handle_);
655 current_world_object_update_observer_handle_ = world_->addObserver(callback);
656 current_world_object_update_callback_ = callback;
661 if (!acm_.has_value())
682 if (!scene_transforms_.has_value())
686 scene_transforms_.emplace(std::make_shared<SceneTransforms>(
this));
687 scene_transforms_.value()->setAllTransforms(parent_->getTransforms().getAllTransforms());
689 return *scene_transforms_.value();
694 scene_msg.name = name_;
696 scene_msg.is_diff =
true;
698 if (scene_transforms_.has_value())
700 scene_transforms_.value()->copyTransforms(scene_msg.fixed_frame_transforms);
704 scene_msg.fixed_frame_transforms.clear();
707 if (robot_state_.has_value())
713 scene_msg.robot_state = moveit_msgs::msg::RobotState();
715 scene_msg.robot_state.is_diff =
true;
717 if (acm_.has_value())
719 acm_.value().getMessage(scene_msg.allowed_collision_matrix);
723 scene_msg.allowed_collision_matrix = moveit_msgs::msg::AllowedCollisionMatrix();
726 collision_detector_->cenv_->getPadding(scene_msg.link_padding);
727 collision_detector_->cenv_->getScale(scene_msg.link_scale);
729 scene_msg.object_colors.clear();
733 scene_msg.object_colors.resize(object_colors_->size());
734 for (ObjectColorMap::const_iterator it = object_colors_->begin(); it != object_colors_->end(); ++it, ++i)
736 scene_msg.object_colors[i].id = it->first;
737 scene_msg.object_colors[i].color = it->second;
741 scene_msg.world.collision_objects.clear();
742 scene_msg.world.octomap = octomap_msgs::msg::OctomapWithPose();
746 bool do_omap =
false;
747 for (
const std::pair<const std::string, collision_detection::World::Action>& it : *world_diff_)
753 scene_msg.world.octomap.octomap.id =
"cleared";
763 if (!std::count_if(scene_msg.robot_state.attached_collision_objects.cbegin(),
764 scene_msg.robot_state.attached_collision_objects.cend(),
765 [&it](
const moveit_msgs::msg::AttachedCollisionObject& aco) {
766 return aco.object.id == it.first &&
767 aco.object.operation == moveit_msgs::msg::CollisionObject::ADD;
770 moveit_msgs::msg::CollisionObject co;
773 co.operation = moveit_msgs::msg::CollisionObject::REMOVE;
774 scene_msg.world.collision_objects.push_back(co);
779 scene_msg.world.collision_objects.emplace_back();
790 for (
const auto& collision_object : scene_msg.world.collision_objects)
792 if (parent_ && parent_->getCurrentState().hasAttachedBody(collision_object.id))
794 moveit_msgs::msg::AttachedCollisionObject aco;
795 aco.object.id = collision_object.id;
796 aco.object.operation = moveit_msgs::msg::CollisionObject::REMOVE;
797 scene_msg.robot_state.attached_collision_objects.push_back(aco);
804class ShapeVisitorAddToCollisionObject :
public boost::static_visitor<void>
807 ShapeVisitorAddToCollisionObject(moveit_msgs::msg::CollisionObject* obj) : boost::static_visitor<void>(), obj_(obj)
811 void setPoseMessage(
const geometry_msgs::msg::Pose* pose)
816 void operator()(
const shape_msgs::msg::Plane& shape_msg)
const
818 obj_->planes.push_back(shape_msg);
819 obj_->plane_poses.push_back(*pose_);
822 void operator()(
const shape_msgs::msg::Mesh& shape_msg)
const
824 obj_->meshes.push_back(shape_msg);
825 obj_->mesh_poses.push_back(*pose_);
828 void operator()(
const shape_msgs::msg::SolidPrimitive& shape_msg)
const
830 obj_->primitives.push_back(shape_msg);
831 obj_->primitive_poses.push_back(*pose_);
835 moveit_msgs::msg::CollisionObject* obj_;
836 const geometry_msgs::msg::Pose* pose_;
846 collision_obj.pose = tf2::toMsg(obj->pose_);
847 collision_obj.id = ns;
848 collision_obj.operation = moveit_msgs::msg::CollisionObject::ADD;
850 ShapeVisitorAddToCollisionObject sv(&collision_obj);
851 for (std::size_t j = 0; j < obj->shapes_.size(); ++j)
854 if (constructMsgFromShape(obj->shapes_[j].get(), sm))
856 geometry_msgs::msg::Pose p = tf2::toMsg(obj->shape_poses_[j]);
857 sv.setPoseMessage(&p);
858 boost::apply_visitor(sv, sm);
862 if (!collision_obj.primitives.empty() || !collision_obj.meshes.empty() || !collision_obj.planes.empty())
867 for (
const auto& frame_pair : obj->subframe_poses_)
869 collision_obj.subframe_names.push_back(frame_pair.first);
870 geometry_msgs::msg::Pose p;
871 p = tf2::toMsg(frame_pair.second);
872 collision_obj.subframe_poses.push_back(p);
880 collision_objs.clear();
881 const std::vector<std::string>& ids = world_->getObjectIds();
882 for (
const std::string&
id : ids)
886 collision_objs.emplace_back();
893 const std::string& ns)
const
895 std::vector<moveit_msgs::msg::AttachedCollisionObject> attached_collision_objs;
897 for (moveit_msgs::msg::AttachedCollisionObject& it : attached_collision_objs)
899 if (it.object.id == ns)
901 attached_collision_obj = it;
909 std::vector<moveit_msgs::msg::AttachedCollisionObject>& attached_collision_objs)
const
911 std::vector<const moveit::core::AttachedBody*> attached_bodies;
913 attachedBodiesToAttachedCollisionObjectMsgs(attached_bodies, attached_collision_objs);
919 octomap.octomap = octomap_msgs::msg::Octomap();
924 if (map->shapes_.size() == 1)
926 const shapes::OcTree* o =
static_cast<const shapes::OcTree*
>(map->shapes_[0].get());
927 octomap_msgs::fullMapToMsg(*o->octree,
octomap.octomap);
928 octomap.origin = tf2::toMsg(map->shape_poses_[0]);
931 RCLCPP_ERROR(getLogger(),
"Unexpected number of shapes in octomap collision object. Not including '%s' object",
939 object_colors.clear();
944 object_colors.resize(cmap.size());
945 for (ObjectColorMap::const_iterator it = cmap.begin(); it != cmap.end(); ++it, ++i)
947 object_colors[i].id = it->first;
948 object_colors[i].color = it->second;
954 scene_msg.name = name_;
955 scene_msg.is_diff =
false;
974 const moveit_msgs::msg::PlanningSceneComponents& comp)
const
976 scene_msg.is_diff =
false;
977 if (comp.components & moveit_msgs::msg::PlanningSceneComponents::SCENE_SETTINGS)
979 scene_msg.name = name_;
983 if (comp.components & moveit_msgs::msg::PlanningSceneComponents::TRANSFORMS)
986 if (comp.components & moveit_msgs::msg::PlanningSceneComponents::ROBOT_STATE_ATTACHED_OBJECTS)
989 for (moveit_msgs::msg::AttachedCollisionObject& attached_collision_object :
990 scene_msg.robot_state.attached_collision_objects)
994 attached_collision_object.object.type =
getObjectType(attached_collision_object.object.id);
998 else if (comp.components & moveit_msgs::msg::PlanningSceneComponents::ROBOT_STATE)
1003 if (comp.components & moveit_msgs::msg::PlanningSceneComponents::ALLOWED_COLLISION_MATRIX)
1006 if (comp.components & moveit_msgs::msg::PlanningSceneComponents::LINK_PADDING_AND_SCALING)
1012 if (comp.components & moveit_msgs::msg::PlanningSceneComponents::OBJECT_COLORS)
1016 if (comp.components & moveit_msgs::msg::PlanningSceneComponents::WORLD_OBJECT_GEOMETRY)
1020 else if (comp.components & moveit_msgs::msg::PlanningSceneComponents::WORLD_OBJECT_NAMES)
1022 const std::vector<std::string>& ids = world_->getObjectIds();
1023 scene_msg.world.collision_objects.clear();
1024 scene_msg.world.collision_objects.reserve(ids.size());
1025 for (
const std::string&
id : ids)
1029 moveit_msgs::msg::CollisionObject co;
1033 scene_msg.world.collision_objects.push_back(co);
1039 if (comp.components & moveit_msgs::msg::PlanningSceneComponents::OCTOMAP)
1045 out << name_ <<
'\n';
1046 const std::vector<std::string>& ids = world_->getObjectIds();
1047 for (
const std::string&
id : ids)
1054 out <<
"* " <<
id <<
'\n';
1059 out << obj->shapes_.size() <<
'\n';
1060 for (std::size_t j = 0; j < obj->shapes_.size(); ++j)
1062 shapes::saveAsText(obj->shapes_[j].get(), out);
1068 out << c.r <<
' ' << c.g <<
' ' << c.b <<
' ' << c.a <<
'\n';
1071 out <<
"0 0 0 0" <<
'\n';
1075 out << obj->subframe_poses_.size() <<
'\n';
1076 for (
auto& pose_pair : obj->subframe_poses_)
1078 out << pose_pair.first <<
'\n';
1094 if (!in.good() || in.eof())
1096 RCLCPP_ERROR(getLogger(),
"Bad input stream when loading scene geometry");
1100 std::getline(in, name_);
1103 auto pos = in.tellg();
1107 std::getline(in, line);
1108 }
while (in.good() && !in.eof() && (line.empty() || line[0] !=
'*'));
1109 std::getline(in, line);
1110 boost::algorithm::trim(line);
1113 bool uses_new_scene_format = line.find(
' ') != std::string::npos;
1116 Eigen::Isometry3d pose;
1121 if (!in.good() || in.eof())
1123 RCLCPP_ERROR(getLogger(),
"Bad input stream when loading marker in scene geometry");
1128 std::string object_id;
1129 std::getline(in, object_id);
1130 if (!in.good() || in.eof())
1132 RCLCPP_ERROR(getLogger(),
"Bad input stream when loading object_id in scene geometry");
1135 boost::algorithm::trim(object_id);
1141 RCLCPP_ERROR(getLogger(),
"Failed to read object pose from scene file");
1144 pose = offset * pose;
1145 world_->setObjectPose(object_id, pose);
1148 unsigned int shape_count;
1150 for (std::size_t i = 0; i < shape_count && in.good() && !in.eof(); ++i)
1152 const auto shape = shapes::ShapeConstPtr(shapes::constructShapeFromText(in));
1155 RCLCPP_ERROR(getLogger(),
"Failed to load shape from scene file");
1160 RCLCPP_ERROR(getLogger(),
"Failed to read pose from scene file");
1164 if (!(in >> r >> g >> b >> a))
1166 RCLCPP_ERROR(getLogger(),
"Improperly formatted color in scene geometry file");
1171 world_->addToObject(object_id, shape, pose);
1172 if (r > 0.0f || g > 0.0f || b > 0.0f || a > 0.0f)
1174 std_msgs::msg::ColorRGBA color;
1185 if (uses_new_scene_format)
1188 unsigned int subframe_count;
1189 in >> subframe_count;
1190 for (std::size_t i = 0; i < subframe_count && in.good() && !in.eof(); ++i)
1192 std::string subframe_name;
1193 in >> subframe_name;
1196 RCLCPP_ERROR(getLogger(),
"Failed to read subframe pose from scene file");
1199 subframes[subframe_name] = pose;
1201 world_->setSubframesOfObject(object_id, subframes);
1204 else if (marker ==
".")
1211 RCLCPP_ERROR(getLogger(),
"Unknown marker in scene geometry file: %s ", marker.c_str());
1221 moveit_msgs::msg::RobotState state_no_attached(state);
1222 state_no_attached.attached_collision_objects.clear();
1226 if (!robot_state_.has_value())
1229 robot_state_.value().setAttachedBodyUpdateCallback(current_state_attached_body_callback_);
1236 for (std::size_t i = 0; i < state.attached_collision_objects.size(); ++i)
1238 if (!state.is_diff && state.attached_collision_objects[i].object.operation != moveit_msgs::msg::CollisionObject::ADD)
1240 RCLCPP_ERROR(getLogger(),
1241 "The specified RobotState is not marked as is_diff. "
1242 "The request to modify the object '%s' is not supported. Object is ignored.",
1243 state.attached_collision_objects[i].object.id.c_str());
1261 if (!scene_transforms_.has_value())
1263 scene_transforms_.emplace(std::make_shared<SceneTransforms>(
this));
1264 scene_transforms_.value()->setAllTransforms(parent_->getTransforms().getAllTransforms());
1267 if (!robot_state_.has_value())
1270 robot_state_.value().setAttachedBodyUpdateCallback(current_state_attached_body_callback_);
1273 if (!acm_.has_value())
1276 world_diff_.reset();
1278 if (!object_colors_)
1281 parent_->getKnownObjectColors(kc);
1282 object_colors_ = std::make_unique<ObjectColorMap>(kc);
1287 parent_->getKnownObjectColors(kc);
1288 for (ObjectColorMap::const_iterator it = kc.begin(); it != kc.end(); ++it)
1290 if (object_colors_->find(it->first) == object_colors_->end())
1291 (*object_colors_)[it->first] = it->second;
1295 if (!object_types_.has_value())
1298 parent_->getKnownObjectTypes(kc);
1304 parent_->getKnownObjectTypes(kc);
1305 for (ObjectTypeMap::const_iterator it = kc.begin(); it != kc.end(); ++it)
1307 if (object_types_.value().find(it->first) == object_types_.value().end())
1308 (object_types_.value())[it->first] = it->second;
1318 RCLCPP_DEBUG(getLogger(),
"Adding planning scene diff");
1319 if (!scene_msg.name.empty())
1320 name_ = scene_msg.name;
1322 if (!scene_msg.robot_model_name.empty() && scene_msg.robot_model_name !=
getRobotModel()->
getName())
1324 RCLCPP_WARN(getLogger(),
"Setting the scene for model '%s' but model '%s' is loaded.",
1330 if (!scene_msg.fixed_frame_transforms.empty())
1332 if (!scene_transforms_.has_value())
1333 scene_transforms_.emplace(std::make_shared<SceneTransforms>(
this));
1334 scene_transforms_.value()->setTransforms(scene_msg.fixed_frame_transforms);
1338 if (!scene_msg.robot_state.multi_dof_joint_state.joint_names.empty() ||
1339 !scene_msg.robot_state.joint_state.name.empty() || !scene_msg.robot_state.attached_collision_objects.empty())
1343 if (!scene_msg.allowed_collision_matrix.entry_names.empty())
1346 if (!scene_msg.link_padding.empty() || !scene_msg.link_scale.empty())
1348 collision_detector_->cenv_->setPadding(scene_msg.link_padding);
1349 collision_detector_->cenv_->setScale(scene_msg.link_scale);
1353 for (
const moveit_msgs::msg::ObjectColor& object_color : scene_msg.object_colors)
1357 for (
const moveit_msgs::msg::CollisionObject& collision_object : scene_msg.world.collision_objects)
1361 if (!scene_msg.world.octomap.octomap.id.empty())
1369 assert(scene_msg.is_diff ==
false);
1370 RCLCPP_DEBUG(getLogger(),
"Setting new planning scene: '%s'", scene_msg.name.c_str());
1371 name_ = scene_msg.name;
1373 if (!scene_msg.robot_model_name.empty() && scene_msg.robot_model_name !=
getRobotModel()->
getName())
1375 RCLCPP_WARN(getLogger(),
"Setting the scene for model '%s' but model '%s' is loaded.",
1382 object_types_.reset();
1383 scene_transforms_.value()->setTransforms(scene_msg.fixed_frame_transforms);
1386 collision_detector_->cenv_->setPadding(scene_msg.link_padding);
1387 collision_detector_->cenv_->setScale(scene_msg.link_scale);
1388 object_colors_ = std::make_unique<ObjectColorMap>();
1389 original_object_colors_ = std::make_unique<ObjectColorMap>();
1390 for (
const moveit_msgs::msg::ObjectColor& object_color : scene_msg.object_colors)
1392 world_->clearObjects();
1399 for (
const moveit_msgs::msg::CollisionObject& collision_object : world.collision_objects)
1407 if (scene_msg.is_diff)
1419 std::shared_ptr<collision_detection::OccMapTree> om =
1420 std::make_shared<collision_detection::OccMapTree>(map.resolution);
1423 octomap_msgs::readTree(om.get(), map);
1427 std::stringstream datastream;
1428 if (!map.data.empty())
1430 datastream.write(
reinterpret_cast<const char*
>(&map.data[0]), map.data.size());
1431 om->readData(datastream);
1442 if (map.data.empty())
1445 if (map.id !=
"OcTree")
1447 RCLCPP_ERROR(getLogger(),
"Received octomap is of type '%s' but type 'OcTree' is expected.", map.id.c_str());
1451 std::shared_ptr<collision_detection::OccMapTree> om =
createOctomap(map);
1452 if (!map.header.frame_id.empty())
1455 world_->addToObject(
OCTOMAP_NS, std::make_shared<const shapes::OcTree>(om), t);
1459 world_->addToObject(
OCTOMAP_NS, std::make_shared<const shapes::OcTree>(om), Eigen::Isometry3d::Identity());
1465 const std::vector<std::string>& object_ids = world_->getObjectIds();
1466 for (
const std::string& object_id : object_ids)
1470 world_->removeObject(object_id);
1483 if (map.octomap.data.empty())
1486 if (map.octomap.id !=
"OcTree")
1488 RCLCPP_ERROR(getLogger(),
"Received octomap is of type '%s' but type 'OcTree' is expected.", map.octomap.id.c_str());
1492 std::shared_ptr<collision_detection::OccMapTree> om =
createOctomap(map.octomap);
1495 Eigen::Isometry3d p;
1498 world_->addToObject(
OCTOMAP_NS, std::make_shared<const shapes::OcTree>(om), p);
1506 if (map->shapes_.size() == 1)
1509 const shapes::OcTree* o =
static_cast<const shapes::OcTree*
>(map->shapes_[0].get());
1510 if (o->octree == octree)
1513 if (map->shape_poses_[0].isApprox(t, std::numeric_limits<double>::epsilon() * 100.0))
1523 shapes::ShapeConstPtr shape = map->shapes_[0];
1525 world_->moveShapeInObject(
OCTOMAP_NS, shape, t);
1533 world_->addToObject(
OCTOMAP_NS, std::make_shared<const shapes::OcTree>(octree), t);
1538 if (
object.
object.operation == moveit_msgs::msg::CollisionObject::ADD &&
1541 RCLCPP_ERROR(getLogger(),
"Unable to attach a body to link '%s' (link not found)",
object.link_name.c_str());
1547 RCLCPP_ERROR(getLogger(),
"The ID '%s' cannot be used for collision objects (name reserved)",
OCTOMAP_NS.c_str());
1551 if (!robot_state_.has_value())
1554 robot_state_.value().setAttachedBodyUpdateCallback(current_state_attached_body_callback_);
1556 robot_state_.value().update();
1563 if (
object.
object.operation == moveit_msgs::msg::CollisionObject::ADD ||
1564 object.
object.operation == moveit_msgs::msg::CollisionObject::APPEND)
1570 Eigen::Isometry3d object_pose_in_link;
1571 std::vector<shapes::ShapeConstPtr>
shapes;
1572 EigenSTL::vector_Isometry3d shape_poses;
1579 if (
object.
object.operation == moveit_msgs::msg::CollisionObject::ADD &&
object.
object.primitives.empty() &&
1580 object.object.meshes.empty() &&
object.object.planes.empty())
1584 RCLCPP_DEBUG(getLogger(),
"Attaching world object '%s' to link '%s'",
object.
object.
id.c_str(),
1585 object.link_name.c_str());
1587 object_pose_in_link = robot_state_.value().getGlobalLinkTransform(link_model).inverse() * obj_in_world->pose_;
1588 shapes = obj_in_world->shapes_;
1589 shape_poses = obj_in_world->shape_poses_;
1590 subframe_poses = obj_in_world->subframe_poses_;
1594 RCLCPP_ERROR(getLogger(),
1595 "Attempting to attach object '%s' to link '%s' but no geometry specified "
1596 "and such an object does not exist in the collision world",
1597 object.
object.
id.c_str(),
object.link_name.c_str());
1603 Eigen::Isometry3d header_frame_to_object_pose;
1606 const Eigen::Isometry3d world_to_header_frame =
getFrameTransform(
object.
object.header.frame_id);
1607 const Eigen::Isometry3d link_to_header_frame =
1608 robot_state_.value().getGlobalLinkTransform(link_model).inverse() * world_to_header_frame;
1609 object_pose_in_link = link_to_header_frame * header_frame_to_object_pose;
1611 Eigen::Isometry3d subframe_pose;
1612 for (std::size_t i = 0; i <
object.object.subframe_poses.size(); ++i)
1615 std::string name =
object.object.subframe_names[i];
1616 subframe_poses[name] = subframe_pose;
1622 RCLCPP_ERROR(getLogger(),
"There is no geometry to attach to link '%s' as part of attached body '%s'",
1623 object.link_name.c_str(),
object.object.id.c_str());
1627 if (!
object.
object.type.db.empty() || !
object.object.type.key.empty())
1631 if (obj_in_world && world_->removeObject(
object.object.id))
1633 if (
object.
object.operation == moveit_msgs::msg::CollisionObject::ADD)
1635 RCLCPP_DEBUG(getLogger(),
"Removing world object with the same name as newly attached object: '%s'",
1636 object.
object.
id.c_str());
1640 RCLCPP_WARN(getLogger(),
1641 "You tried to append geometry to an attached object "
1642 "that is actually a world object ('%s'). World geometry is ignored.",
1643 object.
object.
id.c_str());
1648 if (
object.
object.operation == moveit_msgs::msg::CollisionObject::ADD ||
1649 !robot_state_.value().hasAttachedBody(
object.object.id))
1651 if (robot_state_.value().clearAttachedBody(
object.object.id))
1653 RCLCPP_DEBUG(getLogger(),
1654 "The robot state already had an object named '%s' attached to link '%s'. "
1655 "The object was replaced.",
1656 object.
object.
id.c_str(),
object.link_name.c_str());
1658 robot_state_.value().attachBody(
object.
object.
id, object_pose_in_link,
shapes, shape_poses,
object.touch_links,
1659 object.link_name,
object.detach_posture, subframe_poses);
1660 RCLCPP_DEBUG(getLogger(),
"Attached object '%s' to link '%s'",
object.
object.
id.c_str(),
1661 object.link_name.c_str());
1669 object_pose_in_link = ab->
getPose();
1674 trajectory_msgs::msg::JointTrajectory detach_posture =
1675 object.detach_posture.joint_names.empty() ? ab->
getDetachPosture() :
object.detach_posture;
1678 touch_links.insert(std::make_move_iterator(
object.touch_links.begin()),
1679 std::make_move_iterator(
object.touch_links.end()));
1681 robot_state_.value().clearAttachedBody(
object.
object.
id);
1682 robot_state_.value().attachBody(
object.
object.
id, object_pose_in_link,
shapes, shape_poses, touch_links,
1683 object.link_name, detach_posture, subframe_poses);
1684 RCLCPP_DEBUG(getLogger(),
"Appended things to object '%s' attached to link '%s'",
object.
object.
id.c_str(),
1685 object.link_name.c_str());
1691 RCLCPP_ERROR(getLogger(),
"Robot state is not compatible with robot model. This could be fatal.");
1694 else if (
object.
object.operation == moveit_msgs::msg::CollisionObject::REMOVE)
1697 std::vector<const moveit::core::AttachedBody*> attached_bodies;
1698 if (
object.
object.
id.empty())
1701 object.link_name.empty() ? nullptr :
getRobotModel()->getLinkModel(
object.link_name);
1704 robot_state_.value().getAttachedBodies(attached_bodies, link_model);
1708 robot_state_.value().getAttachedBodies(attached_bodies);
1718 RCLCPP_ERROR_STREAM(getLogger(),
"The AttachedCollisionObject message states the object is attached to "
1719 <<
object.link_name <<
", but it is actually attached to "
1721 <<
". Leave the link_name empty or specify the correct link.");
1724 attached_bodies.push_back(body);
1731 const std::string& name = attached_body->getName();
1732 if (world_->hasObject(name))
1734 RCLCPP_WARN(getLogger(),
1735 "The collision world already has an object with the same name as the body about to be detached. "
1736 "NOT adding the detached body '%s' to the collision world.",
1737 object.
object.
id.c_str());
1741 const Eigen::Isometry3d& pose = attached_body->getGlobalPose();
1742 world_->addToObject(name, pose, attached_body->getShapes(), attached_body->getShapePoses());
1743 world_->setSubframesOfObject(name, attached_body->getSubframes());
1748 if (original_object_color.has_value())
1750 setObjectColor(attached_body->getName(), original_object_color.value());
1753 RCLCPP_DEBUG(getLogger(),
"Detached object '%s' from link '%s' and added it back in the collision world",
1754 name.c_str(),
object.link_name.c_str());
1757 robot_state_.value().clearAttachedBody(name);
1759 if (!attached_bodies.empty() ||
object.object.id.empty())
1762 else if (
object.
object.operation == moveit_msgs::msg::CollisionObject::MOVE)
1764 RCLCPP_ERROR(getLogger(),
"Move for attached objects not yet implemented");
1768 RCLCPP_ERROR(getLogger(),
"Unknown collision object operation: %d",
object.
object.operation);
1778 RCLCPP_ERROR(getLogger(),
"The ID '%s' cannot be used for collision objects (name reserved)",
OCTOMAP_NS.c_str());
1782 if (
object.operation == moveit_msgs::msg::CollisionObject::ADD ||
1783 object.operation == moveit_msgs::msg::CollisionObject::APPEND)
1785 return processCollisionObjectAdd(
object);
1787 else if (
object.operation == moveit_msgs::msg::CollisionObject::REMOVE)
1789 return processCollisionObjectRemove(
object);
1791 else if (
object.operation == moveit_msgs::msg::CollisionObject::MOVE)
1793 return processCollisionObjectMove(
object);
1796 RCLCPP_ERROR(getLogger(),
"Unknown collision object operation: %d",
object.operation);
1801 Eigen::Isometry3d& object_pose,
1802 std::vector<shapes::ShapeConstPtr>&
shapes,
1803 EigenSTL::vector_Isometry3d& shape_poses)
1805 if (
object.primitives.size() <
object.primitive_poses.size())
1807 RCLCPP_ERROR(getLogger(),
"More primitive shape poses than shapes in collision object message.");
1810 if (
object.meshes.size() <
object.mesh_poses.size())
1812 RCLCPP_ERROR(getLogger(),
"More mesh poses than meshes in collision object message.");
1815 if (
object.planes.size() <
object.plane_poses.size())
1817 RCLCPP_ERROR(getLogger(),
"More plane poses than planes in collision object message.");
1821 const int num_shapes =
object.primitives.size() +
object.meshes.size() +
object.planes.size();
1822 shapes.reserve(num_shapes);
1823 shape_poses.reserve(num_shapes);
1825 bool switch_object_pose_and_shape_pose =
false;
1829 switch_object_pose_and_shape_pose =
true;
1830 object_pose.setIdentity();
1837 auto append = [&object_pose, &
shapes, &shape_poses,
1838 &switch_object_pose_and_shape_pose](shapes::Shape* s,
const geometry_msgs::msg::Pose& pose_msg) {
1841 Eigen::Isometry3d pose;
1843 if (!switch_object_pose_and_shape_pose)
1845 shape_poses.emplace_back(std::move(pose));
1849 shape_poses.emplace_back(std::move(object_pose));
1852 shapes.emplace_back(shapes::ShapeConstPtr(s));
1855 auto treat_shape_vectors = [&append](
const auto& shape_vector,
1856 const auto& shape_poses_vector,
1857 const std::string& shape_type) {
1858 if (shape_vector.size() > shape_poses_vector.size())
1860 RCLCPP_DEBUG_STREAM(getLogger(),
"Number of " << shape_type
1861 <<
" does not match number of poses "
1862 "in collision object message. Assuming identity.");
1863 for (std::size_t i = 0; i < shape_vector.size(); ++i)
1865 if (i >= shape_poses_vector.size())
1867 append(shapes::constructShapeFromMsg(shape_vector[i]),
1868 geometry_msgs::msg::Pose());
1871 append(shapes::constructShapeFromMsg(shape_vector[i]), shape_poses_vector[i]);
1876 for (std::size_t i = 0; i < shape_vector.size(); ++i)
1877 append(shapes::constructShapeFromMsg(shape_vector[i]), shape_poses_vector[i]);
1881 treat_shape_vectors(
object.primitives,
object.primitive_poses, std::string(
"primitive_poses"));
1882 treat_shape_vectors(
object.meshes,
object.mesh_poses, std::string(
"meshes"));
1883 treat_shape_vectors(
object.planes,
object.plane_poses, std::string(
"planes"));
1887bool PlanningScene::processCollisionObjectAdd(
const moveit_msgs::msg::CollisionObject&
object)
1891 RCLCPP_ERROR_STREAM(getLogger(),
"Unknown frame: " <<
object.header.frame_id);
1895 if (
object.primitives.empty() &&
object.meshes.empty() &&
object.planes.empty())
1897 RCLCPP_ERROR(getLogger(),
"There are no shapes specified in the collision object message");
1902 if (
object.operation == moveit_msgs::msg::CollisionObject::ADD && world_->hasObject(
object.id))
1903 world_->removeObject(
object.
id);
1905 const Eigen::Isometry3d& world_to_object_header_transform =
getFrameTransform(
object.header.frame_id);
1906 Eigen::Isometry3d header_to_pose_transform;
1907 std::vector<shapes::ShapeConstPtr>
shapes;
1908 EigenSTL::vector_Isometry3d shape_poses;
1911 const Eigen::Isometry3d object_frame_transform = world_to_object_header_transform * header_to_pose_transform;
1913 world_->addToObject(
object.
id, object_frame_transform,
shapes, shape_poses);
1915 if (!
object.type.key.empty() || !
object.type.db.empty())
1920 Eigen::Isometry3d subframe_pose;
1921 for (std::size_t i = 0; i <
object.subframe_poses.size(); ++i)
1924 std::string
name =
object.subframe_names[i];
1925 subframes[
name] = subframe_pose;
1927 world_->setSubframesOfObject(
object.
id, subframes);
1931bool PlanningScene::processCollisionObjectRemove(
const moveit_msgs::msg::CollisionObject&
object)
1933 if (
object.
id.empty())
1939 if (!world_->removeObject(
object.id))
1942 "Tried to remove world object '" <<
object.
id <<
"', but it does not exist in this scene.");
1953bool PlanningScene::processCollisionObjectMove(
const moveit_msgs::msg::CollisionObject&
object)
1955 if (world_->hasObject(
object.id))
1958 if (!
object.primitives.empty() || !
object.meshes.empty() || !
object.planes.empty())
1960 RCLCPP_WARN(
getLogger(),
"Move operation for object '%s' ignores the geometry specified in the message.",
1964 const Eigen::Isometry3d& world_to_object_header_transform =
getFrameTransform(
object.header.frame_id);
1965 Eigen::Isometry3d header_to_pose_transform;
1969 const Eigen::Isometry3d object_frame_transform = world_to_object_header_transform * header_to_pose_transform;
1970 world_->setObjectPose(
object.
id, object_frame_transform);
1973 if (!
object.primitive_poses.empty() || !
object.mesh_poses.empty() || !
object.plane_poses.empty())
1975 auto world_object = world_->getObject(
object.
id);
1977 std::size_t shape_size =
object.primitive_poses.size() +
object.mesh_poses.size() +
object.plane_poses.size();
1978 if (shape_size != world_object->shape_poses_.size())
1981 "Move operation for object '%s' must have same number of geometry poses. Cannot move.",
1987 EigenSTL::vector_Isometry3d shape_poses;
1988 for (
const auto& shape_pose : object.primitive_poses)
1990 shape_poses.emplace_back();
1993 for (
const auto& shape_pose : object.mesh_poses)
1995 shape_poses.emplace_back();
1998 for (
const auto& shape_pose : object.plane_poses)
2000 shape_poses.emplace_back();
2004 if (!world_->moveShapesInObject(
object.id, shape_poses))
2006 RCLCPP_ERROR(
getLogger(),
"Move operation for object '%s' internal world error. Cannot move.",
2015 RCLCPP_ERROR(
getLogger(),
"World object '%s' does not exist. Cannot move.",
object.
id.c_str());
2037 const std::string& frame_id)
const
2039 if (!frame_id.empty() && frame_id[0] ==
'/')
2050 const Eigen::Isometry3d& t2 =
getWorld()->getTransform(frame_id, frame_found);
2063 if (!frame_id.empty() && frame_id[0] ==
'/')
2068 if (
getWorld()->knowsTransform(frame_id))
2075 if (object_types_.has_value())
2077 if (object_types_.value().find(object_id) != object_types_.value().end())
2081 return parent_->hasObjectType(object_id);
2087 if (object_types_.has_value())
2089 ObjectTypeMap::const_iterator it = object_types_.value().find(object_id);
2090 if (it != object_types_.value().end())
2094 return parent_->getObjectType(object_id);
2095 static const object_recognition_msgs::msg::ObjectType EMPTY;
2101 if (!object_types_.has_value())
2103 (object_types_.value())[object_id] = type;
2108 if (object_types_.has_value())
2109 object_types_.value().erase(object_id);
2116 parent_->getKnownObjectTypes(kc);
2117 if (object_types_.has_value())
2119 for (
const auto& it : object_types_.value())
2120 kc[it.first] = it.second;
2128 if (object_colors_->find(object_id) != object_colors_->end())
2132 return parent_->hasObjectColor(object_id);
2140 ObjectColorMap::const_iterator it = object_colors_->find(object_id);
2141 if (it != object_colors_->end())
2145 return parent_->getObjectColor(object_id);
2146 static const std_msgs::msg::ColorRGBA EMPTY;
2152 if (original_object_colors_)
2154 ObjectColorMap::const_iterator it = original_object_colors_->find(object_id);
2155 if (it != original_object_colors_->end())
2158 return std::nullopt;
2165 parent_->getKnownObjectColors(kc);
2168 for (ObjectColorMap::const_iterator it = object_colors_->begin(); it != object_colors_->end(); ++it)
2169 kc[it->first] = it->second;
2175 if (object_id.empty())
2177 RCLCPP_ERROR(getLogger(),
"Cannot set color of object with empty object_id.");
2180 if (!object_colors_)
2181 object_colors_ = std::make_unique<ObjectColorMap>();
2182 (*object_colors_)[object_id] = color;
2185 if (!original_object_colors_)
2186 original_object_colors_ = std::make_unique<ObjectColorMap>();
2188 (*original_object_colors_)[object_id] = color;
2194 object_colors_->erase(object_id);
2229 if (state_feasibility_)
2233 return state_feasibility_(s, verbose);
2240 if (state_feasibility_)
2241 return state_feasibility_(state, verbose);
2246 const moveit_msgs::msg::Constraints& constr,
bool verbose)
const
2254 const moveit_msgs::msg::Constraints& constr,
bool verbose)
const
2256 kinematic_constraints::KinematicConstraintSetPtr ks(
2285 static const moveit_msgs::msg::Constraints EMP_CONSTRAINTS;
2286 return isStateValid(state, EMP_CONSTRAINTS, group, verbose);
2291 static const moveit_msgs::msg::Constraints EMP_CONSTRAINTS;
2292 return isStateValid(state, EMP_CONSTRAINTS, group, verbose);
2296 const std::string& group,
bool verbose)
const
2304 const std::string& group,
bool verbose)
const
2325 const moveit_msgs::msg::RobotTrajectory& trajectory,
const std::string& group,
2326 bool verbose, std::vector<std::size_t>* invalid_index)
const
2328 static const moveit_msgs::msg::Constraints EMP_CONSTRAINTS;
2329 static const std::vector<moveit_msgs::msg::Constraints> EMP_CONSTRAINTS_VECTOR;
2330 return isPathValid(start_state, trajectory, EMP_CONSTRAINTS, EMP_CONSTRAINTS_VECTOR, group, verbose, invalid_index);
2334 const moveit_msgs::msg::RobotTrajectory& trajectory,
2335 const moveit_msgs::msg::Constraints& path_constraints,
const std::string& group,
2336 bool verbose, std::vector<std::size_t>* invalid_index)
const
2338 static const std::vector<moveit_msgs::msg::Constraints> EMP_CONSTRAINTS_VECTOR;
2339 return isPathValid(start_state, trajectory, path_constraints, EMP_CONSTRAINTS_VECTOR, group, verbose, invalid_index);
2343 const moveit_msgs::msg::RobotTrajectory& trajectory,
2344 const moveit_msgs::msg::Constraints& path_constraints,
2345 const moveit_msgs::msg::Constraints& goal_constraints,
const std::string& group,
2346 bool verbose, std::vector<std::size_t>* invalid_index)
const
2348 std::vector<moveit_msgs::msg::Constraints> goal_constraints_vector(1, goal_constraints);
2349 return isPathValid(start_state, trajectory, path_constraints, goal_constraints_vector, group, verbose, invalid_index);
2353 const moveit_msgs::msg::RobotTrajectory& trajectory,
2354 const moveit_msgs::msg::Constraints& path_constraints,
2355 const std::vector<moveit_msgs::msg::Constraints>& goal_constraints,
2356 const std::string& group,
bool verbose, std::vector<std::size_t>* invalid_index)
const
2362 return isPathValid(t, path_constraints, goal_constraints, group, verbose, invalid_index);
2366 const moveit_msgs::msg::Constraints& path_constraints,
2367 const std::vector<moveit_msgs::msg::Constraints>& goal_constraints,
2368 const std::string& group,
bool verbose, std::vector<std::size_t>* invalid_index)
const
2372 invalid_index->clear();
2376 for (std::size_t i = 0; i < n_wp; ++i)
2380 bool this_state_valid =
true;
2382 this_state_valid =
false;
2384 this_state_valid =
false;
2386 this_state_valid =
false;
2388 if (!this_state_valid)
2392 invalid_index->push_back(i);
2402 if (i + 1 == n_wp && !goal_constraints.empty())
2405 for (
const moveit_msgs::msg::Constraints& goal_constraint : goal_constraints)
2416 RCLCPP_INFO(getLogger(),
"Goal not satisfied");
2418 invalid_index->push_back(i);
2427 const moveit_msgs::msg::Constraints& path_constraints,
2428 const moveit_msgs::msg::Constraints& goal_constraints,
const std::string& group,
2429 bool verbose, std::vector<std::size_t>* invalid_index)
const
2431 std::vector<moveit_msgs::msg::Constraints> goal_constraints_vector(1, goal_constraints);
2432 return isPathValid(trajectory, path_constraints, goal_constraints_vector, group, verbose, invalid_index);
2436 const moveit_msgs::msg::Constraints& path_constraints,
const std::string& group,
2437 bool verbose, std::vector<std::size_t>* invalid_index)
const
2439 static const std::vector<moveit_msgs::msg::Constraints> EMP_CONSTRAINTS_VECTOR;
2440 return isPathValid(trajectory, path_constraints, EMP_CONSTRAINTS_VECTOR, group, verbose, invalid_index);
2444 bool verbose, std::vector<std::size_t>* invalid_index)
const
2446 static const moveit_msgs::msg::Constraints EMP_CONSTRAINTS;
2447 static const std::vector<moveit_msgs::msg::Constraints> EMP_CONSTRAINTS_VECTOR;
2448 return isPathValid(trajectory, EMP_CONSTRAINTS, EMP_CONSTRAINTS_VECTOR, group, verbose, invalid_index);
2452 std::set<collision_detection::CostSource>& costs,
double overlap_fraction)
const
2454 getCostSources(trajectory, max_costs, std::string(), costs, overlap_fraction);
2458 const std::string& group_name, std::set<collision_detection::CostSource>& costs,
2459 double overlap_fraction)
const
2465 std::set<collision_detection::CostSource> cs;
2466 std::set<collision_detection::CostSource> cs_start;
2468 for (std::size_t i = 0; i < n_wp; ++i)
2477 if (cs.size() <= max_costs)
2485 for (std::set<collision_detection::CostSource>::iterator it = cs.begin(); i < max_costs; ++it, ++i)
2494 std::set<collision_detection::CostSource>& costs)
const
2500 const std::string& group_name,
2501 std::set<collision_detection::CostSource>& costs)
const
2514 const std::vector<std::string>& objects =
getWorld()->getObjectIds();
2515 std::vector<const moveit::core::AttachedBody*> attached_bodies;
2519 out <<
"-----------------------------------------\n";
2520 out <<
"PlanningScene Known Objects:\n";
2521 out <<
" - Collision World Objects:\n ";
2522 for (
const std::string&
object : objects)
2524 out <<
"\t- " <<
object <<
'\n';
2527 out <<
" - Attached Bodies:\n";
2530 out <<
"\t- " << attached_body->getName() <<
'\n';
2532 out <<
"-----------------------------------------\n";
Definition of a structure for the allowed collision matrix. All elements in the collision world are r...
void removeEntry(const std::string &name1, const std::string &name2)
Remove an entry corresponding to a pair of elements. Nothing happens if the pair does not exist in th...
void getMessage(moveit_msgs::msg::AllowedCollisionMatrix &msg) const
Get the allowed collision matrix as a message.
static CollisionDetectorAllocatorPtr create()
World::ObjectConstPtr ObjectConstPtr
std::function< void(const ObjectConstPtr &, Action)> ObserverCallbackFn
A class that contains many different constraints, and can check RobotState *versus the full set....
bool empty() const
Returns whether or not there are any constraints in the set.
bool add(const moveit_msgs::msg::Constraints &c, const moveit::core::Transforms &tf)
Add all known constraints.
ConstraintEvaluationResult decide(const moveit::core::RobotState &state, bool verbose=false) const
Determines whether all constraints are satisfied by state, returning a single evaluation result.
This may be thrown during construction of objects if errors occur.
Object defining bodies that can be attached to robot links.
const Eigen::Isometry3d & getPose() const
Get the pose of the attached body relative to the parent link.
const moveit::core::FixedTransformsMap & getSubframes() const
Get subframes of this object (relative to the object pose). The returned transforms are guaranteed to...
const std::set< std::string > & getTouchLinks() const
Get the links that the attached body is allowed to touch.
const EigenSTL::vector_Isometry3d & getShapePoses() const
Get the shape poses (the transforms to the shapes of this body, relative to the pose)....
const std::string & getAttachedLinkName() const
Get the name of the link this body is attached to.
const std::vector< shapes::ShapeConstPtr > & getShapes() const
Get the shapes that make up this attached body.
const trajectory_msgs::msg::JointTrajectory & getDetachPosture() const
Return the posture that is necessary for the object to be released, (if any). This is useful for exam...
A link from the robot. Contains the constant transform applied to the link and its geometry.
Representation of a robot's state. This includes position, velocity, acceleration and effort.
void getAttachedBodies(std::vector< const AttachedBody * > &attached_bodies) const
Get all bodies attached to the model corresponding to this state.
bool dirtyCollisionBodyTransforms() const
const Eigen::Isometry3d & getFrameTransform(const std::string &frame_id, bool *frame_found=nullptr)
Get the transformation matrix from the model frame (root of model) to the frame identified by frame_i...
void update(bool force=false)
Update all transforms.
bool knowsFrameTransform(const std::string &frame_id) const
Check if a transformation matrix from the model frame (root of model) to frame frame_id is known.
void updateCollisionBodyTransforms()
Update the transforms for the collision bodies. This call is needed before calling collision checking...
This class maintains the representation of the environment as seen by a planning instance....
void getAttachedCollisionObjectMsgs(std::vector< moveit_msgs::msg::AttachedCollisionObject > &attached_collision_objs) const
Construct a vector of messages (attached_collision_objects) with the attached collision object data f...
std::optional< std_msgs::msg::ColorRGBA > getOriginalObjectColor(const std::string &id) const
Tries to get the original color of an object, if one has been set before.
bool usePlanningSceneMsg(const moveit_msgs::msg::PlanningScene &scene)
Call setPlanningSceneMsg() or setPlanningSceneDiffMsg() depending on how the is_diff member of the me...
void getPlanningSceneMsg(moveit_msgs::msg::PlanningScene &scene) const
Construct a message (scene) with all the necessary data so that the scene can be later reconstructed ...
collision_detection::AllowedCollisionMatrix & getAllowedCollisionMatrixNonConst()
Get the allowed collision matrix.
bool isStateFeasible(const moveit_msgs::msg::RobotState &state, bool verbose=false) const
Check if a given state is feasible, in accordance to the feasibility predicate specified by setStateF...
void setAllowedCollisionMatrix(const collision_detection::AllowedCollisionMatrix &acm)
Set the allowed collision matrix.
const moveit::core::RobotModelConstPtr & getRobotModel() const
Get the kinematic model for which the planning scene is maintained.
static PlanningScenePtr clone(const PlanningSceneConstPtr &scene)
Clone a planning scene. Even if the scene scene depends on a parent, the cloned scene will not.
bool processCollisionObjectMsg(const moveit_msgs::msg::CollisionObject &object)
void setCurrentState(const moveit_msgs::msg::RobotState &state)
Set the current robot state to be state. If not all joint values are specified, the previously mainta...
moveit::core::RobotStatePtr getCurrentStateUpdated(const moveit_msgs::msg::RobotState &update) const
Get a copy of the current state with components overwritten by the state message update.
const Eigen::Isometry3d & getFrameTransform(const std::string &id) const
Get the transform corresponding to the frame id. This will be known if id is a link name,...
const object_recognition_msgs::msg::ObjectType & getObjectType(const std::string &id) const
void getObjectColorMsgs(std::vector< moveit_msgs::msg::ObjectColor > &object_colors) const
Construct a vector of messages (object_colors) with the colors of the objects from the planning_scene...
const collision_detection::CollisionEnvPtr & getCollisionEnvNonConst()
Get the representation of the collision robot This can be used to set padding and link scale on the a...
bool getCollisionObjectMsg(moveit_msgs::msg::CollisionObject &collision_obj, const std::string &ns) const
Construct a message (collision_object) with the collision object data from the planning_scene for the...
const collision_detection::CollisionEnvConstPtr & getCollisionEnv() const
Get the active collision environment.
bool isPathValid(const moveit_msgs::msg::RobotState &start_state, const moveit_msgs::msg::RobotTrajectory &trajectory, const std::string &group="", bool verbose=false, std::vector< std::size_t > *invalid_index=nullptr) const
Check if a given path is valid. Each state is checked for validity (collision avoidance and feasibili...
void checkCollision(const collision_detection::CollisionRequest &req, collision_detection::CollisionResult &res)
Check whether the current state is in collision, and if needed, updates the collision transforms of t...
bool knowsFrameTransform(const std::string &id) const
Check if a transform to the frame id is known. This will be known if id is a link name,...
void getCollisionObjectMsgs(std::vector< moveit_msgs::msg::CollisionObject > &collision_objs) const
Construct a vector of messages (collision_objects) with the collision object data for all objects in ...
moveit::core::RobotState & getCurrentStateNonConst()
Get the state at which the robot is assumed to be.
bool isStateValid(const moveit_msgs::msg::RobotState &state, const std::string &group="", bool verbose=false) const
Check if a given state is valid. This means checking for collisions and feasibility....
void checkCollisionUnpadded(const collision_detection::CollisionRequest &req, collision_detection::CollisionResult &res)
Check whether the current state is in collision, but use a collision_detection::CollisionRobot instan...
void processOctomapMsg(const octomap_msgs::msg::OctomapWithPose &map)
void getPlanningSceneDiffMsg(moveit_msgs::msg::PlanningScene &scene) const
Fill the message scene with the differences between this instance of PlanningScene with respect to th...
void getKnownObjectColors(ObjectColorMap &kc) const
void setMotionFeasibilityPredicate(const MotionFeasibilityFn &fn)
Specify a predicate that decides whether motion segments are considered valid or invalid for reasons ...
bool loadGeometryFromStream(std::istream &in)
Load the geometry of the planning scene from a stream.
PlanningScenePtr diff() const
Return a new child PlanningScene that uses this one as parent.
const collision_detection::WorldConstPtr & getWorld() const
Get the representation of the world.
bool setPlanningSceneDiffMsg(const moveit_msgs::msg::PlanningScene &scene)
Apply changes to this planning scene as diffs, even if the message itself is not marked as being a di...
bool processAttachedCollisionObjectMsg(const moveit_msgs::msg::AttachedCollisionObject &object)
const moveit::core::RobotState & getCurrentState() const
Get the state at which the robot is assumed to be.
bool processPlanningSceneWorldMsg(const moveit_msgs::msg::PlanningSceneWorld &world)
void setObjectColor(const std::string &id, const std_msgs::msg::ColorRGBA &color)
void getKnownObjectTypes(ObjectTypeMap &kc) const
PlanningScene(const PlanningScene &)=delete
PlanningScene cannot be copy-constructed.
bool hasObjectColor(const std::string &id) const
bool getOctomapMsg(octomap_msgs::msg::OctomapWithPose &octomap) const
Construct a message (octomap) with the octomap data from the planning_scene.
void clearDiffs()
Clear the diffs accumulated for this planning scene, with respect to: the parent PlanningScene (if it...
void setAttachedBodyUpdateCallback(const moveit::core::AttachedBodyCallback &callback)
Set the callback to be triggered when changes are made to the current scene state.
void setObjectType(const std::string &id, const object_recognition_msgs::msg::ObjectType &type)
void printKnownObjects(std::ostream &out=std::cout) const
Outputs debug information about the planning scene contents.
const std::string getCollisionDetectorName() const
void pushDiffs(const PlanningScenePtr &scene)
If there is a parent specified for this scene, then the diffs with respect to that parent are applied...
bool shapesAndPosesFromCollisionObjectMessage(const moveit_msgs::msg::CollisionObject &object, Eigen::Isometry3d &object_pose_in_header_frame, std::vector< shapes::ShapeConstPtr > &shapes, EigenSTL::vector_Isometry3d &shape_poses)
Takes the object message and returns the object pose, shapes and shape poses. If the object pose is e...
const collision_detection::CollisionEnvConstPtr & getCollisionEnvUnpadded() const
Get the active collision detector for the robot.
bool hasObjectType(const std::string &id) const
const std::string & getPlanningFrame() const
Get the frame in which planning is performed.
void decoupleParent()
Make sure that all the data maintained in this scene is local. All unmodified data is copied from the...
void allocateCollisionDetector(const collision_detection::CollisionDetectorAllocatorPtr &allocator)
Allocate a new collision detector and replace the previous one if there was any.
const moveit::core::Transforms & getTransforms() const
Get the set of fixed transforms from known frames to the planning frame.
void getCostSources(const robot_trajectory::RobotTrajectory &trajectory, std::size_t max_costs, std::set< collision_detection::CostSource > &costs, double overlap_fraction=0.9) const
Get the top max_costs cost sources for a specified trajectory. The resulting costs are stored in cost...
void removeAllCollisionObjects()
Clear all collision objects in planning scene.
const std::string & getName() const
Get the name of the planning scene. This is empty by default.
bool isStateColliding(const std::string &group="", bool verbose=false)
Check if the current state is in collision (with the environment or self collision)....
bool isStateConstrained(const moveit_msgs::msg::RobotState &state, const moveit_msgs::msg::Constraints &constr, bool verbose=false) const
Check if a given state satisfies a set of constraints.
bool setPlanningSceneMsg(const moveit_msgs::msg::PlanningScene &scene)
Set this instance of a planning scene to be the same as the one serialized in the scene message,...
bool getAttachedCollisionObjectMsg(moveit_msgs::msg::AttachedCollisionObject &attached_collision_obj, const std::string &ns) const
Construct a message (attached_collision_object) with the attached collision object data from the plan...
void saveGeometryToStream(std::ostream &out) const
Save the geometry of the planning scene to a stream, as plain text.
void getCollidingLinks(std::vector< std::string > &links)
Get the names of the links that are involved in collisions for the current state.
moveit::core::Transforms & getTransformsNonConst()
Get the set of fixed transforms from known frames to the planning frame.
void setStateFeasibilityPredicate(const StateFeasibilityFn &fn)
Specify a predicate that decides whether states are considered valid or invalid for reasons beyond on...
void checkSelfCollision(const collision_detection::CollisionRequest &req, collision_detection::CollisionResult &res)
Check whether the current state is in self collision.
void removeObjectColor(const std::string &id)
static const std::string OCTOMAP_NS
static const std::string DEFAULT_SCENE_NAME
void setCollisionObjectUpdateCallback(const collision_detection::World::ObserverCallbackFn &callback)
Set the callback to be triggered when changes are made to the current scene world.
void getCollidingPairs(collision_detection::CollisionResult::ContactMap &contacts)
Get the names of the links that are involved in collisions for the current state. Update the link tra...
const std_msgs::msg::ColorRGBA & getObjectColor(const std::string &id) const
Gets the current color of an object.
const collision_detection::AllowedCollisionMatrix & getAllowedCollisionMatrix() const
Get the allowed collision matrix.
void processOctomapPtr(const std::shared_ptr< const octomap::OcTree > &octree, const Eigen::Isometry3d &t)
void removeObjectType(const std::string &id)
Maintain a sequence of waypoints and the time durations between these waypoints.
RobotTrajectory & setRobotTrajectoryMsg(const moveit::core::RobotState &reference_state, const trajectory_msgs::msg::JointTrajectory &trajectory)
Copy the content of the trajectory message into this class. The trajectory message itself is not requ...
std::size_t getWayPointCount() const
const moveit::core::RobotState & getWayPoint(std::size_t index) const
@ ROBOT_LINK
A link on the robot.
rclcpp::Logger getLogger()
std::shared_ptr< OccMapTree > OccMapTreePtr
void removeCostSources(std::set< CostSource > &cost_sources, const std::set< CostSource > &cost_sources_to_remove, double overlap_fraction)
void removeOverlapping(std::set< CostSource > &cost_sources, double overlap_fraction)
void robotStateToRobotStateMsg(const RobotState &state, moveit_msgs::msg::RobotState &robot_state, bool copy_attached_bodies=true)
Convert a MoveIt robot state to a robot state message.
bool isEmpty(const moveit_msgs::msg::PlanningScene &msg)
Check if a message includes any information about a planning scene, or whether it is empty.
std::map< std::string, Eigen::Isometry3d, std::less< std::string >, Eigen::aligned_allocator< std::pair< const std::string, Eigen::Isometry3d > > > FixedTransformsMap
Map frame names to the transformation matrix that can transform objects from the frame name to the pl...
std::function< void(AttachedBody *body, bool attached)> AttachedBodyCallback
bool robotStateMsgToRobotState(const Transforms &tf, const moveit_msgs::msg::RobotState &robot_state, RobotState &state, bool copy_attached_bodies=true)
Convert a robot state msg (with accompanying extra transforms) to a MoveIt robot state.
rclcpp::Logger getLogger(const std::string &name)
Creates a namespaced logger.
void poseMsgToEigen(const geometry_msgs::msg::Pose &msg, Eigen::Isometry3d &out)
void writePoseToText(std::ostream &out, const Eigen::Isometry3d &pose)
Write a pose to text.
bool readPoseFromText(std::istream &in, Eigen::Isometry3d &pose)
Read a pose from text.
This namespace includes the central class for representing planning contexts.
std::map< std::string, std_msgs::msg::ColorRGBA > ObjectColorMap
A map from object names (e.g., attached bodies, collision objects) to their colors.
std::map< std::string, object_recognition_msgs::msg::ObjectType > ObjectTypeMap
A map from object names (e.g., attached bodies, collision objects) to their types.
collision_detection::OccMapTreePtr createOctomap(const octomap_msgs::msg::Octomap &map)
Representation of a collision checking request.
std::string group_name
The group name to check collisions for (optional; if empty, assume the complete robot)....
bool pad_self_collisions
If true, do self collision check with padded robot links.
bool verbose
Flag indicating whether information about detected collisions should be reported.
std::size_t max_cost_sources
When costs are computed, this value defines how many of the top cost sources should be returned.
bool contacts
If true, compute contacts. Otherwise only a binary collision yes/no is reported.
bool pad_environment_collisions
If true, use padded collision environment.
bool cost
If true, a collision cost is computed.
std::size_t max_contacts
Overall maximum number of contacts to compute.
std::size_t max_contacts_per_pair
Maximum number of contacts to compute per pair of bodies (multiple bodies may be in contact at differ...
Representation of a collision checking result.
std::map< std::pair< std::string, std::string >, std::vector< Contact > > ContactMap
A map returning the pairs of body ids in contact, plus their contact details.
std::set< CostSource > cost_sources
These are the individual cost sources when costs are computed.
bool collision
True if collision was found, false otherwise.
A representation of an object.
moveit::core::FixedTransformsMap subframe_poses_
Transforms from the object pose to subframes on the object. Use them to define points of interest on ...
Eigen::Isometry3d pose_
The object's pose. All shapes and subframes are defined relative to this frame. This frame is returne...
EIGEN_MAKE_ALIGNED_OPERATOR_NEW std::string id_
The id for this object.
EigenSTL::vector_Isometry3d shape_poses_
The poses of the corresponding entries in shapes_, relative to the object pose.
std::vector< shapes::ShapeConstPtr > shapes_
All the shapes making up this object.
bool satisfied
Whether or not the constraint or constraints were satisfied.