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>
57 static const rclcpp::Logger LOGGER =
rclcpp::get_logger(
"moveit_planning_scene.planning_scene");
69 void poseMsgToEigen(
const geometry_msgs::msg::Pose& msg, Eigen::Isometry3d& out)
71 Eigen::Translation3d translation(msg.position.x, msg.position.y, msg.position.z);
72 Eigen::Quaterniond quaternion(msg.orientation.w, msg.orientation.x, msg.orientation.y, msg.orientation.z);
73 quaternion.normalize();
74 out = translation * quaternion;
80 double x, y, z, rx, ry, rz, rw;
81 if (!(in >> x >> y >> z))
83 RCLCPP_ERROR(LOGGER,
"Improperly formatted translation in scene geometry file");
86 if (!(in >> rx >> ry >> rz >> rw))
88 RCLCPP_ERROR(LOGGER,
"Improperly formatted rotation in scene geometry file");
91 pose = Eigen::Translation3d(x, y, z) * Eigen::Quaterniond(rw, rx, ry, rz);
98 out << pose.translation().x() <<
' ' << pose.translation().y() <<
' ' << pose.translation().z() <<
'\n';
99 Eigen::Quaterniond r(pose.linear());
100 out << r.x() <<
' ' << r.y() <<
' ' << r.z() <<
' ' << r.w() <<
'\n';
120 if (Transforms::isFixedFrame(frame))
124 return knowsObjectFrame(frame.substr(1));
128 return knowsObjectFrame(frame);
132 const Eigen::Isometry3d&
getTransform(
const std::string& from_frame)
const override
139 bool knowsObjectFrame(
const std::string& frame_id)
const
141 return scene_->
getWorld()->knowsTransform(frame_id);
144 const PlanningScene* scene_;
148 const collision_detection::WorldPtr& world)
150 : robot_model_(robot_model), world_(world), world_const_(world)
156 const srdf::ModelConstSharedPtr& srdf_model,
const collision_detection::WorldPtr& world)
157 : world_(world), world_const_(world)
165 robot_model_ = std::make_shared<moveit::core::RobotModel>(urdf_model, srdf_model);
166 if (!robot_model_ || !robot_model_->getRootJoint())
168 robot_model_ =
nullptr;
177 if (current_world_object_update_callback_)
178 world_->removeObserver(current_world_object_update_observer_handle_);
181 void PlanningScene::initialize()
185 scene_transforms_ = std::make_shared<SceneTransforms>(
this);
187 robot_state_ = std::make_shared<moveit::core::RobotState>(robot_model_);
188 robot_state_->setToDefaultValues();
189 robot_state_->update();
191 acm_ = std::make_shared<collision_detection::AllowedCollisionMatrix>(*
getRobotModel()->getSRDF());
201 if (!parent_->getName().empty())
202 name_ = parent_->getName() +
"+";
204 robot_model_ = parent_->robot_model_;
208 world_ = std::make_shared<collision_detection::World>(*parent_->world_);
209 world_const_ = world_;
212 world_diff_ = std::make_shared<collision_detection::WorldDiff>(world_);
215 collision_detector_->copyPadding(*parent_->collision_detector_);
220 PlanningScenePtr result = scene->diff();
221 result->decoupleParent();
222 result->setName(scene->getName());
228 return PlanningScenePtr(
new PlanningScene(shared_from_this()));
233 PlanningScenePtr result =
diff();
234 result->setPlanningSceneDiffMsg(msg);
240 cenv_->setLinkPadding(src.getCollisionEnv()->getLinkPadding());
241 cenv_->setLinkScale(src.getCollisionEnv()->getLinkScale());
245 const CollisionDetectorPtr& parent_detector)
248 CollisionDetectorPtr prev_coll_detector = collision_detector_;
251 collision_detector_ = std::make_shared<CollisionDetector>();
252 collision_detector_->alloc_ = allocator;
258 collision_detector_->cenv_ = collision_detector_->alloc_->allocateEnv(parent_detector->cenv_, world_);
259 collision_detector_->cenv_unpadded_ =
260 collision_detector_->alloc_->allocateEnv(parent_detector->cenv_unpadded_, world_);
264 collision_detector_->cenv_ = collision_detector_->alloc_->allocateEnv(world_,
getRobotModel());
265 collision_detector_->cenv_unpadded_ = collision_detector_->alloc_->allocateEnv(world_,
getRobotModel());
268 if (prev_coll_detector)
269 collision_detector_->copyPadding(*prev_coll_detector);
273 collision_detector_->cenv_const_ = collision_detector_->cenv_;
274 collision_detector_->cenv_unpadded_const_ = collision_detector_->cenv_unpadded_;
277 const collision_detection::CollisionEnvConstPtr&
282 RCLCPP_ERROR(LOGGER,
"Could not get CollisionRobot named '%s'. Returning active CollisionRobot '%s' instead",
283 collision_detector_name.c_str(), collision_detector_->alloc_->getName().c_str());
284 return collision_detector_->getCollisionEnv();
287 return collision_detector_->getCollisionEnv();
290 const collision_detection::CollisionEnvConstPtr&
296 "Could not get CollisionRobotUnpadded named '%s'. "
297 "Returning active CollisionRobotUnpadded '%s' instead",
298 collision_detector_name.c_str(), collision_detector_->alloc_->getName().c_str());
299 return collision_detector_->getCollisionEnvUnpadded();
302 return collision_detector_->getCollisionEnvUnpadded();
311 world_ = std::make_shared<collision_detection::World>(*parent_->world_);
312 world_const_ = world_;
313 world_diff_ = std::make_shared<collision_detection::WorldDiff>(world_);
314 if (current_world_object_update_callback_)
315 current_world_object_update_observer_handle_ = world_->addObserver(current_world_object_update_callback_);
320 scene_transforms_.reset();
321 robot_state_.reset();
323 object_colors_.reset();
324 object_types_.reset();
332 if (scene_transforms_)
333 scene->getTransformsNonConst().setAllTransforms(scene_transforms_->getAllTransforms());
337 scene->getCurrentStateNonConst() = *robot_state_;
339 std::vector<const moveit::core::AttachedBody*> attached_objs;
340 robot_state_->getAttachedBodies(attached_objs);
344 scene->setObjectType(attached_obj->getName(),
getObjectType(attached_obj->getName()));
346 scene->setObjectColor(attached_obj->getName(),
getObjectColor(attached_obj->getName()));
351 scene->getAllowedCollisionMatrixNonConst() = *acm_;
353 collision_detection::CollisionEnvPtr active_cenv = scene->getCollisionEnvNonConst();
354 active_cenv->setLinkPadding(collision_detector_->cenv_->getLinkPadding());
355 active_cenv->setLinkScale(collision_detector_->cenv_->getLinkScale());
359 for (
const std::pair<const std::string, collision_detection::World::Action>& it : *world_diff_)
363 scene->world_->removeObject(it.first);
364 scene->removeObjectColor(it.first);
365 scene->removeObjectType(it.first);
370 scene->world_->removeObject(obj.
id_);
472 const std::string& group_name)
const
502 for (collision_detection::CollisionResult::ContactMap::const_iterator it = contacts.begin(); it != contacts.end();
517 return collision_detector_->cenv_;
524 robot_state_ = std::make_shared<moveit::core::RobotState>(parent_->getCurrentState());
525 robot_state_->setAttachedBodyUpdateCallback(current_state_attached_body_callback_);
527 robot_state_->update();
528 return *robot_state_;
533 auto state = std::make_shared<moveit::core::RobotState>(
getCurrentState());
540 current_state_attached_body_callback_ = callback;
542 robot_state_->setAttachedBodyUpdateCallback(callback);
547 if (current_world_object_update_callback_)
548 world_->removeObserver(current_world_object_update_observer_handle_);
550 current_world_object_update_observer_handle_ = world_->addObserver(callback);
551 current_world_object_update_callback_ = callback;
557 acm_ = std::make_shared<collision_detection::AllowedCollisionMatrix>(parent_->getAllowedCollisionMatrix());
572 if (!scene_transforms_)
576 scene_transforms_ = std::make_shared<SceneTransforms>(
this);
577 scene_transforms_->setAllTransforms(parent_->getTransforms().getAllTransforms());
579 return *scene_transforms_;
584 scene_msg.name = name_;
586 scene_msg.is_diff =
true;
588 if (scene_transforms_)
590 scene_transforms_->copyTransforms(scene_msg.fixed_frame_transforms);
594 scene_msg.fixed_frame_transforms.clear();
603 scene_msg.robot_state = moveit_msgs::msg::RobotState();
605 scene_msg.robot_state.is_diff =
true;
609 acm_->getMessage(scene_msg.allowed_collision_matrix);
613 scene_msg.allowed_collision_matrix = moveit_msgs::msg::AllowedCollisionMatrix();
616 collision_detector_->cenv_->getPadding(scene_msg.link_padding);
617 collision_detector_->cenv_->getScale(scene_msg.link_scale);
619 scene_msg.object_colors.clear();
623 scene_msg.object_colors.resize(object_colors_->size());
624 for (ObjectColorMap::const_iterator it = object_colors_->begin(); it != object_colors_->end(); ++it, ++i)
626 scene_msg.object_colors[i].id = it->first;
627 scene_msg.object_colors[i].color = it->second;
631 scene_msg.world.collision_objects.clear();
632 scene_msg.world.octomap = octomap_msgs::msg::OctomapWithPose();
636 bool do_omap =
false;
637 for (
const std::pair<const std::string, collision_detection::World::Action>& it : *world_diff_)
646 if (!std::count_if(scene_msg.robot_state.attached_collision_objects.cbegin(),
647 scene_msg.robot_state.attached_collision_objects.cend(),
648 [&it](
const moveit_msgs::msg::AttachedCollisionObject& aco) {
649 return aco.object.id == it.first &&
650 aco.object.operation == moveit_msgs::msg::CollisionObject::ADD;
653 moveit_msgs::msg::CollisionObject co;
656 co.operation = moveit_msgs::msg::CollisionObject::REMOVE;
657 scene_msg.world.collision_objects.push_back(co);
662 scene_msg.world.collision_objects.emplace_back();
673 for (
const auto& collision_object : scene_msg.world.collision_objects)
675 if (parent_ && parent_->getCurrentState().hasAttachedBody(collision_object.id))
677 moveit_msgs::msg::AttachedCollisionObject aco;
678 aco.object.id = collision_object.id;
679 aco.object.operation = moveit_msgs::msg::CollisionObject::REMOVE;
680 scene_msg.robot_state.attached_collision_objects.push_back(aco);
687 class ShapeVisitorAddToCollisionObject :
public boost::static_visitor<void>
690 ShapeVisitorAddToCollisionObject(moveit_msgs::msg::CollisionObject* obj) :
boost::static_visitor<void>(), obj_(obj)
694 void setPoseMessage(
const geometry_msgs::msg::Pose* pose)
699 void operator()(
const shape_msgs::msg::Plane& shape_msg)
const
701 obj_->planes.push_back(shape_msg);
702 obj_->plane_poses.push_back(*pose_);
705 void operator()(
const shape_msgs::msg::Mesh& shape_msg)
const
707 obj_->meshes.push_back(shape_msg);
708 obj_->mesh_poses.push_back(*pose_);
711 void operator()(
const shape_msgs::msg::SolidPrimitive& shape_msg)
const
713 obj_->primitives.push_back(shape_msg);
714 obj_->primitive_poses.push_back(*pose_);
718 moveit_msgs::msg::CollisionObject* obj_;
719 const geometry_msgs::msg::Pose* pose_;
729 collision_obj.pose = tf2::toMsg(obj->pose_);
730 collision_obj.id = ns;
731 collision_obj.operation = moveit_msgs::msg::CollisionObject::ADD;
733 ShapeVisitorAddToCollisionObject sv(&collision_obj);
734 for (std::size_t j = 0; j < obj->shapes_.size(); ++j)
737 if (constructMsgFromShape(obj->shapes_[j].get(), sm))
739 geometry_msgs::msg::Pose p = tf2::toMsg(obj->shape_poses_[j]);
740 sv.setPoseMessage(&p);
741 boost::apply_visitor(sv, sm);
745 if (!collision_obj.primitives.empty() || !collision_obj.meshes.empty() || !collision_obj.planes.empty())
750 for (
const auto& frame_pair : obj->subframe_poses_)
752 collision_obj.subframe_names.push_back(frame_pair.first);
753 geometry_msgs::msg::Pose p;
754 p = tf2::toMsg(frame_pair.second);
755 collision_obj.subframe_poses.push_back(p);
763 collision_objs.clear();
764 const std::vector<std::string>& ids = world_->getObjectIds();
765 for (
const std::string&
id : ids)
769 collision_objs.emplace_back();
776 const std::string& ns)
const
778 std::vector<moveit_msgs::msg::AttachedCollisionObject> attached_collision_objs;
780 for (moveit_msgs::msg::AttachedCollisionObject& it : attached_collision_objs)
782 if (it.object.id == ns)
784 attached_collision_obj = it;
792 std::vector<moveit_msgs::msg::AttachedCollisionObject>& attached_collision_objs)
const
794 std::vector<const moveit::core::AttachedBody*> attached_bodies;
802 octomap.octomap = octomap_msgs::msg::Octomap();
807 if (map->shapes_.size() == 1)
809 const shapes::OcTree* o =
static_cast<const shapes::OcTree*
>(map->shapes_[0].get());
810 octomap_msgs::fullMapToMsg(*o->octree,
octomap.octomap);
811 octomap.origin = tf2::toMsg(map->shape_poses_[0]);
814 RCLCPP_ERROR(LOGGER,
"Unexpected number of shapes in octomap collision object. Not including '%s' object",
822 object_colors.clear();
827 object_colors.resize(cmap.size());
828 for (ObjectColorMap::const_iterator it = cmap.begin(); it != cmap.end(); ++it, ++i)
830 object_colors[i].id = it->first;
831 object_colors[i].color = it->second;
837 scene_msg.name = name_;
838 scene_msg.is_diff =
false;
857 const moveit_msgs::msg::PlanningSceneComponents& comp)
const
859 scene_msg.is_diff =
false;
860 if (comp.components & moveit_msgs::msg::PlanningSceneComponents::SCENE_SETTINGS)
862 scene_msg.name = name_;
866 if (comp.components & moveit_msgs::msg::PlanningSceneComponents::TRANSFORMS)
869 if (comp.components & moveit_msgs::msg::PlanningSceneComponents::ROBOT_STATE_ATTACHED_OBJECTS)
872 for (moveit_msgs::msg::AttachedCollisionObject& attached_collision_object :
873 scene_msg.robot_state.attached_collision_objects)
877 attached_collision_object.object.type =
getObjectType(attached_collision_object.object.id);
881 else if (comp.components & moveit_msgs::msg::PlanningSceneComponents::ROBOT_STATE)
886 if (comp.components & moveit_msgs::msg::PlanningSceneComponents::ALLOWED_COLLISION_MATRIX)
889 if (comp.components & moveit_msgs::msg::PlanningSceneComponents::LINK_PADDING_AND_SCALING)
895 if (comp.components & moveit_msgs::msg::PlanningSceneComponents::OBJECT_COLORS)
899 if (comp.components & moveit_msgs::msg::PlanningSceneComponents::WORLD_OBJECT_GEOMETRY)
903 else if (comp.components & moveit_msgs::msg::PlanningSceneComponents::WORLD_OBJECT_NAMES)
905 const std::vector<std::string>& ids = world_->getObjectIds();
906 scene_msg.world.collision_objects.clear();
907 scene_msg.world.collision_objects.reserve(ids.size());
908 for (
const std::string&
id : ids)
912 moveit_msgs::msg::CollisionObject co;
916 scene_msg.world.collision_objects.push_back(co);
922 if (comp.components & moveit_msgs::msg::PlanningSceneComponents::OCTOMAP)
928 out << name_ <<
'\n';
929 const std::vector<std::string>& ids = world_->getObjectIds();
930 for (
const std::string&
id : ids)
937 out <<
"* " <<
id <<
'\n';
942 out << obj->shapes_.size() <<
'\n';
943 for (std::size_t j = 0; j < obj->shapes_.size(); ++j)
945 shapes::saveAsText(obj->shapes_[j].get(), out);
951 out << c.r <<
' ' << c.g <<
' ' << c.b <<
' ' << c.a <<
'\n';
954 out <<
"0 0 0 0" <<
'\n';
958 out << obj->subframe_poses_.size() <<
'\n';
959 for (
auto& pose_pair : obj->subframe_poses_)
961 out << pose_pair.first <<
'\n';
977 if (!in.good() || in.eof())
979 RCLCPP_ERROR(LOGGER,
"Bad input stream when loading scene geometry");
983 std::getline(in, name_);
986 auto pos = in.tellg();
990 std::getline(in, line);
991 }
while (in.good() && !in.eof() && (line.empty() || line[0] !=
'*'));
992 std::getline(in, line);
993 boost::algorithm::trim(line);
996 bool uses_new_scene_format = line.find(
' ') != std::string::npos;
999 Eigen::Isometry3d pose;
1004 if (!in.good() || in.eof())
1006 RCLCPP_ERROR(LOGGER,
"Bad input stream when loading marker in scene geometry");
1011 std::string object_id;
1012 std::getline(in, object_id);
1013 if (!in.good() || in.eof())
1015 RCLCPP_ERROR(LOGGER,
"Bad input stream when loading object_id in scene geometry");
1018 boost::algorithm::trim(object_id);
1024 RCLCPP_ERROR(LOGGER,
"Failed to read object pose from scene file");
1027 pose = offset * pose;
1028 world_->setObjectPose(object_id, pose);
1031 unsigned int shape_count;
1033 for (std::size_t i = 0; i < shape_count && in.good() && !in.eof(); ++i)
1035 const auto shape = shapes::ShapeConstPtr(shapes::constructShapeFromText(in));
1038 RCLCPP_ERROR(LOGGER,
"Failed to load shape from scene file");
1043 RCLCPP_ERROR(LOGGER,
"Failed to read pose from scene file");
1047 if (!(in >> r >> g >> b >> a))
1049 RCLCPP_ERROR(LOGGER,
"Improperly formatted color in scene geometry file");
1054 world_->addToObject(object_id, shape, pose);
1055 if (r > 0.0f || g > 0.0f || b > 0.0f || a > 0.0f)
1057 std_msgs::msg::ColorRGBA color;
1068 if (uses_new_scene_format)
1071 unsigned int subframe_count;
1072 in >> subframe_count;
1073 for (std::size_t i = 0; i < subframe_count && in.good() && !in.eof(); ++i)
1075 std::string subframe_name;
1076 in >> subframe_name;
1079 RCLCPP_ERROR(LOGGER,
"Failed to read subframe pose from scene file");
1082 subframes[subframe_name] = pose;
1084 world_->setSubframesOfObject(object_id, subframes);
1087 else if (marker ==
".")
1094 RCLCPP_ERROR(LOGGER,
"Unknown marker in scene geometry file: %s ", marker.c_str());
1104 moveit_msgs::msg::RobotState state_no_attached(state);
1105 state_no_attached.attached_collision_objects.clear();
1111 robot_state_ = std::make_shared<moveit::core::RobotState>(parent_->getCurrentState());
1112 robot_state_->setAttachedBodyUpdateCallback(current_state_attached_body_callback_);
1119 for (std::size_t i = 0; i < state.attached_collision_objects.size(); ++i)
1121 if (!state.is_diff && state.attached_collision_objects[i].object.operation != moveit_msgs::msg::CollisionObject::ADD)
1123 RCLCPP_ERROR(LOGGER,
1124 "The specified RobotState is not marked as is_diff. "
1125 "The request to modify the object '%s' is not supported. Object is ignored.",
1126 state.attached_collision_objects[i].object.id.c_str());
1144 if (!scene_transforms_)
1146 scene_transforms_ = std::make_shared<SceneTransforms>(
this);
1147 scene_transforms_->setAllTransforms(parent_->getTransforms().getAllTransforms());
1152 robot_state_ = std::make_shared<moveit::core::RobotState>(parent_->getCurrentState());
1153 robot_state_->setAttachedBodyUpdateCallback(current_state_attached_body_callback_);
1157 acm_ = std::make_shared<collision_detection::AllowedCollisionMatrix>(parent_->getAllowedCollisionMatrix());
1159 world_diff_.reset();
1161 if (!object_colors_)
1164 parent_->getKnownObjectColors(kc);
1165 object_colors_ = std::make_unique<ObjectColorMap>(kc);
1170 parent_->getKnownObjectColors(kc);
1171 for (ObjectColorMap::const_iterator it = kc.begin(); it != kc.end(); ++it)
1173 if (object_colors_->find(it->first) == object_colors_->end())
1174 (*object_colors_)[it->first] = it->second;
1181 parent_->getKnownObjectTypes(kc);
1182 object_types_ = std::make_unique<ObjectTypeMap>(kc);
1187 parent_->getKnownObjectTypes(kc);
1188 for (ObjectTypeMap::const_iterator it = kc.begin(); it != kc.end(); ++it)
1190 if (object_types_->find(it->first) == object_types_->end())
1191 (*object_types_)[it->first] = it->second;
1202 RCLCPP_DEBUG(LOGGER,
"Adding planning scene diff");
1203 if (!scene_msg.name.empty())
1204 name_ = scene_msg.name;
1206 if (!scene_msg.robot_model_name.empty() && scene_msg.robot_model_name !=
getRobotModel()->
getName())
1208 RCLCPP_WARN(LOGGER,
"Setting the scene for model '%s' but model '%s' is loaded.",
1214 if (!scene_msg.fixed_frame_transforms.empty())
1216 if (!scene_transforms_)
1217 scene_transforms_ = std::make_shared<SceneTransforms>(
this);
1218 scene_transforms_->setTransforms(scene_msg.fixed_frame_transforms);
1222 if (!scene_msg.robot_state.multi_dof_joint_state.joint_names.empty() ||
1223 !scene_msg.robot_state.joint_state.name.empty() || !scene_msg.robot_state.attached_collision_objects.empty())
1227 if (!scene_msg.allowed_collision_matrix.entry_names.empty())
1228 acm_ = std::make_shared<collision_detection::AllowedCollisionMatrix>(scene_msg.allowed_collision_matrix);
1230 if (!scene_msg.link_padding.empty() || !scene_msg.link_scale.empty())
1232 collision_detector_->cenv_->setPadding(scene_msg.link_padding);
1233 collision_detector_->cenv_->setScale(scene_msg.link_scale);
1237 for (
const moveit_msgs::msg::ObjectColor& object_color : scene_msg.object_colors)
1241 for (
const moveit_msgs::msg::CollisionObject& collision_object : scene_msg.world.collision_objects)
1245 if (!scene_msg.world.octomap.octomap.data.empty())
1253 RCLCPP_DEBUG(LOGGER,
"Setting new planning scene: '%s'", scene_msg.name.c_str());
1254 name_ = scene_msg.name;
1256 if (!scene_msg.robot_model_name.empty() && scene_msg.robot_model_name !=
getRobotModel()->
getName())
1258 RCLCPP_WARN(LOGGER,
"Setting the scene for model '%s' but model '%s' is loaded.",
1265 object_types_.reset();
1266 scene_transforms_->setTransforms(scene_msg.fixed_frame_transforms);
1268 acm_ = std::make_shared<collision_detection::AllowedCollisionMatrix>(scene_msg.allowed_collision_matrix);
1269 collision_detector_->cenv_->setPadding(scene_msg.link_padding);
1270 collision_detector_->cenv_->setScale(scene_msg.link_scale);
1271 object_colors_ = std::make_unique<ObjectColorMap>();
1272 for (
const moveit_msgs::msg::ObjectColor& object_color : scene_msg.object_colors)
1274 world_->clearObjects();
1281 for (
const moveit_msgs::msg::CollisionObject& collision_object : world.collision_objects)
1289 if (scene_msg.is_diff)
1301 std::shared_ptr<collision_detection::OccMapTree> om =
1302 std::make_shared<collision_detection::OccMapTree>(map.resolution);
1305 octomap_msgs::readTree(om.get(), map);
1309 std::stringstream datastream;
1310 if (!map.data.empty())
1312 datastream.write(
reinterpret_cast<const char*
>(&map.data[0]), map.data.size());
1313 om->readData(datastream);
1324 if (map.data.empty())
1327 if (map.id !=
"OcTree")
1329 RCLCPP_ERROR(LOGGER,
"Received octomap is of type '%s' but type 'OcTree' is expected.", map.id.c_str());
1333 std::shared_ptr<collision_detection::OccMapTree> om =
createOctomap(map);
1334 if (!map.header.frame_id.empty())
1337 world_->addToObject(
OCTOMAP_NS, std::make_shared<const shapes::OcTree>(om), t);
1341 world_->addToObject(
OCTOMAP_NS, std::make_shared<const shapes::OcTree>(om), Eigen::Isometry3d::Identity());
1347 const std::vector<std::string>& object_ids = world_->getObjectIds();
1348 for (
const std::string& object_id : object_ids)
1352 world_->removeObject(object_id);
1364 if (map.octomap.data.empty())
1367 if (map.octomap.id !=
"OcTree")
1369 RCLCPP_ERROR(LOGGER,
"Received octomap is of type '%s' but type 'OcTree' is expected.", map.octomap.id.c_str());
1373 std::shared_ptr<collision_detection::OccMapTree> om =
createOctomap(map.octomap);
1376 Eigen::Isometry3d p;
1379 world_->addToObject(
OCTOMAP_NS, std::make_shared<const shapes::OcTree>(om), p);
1387 if (map->shapes_.size() == 1)
1390 const shapes::OcTree* o =
static_cast<const shapes::OcTree*
>(map->shapes_[0].get());
1391 if (o->octree == octree)
1394 if (map->shape_poses_[0].isApprox(t, std::numeric_limits<double>::epsilon() * 100.0))
1404 shapes::ShapeConstPtr shape = map->shapes_[0];
1406 world_->moveShapeInObject(
OCTOMAP_NS, shape, t);
1414 world_->addToObject(
OCTOMAP_NS, std::make_shared<const shapes::OcTree>(octree), t);
1419 if (
object.
object.operation == moveit_msgs::msg::CollisionObject::ADD &&
1422 RCLCPP_ERROR(LOGGER,
"Unable to attach a body to link '%s' (link not found)",
object.link_name.c_str());
1428 RCLCPP_ERROR(LOGGER,
"The ID '%s' cannot be used for collision objects (name reserved)",
OCTOMAP_NS.c_str());
1434 robot_state_ = std::make_shared<moveit::core::RobotState>(parent_->getCurrentState());
1435 robot_state_->setAttachedBodyUpdateCallback(current_state_attached_body_callback_);
1437 robot_state_->update();
1444 if (
object.
object.operation == moveit_msgs::msg::CollisionObject::ADD ||
1445 object.
object.operation == moveit_msgs::msg::CollisionObject::APPEND)
1451 Eigen::Isometry3d object_pose_in_link;
1452 std::vector<shapes::ShapeConstPtr>
shapes;
1453 EigenSTL::vector_Isometry3d shape_poses;
1460 if (
object.
object.operation == moveit_msgs::msg::CollisionObject::ADD &&
object.
object.primitives.empty() &&
1461 object.object.meshes.empty() &&
object.object.planes.empty())
1465 RCLCPP_DEBUG(LOGGER,
"Attaching world object '%s' to link '%s'",
object.
object.
id.c_str(),
1466 object.link_name.c_str());
1468 object_pose_in_link = robot_state_->getGlobalLinkTransform(link_model).inverse() * obj_in_world->pose_;
1469 shapes = obj_in_world->shapes_;
1470 shape_poses = obj_in_world->shape_poses_;
1471 subframe_poses = obj_in_world->subframe_poses_;
1475 RCLCPP_ERROR(LOGGER,
1476 "Attempting to attach object '%s' to link '%s' but no geometry specified "
1477 "and such an object does not exist in the collision world",
1478 object.
object.
id.c_str(),
object.link_name.c_str());
1484 Eigen::Isometry3d header_frame_to_object_pose;
1487 const Eigen::Isometry3d world_to_header_frame =
getFrameTransform(
object.
object.header.frame_id);
1488 const Eigen::Isometry3d link_to_header_frame =
1489 robot_state_->getGlobalLinkTransform(link_model).inverse() * world_to_header_frame;
1490 object_pose_in_link = link_to_header_frame * header_frame_to_object_pose;
1492 Eigen::Isometry3d subframe_pose;
1493 for (std::size_t i = 0; i <
object.object.subframe_poses.size(); ++i)
1496 std::string
name =
object.object.subframe_names[i];
1497 subframe_poses[
name] = subframe_pose;
1503 RCLCPP_ERROR(LOGGER,
"There is no geometry to attach to link '%s' as part of attached body '%s'",
1504 object.link_name.c_str(),
object.object.id.c_str());
1508 if (!
object.
object.type.db.empty() || !
object.object.type.key.empty())
1512 if (obj_in_world && world_->removeObject(
object.object.id))
1514 if (
object.
object.operation == moveit_msgs::msg::CollisionObject::ADD)
1516 RCLCPP_DEBUG(LOGGER,
"Removing world object with the same name as newly attached object: '%s'",
1517 object.
object.
id.c_str());
1522 "You tried to append geometry to an attached object "
1523 "that is actually a world object ('%s'). World geometry is ignored.",
1524 object.
object.
id.c_str());
1529 if (
object.
object.operation == moveit_msgs::msg::CollisionObject::ADD ||
1530 !robot_state_->hasAttachedBody(
object.object.id))
1532 if (robot_state_->clearAttachedBody(
object.object.id))
1534 RCLCPP_DEBUG(LOGGER,
1535 "The robot state already had an object named '%s' attached to link '%s'. "
1536 "The object was replaced.",
1537 object.
object.
id.c_str(),
object.link_name.c_str());
1539 robot_state_->attachBody(
object.
object.
id, object_pose_in_link,
shapes, shape_poses,
object.touch_links,
1540 object.link_name,
object.detach_posture, subframe_poses);
1541 RCLCPP_DEBUG(LOGGER,
"Attached object '%s' to link '%s'",
object.
object.
id.c_str(),
object.link_name.c_str());
1549 object_pose_in_link = ab->
getPose();
1554 trajectory_msgs::msg::JointTrajectory detach_posture =
1555 object.detach_posture.joint_names.empty() ? ab->
getDetachPosture() :
object.detach_posture;
1558 touch_links.insert(std::make_move_iterator(
object.touch_links.begin()),
1559 std::make_move_iterator(
object.touch_links.end()));
1561 robot_state_->clearAttachedBody(
object.
object.
id);
1562 robot_state_->attachBody(
object.
object.
id, object_pose_in_link,
shapes, shape_poses, touch_links,
1563 object.link_name, detach_posture, subframe_poses);
1564 RCLCPP_DEBUG(LOGGER,
"Appended things to object '%s' attached to link '%s'",
object.
object.
id.c_str(),
1565 object.link_name.c_str());
1571 RCLCPP_ERROR(LOGGER,
"Robot state is not compatible with robot model. This could be fatal.");
1574 else if (
object.
object.operation == moveit_msgs::msg::CollisionObject::REMOVE)
1577 std::vector<const moveit::core::AttachedBody*> attached_bodies;
1578 if (
object.
object.
id.empty())
1581 object.link_name.empty() ? nullptr :
getRobotModel()->getLinkModel(
object.link_name);
1584 robot_state_->getAttachedBodies(attached_bodies, link_model);
1588 robot_state_->getAttachedBodies(attached_bodies);
1598 RCLCPP_ERROR_STREAM(LOGGER,
"The AttachedCollisionObject message states the object is attached to "
1599 <<
object.link_name <<
", but it is actually attached to "
1601 <<
". Leave the link_name empty or specify the correct link.");
1604 attached_bodies.push_back(body);
1611 const std::string&
name = attached_body->getName();
1612 if (world_->hasObject(
name))
1615 "The collision world already has an object with the same name as the body about to be detached. "
1616 "NOT adding the detached body '%s' to the collision world.",
1617 object.
object.
id.c_str());
1621 const Eigen::Isometry3d& pose = attached_body->getGlobalPose();
1622 world_->addToObject(
name, pose, attached_body->getShapes(), attached_body->getShapePoses());
1623 world_->setSubframesOfObject(
name, attached_body->getSubframes());
1624 RCLCPP_DEBUG(LOGGER,
"Detached object '%s' from link '%s' and added it back in the collision world",
1625 name.c_str(),
object.link_name.c_str());
1628 robot_state_->clearAttachedBody(
name);
1630 if (!attached_bodies.empty() ||
object.object.id.empty())
1633 else if (
object.
object.operation == moveit_msgs::msg::CollisionObject::MOVE)
1635 RCLCPP_ERROR(LOGGER,
"Move for attached objects not yet implemented");
1639 RCLCPP_ERROR(LOGGER,
"Unknown collision object operation: %d",
object.
object.operation);
1649 RCLCPP_ERROR(LOGGER,
"The ID '%s' cannot be used for collision objects (name reserved)",
OCTOMAP_NS.c_str());
1653 if (
object.operation == moveit_msgs::msg::CollisionObject::ADD ||
1654 object.operation == moveit_msgs::msg::CollisionObject::APPEND)
1656 return processCollisionObjectAdd(
object);
1658 else if (
object.operation == moveit_msgs::msg::CollisionObject::REMOVE)
1660 return processCollisionObjectRemove(
object);
1662 else if (
object.operation == moveit_msgs::msg::CollisionObject::MOVE)
1664 return processCollisionObjectMove(
object);
1667 RCLCPP_ERROR(LOGGER,
"Unknown collision object operation: %d",
object.operation);
1672 Eigen::Isometry3d& object_pose,
1673 std::vector<shapes::ShapeConstPtr>&
shapes,
1674 EigenSTL::vector_Isometry3d& shape_poses)
1676 if (
object.primitives.size() <
object.primitive_poses.size())
1678 RCLCPP_ERROR(LOGGER,
"More primitive shape poses than shapes in collision object message.");
1681 if (
object.meshes.size() <
object.mesh_poses.size())
1683 RCLCPP_ERROR(LOGGER,
"More mesh poses than meshes in collision object message.");
1686 if (
object.planes.size() <
object.plane_poses.size())
1688 RCLCPP_ERROR(LOGGER,
"More plane poses than planes in collision object message.");
1692 const int num_shapes =
object.primitives.size() +
object.meshes.size() +
object.planes.size();
1693 shapes.reserve(num_shapes);
1694 shape_poses.reserve(num_shapes);
1698 bool switch_object_pose_and_shape_pose =
false;
1699 if (num_shapes == 1)
1703 switch_object_pose_and_shape_pose =
true;
1709 &switch_object_pose_and_shape_pose](shapes::Shape* s,
const geometry_msgs::msg::Pose& pose_msg) {
1712 Eigen::Isometry3d pose;
1714 if (!switch_object_pose_and_shape_pose)
1716 shape_poses.emplace_back(std::move(pose));
1720 shape_poses.emplace_back(std::move(object_pose));
1723 shapes.emplace_back(shapes::ShapeConstPtr(s));
1726 auto treat_shape_vectors = [&
append](
const auto& shape_vector,
1727 const auto& shape_poses_vector,
1728 const std::string& shape_type) {
1729 if (shape_vector.size() > shape_poses_vector.size())
1731 RCLCPP_DEBUG_STREAM(LOGGER,
"Number of " << shape_type
1732 <<
" does not match number of poses "
1733 "in collision object message. Assuming identity.");
1734 for (std::size_t i = 0; i < shape_vector.size(); ++i)
1736 if (i >= shape_poses_vector.size())
1738 append(shapes::constructShapeFromMsg(shape_vector[i]),
1739 geometry_msgs::msg::Pose());
1742 append(shapes::constructShapeFromMsg(shape_vector[i]), shape_poses_vector[i]);
1747 for (std::size_t i = 0; i < shape_vector.size(); ++i)
1748 append(shapes::constructShapeFromMsg(shape_vector[i]), shape_poses_vector[i]);
1752 treat_shape_vectors(
object.primitives,
object.primitive_poses, std::string(
"primitive_poses"));
1753 treat_shape_vectors(
object.meshes,
object.mesh_poses, std::string(
"meshes"));
1754 treat_shape_vectors(
object.planes,
object.plane_poses, std::string(
"planes"));
1758 bool PlanningScene::processCollisionObjectAdd(
const moveit_msgs::msg::CollisionObject&
object)
1762 RCLCPP_ERROR_STREAM(LOGGER,
"Unknown frame: " <<
object.header.frame_id);
1766 if (
object.primitives.empty() &&
object.meshes.empty() &&
object.planes.empty())
1768 RCLCPP_ERROR(LOGGER,
"There are no shapes specified in the collision object message");
1773 if (
object.operation == moveit_msgs::msg::CollisionObject::ADD && world_->hasObject(
object.id))
1774 world_->removeObject(
object.
id);
1776 const Eigen::Isometry3d& world_to_object_header_transform =
getFrameTransform(
object.header.frame_id);
1777 Eigen::Isometry3d header_to_pose_transform;
1778 std::vector<shapes::ShapeConstPtr>
shapes;
1779 EigenSTL::vector_Isometry3d shape_poses;
1782 const Eigen::Isometry3d object_frame_transform = world_to_object_header_transform * header_to_pose_transform;
1784 world_->addToObject(
object.
id, object_frame_transform,
shapes, shape_poses);
1786 if (!
object.type.key.empty() || !
object.type.db.empty())
1791 Eigen::Isometry3d subframe_pose;
1792 for (std::size_t i = 0; i <
object.subframe_poses.size(); ++i)
1795 std::string
name =
object.subframe_names[i];
1796 subframes[
name] = subframe_pose;
1798 world_->setSubframesOfObject(
object.
id, subframes);
1802 bool PlanningScene::processCollisionObjectRemove(
const moveit_msgs::msg::CollisionObject&
object)
1804 if (
object.
id.empty())
1810 if (!world_->removeObject(
object.id))
1812 RCLCPP_WARN_STREAM(LOGGER,
1813 "Tried to remove world object '" <<
object.
id <<
"', but it does not exist in this scene.");
1823 bool PlanningScene::processCollisionObjectMove(
const moveit_msgs::msg::CollisionObject&
object)
1825 if (world_->hasObject(
object.id))
1827 if (!
object.primitives.empty() || !
object.meshes.empty() || !
object.planes.empty())
1829 RCLCPP_WARN(LOGGER,
"Move operation for object '%s' ignores the geometry specified in the message.",
1833 const Eigen::Isometry3d& world_to_object_header_transform =
getFrameTransform(
object.header.frame_id);
1834 Eigen::Isometry3d header_to_pose_transform;
1838 const Eigen::Isometry3d object_frame_transform = world_to_object_header_transform * header_to_pose_transform;
1839 world_->setObjectPose(
object.
id, object_frame_transform);
1843 RCLCPP_ERROR(LOGGER,
"World object '%s' does not exist. Cannot move.",
object.
id.c_str());
1865 const std::string& frame_id)
const
1867 if (!frame_id.empty() && frame_id[0] ==
'/')
1878 const Eigen::Isometry3d& t2 =
getWorld()->getTransform(frame_id, frame_found);
1891 if (!frame_id.empty() && frame_id[0] ==
'/')
1896 if (
getWorld()->knowsTransform(frame_id))
1905 if (object_types_->find(object_id) != object_types_->end())
1909 return parent_->hasObjectType(object_id);
1917 ObjectTypeMap::const_iterator it = object_types_->find(object_id);
1918 if (it != object_types_->end())
1922 return parent_->getObjectType(object_id);
1923 static const object_recognition_msgs::msg::ObjectType EMPTY;
1930 object_types_ = std::make_unique<ObjectTypeMap>();
1931 (*object_types_)[object_id] = type;
1937 object_types_->erase(object_id);
1944 parent_->getKnownObjectTypes(kc);
1947 for (ObjectTypeMap::const_iterator it = object_types_->begin(); it != object_types_->end(); ++it)
1948 kc[it->first] = it->second;
1956 if (object_colors_->find(object_id) != object_colors_->end())
1960 return parent_->hasObjectColor(object_id);
1968 ObjectColorMap::const_iterator it = object_colors_->find(object_id);
1969 if (it != object_colors_->end())
1973 return parent_->getObjectColor(object_id);
1974 static const std_msgs::msg::ColorRGBA EMPTY;
1982 parent_->getKnownObjectColors(kc);
1985 for (ObjectColorMap::const_iterator it = object_colors_->begin(); it != object_colors_->end(); ++it)
1986 kc[it->first] = it->second;
1992 if (object_id.empty())
1994 RCLCPP_ERROR(LOGGER,
"Cannot set color of object with empty object_id.");
1997 if (!object_colors_)
1998 object_colors_ = std::make_unique<ObjectColorMap>();
1999 (*object_colors_)[object_id] = color;
2005 object_colors_->erase(object_id);
2040 if (state_feasibility_)
2044 return state_feasibility_(s, verbose);
2051 if (state_feasibility_)
2052 return state_feasibility_(state, verbose);
2057 const moveit_msgs::msg::Constraints& constr,
bool verbose)
const
2065 const moveit_msgs::msg::Constraints& constr,
bool verbose)
const
2067 kinematic_constraints::KinematicConstraintSetPtr ks(
2096 static const moveit_msgs::msg::Constraints EMP_CONSTRAINTS;
2102 static const moveit_msgs::msg::Constraints EMP_CONSTRAINTS;
2107 const std::string&
group,
bool verbose)
const
2115 const std::string&
group,
bool verbose)
const
2136 const moveit_msgs::msg::RobotTrajectory& trajectory,
const std::string&
group,
2137 bool verbose, std::vector<std::size_t>* invalid_index)
const
2139 static const moveit_msgs::msg::Constraints EMP_CONSTRAINTS;
2140 static const std::vector<moveit_msgs::msg::Constraints> EMP_CONSTRAINTS_VECTOR;
2141 return isPathValid(start_state, trajectory, EMP_CONSTRAINTS, EMP_CONSTRAINTS_VECTOR,
group, verbose, invalid_index);
2145 const moveit_msgs::msg::RobotTrajectory& trajectory,
2146 const moveit_msgs::msg::Constraints& path_constraints,
const std::string&
group,
2147 bool verbose, std::vector<std::size_t>* invalid_index)
const
2149 static const std::vector<moveit_msgs::msg::Constraints> EMP_CONSTRAINTS_VECTOR;
2150 return isPathValid(start_state, trajectory, path_constraints, EMP_CONSTRAINTS_VECTOR,
group, verbose, invalid_index);
2154 const moveit_msgs::msg::RobotTrajectory& trajectory,
2155 const moveit_msgs::msg::Constraints& path_constraints,
2156 const moveit_msgs::msg::Constraints& goal_constraints,
const std::string&
group,
2157 bool verbose, std::vector<std::size_t>* invalid_index)
const
2159 std::vector<moveit_msgs::msg::Constraints> goal_constraints_vector(1, goal_constraints);
2160 return isPathValid(start_state, trajectory, path_constraints, goal_constraints_vector,
group, verbose, invalid_index);
2164 const moveit_msgs::msg::RobotTrajectory& trajectory,
2165 const moveit_msgs::msg::Constraints& path_constraints,
2166 const std::vector<moveit_msgs::msg::Constraints>& goal_constraints,
2167 const std::string&
group,
bool verbose, std::vector<std::size_t>* invalid_index)
const
2173 return isPathValid(t, path_constraints, goal_constraints,
group, verbose, invalid_index);
2177 const moveit_msgs::msg::Constraints& path_constraints,
2178 const std::vector<moveit_msgs::msg::Constraints>& goal_constraints,
2179 const std::string&
group,
bool verbose, std::vector<std::size_t>* invalid_index)
const
2183 invalid_index->clear();
2187 for (std::size_t i = 0; i < n_wp; ++i)
2191 bool this_state_valid =
true;
2193 this_state_valid =
false;
2195 this_state_valid =
false;
2197 this_state_valid =
false;
2199 if (!this_state_valid)
2203 invalid_index->push_back(i);
2213 if (i + 1 == n_wp && !goal_constraints.empty())
2216 for (
const moveit_msgs::msg::Constraints& goal_constraint : goal_constraints)
2227 RCLCPP_INFO(LOGGER,
"Goal not satisfied");
2229 invalid_index->push_back(i);
2238 const moveit_msgs::msg::Constraints& path_constraints,
2239 const moveit_msgs::msg::Constraints& goal_constraints,
const std::string&
group,
2240 bool verbose, std::vector<std::size_t>* invalid_index)
const
2242 std::vector<moveit_msgs::msg::Constraints> goal_constraints_vector(1, goal_constraints);
2243 return isPathValid(trajectory, path_constraints, goal_constraints_vector,
group, verbose, invalid_index);
2247 const moveit_msgs::msg::Constraints& path_constraints,
const std::string&
group,
2248 bool verbose, std::vector<std::size_t>* invalid_index)
const
2250 static const std::vector<moveit_msgs::msg::Constraints> EMP_CONSTRAINTS_VECTOR;
2251 return isPathValid(trajectory, path_constraints, EMP_CONSTRAINTS_VECTOR,
group, verbose, invalid_index);
2255 bool verbose, std::vector<std::size_t>* invalid_index)
const
2257 static const moveit_msgs::msg::Constraints EMP_CONSTRAINTS;
2258 static const std::vector<moveit_msgs::msg::Constraints> EMP_CONSTRAINTS_VECTOR;
2259 return isPathValid(trajectory, EMP_CONSTRAINTS, EMP_CONSTRAINTS_VECTOR,
group, verbose, invalid_index);
2263 std::set<collision_detection::CostSource>& costs,
double overlap_fraction)
const
2265 getCostSources(trajectory, max_costs, std::string(), costs, overlap_fraction);
2269 const std::string& group_name, std::set<collision_detection::CostSource>& costs,
2270 double overlap_fraction)
const
2276 std::set<collision_detection::CostSource> cs;
2277 std::set<collision_detection::CostSource> cs_start;
2279 for (std::size_t i = 0; i < n_wp; ++i)
2288 if (cs.size() <= max_costs)
2296 for (std::set<collision_detection::CostSource>::iterator it = cs.begin(); i < max_costs; ++it, ++i)
2305 std::set<collision_detection::CostSource>& costs)
const
2311 const std::string& group_name,
2312 std::set<collision_detection::CostSource>& costs)
const
2325 const std::vector<std::string>& objects =
getWorld()->getObjectIds();
2326 std::vector<const moveit::core::AttachedBody*> attached_bodies;
2330 out <<
"-----------------------------------------\n";
2331 out <<
"PlanningScene Known Objects:\n";
2332 out <<
" - Collision World Objects:\n ";
2333 for (
const std::string&
object : objects)
2335 out <<
"\t- " <<
object <<
'\n';
2338 out <<
" - Attached Bodies:\n";
2341 out <<
"\t- " << attached_body->getName() <<
'\n';
2343 out <<
"-----------------------------------------\n";
Definition of a structure for the allowed collision matrix. All elements in the collision world are r...
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 std::string & getAttachedLinkName() const
Get the name of the link this body is attached to.
const std::set< std::string > & getTouchLinks() const
Get the links that the attached body is allowed to touch.
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...
const moveit::core::FixedTransformsMap & getSubframes() const
Get subframes of this object (relative to the object pose). The returned transforms are guaranteed to...
const std::vector< shapes::ShapeConstPtr > & getShapes() const
Get the shapes that make up this attached body.
const Eigen::Isometry3d & getPose() const
Get the pose of the attached body relative to the parent link.
const EigenSTL::vector_Isometry3d & getShapePoses() const
Get the shape poses (the transforms to the shapes of this body, relative to the pose)....
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.
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.
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...
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...
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 std::string & getName() const
Get the name of the planning scene. This is empty by default.
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 std::string & getPlanningFrame() const
Get the frame in which planning is performed.
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
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::CollisionEnvConstPtr & getCollisionEnvUnpadded() const
Get the active collision detector for the robot.
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)
bool processPlanningSceneWorldMsg(const moveit_msgs::msg::PlanningSceneWorld &world)
void setObjectColor(const std::string &id, const std_msgs::msg::ColorRGBA &color)
const collision_detection::AllowedCollisionMatrix & getAllowedCollisionMatrix() const
Get the allowed collision matrix.
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...
bool hasObjectType(const std::string &id) const
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.
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...
const moveit::core::RobotState & getCurrentState() const
Get the state at which the robot is assumed to be.
void removeAllCollisionObjects()
Clear all collision objects in planning scene.
const collision_detection::WorldConstPtr & getWorld() const
Get the representation of the world.
bool isStateColliding(const std::string &group="", bool verbose=false)
Check if the current state is in collision (with the environment or self collision)....
const moveit::core::Transforms & getTransforms() const
Get the set of fixed transforms from known frames to the planning frame.
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.
const moveit::core::RobotModelConstPtr & getRobotModel() const
Get the kinematic model for which the planning scene is maintained.
moveit::core::Transforms & getTransformsNonConst()
Get the set of fixed transforms from known frames to the planning frame.
void checkSelfCollision(const collision_detection::CollisionRequest &req, collision_detection::CollisionResult &res)
Check whether the current state is in self collision.
const collision_detection::CollisionEnvConstPtr & getCollisionEnv() const
Get the active collision environment.
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
friend struct CollisionDetector
Enumerates the available collision detectors.
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.
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.
void attachedBodiesToAttachedCollisionObjectMsgs(const std::vector< const AttachedBody * > &attached_bodies, std::vector< moveit_msgs::msg::AttachedCollisionObject > &attached_collision_objs)
Convert AttachedBodies to AttachedCollisionObjects.
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 get_logger()
void update(moveit::core::RobotState *self, bool force, std::string &category)
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)
std::string append(const std::string &left, const std::string &right)
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 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 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.
ContactMap contacts
A map returning the pairs of body ids in contact, plus their contact details.
std::map< std::pair< std::string, std::string >, std::vector< Contact > > ContactMap
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.