41 #include <moveit_msgs/GetPlanningScene.h>
43 #include <dynamic_reconfigure/server.h>
44 #include <moveit_ros_planning/PlanningSceneMonitorDynamicReconfigureConfig.h>
51 #include <boost/algorithm/string/join.hpp>
57 using namespace moveit_ros_planning;
59 static const std::string
LOGNAME =
"planning_scene_monitor";
61 class PlanningSceneMonitor::DynamicReconfigureImpl
64 DynamicReconfigureImpl(PlanningSceneMonitor* owner)
65 : owner_(owner), dynamic_reconfigure_server_(
ros::NodeHandle(decideNamespace(owner->
getName())))
67 dynamic_reconfigure_server_.setCallback(
68 [
this](
const auto& config, uint32_t level) { dynamicReconfigureCallback(config, level); });
74 static std::string decideNamespace(
const std::string& name)
76 std::string ns =
"~/" +
name;
77 std::replace(ns.begin(), ns.end(),
' ',
'_');
78 std::transform(ns.begin(), ns.end(), ns.begin(), ::tolower);
82 while (
ros::service::exists(ns + boost::lexical_cast<std::string>(c) +
"/set_parameters",
false))
84 ns += boost::lexical_cast<std::string>(c);
89 void dynamicReconfigureCallback(
const PlanningSceneMonitorDynamicReconfigureConfig& config, uint32_t )
92 if (config.publish_geometry_updates)
94 if (config.publish_state_updates)
96 if (config.publish_transforms_updates)
98 if (config.publish_planning_scene)
100 owner_->setPlanningScenePublishingFrequency(config.publish_planning_scene_hz);
101 owner_->startPublishingPlanningScene(event);
104 owner_->stopPublishingPlanningScene();
108 dynamic_reconfigure::Server<PlanningSceneMonitorDynamicReconfigureConfig> dynamic_reconfigure_server_;
120 const std::shared_ptr<tf2_ros::Buffer>& tf_buffer,
const std::string& name)
126 const std::string& robot_description,
127 const std::shared_ptr<tf2_ros::Buffer>& tf_buffer,
const std::string& name)
134 const std::shared_ptr<tf2_ros::Buffer>& tf_buffer,
const std::string& name)
140 const robot_model_loader::RobotModelLoaderPtr& rm_loader,
141 const std::shared_ptr<tf2_ros::Buffer>& tf_buffer,
const std::string& name)
152 const robot_model_loader::RobotModelLoaderPtr& rm_loader,
153 const ros::NodeHandle& nh,
const std::shared_ptr<tf2_ros::Buffer>& tf_buffer,
154 const std::string& name)
200 scene_ = std::make_shared<planning_scene::PlanningScene>(
rm_loader_->getModel());
208 scene_->getCollisionEnvNonConst()->setLinkPadding(it.first, it.second);
212 scene_->getCollisionEnvNonConst()->setLinkScale(it.first, it.second);
214 scene_->propogateRobotPadding();
231 scene_->setCollisionObjectUpdateCallback(
249 double temp_wait_time = 0.05;
263 std::vector<std::string> ignored_frames_vector;
264 nh_.
param(
"planning_scene_monitor_options/ignored_frames", ignored_frames_vector, std::vector<std::string>());
265 ignored_frames_ = std::set<std::string>(ignored_frames_vector.begin(), ignored_frames_vector.end());
286 scene_->setCollisionObjectUpdateCallback(
287 [
this](
const collision_detection::World::ObjectConstPtr&
object,
296 "Stopping planning scene diff publisher");
306 if (!
scene_->getName().empty())
308 if (
scene_->getName()[
scene_->getName().length() - 1] ==
'+')
321 std::unique_ptr<boost::thread> copy;
332 const std::string& planning_scene_topic)
338 ROS_INFO_NAMED(
LOGNAME,
"Publishing maintained planning scene on '%s'", planning_scene_topic.c_str());
350 moveit_msgs::PlanningScene msg;
355 scene_->getPlanningSceneMsg(msg);
363 moveit_msgs::PlanningScene msg;
364 bool publish_msg =
false;
365 bool is_full =
false;
382 scene_->getPlanningSceneDiffMsg(msg);
385 msg.robot_state.attached_collision_objects.clear();
386 msg.robot_state.is_diff =
true;
401 scene_->setCollisionObjectUpdateCallback(
402 [
this](
const collision_detection::World::ObjectConstPtr&
object,
414 scene_->getPlanningSceneMsg(msg);
452 bool sceneIsParentOf(
const planning_scene::PlanningSceneConstPtr& scene,
455 if (scene && scene.get() == possible_parent)
458 return sceneIsParentOf(scene->getParent(), possible_parent);
479 update_callback(update_type);
489 throw std::runtime_error(
"requestPlanningSceneState() to self-provided service: " + service_name);
494 moveit_msgs::GetPlanningScene srv;
503 if (client.
call(srv))
510 LOGNAME,
"Failed to call service %s, have you launched move_group or called psm.providePlanningSceneService()?",
511 service_name.c_str());
525 moveit_msgs::GetPlanningScene::Response& res)
527 if (req.components.components & moveit_msgs::PlanningSceneComponents::TRANSFORMS)
530 moveit_msgs::PlanningSceneComponents all_components;
531 all_components.components = UINT_MAX;
534 scene_->getPlanningSceneMsg(res.scene, req.components.components ? req.components : all_components);
546 bool removed =
false;
549 removed =
scene_->getWorldNonConst()->removeObject(
scene_->OCTOMAP_NS);
575 std::string old_scene_name;
586 old_scene_name =
scene_->getName();
599 result =
scene_->usePlanningSceneMsg(scene);
604 if (!scene.is_diff && scene.world.octomap.octomap.data.empty())
623 bool no_other_scene_upd = (scene.name.empty() || scene.name == old_scene_name) &&
624 scene.allowed_collision_matrix.entry_names.empty() && scene.link_padding.empty() &&
625 scene.link_scale.empty();
626 if (no_other_scene_upd)
632 if (!scene.fixed_frame_transforms.empty())
638 if (!scene.robot_state.attached_collision_objects.empty() || !
static_cast<bool>(scene.robot_state.is_diff))
655 scene_->getWorldNonConst()->clearObjects();
656 scene_->processPlanningSceneWorldMsg(*world);
659 if (world->octomap.octomap.data.empty())
680 if (!
scene_->processCollisionObjectMsg(*obj))
694 scene_->processAttachedCollisionObjectMsg(*obj);
708 const std::vector<const moveit::core::LinkModel*>& links =
getRobotModel()->getLinkModelsWithCollisionGeometry();
713 std::vector<shapes::ShapeConstPtr>
shapes = link->getShapes();
714 for (std::size_t j = 0; j <
shapes.size(); ++j)
744 std::vector<std::pair<occupancy_map_monitor::ShapeHandle, std::size_t>>>& link_shape_handle :
746 for (std::pair<occupancy_map_monitor::ShapeHandle, std::size_t>& it : link_shape_handle.second)
760 std::vector<std::pair<occupancy_map_monitor::ShapeHandle, std::size_t>>>& attached_body_shape_handle :
762 for (std::pair<occupancy_map_monitor::ShapeHandle, std::size_t>& it : attached_body_shape_handle.second)
773 std::vector<const moveit::core::AttachedBody*> ab;
774 scene_->getCurrentState().getAttachedBodies(ab);
787 for (std::pair<
const std::string, std::vector<std::pair<occupancy_map_monitor::ShapeHandle, const Eigen::Isometry3d*>>>&
789 for (std::pair<occupancy_map_monitor::ShapeHandle, const Eigen::Isometry3d*>& it :
790 collision_body_shape_handle.second)
800 for (
const std::pair<const std::string, collision_detection::World::ObjectPtr>& it : *
scene_->getWorld())
811 for (std::size_t i = 0; i < attached_body->
getShapes().size(); ++i)
836 for (std::pair<occupancy_map_monitor::ShapeHandle, std::size_t>& shape_handle : it->second)
851 for (std::size_t i = 0; i <
obj->shapes_.size(); ++i)
876 for (std::pair<occupancy_map_monitor::ShapeHandle, const Eigen::Isometry3d*>& shape_handle : it->second)
1005 if (!scene_topic.empty())
1032 std::vector<std::pair<occupancy_map_monitor::ShapeHandle, std::size_t>>>& link_shape_handle :
1035 tf_buffer_->canTransform(target_frame, link_shape_handle.first->getName(), target_time,
1038 tf_buffer_->lookupTransform(target_frame, link_shape_handle.first->getName(), target_time));
1039 for (std::size_t j = 0; j < link_shape_handle.second.size(); ++j)
1040 cache[link_shape_handle.second[j].first] =
1041 ttr * link_shape_handle.first->getCollisionOriginTransforms()[link_shape_handle.second[j].second];
1044 std::vector<std::pair<occupancy_map_monitor::ShapeHandle, std::size_t>>>&
1047 tf_buffer_->canTransform(target_frame, attached_body_shape_handle.first->getAttachedLinkName(), target_time,
1050 target_frame, attached_body_shape_handle.first->getAttachedLinkName(), target_time));
1051 for (std::size_t k = 0; k < attached_body_shape_handle.second.size(); ++k)
1052 cache[attached_body_shape_handle.second[k].first] =
1054 attached_body_shape_handle.first->getShapePosesInLinkFrame()[attached_body_shape_handle.second[k].second];
1057 tf_buffer_->canTransform(target_frame,
scene_->getPlanningFrame(), target_time,
1061 for (
const std::pair<
const std::string,
1062 std::vector<std::pair<occupancy_map_monitor::ShapeHandle, const Eigen::Isometry3d*>>>&
1064 for (
const std::pair<occupancy_map_monitor::ShapeHandle, const Eigen::Isometry3d*>& it :
1065 collision_body_shape_handle.second)
1066 cache[it.first] =
transform * (*it.second);
1078 const std::string& planning_scene_world_topic,
1079 const bool load_octomap_monitor)
1082 ROS_INFO_NAMED(
LOGNAME,
"Starting world geometry update monitor for collision objects, attached objects, octomap "
1086 if (!collision_objects_topic.empty())
1093 if (!planning_scene_world_topic.empty())
1102 if (load_octomap_monitor)
1107 std::make_unique<occupancy_map_monitor::OccupancyMapMonitor>(
tf_buffer_,
scene_->getPlanningFrame());
1139 const std::string& attached_objects_topic)
1147 [
this](
const sensor_msgs::JointStateConstPtr& state) {
onStateUpdate(state); });
1156 if (!attached_objects_topic.empty())
1267 if (hz > std::numeric_limits<double>::epsilon())
1293 std::vector<std::string> missing;
1297 std::string missing_str = boost::algorithm::join(missing,
", ");
1299 missing_str.c_str());
1307 scene_->getCurrentStateNonConst().update();
1317 boost::recursive_mutex::scoped_lock lock(
update_lock_);
1324 boost::recursive_mutex::scoped_lock lock(
update_lock_);
1337 const std::string& target =
getRobotModel()->getModelFrame();
1339 std::vector<std::string> all_frame_names;
1340 tf_buffer_->_getFrameStrings(all_frame_names);
1341 for (
const std::string& all_frame_name : all_frame_names)
1346 geometry_msgs::TransformStamped
f;
1354 << all_frame_name <<
"' to planning frame '" << target <<
"' (" << ex.what()
1358 f.header.frame_id = all_frame_name;
1359 f.child_frame_id = target;
1360 transforms.push_back(f);
1371 std::vector<geometry_msgs::TransformStamped> transforms;
1375 scene_->getTransformsNonConst().setTransforms(transforms);
1412 if (coll_ops.
size() == 0)
1418 for (
int i = 0; i < coll_ops.
size(); ++i)
1420 if (!coll_ops[i].hasMember(
"object1") || !coll_ops[i].hasMember(
"object2") || !coll_ops[i].hasMember(
"operation"))
1425 acm.
setEntry(std::string(coll_ops[i][
"object1"]), std::string(coll_ops[i][
"object2"]),
1426 std::string(coll_ops[i][
"operation"]) ==
"disable");
1444 const std::string old_robot_description =
1448 if (
nh_.
hasParam(old_robot_description +
"_planning/default_robot_padding") ||
1449 nh_.
hasParam(old_robot_description +
"_planning/default_robot_scale") ||
1450 nh_.
hasParam(old_robot_description +
"_planning/default_object_padding") ||
1451 nh_.
hasParam(old_robot_description +
"_planning/default_attached_padding") ||
1452 nh_.
hasParam(old_robot_description +
"_planning/default_robot_link_padding") ||
1453 nh_.
hasParam(old_robot_description +
"_planning/default_robot_link_scale"))
1456 "Old parameter path: '"
1459 "New parameter path: '"
1462 "Ignoring old parameters. Please update your moveit config!");
1471 std::map<std::string, double>());
1473 std::map<std::string, double>());