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)
193 scene->setPlanningSceneDiffMsg(diff);
213 scene_ = std::make_shared<planning_scene::PlanningScene>(
rm_loader_->getModel());
221 scene_->getCollisionEnvNonConst()->setLinkPadding(it.first, it.second);
225 scene_->getCollisionEnvNonConst()->setLinkScale(it.first, it.second);
227 scene_->propogateRobotPadding();
244 scene_->setCollisionObjectUpdateCallback(
262 double temp_wait_time = 0.05;
276 std::vector<std::string> ignored_frames_vector;
277 nh_.
param(
"planning_scene_monitor_options/ignored_frames", ignored_frames_vector, std::vector<std::string>());
278 ignored_frames_ = std::set<std::string>(ignored_frames_vector.begin(), ignored_frames_vector.end());
299 scene_->setCollisionObjectUpdateCallback(
300 [
this](
const collision_detection::World::ObjectConstPtr&
object,
309 "Stopping planning scene diff publisher");
319 if (!
scene_->getName().empty())
321 if (
scene_->getName()[
scene_->getName().length() - 1] ==
'+')
334 std::unique_ptr<boost::thread> copy;
345 const std::string& planning_scene_topic)
351 ROS_INFO_NAMED(
LOGNAME,
"Publishing maintained planning scene on '%s'", planning_scene_topic.c_str());
363 moveit_msgs::PlanningScene msg;
368 scene_->getPlanningSceneMsg(msg);
376 moveit_msgs::PlanningScene msg;
377 bool publish_msg =
false;
378 bool is_full =
false;
395 scene_->getPlanningSceneDiffMsg(msg);
398 msg.robot_state.attached_collision_objects.clear();
399 msg.robot_state.is_diff =
true;
414 scene_->setCollisionObjectUpdateCallback(
415 [
this](
const collision_detection::World::ObjectConstPtr&
object,
427 scene_->getPlanningSceneMsg(msg);
465 bool sceneIsParentOf(
const planning_scene::PlanningSceneConstPtr& scene,
468 if (scene && scene.get() == possible_parent)
471 return sceneIsParentOf(scene->getParent(), possible_parent);
492 update_callback(update_type);
502 throw std::runtime_error(
"requestPlanningSceneState() to self-provided service: " + service_name);
507 moveit_msgs::GetPlanningScene srv;
516 if (client.
call(srv))
523 LOGNAME,
"Failed to call service %s, have you launched move_group or called psm.providePlanningSceneService()?",
524 service_name.c_str());
538 moveit_msgs::GetPlanningScene::Response& res)
540 if (req.components.components & moveit_msgs::PlanningSceneComponents::TRANSFORMS)
543 moveit_msgs::PlanningSceneComponents all_components;
544 all_components.components = UINT_MAX;
547 scene_->getPlanningSceneMsg(res.scene, req.components.components ? req.components : all_components);
559 bool removed =
false;
562 removed =
scene_->getWorldNonConst()->removeObject(
scene_->OCTOMAP_NS);
588 std::string old_scene_name;
599 old_scene_name =
scene_->getName();
604 if (scene.robot_state.is_diff)
614 result =
scene_->usePlanningSceneMsg(scene);
619 if (!scene.is_diff && scene.world.octomap.octomap.data.empty())
638 bool no_other_scene_upd = (scene.name.empty() || scene.name == old_scene_name) &&
639 scene.allowed_collision_matrix.entry_names.empty() && scene.link_padding.empty() &&
640 scene.link_scale.empty();
641 if (no_other_scene_upd)
647 if (!scene.fixed_frame_transforms.empty())
653 if (!scene.robot_state.attached_collision_objects.empty() || !
static_cast<bool>(scene.robot_state.is_diff))
670 scene_->getWorldNonConst()->clearObjects();
671 scene_->processPlanningSceneWorldMsg(*world);
674 if (world->octomap.octomap.data.empty())
695 if (!
scene_->processCollisionObjectMsg(*obj))
709 scene_->processAttachedCollisionObjectMsg(*obj);
723 const std::vector<const moveit::core::LinkModel*>& links =
getRobotModel()->getLinkModelsWithCollisionGeometry();
728 std::vector<shapes::ShapeConstPtr>
shapes = link->getShapes();
729 for (std::size_t j = 0; j <
shapes.size(); ++j)
759 std::vector<std::pair<occupancy_map_monitor::ShapeHandle, std::size_t>>>& link_shape_handle :
761 for (std::pair<occupancy_map_monitor::ShapeHandle, std::size_t>& it : link_shape_handle.second)
775 std::vector<std::pair<occupancy_map_monitor::ShapeHandle, std::size_t>>>& attached_body_shape_handle :
777 for (std::pair<occupancy_map_monitor::ShapeHandle, std::size_t>& it : attached_body_shape_handle.second)
788 std::vector<const moveit::core::AttachedBody*> ab;
789 scene_->getCurrentState().getAttachedBodies(ab);
802 for (std::pair<
const std::string, std::vector<std::pair<occupancy_map_monitor::ShapeHandle, const Eigen::Isometry3d*>>>&
804 for (std::pair<occupancy_map_monitor::ShapeHandle, const Eigen::Isometry3d*>& it :
805 collision_body_shape_handle.second)
815 for (
const std::pair<const std::string, collision_detection::World::ObjectPtr>& it : *
scene_->getWorld())
826 for (std::size_t i = 0; i < attached_body->
getShapes().size(); ++i)
851 for (std::pair<occupancy_map_monitor::ShapeHandle, std::size_t>& shape_handle : it->second)
866 for (std::size_t i = 0; i <
obj->shapes_.size(); ++i)
891 for (std::pair<occupancy_map_monitor::ShapeHandle, const Eigen::Isometry3d*>& shape_handle : it->second)
1014 if (!scene_topic.empty())
1041 std::vector<std::pair<occupancy_map_monitor::ShapeHandle, std::size_t>>>& link_shape_handle :
1044 tf_buffer_->canTransform(target_frame, link_shape_handle.first->getName(), target_time,
1047 tf_buffer_->lookupTransform(target_frame, link_shape_handle.first->getName(), target_time));
1048 for (std::size_t j = 0; j < link_shape_handle.second.size(); ++j)
1049 cache[link_shape_handle.second[j].first] =
1050 ttr * link_shape_handle.first->getCollisionOriginTransforms()[link_shape_handle.second[j].second];
1053 std::vector<std::pair<occupancy_map_monitor::ShapeHandle, std::size_t>>>&
1056 tf_buffer_->canTransform(target_frame, attached_body_shape_handle.first->getAttachedLinkName(), target_time,
1059 target_frame, attached_body_shape_handle.first->getAttachedLinkName(), target_time));
1060 for (std::size_t k = 0; k < attached_body_shape_handle.second.size(); ++k)
1061 cache[attached_body_shape_handle.second[k].first] =
1063 attached_body_shape_handle.first->getShapePosesInLinkFrame()[attached_body_shape_handle.second[k].second];
1066 tf_buffer_->canTransform(target_frame,
scene_->getPlanningFrame(), target_time,
1070 for (
const std::pair<
const std::string,
1071 std::vector<std::pair<occupancy_map_monitor::ShapeHandle, const Eigen::Isometry3d*>>>&
1073 for (
const std::pair<occupancy_map_monitor::ShapeHandle, const Eigen::Isometry3d*>& it :
1074 collision_body_shape_handle.second)
1075 cache[it.first] =
transform * (*it.second);
1087 const std::string& planning_scene_world_topic,
1088 const bool load_octomap_monitor)
1091 ROS_INFO_NAMED(
LOGNAME,
"Starting world geometry update monitor for collision objects, attached objects, octomap "
1095 if (!collision_objects_topic.empty())
1102 if (!planning_scene_world_topic.empty())
1111 if (load_octomap_monitor)
1116 std::make_unique<occupancy_map_monitor::OccupancyMapMonitor>(
tf_buffer_,
scene_->getPlanningFrame());
1148 const std::string& attached_objects_topic)
1156 [
this](
const sensor_msgs::JointStateConstPtr& state) {
onStateUpdate(state); });
1165 if (!attached_objects_topic.empty())
1235 if (hz > std::numeric_limits<double>::epsilon())
1261 std::vector<std::string> missing;
1265 std::string missing_str = boost::algorithm::join(missing,
", ");
1267 missing_str.c_str());
1272 if (!skip_update_if_locked)
1274 else if (!ulock.try_lock())
1281 scene_->getCurrentStateNonConst().update();
1299 boost::recursive_mutex::scoped_lock lock(
update_lock_);
1306 boost::recursive_mutex::scoped_lock lock(
update_lock_);
1319 const std::string& target =
getRobotModel()->getModelFrame();
1321 std::vector<std::string> all_frame_names;
1322 tf_buffer_->_getFrameStrings(all_frame_names);
1323 for (
const std::string& all_frame_name : all_frame_names)
1328 geometry_msgs::TransformStamped
f;
1336 << all_frame_name <<
"' to planning frame '" << target <<
"' (" << ex.what()
1340 f.header.frame_id = all_frame_name;
1341 f.child_frame_id = target;
1342 transforms.push_back(f);
1353 std::vector<geometry_msgs::TransformStamped> transforms;
1357 scene_->getTransformsNonConst().setTransforms(transforms);
1394 if (coll_ops.
size() == 0)
1400 for (
int i = 0; i < coll_ops.
size(); ++i)
1402 if (!coll_ops[i].hasMember(
"object1") || !coll_ops[i].hasMember(
"object2") || !coll_ops[i].hasMember(
"operation"))
1407 acm.
setEntry(std::string(coll_ops[i][
"object1"]), std::string(coll_ops[i][
"object2"]),
1408 std::string(coll_ops[i][
"operation"]) ==
"disable");
1426 const std::string old_robot_description =
1430 if (
nh_.
hasParam(old_robot_description +
"_planning/default_robot_padding") ||
1431 nh_.
hasParam(old_robot_description +
"_planning/default_robot_scale") ||
1432 nh_.
hasParam(old_robot_description +
"_planning/default_object_padding") ||
1433 nh_.
hasParam(old_robot_description +
"_planning/default_attached_padding") ||
1434 nh_.
hasParam(old_robot_description +
"_planning/default_robot_link_padding") ||
1435 nh_.
hasParam(old_robot_description +
"_planning/default_robot_link_scale"))
1438 "Old parameter path: '"
1441 "New parameter path: '"
1444 "Ignoring old parameters. Please update your moveit config!");
1453 std::map<std::string, double>());
1455 std::map<std::string, double>());