planning_scene_monitor.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2011, Willow Garage, Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of Willow Garage nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *********************************************************************/
34 
35 /* Author: Ioan Sucan */
36 
41 #include <moveit_msgs/GetPlanningScene.h>
42 
43 #include <dynamic_reconfigure/server.h>
44 #include <moveit_ros_planning/PlanningSceneMonitorDynamicReconfigureConfig.h>
45 #include <tf2/exceptions.h>
47 #include <tf2_eigen/tf2_eigen.h>
50 
51 #include <boost/algorithm/string/join.hpp>
52 
53 #include <memory>
54 
55 namespace planning_scene_monitor
56 {
57 using namespace moveit_ros_planning;
58 
59 static const std::string LOGNAME = "planning_scene_monitor";
60 
61 class PlanningSceneMonitor::DynamicReconfigureImpl
62 {
63 public:
64  DynamicReconfigureImpl(PlanningSceneMonitor* owner)
65  : owner_(owner), dynamic_reconfigure_server_(ros::NodeHandle(decideNamespace(owner->getName())))
66  {
67  dynamic_reconfigure_server_.setCallback(
68  [this](const auto& config, uint32_t level) { dynamicReconfigureCallback(config, level); });
69  }
70 
71 private:
72  // make sure we do not advertise the same service multiple times, in case we use multiple PlanningSceneMonitor
73  // instances in a process
74  static std::string decideNamespace(const std::string& name)
75  {
76  std::string ns = "~/" + name;
77  std::replace(ns.begin(), ns.end(), ' ', '_');
78  std::transform(ns.begin(), ns.end(), ns.begin(), ::tolower);
79  if (ros::service::exists(ns + "/set_parameters", false))
80  {
81  unsigned int c = 1;
82  while (ros::service::exists(ns + boost::lexical_cast<std::string>(c) + "/set_parameters", false))
83  c++;
84  ns += boost::lexical_cast<std::string>(c);
85  }
86  return ns;
87  }
88 
89  void dynamicReconfigureCallback(const PlanningSceneMonitorDynamicReconfigureConfig& config, uint32_t /*level*/)
90  {
92  if (config.publish_geometry_updates)
94  if (config.publish_state_updates)
96  if (config.publish_transforms_updates)
98  if (config.publish_planning_scene)
99  {
100  owner_->setPlanningScenePublishingFrequency(config.publish_planning_scene_hz);
101  owner_->startPublishingPlanningScene(event);
102  }
103  else
104  owner_->stopPublishingPlanningScene();
105  }
106 
107  PlanningSceneMonitor* owner_;
108  dynamic_reconfigure::Server<PlanningSceneMonitorDynamicReconfigureConfig> dynamic_reconfigure_server_;
109 };
110 
111 const std::string PlanningSceneMonitor::DEFAULT_JOINT_STATES_TOPIC = "joint_states";
112 const std::string PlanningSceneMonitor::DEFAULT_ATTACHED_COLLISION_OBJECT_TOPIC = "attached_collision_object";
113 const std::string PlanningSceneMonitor::DEFAULT_COLLISION_OBJECT_TOPIC = "collision_object";
114 const std::string PlanningSceneMonitor::DEFAULT_PLANNING_SCENE_WORLD_TOPIC = "planning_scene_world";
115 const std::string PlanningSceneMonitor::DEFAULT_PLANNING_SCENE_TOPIC = "planning_scene";
116 const std::string PlanningSceneMonitor::DEFAULT_PLANNING_SCENE_SERVICE = "get_planning_scene";
117 const std::string PlanningSceneMonitor::MONITORED_PLANNING_SCENE_TOPIC = "monitored_planning_scene";
118 
119 PlanningSceneMonitor::PlanningSceneMonitor(const std::string& robot_description,
120  const std::shared_ptr<tf2_ros::Buffer>& tf_buffer, const std::string& name)
121  : PlanningSceneMonitor(planning_scene::PlanningScenePtr(), robot_description, tf_buffer, name)
122 {
123 }
124 
125 PlanningSceneMonitor::PlanningSceneMonitor(const planning_scene::PlanningScenePtr& scene,
126  const std::string& robot_description,
127  const std::shared_ptr<tf2_ros::Buffer>& tf_buffer, const std::string& name)
128  : PlanningSceneMonitor(scene, std::make_shared<robot_model_loader::RobotModelLoader>(robot_description), tf_buffer,
129  name)
130 {
131 }
132 
133 PlanningSceneMonitor::PlanningSceneMonitor(const robot_model_loader::RobotModelLoaderPtr& rm_loader,
134  const std::shared_ptr<tf2_ros::Buffer>& tf_buffer, const std::string& name)
135  : PlanningSceneMonitor(planning_scene::PlanningScenePtr(), rm_loader, tf_buffer, name)
136 {
137 }
138 
139 PlanningSceneMonitor::PlanningSceneMonitor(const planning_scene::PlanningScenePtr& scene,
140  const robot_model_loader::RobotModelLoaderPtr& rm_loader,
141  const std::shared_ptr<tf2_ros::Buffer>& tf_buffer, const std::string& name)
142  : monitor_name_(name), nh_("~"), tf_buffer_(tf_buffer), rm_loader_(rm_loader)
143 {
146  spinner_ = std::make_shared<ros::AsyncSpinner>(1, &queue_);
147  spinner_->start();
148  initialize(scene);
149 }
150 
151 PlanningSceneMonitor::PlanningSceneMonitor(const planning_scene::PlanningScenePtr& scene,
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)
155  : monitor_name_(name), nh_("~"), root_nh_(nh), tf_buffer_(tf_buffer), rm_loader_(rm_loader)
156 {
157  // use same callback queue as root_nh_
159  initialize(scene);
160 }
161 
163 {
164  if (scene_)
165  {
166  scene_->setCollisionObjectUpdateCallback(collision_detection::World::ObserverCallbackFn());
167  scene_->setAttachedBodyUpdateCallback(moveit::core::AttachedBodyCallback());
168  }
173 
174  spinner_.reset();
175  delete reconfigure_impl_;
176  current_state_monitor_.reset();
177  scene_const_.reset();
178  scene_.reset();
179  parent_scene_.reset();
180  robot_model_.reset();
181  rm_loader_.reset();
182 }
183 
184 void PlanningSceneMonitor::initialize(const planning_scene::PlanningScenePtr& scene)
185 {
187  moveit::tools::Profiler::ScopedBlock prof_block("PlanningSceneMonitor::initialize");
188 
189  if (monitor_name_.empty())
190  monitor_name_ = "planning_scene_monitor";
191  robot_description_ = rm_loader_->getRobotDescription();
192  if (rm_loader_->getModel())
193  {
194  robot_model_ = rm_loader_->getModel();
195  scene_ = scene;
196  if (!scene_)
197  {
198  try
199  {
200  scene_ = std::make_shared<planning_scene::PlanningScene>(rm_loader_->getModel());
203 
204  scene_->getCollisionEnvNonConst()->setPadding(default_robot_padd_);
205  scene_->getCollisionEnvNonConst()->setScale(default_robot_scale_);
206  for (const std::pair<const std::string, double>& it : default_robot_link_padd_)
207  {
208  scene_->getCollisionEnvNonConst()->setLinkPadding(it.first, it.second);
209  }
210  for (const std::pair<const std::string, double>& it : default_robot_link_scale_)
211  {
212  scene_->getCollisionEnvNonConst()->setLinkScale(it.first, it.second);
213  }
214  scene_->propogateRobotPadding();
215  }
217  {
218  ROS_ERROR_NAMED(LOGNAME, "Configuration of planning scene failed");
219  scene_.reset();
220  }
221  }
222  // scene_const_ is set regardless if scene_ is null or not
224  if (scene_)
225  {
226  // The scene_ is loaded on the collision loader only if it was correctly instantiated
228  scene_->setAttachedBodyUpdateCallback([this](moveit::core::AttachedBody* body, bool attached) {
230  });
231  scene_->setCollisionObjectUpdateCallback(
232  [this](const collision_detection::World::ObjectConstPtr& object, collision_detection::World::Action action) {
233  currentWorldObjectUpdateCallback(object, action);
234  });
235  }
236  }
237  else
238  {
239  ROS_ERROR_NAMED(LOGNAME, "Robot model not loaded");
240  }
241 
244 
248 
249  double temp_wait_time = 0.05;
250 
251  if (!robot_description_.empty())
252  nh_.param(robot_description_ + "_planning/shape_transform_cache_lookup_wait_time", temp_wait_time, temp_wait_time);
253 
255 
256  state_update_pending_ = false;
258  false, // not a oneshot timer
259  false); // do not start the timer yet
260 
261  reconfigure_impl_ = new DynamicReconfigureImpl(this);
262 
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());
266 }
267 
269 {
270  if (scene_)
271  {
272  if (flag)
273  {
274  boost::unique_lock<boost::shared_mutex> ulock(scene_update_mutex_);
275  if (scene_)
276  {
277  scene_->setAttachedBodyUpdateCallback(moveit::core::AttachedBodyCallback());
278  scene_->setCollisionObjectUpdateCallback(collision_detection::World::ObserverCallbackFn());
279  scene_->decoupleParent();
281  scene_ = parent_scene_->diff();
283  scene_->setAttachedBodyUpdateCallback([this](moveit::core::AttachedBody* body, bool attached) {
285  });
286  scene_->setCollisionObjectUpdateCallback(
287  [this](const collision_detection::World::ObjectConstPtr& object,
289  }
290  }
291  else
292  {
294  {
295  ROS_WARN_NAMED(LOGNAME, "Diff monitoring was stopped while publishing planning scene diffs. "
296  "Stopping planning scene diff publisher");
298  }
299  {
300  boost::unique_lock<boost::shared_mutex> ulock(scene_update_mutex_);
301  if (scene_)
302  {
303  scene_->decoupleParent();
304  parent_scene_.reset();
305  // remove the '+' added by .diff() at the end of the scene name
306  if (!scene_->getName().empty())
307  {
308  if (scene_->getName()[scene_->getName().length() - 1] == '+')
309  scene_->setName(scene_->getName().substr(0, scene_->getName().length() - 1));
310  }
311  }
312  }
313  }
314  }
315 }
316 
318 {
320  {
321  std::unique_ptr<boost::thread> copy;
322  copy.swap(publish_planning_scene_);
323  new_scene_update_condition_.notify_all();
324  copy->join();
325  monitorDiffs(false);
327  ROS_INFO_NAMED(LOGNAME, "Stopped publishing maintained planning scene.");
328  }
329 }
330 
331 void PlanningSceneMonitor::startPublishingPlanningScene(SceneUpdateType update_type,
332  const std::string& planning_scene_topic)
333 {
334  publish_update_types_ = update_type;
336  {
337  planning_scene_publisher_ = nh_.advertise<moveit_msgs::PlanningScene>(planning_scene_topic, 100, false);
338  ROS_INFO_NAMED(LOGNAME, "Publishing maintained planning scene on '%s'", planning_scene_topic.c_str());
339  monitorDiffs(true);
340  publish_planning_scene_ = std::make_unique<boost::thread>([this] { scenePublishingThread(); });
341  }
342 }
343 
345 {
346  ROS_DEBUG_NAMED(LOGNAME, "Started scene publishing thread ...");
347 
348  // publish the full planning scene once
349  {
350  moveit_msgs::PlanningScene msg;
351  {
353  if (octomap_monitor_)
354  lock = octomap_monitor_->getOcTreePtr()->reading();
355  scene_->getPlanningSceneMsg(msg);
356  }
358  ROS_DEBUG_NAMED(LOGNAME, "Published the full planning scene: '%s'", msg.name.c_str());
359  }
360 
361  do
362  {
363  moveit_msgs::PlanningScene msg;
364  bool publish_msg = false;
365  bool is_full = false;
367  {
368  boost::unique_lock<boost::shared_mutex> ulock(scene_update_mutex_);
370  new_scene_update_condition_.wait(ulock);
372  {
374  {
376  is_full = true;
377  else
378  {
380  if (octomap_monitor_)
381  lock = octomap_monitor_->getOcTreePtr()->reading();
382  scene_->getPlanningSceneDiffMsg(msg);
384  {
385  msg.robot_state.attached_collision_objects.clear();
386  msg.robot_state.is_diff = true;
387  }
388  }
389  boost::recursive_mutex::scoped_lock prevent_shape_cache_updates(shape_handles_lock_); // we don't want the
390  // transform cache to
391  // update while we are
392  // potentially changing
393  // attached bodies
394  scene_->setAttachedBodyUpdateCallback(moveit::core::AttachedBodyCallback());
395  scene_->setCollisionObjectUpdateCallback(collision_detection::World::ObserverCallbackFn());
396  scene_->pushDiffs(parent_scene_);
397  scene_->clearDiffs();
398  scene_->setAttachedBodyUpdateCallback([this](moveit::core::AttachedBody* body, bool attached) {
400  });
401  scene_->setCollisionObjectUpdateCallback(
402  [this](const collision_detection::World::ObjectConstPtr& object,
404  if (octomap_monitor_)
405  {
406  excludeAttachedBodiesFromOctree(); // in case updates have happened to the attached bodies, put them in
407  excludeWorldObjectsFromOctree(); // in case updates have happened to the attached bodies, put them in
408  }
409  if (is_full)
410  {
412  if (octomap_monitor_)
413  lock = octomap_monitor_->getOcTreePtr()->reading();
414  scene_->getPlanningSceneMsg(msg);
415  }
416  // also publish timestamp of this robot_state
417  msg.robot_state.joint_state.header.stamp = last_robot_motion_time_;
418  publish_msg = true;
419  }
421  }
422  }
423  if (publish_msg)
424  {
426  if (is_full)
427  ROS_DEBUG_NAMED(LOGNAME, "Published full planning scene: '%s'", msg.name.c_str());
428  rate.sleep();
429  }
430  } while (publish_planning_scene_);
431 }
432 
433 void PlanningSceneMonitor::getMonitoredTopics(std::vector<std::string>& topics) const
434 {
435  topics.clear();
437  {
438  const std::string& t = current_state_monitor_->getMonitoredTopic();
439  if (!t.empty())
440  topics.push_back(t);
441  }
443  topics.push_back(planning_scene_subscriber_.getTopic());
445  topics.push_back(collision_object_subscriber_.getTopic());
447  topics.push_back(planning_scene_world_subscriber_.getTopic());
448 }
449 
450 namespace
451 {
452 bool sceneIsParentOf(const planning_scene::PlanningSceneConstPtr& scene,
453  const planning_scene::PlanningScene* possible_parent)
454 {
455  if (scene && scene.get() == possible_parent)
456  return true;
457  if (scene)
458  return sceneIsParentOf(scene->getParent(), possible_parent);
459  return false;
460 }
461 } // namespace
462 
463 bool PlanningSceneMonitor::updatesScene(const planning_scene::PlanningScenePtr& scene) const
464 {
465  return sceneIsParentOf(scene_const_, scene.get());
466 }
467 
468 bool PlanningSceneMonitor::updatesScene(const planning_scene::PlanningSceneConstPtr& scene) const
469 {
470  return sceneIsParentOf(scene_const_, scene.get());
471 }
472 
473 void PlanningSceneMonitor::triggerSceneUpdateEvent(SceneUpdateType update_type)
474 {
475  // do not modify update functions while we are calling them
476  boost::recursive_mutex::scoped_lock lock(update_lock_);
477 
478  for (boost::function<void(SceneUpdateType)>& update_callback : update_callbacks_)
479  update_callback(update_type);
480  new_scene_update_ = (SceneUpdateType)((int)new_scene_update_ | (int)update_type);
481  new_scene_update_condition_.notify_all();
482 }
483 
484 bool PlanningSceneMonitor::requestPlanningSceneState(const std::string& service_name)
485 {
486  if (get_scene_service_.getService() == service_name)
487  {
488  ROS_FATAL_STREAM_NAMED(LOGNAME, "requestPlanningSceneState() to self-provided service '" << service_name << "'");
489  throw std::runtime_error("requestPlanningSceneState() to self-provided service: " + service_name);
490  }
491  // use global namespace for service
492  ros::ServiceClient client = ros::NodeHandle().serviceClient<moveit_msgs::GetPlanningScene>(service_name);
493  // all scene components are returned if none are specified
494  moveit_msgs::GetPlanningScene srv;
495 
496  // Make sure client is connected to server
497  if (!client.exists())
498  {
499  ROS_DEBUG_STREAM_NAMED(LOGNAME, "Waiting for service `" << service_name << "` to exist.");
501  }
502 
503  if (client.call(srv))
504  {
505  newPlanningSceneMessage(srv.response.scene);
506  }
507  else
508  {
510  LOGNAME, "Failed to call service %s, have you launched move_group or called psm.providePlanningSceneService()?",
511  service_name.c_str());
512  return false;
513  }
514  return true;
515 }
516 
517 void PlanningSceneMonitor::providePlanningSceneService(const std::string& service_name)
518 {
519  // Load the service
522 }
523 
524 bool PlanningSceneMonitor::getPlanningSceneServiceCallback(moveit_msgs::GetPlanningScene::Request& req,
525  moveit_msgs::GetPlanningScene::Response& res)
526 {
527  if (req.components.components & moveit_msgs::PlanningSceneComponents::TRANSFORMS)
529 
530  moveit_msgs::PlanningSceneComponents all_components;
531  all_components.components = UINT_MAX; // Return all scene components if nothing is specified.
532 
533  boost::unique_lock<boost::shared_mutex> ulock(scene_update_mutex_);
534  scene_->getPlanningSceneMsg(res.scene, req.components.components ? req.components : all_components);
535 
536  return true;
537 }
538 
539 void PlanningSceneMonitor::newPlanningSceneCallback(const moveit_msgs::PlanningSceneConstPtr& scene)
540 {
541  newPlanningSceneMessage(*scene);
542 }
543 
545 {
546  bool removed = false;
547  {
548  boost::unique_lock<boost::shared_mutex> ulock(scene_update_mutex_);
549  removed = scene_->getWorldNonConst()->removeObject(scene_->OCTOMAP_NS);
550 
551  if (octomap_monitor_)
552  {
553  octomap_monitor_->getOcTreePtr()->lockWrite();
554  octomap_monitor_->getOcTreePtr()->clear();
555  octomap_monitor_->getOcTreePtr()->unlockWrite();
556  }
557  else
558  {
559  ROS_WARN_NAMED(LOGNAME, "Unable to clear octomap since no octomap monitor has been initialized");
560  } // Lift the scoped lock before calling triggerSceneUpdateEvent to avoid deadlock
561  }
562 
563  if (removed)
565 }
566 
567 bool PlanningSceneMonitor::newPlanningSceneMessage(const moveit_msgs::PlanningScene& scene)
568 {
569  if (!scene_)
570  return false;
571 
572  bool result;
573 
575  std::string old_scene_name;
576  {
577  boost::unique_lock<boost::shared_mutex> ulock(scene_update_mutex_);
578  // we don't want the transform cache to update while we are potentially changing attached bodies
579  boost::recursive_mutex::scoped_lock prevent_shape_cache_updates(shape_handles_lock_);
580 
582  last_robot_motion_time_ = scene.robot_state.joint_state.header.stamp;
583  ROS_DEBUG_STREAM_NAMED("planning_scene_monitor",
584  "scene update " << fmod(last_update_time_.toSec(), 10.)
585  << " robot stamp: " << fmod(last_robot_motion_time_.toSec(), 10.));
586  old_scene_name = scene_->getName();
587 
588  if (!scene.is_diff && parent_scene_)
589  {
590  // clear maintained (diff) scene_ and set the full new scene in parent_scene_ instead
591  scene_->clearDiffs();
592  result = parent_scene_->setPlanningSceneMsg(scene);
593  // There were no callbacks for individual object changes, so rebuild the octree masks
596  }
597  else
598  {
599  result = scene_->usePlanningSceneMsg(scene);
600  }
601 
602  if (octomap_monitor_)
603  {
604  if (!scene.is_diff && scene.world.octomap.octomap.data.empty())
605  {
606  octomap_monitor_->getOcTreePtr()->lockWrite();
607  octomap_monitor_->getOcTreePtr()->clear();
608  octomap_monitor_->getOcTreePtr()->unlockWrite();
609  }
610  }
611  robot_model_ = scene_->getRobotModel();
612 
613  if (octomap_monitor_)
614  {
615  excludeAttachedBodiesFromOctree(); // in case updates have happened to the attached bodies, put them in
616  excludeWorldObjectsFromOctree(); // in case updates have happened to the attached bodies, put them in
617  }
618  }
619 
620  // if we have a diff, try to more accurately determine the update type
621  if (scene.is_diff)
622  {
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)
627  {
628  upd = UPDATE_NONE;
629  if (!moveit::core::isEmpty(scene.world))
630  upd = (SceneUpdateType)((int)upd | (int)UPDATE_GEOMETRY);
631 
632  if (!scene.fixed_frame_transforms.empty())
633  upd = (SceneUpdateType)((int)upd | (int)UPDATE_TRANSFORMS);
634 
635  if (!moveit::core::isEmpty(scene.robot_state))
636  {
637  upd = (SceneUpdateType)((int)upd | (int)UPDATE_STATE);
638  if (!scene.robot_state.attached_collision_objects.empty() || !static_cast<bool>(scene.robot_state.is_diff))
639  upd = (SceneUpdateType)((int)upd | (int)UPDATE_GEOMETRY);
640  }
641  }
642  }
644  return result;
645 }
646 
647 void PlanningSceneMonitor::newPlanningSceneWorldCallback(const moveit_msgs::PlanningSceneWorldConstPtr& world)
648 {
649  if (scene_)
650  {
652  {
653  boost::unique_lock<boost::shared_mutex> ulock(scene_update_mutex_);
655  scene_->getWorldNonConst()->clearObjects();
656  scene_->processPlanningSceneWorldMsg(*world);
657  if (octomap_monitor_)
658  {
659  if (world->octomap.octomap.data.empty())
660  {
661  octomap_monitor_->getOcTreePtr()->lockWrite();
662  octomap_monitor_->getOcTreePtr()->clear();
663  octomap_monitor_->getOcTreePtr()->unlockWrite();
664  }
665  }
666  }
668  }
669 }
670 
671 void PlanningSceneMonitor::collisionObjectCallback(const moveit_msgs::CollisionObjectConstPtr& obj)
672 {
673  if (!scene_)
674  return;
675 
677  {
678  boost::unique_lock<boost::shared_mutex> ulock(scene_update_mutex_);
680  if (!scene_->processCollisionObjectMsg(*obj))
681  return;
682  }
684 }
685 
686 void PlanningSceneMonitor::attachObjectCallback(const moveit_msgs::AttachedCollisionObjectConstPtr& obj)
687 {
688  if (scene_)
689  {
691  {
692  boost::unique_lock<boost::shared_mutex> ulock(scene_update_mutex_);
694  scene_->processAttachedCollisionObjectMsg(*obj);
695  }
697  }
698 }
699 
701 {
702  if (!octomap_monitor_)
703  return;
704 
705  boost::recursive_mutex::scoped_lock _(shape_handles_lock_);
706 
708  const std::vector<const moveit::core::LinkModel*>& links = getRobotModel()->getLinkModelsWithCollisionGeometry();
710  bool warned = false;
711  for (const moveit::core::LinkModel* link : links)
712  {
713  std::vector<shapes::ShapeConstPtr> shapes = link->getShapes(); // copy shared ptrs on purpuse
714  for (std::size_t j = 0; j < shapes.size(); ++j)
715  {
716  // merge mesh vertices up to 0.1 mm apart
717  if (shapes[j]->type == shapes::MESH)
718  {
719  shapes::Mesh* m = static_cast<shapes::Mesh*>(shapes[j]->clone());
720  m->mergeVertices(1e-4);
721  shapes[j].reset(m);
722  }
723 
725  if (h)
726  link_shape_handles_[link].push_back(std::make_pair(h, j));
727  }
728  if (!warned && ((ros::WallTime::now() - start) > ros::WallDuration(30.0)))
729  {
730  ROS_WARN_STREAM_NAMED(LOGNAME, "It is likely there are too many vertices in collision geometry");
731  warned = true;
732  }
733  }
734 }
735 
737 {
738  if (!octomap_monitor_)
739  return;
740 
741  boost::recursive_mutex::scoped_lock _(shape_handles_lock_);
742 
743  for (std::pair<const moveit::core::LinkModel* const,
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)
747  octomap_monitor_->forgetShape(it.first);
748  link_shape_handles_.clear();
749 }
750 
752 {
753  if (!octomap_monitor_)
754  return;
755 
756  boost::recursive_mutex::scoped_lock _(shape_handles_lock_);
757 
758  // clear information about any attached body, without refering to the AttachedBody* ptr (could be invalid)
759  for (std::pair<const moveit::core::AttachedBody* const,
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)
763  octomap_monitor_->forgetShape(it.first);
765 }
766 
768 {
769  boost::recursive_mutex::scoped_lock _(shape_handles_lock_);
770 
772  // add attached objects again
773  std::vector<const moveit::core::AttachedBody*> ab;
774  scene_->getCurrentState().getAttachedBodies(ab);
775  for (const moveit::core::AttachedBody* body : ab)
777 }
778 
780 {
781  if (!octomap_monitor_)
782  return;
783 
784  boost::recursive_mutex::scoped_lock _(shape_handles_lock_);
785 
786  // clear information about any attached object
787  for (std::pair<const std::string, std::vector<std::pair<occupancy_map_monitor::ShapeHandle, const Eigen::Isometry3d*>>>&
788  collision_body_shape_handle : collision_body_shape_handles_)
789  for (std::pair<occupancy_map_monitor::ShapeHandle, const Eigen::Isometry3d*>& it :
790  collision_body_shape_handle.second)
791  octomap_monitor_->forgetShape(it.first);
793 }
794 
796 {
797  boost::recursive_mutex::scoped_lock _(shape_handles_lock_);
798 
800  for (const std::pair<const std::string, collision_detection::World::ObjectPtr>& it : *scene_->getWorld())
801  excludeWorldObjectFromOctree(it.second);
802 }
803 
805 {
806  if (!octomap_monitor_)
807  return;
808 
809  boost::recursive_mutex::scoped_lock _(shape_handles_lock_);
810  bool found = false;
811  for (std::size_t i = 0; i < attached_body->getShapes().size(); ++i)
812  {
813  if (attached_body->getShapes()[i]->type == shapes::PLANE || attached_body->getShapes()[i]->type == shapes::OCTREE)
814  continue;
815  occupancy_map_monitor::ShapeHandle h = octomap_monitor_->excludeShape(attached_body->getShapes()[i]);
816  if (h)
817  {
818  found = true;
819  attached_body_shape_handles_[attached_body].push_back(std::make_pair(h, i));
820  }
821  }
822  if (found)
823  ROS_DEBUG_NAMED(LOGNAME, "Excluding attached body '%s' from monitored octomap", attached_body->getName().c_str());
824 }
825 
827 {
828  if (!octomap_monitor_)
829  return;
830 
831  boost::recursive_mutex::scoped_lock _(shape_handles_lock_);
832 
833  AttachedBodyShapeHandles::iterator it = attached_body_shape_handles_.find(attached_body);
834  if (it != attached_body_shape_handles_.end())
835  {
836  for (std::pair<occupancy_map_monitor::ShapeHandle, std::size_t>& shape_handle : it->second)
837  octomap_monitor_->forgetShape(shape_handle.first);
838  ROS_DEBUG_NAMED(LOGNAME, "Including attached body '%s' in monitored octomap", attached_body->getName().c_str());
840  }
841 }
842 
843 void PlanningSceneMonitor::excludeWorldObjectFromOctree(const collision_detection::World::ObjectConstPtr& obj)
844 {
845  if (!octomap_monitor_)
846  return;
847 
848  boost::recursive_mutex::scoped_lock _(shape_handles_lock_);
849 
850  bool found = false;
851  for (std::size_t i = 0; i < obj->shapes_.size(); ++i)
852  {
853  if (obj->shapes_[i]->type == shapes::PLANE || obj->shapes_[i]->type == shapes::OCTREE)
854  continue;
855  occupancy_map_monitor::ShapeHandle h = octomap_monitor_->excludeShape(obj->shapes_[i]);
856  if (h)
857  {
858  collision_body_shape_handles_[obj->id_].push_back(std::make_pair(h, &obj->global_shape_poses_[i]));
859  found = true;
860  }
861  }
862  if (found)
863  ROS_DEBUG_NAMED(LOGNAME, "Excluding collision object '%s' from monitored octomap", obj->id_.c_str());
864 }
865 
866 void PlanningSceneMonitor::includeWorldObjectInOctree(const collision_detection::World::ObjectConstPtr& obj)
867 {
868  if (!octomap_monitor_)
869  return;
870 
871  boost::recursive_mutex::scoped_lock _(shape_handles_lock_);
872 
873  CollisionBodyShapeHandles::iterator it = collision_body_shape_handles_.find(obj->id_);
874  if (it != collision_body_shape_handles_.end())
875  {
876  for (std::pair<occupancy_map_monitor::ShapeHandle, const Eigen::Isometry3d*>& shape_handle : it->second)
877  octomap_monitor_->forgetShape(shape_handle.first);
878  ROS_DEBUG_NAMED(LOGNAME, "Including collision object '%s' in monitored octomap", obj->id_.c_str());
880  }
881 }
882 
884  bool just_attached)
885 {
886  if (!octomap_monitor_)
887  return;
888 
889  if (just_attached)
890  excludeAttachedBodyFromOctree(attached_body);
891  else
892  includeAttachedBodyInOctree(attached_body);
893 }
894 
895 void PlanningSceneMonitor::currentWorldObjectUpdateCallback(const collision_detection::World::ObjectConstPtr& obj,
897 {
899  return;
901  return;
902 
905  else if (action & collision_detection::World::DESTROY)
907  else
908  {
911  }
912 }
913 
914 bool PlanningSceneMonitor::waitForCurrentRobotState(const ros::Time& t, double wait_time)
915 {
916  if (t.isZero())
917  return false;
919  ros::WallDuration timeout(wait_time);
920 
921  ROS_DEBUG_NAMED(LOGNAME, "sync robot state to: %.3fs", fmod(t.toSec(), 10.));
922 
924  {
925  // Wait for next robot update in state monitor.
926  bool success = current_state_monitor_->waitForCurrentState(t, wait_time);
927 
928  /* As robot updates are passed to the planning scene only in throttled fashion, there might
929  be still an update pending. If so, explicitly update the planning scene here.
930  If waitForCurrentState failed, we didn't get any new state updates within wait_time. */
931  if (success)
932  {
933  boost::mutex::scoped_lock lock(state_pending_mutex_);
934  if (state_update_pending_) // enforce state update
935  {
936  state_update_pending_ = false;
938  lock.unlock();
940  }
941  return true;
942  }
943 
944  ROS_WARN_NAMED(LOGNAME, "Failed to fetch current robot state.");
945  return false;
946  }
947 
948  // Sometimes there is no state monitor. In this case state updates are received as part of scene updates only.
949  // However, scene updates are only published if the robot actually moves. Hence we need a timeout!
950  // As publishing planning scene updates is throttled (2Hz by default), a 1s timeout is a suitable default.
951  boost::shared_lock<boost::shared_mutex> lock(scene_update_mutex_);
952  ros::Time prev_robot_motion_time = last_robot_motion_time_;
953  while (last_robot_motion_time_ < t && // Wait until the state update actually reaches the scene.
954  timeout > ros::WallDuration())
955  {
956  ROS_DEBUG_STREAM_NAMED(LOGNAME, "last robot motion: " << (t - last_robot_motion_time_).toSec() << " ago");
957  new_scene_update_condition_.wait_for(lock, boost::chrono::nanoseconds(timeout.toNSec()));
958  timeout -= ros::WallTime::now() - start; // compute remaining wait_time
959  }
960  bool success = last_robot_motion_time_ >= t;
961  // suppress warning if we received an update at all
962  if (!success && prev_robot_motion_time != last_robot_motion_time_)
963  ROS_WARN_NAMED(LOGNAME, "Maybe failed to update robot state, time diff: %.3fs",
964  (t - last_robot_motion_time_).toSec());
965 
966  ROS_DEBUG_STREAM_NAMED(LOGNAME, "sync done: robot motion: " << (t - last_robot_motion_time_).toSec()
967  << " scene update: " << (t - last_update_time_).toSec());
968  return success;
969 }
970 
972 {
973  scene_update_mutex_.lock_shared();
974  if (octomap_monitor_)
975  octomap_monitor_->getOcTreePtr()->lockRead();
976 }
977 
979 {
980  if (octomap_monitor_)
981  octomap_monitor_->getOcTreePtr()->unlockRead();
982  scene_update_mutex_.unlock_shared();
983 }
984 
986 {
987  scene_update_mutex_.lock();
988  if (octomap_monitor_)
989  octomap_monitor_->getOcTreePtr()->lockWrite();
990 }
991 
993 {
994  if (octomap_monitor_)
995  octomap_monitor_->getOcTreePtr()->unlockWrite();
996  scene_update_mutex_.unlock();
997 }
998 
999 void PlanningSceneMonitor::startSceneMonitor(const std::string& scene_topic)
1000 {
1001  stopSceneMonitor();
1002 
1003  ROS_INFO_NAMED(LOGNAME, "Starting planning scene monitor");
1004  // listen for planning scene updates; these messages include transforms, so no need for filters
1005  if (!scene_topic.empty())
1006  {
1009  ROS_INFO_NAMED(LOGNAME, "Listening to '%s'", root_nh_.resolveName(scene_topic).c_str());
1010  }
1011 }
1012 
1014 {
1016  {
1017  ROS_INFO_NAMED(LOGNAME, "Stopping planning scene monitor");
1019  }
1020 }
1021 
1022 bool PlanningSceneMonitor::getShapeTransformCache(const std::string& target_frame, const ros::Time& target_time,
1025  if (!tf_buffer_)
1026  return false;
1027  try
1028  {
1029  boost::recursive_mutex::scoped_lock _(shape_handles_lock_);
1030 
1031  for (const std::pair<const moveit::core::LinkModel* const,
1032  std::vector<std::pair<occupancy_map_monitor::ShapeHandle, std::size_t>>>& link_shape_handle :
1034  {
1035  tf_buffer_->canTransform(target_frame, link_shape_handle.first->getName(), target_time,
1037  Eigen::Isometry3d ttr = tf2::transformToEigen(
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];
1042  }
1043  for (const std::pair<const moveit::core::AttachedBody* const,
1044  std::vector<std::pair<occupancy_map_monitor::ShapeHandle, std::size_t>>>&
1045  attached_body_shape_handle : attached_body_shape_handles_)
1046  {
1047  tf_buffer_->canTransform(target_frame, attached_body_shape_handle.first->getAttachedLinkName(), target_time,
1049  Eigen::Isometry3d transform = tf2::transformToEigen(tf_buffer_->lookupTransform(
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] =
1053  transform *
1054  attached_body_shape_handle.first->getShapePosesInLinkFrame()[attached_body_shape_handle.second[k].second];
1055  }
1056  {
1057  tf_buffer_->canTransform(target_frame, scene_->getPlanningFrame(), target_time,
1059  Eigen::Isometry3d transform =
1060  tf2::transformToEigen(tf_buffer_->lookupTransform(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*>>>&
1063  collision_body_shape_handle : collision_body_shape_handles_)
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);
1067  }
1068  }
1069  catch (tf2::TransformException& ex)
1070  {
1071  ROS_ERROR_THROTTLE_NAMED(1, LOGNAME, "Transform error: %s", ex.what());
1072  return false;
1073  }
1074  return true;
1075 }
1076 
1077 void PlanningSceneMonitor::startWorldGeometryMonitor(const std::string& collision_objects_topic,
1078  const std::string& planning_scene_world_topic,
1079  const bool load_octomap_monitor)
1080 {
1082  ROS_INFO_NAMED(LOGNAME, "Starting world geometry update monitor for collision objects, attached objects, octomap "
1083  "updates.");
1084 
1085  // Listen to the /collision_objects topic to detect requests to add/remove/update collision objects to/from the world
1086  if (!collision_objects_topic.empty())
1087  {
1089  root_nh_.subscribe(collision_objects_topic, 1024, &PlanningSceneMonitor::collisionObjectCallback, this);
1090  ROS_INFO_NAMED(LOGNAME, "Listening to '%s'", root_nh_.resolveName(collision_objects_topic).c_str());
1091  }
1092 
1093  if (!planning_scene_world_topic.empty())
1094  {
1096  root_nh_.subscribe(planning_scene_world_topic, 1, &PlanningSceneMonitor::newPlanningSceneWorldCallback, this);
1097  ROS_INFO_NAMED(LOGNAME, "Listening to '%s' for planning scene world geometry",
1098  root_nh_.resolveName(planning_scene_world_topic).c_str());
1099  }
1100 
1101  // Ocotomap monitor is optional
1102  if (load_octomap_monitor)
1103  {
1104  if (!octomap_monitor_)
1105  {
1107  std::make_unique<occupancy_map_monitor::OccupancyMapMonitor>(tf_buffer_, scene_->getPlanningFrame());
1111 
1112  octomap_monitor_->setTransformCacheCallback(
1113  [this](const std::string& frame, const ros::Time& stamp, occupancy_map_monitor::ShapeTransformCache& cache) {
1114  return getShapeTransformCache(frame, stamp, cache);
1115  });
1116  octomap_monitor_->setUpdateCallback([this] { octomapUpdateCallback(); });
1117  }
1118  octomap_monitor_->startMonitor();
1119  }
1120 }
1121 
1123 {
1125  {
1126  ROS_INFO_NAMED(LOGNAME, "Stopping world geometry monitor");
1128  }
1130  {
1131  ROS_INFO_NAMED(LOGNAME, "Stopping world geometry monitor");
1133  }
1134  if (octomap_monitor_)
1135  octomap_monitor_->stopMonitor();
1136 }
1137 
1138 void PlanningSceneMonitor::startStateMonitor(const std::string& joint_states_topic,
1139  const std::string& attached_objects_topic)
1140 {
1141  stopStateMonitor();
1142  if (scene_)
1143  {
1145  current_state_monitor_ = std::make_shared<CurrentStateMonitor>(getRobotModel(), tf_buffer_, root_nh_);
1146  current_state_monitor_->addUpdateCallback(
1147  [this](const sensor_msgs::JointStateConstPtr& state) { onStateUpdate(state); });
1148  current_state_monitor_->startStateMonitor(joint_states_topic);
1149 
1150  {
1151  boost::mutex::scoped_lock lock(state_pending_mutex_);
1152  if (!dt_state_update_.isZero())
1154  }
1155 
1156  if (!attached_objects_topic.empty())
1157  {
1158  // using regular message filter as there's no header
1160  root_nh_.subscribe(attached_objects_topic, 1024, &PlanningSceneMonitor::attachObjectCallback, this);
1161  ROS_INFO_NAMED(LOGNAME, "Listening to '%s' for attached collision objects",
1162  root_nh_.resolveName(attached_objects_topic).c_str());
1163  }
1164  }
1165  else
1166  ROS_ERROR_NAMED(LOGNAME, "Cannot monitor robot state because planning scene is not configured");
1167 }
1168 
1172  current_state_monitor_->stopStateMonitor();
1175 
1176  // stop must be called with state_pending_mutex_ unlocked to avoid deadlock
1178  {
1179  boost::mutex::scoped_lock lock(state_pending_mutex_);
1180  state_update_pending_ = false;
1181  }
1182 }
1183 
1184 void PlanningSceneMonitor::onStateUpdate(const sensor_msgs::JointStateConstPtr& /* joint_state */)
1185 {
1186  const ros::WallTime& n = ros::WallTime::now();
1188 
1189  bool update = false;
1190  {
1191  boost::mutex::scoped_lock lock(state_pending_mutex_);
1192 
1193  if (dt < dt_state_update_)
1194  {
1195  state_update_pending_ = true;
1196  }
1197  else
1198  {
1199  state_update_pending_ = false;
1201  update = true;
1202  }
1203  }
1204  // run the state update with state_pending_mutex_ unlocked
1205  if (update)
1207 }
1208 
1210 {
1212  {
1213  bool update = false;
1214 
1215  const ros::WallTime& n = ros::WallTime::now();
1217 
1218  {
1219  // lock for access to dt_state_update_ and state_update_pending_
1220  boost::mutex::scoped_lock lock(state_pending_mutex_);
1222  {
1223  state_update_pending_ = false;
1225  update = true;
1227  "performPendingStateUpdate: " << fmod(last_robot_state_update_wall_time_.toSec(), 10));
1228  }
1229  }
1230 
1231  // run the state update with state_pending_mutex_ unlocked
1232  if (update)
1233  {
1235  ROS_DEBUG_NAMED(LOGNAME, "performPendingStateUpdate done");
1236  }
1237  }
1238 }
1239 
1242  if (!octomap_monitor_)
1243  return;
1244 
1246  {
1247  boost::unique_lock<boost::shared_mutex> ulock(scene_update_mutex_);
1249  octomap_monitor_->getOcTreePtr()->lockRead();
1250  try
1251  {
1252  scene_->processOctomapPtr(octomap_monitor_->getOcTreePtr(), Eigen::Isometry3d::Identity());
1253  octomap_monitor_->getOcTreePtr()->unlockRead();
1254  }
1255  catch (...)
1256  {
1257  octomap_monitor_->getOcTreePtr()->unlockRead(); // unlock and rethrow
1258  throw;
1259  }
1260  }
1262 }
1263 
1265 {
1266  bool update = false;
1267  if (hz > std::numeric_limits<double>::epsilon())
1268  {
1269  boost::mutex::scoped_lock lock(state_pending_mutex_);
1270  dt_state_update_.fromSec(1.0 / hz);
1273  }
1274  else
1275  {
1276  // stop must be called with state_pending_mutex_ unlocked to avoid deadlock
1278  boost::mutex::scoped_lock lock(state_pending_mutex_);
1281  update = true;
1282  }
1283  ROS_INFO_NAMED(LOGNAME, "Updating internal planning scene state at most every %lf seconds", dt_state_update_.toSec());
1284 
1285  if (update)
1287 }
1288 
1290 {
1292  {
1293  std::vector<std::string> missing;
1294  if (!current_state_monitor_->haveCompleteState(missing) &&
1295  (ros::Time::now() - current_state_monitor_->getMonitorStartTime()).toSec() > 1.0)
1296  {
1297  std::string missing_str = boost::algorithm::join(missing, ", ");
1298  ROS_WARN_THROTTLE_NAMED(1, LOGNAME, "The complete state of the robot is not yet known. Missing %s",
1299  missing_str.c_str());
1300  }
1301 
1302  {
1303  boost::unique_lock<boost::shared_mutex> ulock(scene_update_mutex_);
1305  ROS_DEBUG_STREAM_NAMED(LOGNAME, "robot state update " << fmod(last_robot_motion_time_.toSec(), 10.));
1306  current_state_monitor_->setToCurrentState(scene_->getCurrentStateNonConst());
1307  scene_->getCurrentStateNonConst().update(); // compute all transforms
1308  }
1310  }
1311  else
1312  ROS_ERROR_THROTTLE_NAMED(1, LOGNAME, "State monitor is not active. Unable to set the planning scene state");
1313 }
1314 
1315 void PlanningSceneMonitor::addUpdateCallback(const boost::function<void(SceneUpdateType)>& fn)
1316 {
1317  boost::recursive_mutex::scoped_lock lock(update_lock_);
1318  if (fn)
1319  update_callbacks_.push_back(fn);
1320 }
1323 {
1324  boost::recursive_mutex::scoped_lock lock(update_lock_);
1325  update_callbacks_.clear();
1326 }
1327 
1329 {
1331  ROS_DEBUG_NAMED(LOGNAME, "Maximum frequency for publishing a planning scene is now %lf Hz",
1333 }
1334 
1335 void PlanningSceneMonitor::getUpdatedFrameTransforms(std::vector<geometry_msgs::TransformStamped>& transforms)
1336 {
1337  const std::string& target = getRobotModel()->getModelFrame();
1338 
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)
1342  {
1343  if (all_frame_name == target || getRobotModel()->hasLinkModel(all_frame_name) || checkFrameIgnored(all_frame_name))
1344  continue;
1345 
1346  geometry_msgs::TransformStamped f;
1347  try
1348  {
1349  f = tf_buffer_->lookupTransform(target, all_frame_name, ros::Time(0));
1350  }
1351  catch (tf2::TransformException& ex)
1352  {
1353  ROS_WARN_STREAM_NAMED(LOGNAME, "Unable to transform object from frame '"
1354  << all_frame_name << "' to planning frame '" << target << "' (" << ex.what()
1355  << ")");
1356  continue;
1357  }
1358  f.header.frame_id = all_frame_name;
1359  f.child_frame_id = target;
1360  transforms.push_back(f);
1361  }
1362 }
1363 
1365 {
1366  if (!tf_buffer_)
1367  return;
1368 
1369  if (scene_)
1370  {
1371  std::vector<geometry_msgs::TransformStamped> transforms;
1372  getUpdatedFrameTransforms(transforms);
1373  {
1374  boost::unique_lock<boost::shared_mutex> ulock(scene_update_mutex_);
1375  scene_->getTransformsNonConst().setTransforms(transforms);
1377  }
1379  }
1380 }
1381 
1383 {
1384  if (octomap_monitor_)
1385  octomap_monitor_->publishDebugInformation(flag);
1386 }
1387 
1388 void PlanningSceneMonitor::configureCollisionMatrix(const planning_scene::PlanningScenePtr& scene)
1389 {
1390  if (!scene || robot_description_.empty())
1391  return;
1392  collision_detection::AllowedCollisionMatrix& acm = scene->getAllowedCollisionMatrixNonConst();
1393 
1394  // read overriding values from the param server
1395 
1396  // first we do default collision operations
1397  if (!nh_.hasParam(robot_description_ + "_planning/default_collision_operations"))
1398  ROS_DEBUG_NAMED(LOGNAME, "No additional default collision operations specified");
1399  else
1400  {
1401  ROS_DEBUG_NAMED(LOGNAME, "Reading additional default collision operations");
1402 
1403  XmlRpc::XmlRpcValue coll_ops;
1404  nh_.getParam(robot_description_ + "_planning/default_collision_operations", coll_ops);
1405 
1406  if (coll_ops.getType() != XmlRpc::XmlRpcValue::TypeArray)
1407  {
1408  ROS_WARN_NAMED(LOGNAME, "default_collision_operations is not an array");
1409  return;
1410  }
1411 
1412  if (coll_ops.size() == 0)
1413  {
1414  ROS_WARN_NAMED(LOGNAME, "No collision operations in default collision operations");
1415  return;
1416  }
1417 
1418  for (int i = 0; i < coll_ops.size(); ++i) // NOLINT(modernize-loop-convert)
1419  {
1420  if (!coll_ops[i].hasMember("object1") || !coll_ops[i].hasMember("object2") || !coll_ops[i].hasMember("operation"))
1421  {
1422  ROS_WARN_NAMED(LOGNAME, "All collision operations must have two objects and an operation");
1423  continue;
1424  }
1425  acm.setEntry(std::string(coll_ops[i]["object1"]), std::string(coll_ops[i]["object2"]),
1426  std::string(coll_ops[i]["operation"]) == "disable");
1427  }
1428  }
1429 }
1430 
1432 {
1433  if (robot_description_.empty())
1434  {
1435  default_robot_padd_ = 0.0;
1436  default_robot_scale_ = 1.0;
1437  default_object_padd_ = 0.0;
1438  default_attached_padd_ = 0.0;
1439  return;
1440  }
1441 
1442  // print deprecation warning if necessary
1443  // TODO: remove this warning after 06/2022
1444  const std::string old_robot_description =
1445  (robot_description_[0] == '/') ? robot_description_.substr(1) : robot_description_;
1446  if (nh_.resolveName(old_robot_description) != nh_.resolveName(robot_description_))
1447  {
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"))
1454  {
1455  ROS_WARN_STREAM_NAMED(LOGNAME, "The path for the padding parameters has changed!\n"
1456  "Old parameter path: '"
1457  << nh_.resolveName(old_robot_description + "_planning/")
1458  << "'\n"
1459  "New parameter path: '"
1460  << nh_.resolveName(robot_description_ + "_planning/")
1461  << "'\n"
1462  "Ignoring old parameters. Please update your moveit config!");
1463  }
1464  }
1465 
1466  nh_.param(robot_description_ + "_planning/default_robot_padding", default_robot_padd_, 0.0);
1467  nh_.param(robot_description_ + "_planning/default_robot_scale", default_robot_scale_, 1.0);
1468  nh_.param(robot_description_ + "_planning/default_object_padding", default_object_padd_, 0.0);
1469  nh_.param(robot_description_ + "_planning/default_attached_padding", default_attached_padd_, 0.0);
1470  nh_.param(robot_description_ + "_planning/default_robot_link_padding", default_robot_link_padd_,
1471  std::map<std::string, double>());
1472  nh_.param(robot_description_ + "_planning/default_robot_link_scale", default_robot_link_scale_,
1473  std::map<std::string, double>());
1474 
1475  ROS_DEBUG_STREAM_NAMED(LOGNAME, "Loaded " << default_robot_link_padd_.size() << " default link paddings");
1476  ROS_DEBUG_STREAM_NAMED(LOGNAME, "Loaded " << default_robot_link_scale_.size() << " default link scales");
1477 }
1478 
1479 bool PlanningSceneMonitor::checkFrameIgnored(const std::string& frame)
1480 {
1481  return (ignored_frames_.find(frame) != ignored_frames_.end());
1482 }
1483 } // namespace planning_scene_monitor
planning_scene_monitor::PlanningSceneMonitor::excludeWorldObjectFromOctree
void excludeWorldObjectFromOctree(const collision_detection::World::ObjectConstPtr &obj)
Definition: planning_scene_monitor.cpp:875
XmlRpc::XmlRpcValue::size
int size() const
planning_scene_monitor::PlanningSceneMonitor::planning_scene_world_subscriber_
ros::Subscriber planning_scene_world_subscriber_
Definition: planning_scene_monitor.h:536
moveit::core::LinkModel
planning_scene_monitor::PlanningSceneMonitor::collision_body_shape_handles_
CollisionBodyShapeHandles collision_body_shape_handles_
Definition: planning_scene_monitor.h:561
planning_scene_monitor::PlanningSceneMonitor::publishDebugInformation
void publishDebugInformation(bool flag)
Definition: planning_scene_monitor.cpp:1414
planning_scene_monitor
Definition: current_state_monitor.h:47
planning_scene_monitor::PlanningSceneMonitor::onStateUpdate
void onStateUpdate(const sensor_msgs::JointStateConstPtr &joint_state)
Definition: planning_scene_monitor.cpp:1216
planning_scene_monitor::PlanningSceneMonitor::currentWorldObjectUpdateCallback
void currentWorldObjectUpdateCallback(const collision_detection::World::ObjectConstPtr &object, collision_detection::World::Action action)
Callback for a change in the world maintained by the planning scene.
Definition: planning_scene_monitor.cpp:927
planning_scene_monitor::PlanningSceneMonitor::default_attached_padd_
double default_attached_padd_
default attached padding
Definition: planning_scene_monitor.h:520
planning_scene_monitor::PlanningSceneMonitor::default_robot_link_padd_
std::map< std::string, double > default_robot_link_padd_
default robot link padding
Definition: planning_scene_monitor.h:522
ros::ServiceClient::waitForExistence
bool waitForExistence(ros::Duration timeout=ros::Duration(-1))
ROS_ERROR_THROTTLE_NAMED
#define ROS_ERROR_THROTTLE_NAMED(period, name,...)
collision_detection::World::DESTROY
DESTROY
ros::service::exists
ROSCPP_DECL bool exists(const std::string &service_name, bool print_failure_reason)
planning_scene_monitor::PlanningSceneMonitor::configureDefaultPadding
void configureDefaultPadding()
Configure the default padding.
Definition: planning_scene_monitor.cpp:1463
shapes
planning_scene_monitor::PlanningSceneMonitor::attached_body_shape_handles_
AttachedBodyShapeHandles attached_body_shape_handles_
Definition: planning_scene_monitor.h:560
planning_scene_monitor::PlanningSceneMonitor::DEFAULT_PLANNING_SCENE_SERVICE
static const std::string DEFAULT_PLANNING_SCENE_SERVICE
The name of the service used by default for requesting full planning scene state.
Definition: planning_scene_monitor.h:132
occupancy_map_monitor::ShapeTransformCache
std::map< ShapeHandle, Eigen::Isometry3d, std::less< ShapeHandle >, Eigen::aligned_allocator< std::pair< const ShapeHandle, Eigen::Isometry3d > > > ShapeTransformCache
DurationBase< WallDuration >::fromSec
WallDuration & fromSec(double t)
planning_scene_monitor::PlanningSceneMonitor::triggerSceneUpdateEvent
void triggerSceneUpdateEvent(SceneUpdateType update_type)
This function is called every time there is a change to the planning scene.
Definition: planning_scene_monitor.cpp:505
planning_scene_monitor::PlanningSceneMonitor::~PlanningSceneMonitor
~PlanningSceneMonitor()
Definition: planning_scene_monitor.cpp:194
planning_scene_monitor::PlanningSceneMonitor::getShapeTransformCache
bool getShapeTransformCache(const std::string &target_frame, const ros::Time &target_time, occupancy_map_monitor::ShapeTransformCache &cache) const
Definition: planning_scene_monitor.cpp:1054
planning_scene_monitor::PlanningSceneMonitor::stopStateMonitor
void stopStateMonitor()
Stop the state monitor.
Definition: planning_scene_monitor.cpp:1201
planning_scene_monitor::PlanningSceneMonitor::updatesScene
bool updatesScene(const planning_scene::PlanningSceneConstPtr &scene) const
Return true if the scene scene can be updated directly or indirectly by this monitor....
Definition: planning_scene_monitor.cpp:500
planning_scene_monitor::PlanningSceneMonitor::newPlanningSceneMessage
bool newPlanningSceneMessage(const moveit_msgs::PlanningScene &scene)
Definition: planning_scene_monitor.cpp:599
planning_scene_monitor::PlanningSceneMonitor::octomapUpdateCallback
void octomapUpdateCallback()
Callback for octomap updates.
Definition: planning_scene_monitor.cpp:1272
planning_scene_monitor::PlanningSceneMonitor::addUpdateCallback
void addUpdateCallback(const boost::function< void(SceneUpdateType)> &fn)
Add a function to be called when an update to the scene is received.
Definition: planning_scene_monitor.cpp:1347
planning_scene_monitor::PlanningSceneMonitor::spinner_
std::shared_ptr< ros::AsyncSpinner > spinner_
Definition: planning_scene_monitor.h:507
ros::ServiceClient::exists
bool exists()
shapes::PLANE
PLANE
tf2_eigen.h
ROS_DEBUG_STREAM_NAMED
#define ROS_DEBUG_STREAM_NAMED(name, args)
ros
ros::NodeHandle::getParam
bool getParam(const std::string &key, bool &b) const
planning_scene_monitor::PlanningSceneMonitor::collision_loader_
collision_detection::CollisionPluginLoader collision_loader_
Definition: planning_scene_monitor.h:616
planning_scene_monitor::PlanningSceneMonitor::scenePublishingThread
void scenePublishingThread()
Definition: planning_scene_monitor.cpp:376
planning_scene_monitor::PlanningSceneMonitor::default_robot_padd_
double default_robot_padd_
default robot padding
Definition: planning_scene_monitor.h:514
robot_model_loader
Definition: robot_model_loader.h:44
planning_scene::PlanningScene
getName
ROSCONSOLE_CONSOLE_IMPL_DECL std::string getName(void *handle)
planning_scene_monitor::PlanningSceneMonitor::attached_collision_object_subscriber_
ros::Subscriber attached_collision_object_subscriber_
Definition: planning_scene_monitor.h:538
planning_scene_monitor::PlanningSceneMonitor::setStateUpdateFrequency
void setStateUpdateFrequency(double hz)
Update the scene using the monitored state at a specified frequency, in Hz. This function has an effe...
Definition: planning_scene_monitor.cpp:1296
planning_scene_monitor::PlanningSceneMonitor::collisionObjectCallback
void collisionObjectCallback(const moveit_msgs::CollisionObjectConstPtr &obj)
Callback for a new collision object msg.
Definition: planning_scene_monitor.cpp:703
planning_scene_monitor::PlanningSceneMonitor::scene_const_
planning_scene::PlanningSceneConstPtr scene_const_
Definition: planning_scene_monitor.h:498
ros::Subscriber::getTopic
std::string getTopic() const
planning_scene_monitor::PlanningSceneMonitor::update_lock_
boost::recursive_mutex update_lock_
lock access to update_callbacks_
Definition: planning_scene_monitor.h:565
TimeBase< Time, Duration >::toSec
double toSec() const
planning_scene_monitor::PlanningSceneMonitor::collision_object_subscriber_
ros::Subscriber collision_object_subscriber_
Definition: planning_scene_monitor.h:539
ros::NodeHandle::advertiseService
ServiceServer advertiseService(AdvertiseServiceOptions &ops)
collision_detection::World::Action
ros::Subscriber::shutdown
void shutdown()
moveit::tools::Profiler::ScopedStart
ROS_ERROR_NAMED
#define ROS_ERROR_NAMED(name,...)
transform
template Halfspace< double > transform(const Halfspace< double > &a, const Transform3< double > &tf)
shapes::Mesh::mergeVertices
void mergeVertices(double threshold)
shapes::Mesh
planning_scene_monitor::PlanningSceneMonitor::updateFrameTransforms
void updateFrameTransforms()
Update the transforms for the frames that are not part of the kinematic model using tf....
Definition: planning_scene_monitor.cpp:1396
planning_scene_monitor::LOGNAME
static const std::string LOGNAME
Definition: planning_scene_monitor.cpp:91
planning_scene_monitor::PlanningSceneMonitor::excludeWorldObjectsFromOctree
void excludeWorldObjectsFromOctree()
Definition: planning_scene_monitor.cpp:827
planning_scene_monitor::PlanningSceneMonitor::last_robot_motion_time_
ros::Time last_robot_motion_time_
Last time the state was updated.
Definition: planning_scene_monitor.h:502
ros::Publisher::publish
void publish(const boost::shared_ptr< M > &message) const
ros::NodeHandle::advertise
Publisher advertise(AdvertiseOptions &ops)
obj
CollisionObject< S > * obj
planning_scene_monitor::PlanningSceneMonitor::rm_loader_
robot_model_loader::RobotModelLoaderPtr rm_loader_
Definition: planning_scene_monitor.h:613
planning_scene_monitor::PlanningSceneMonitor::new_scene_update_
SceneUpdateType new_scene_update_
Definition: planning_scene_monitor.h:531
planning_scene_monitor::PlanningSceneMonitor::tf_buffer_
std::shared_ptr< tf2_ros::Buffer > tf_buffer_
Definition: planning_scene_monitor.h:509
shapes::MESH
MESH
f
f
planning_scene_monitor::PlanningSceneMonitor::state_update_timer_
ros::WallTimer state_update_timer_
timer for state updates.
Definition: planning_scene_monitor.h:607
ros::WallTimer::start
void start()
planning_scene_monitor::PlanningSceneMonitor::SceneUpdateType
SceneUpdateType
Definition: planning_scene_monitor.h:96
moveit::core::AttachedBody
planning_scene_monitor::PlanningSceneMonitor::default_robot_scale_
double default_robot_scale_
default robot scaling
Definition: planning_scene_monitor.h:516
planning_scene_monitor::PlanningSceneMonitor::state_pending_mutex_
boost::mutex state_pending_mutex_
Definition: planning_scene_monitor.h:589
planning_scene_monitor::PlanningSceneMonitor::initialize
void initialize(const planning_scene::PlanningScenePtr &scene)
Initialize the planning scene monitor.
Definition: planning_scene_monitor.cpp:216
ros::NodeHandle::resolveName
std::string resolveName(const std::string &name, bool remap=true) const
planning_scene_monitor::PlanningSceneMonitor::publish_update_types_
SceneUpdateType publish_update_types_
Definition: planning_scene_monitor.h:530
collision_detection::AllowedCollisionMatrix::setEntry
void setEntry(bool allowed)
collision_detection::AllowedCollisionMatrix
message_checks.h
planning_scene_monitor::PlanningSceneMonitor::octomap_monitor_
std::unique_ptr< occupancy_map_monitor::OccupancyMapMonitor > octomap_monitor_
Definition: planning_scene_monitor.h:546
planning_scene_monitor::PlanningSceneMonitor::updateSceneWithCurrentState
void updateSceneWithCurrentState()
Update the scene using the monitored state. This function is automatically called when an update to t...
Definition: planning_scene_monitor.cpp:1321
moveit::core::isEmpty
bool isEmpty(const geometry_msgs::Pose &msg)
planning_scene_monitor::PlanningSceneMonitor::getRobotModel
const moveit::core::RobotModelConstPtr & getRobotModel() const
Definition: planning_scene_monitor.h:205
planning_scene_monitor::PlanningSceneMonitor::last_update_time_
ros::Time last_update_time_
mutex for stored scene
Definition: planning_scene_monitor.h:501
planning_scene_monitor::PlanningSceneMonitor::new_scene_update_condition_
boost::condition_variable_any new_scene_update_condition_
Definition: planning_scene_monitor.h:532
name
std::string name
ros::Publisher::shutdown
void shutdown()
planning_scene_monitor::PlanningSceneMonitor::lockSceneRead
void lockSceneRead()
Lock the scene for reading (multiple threads can lock for reading at the same time)
Definition: planning_scene_monitor.cpp:1003
ROS_INFO_NAMED
#define ROS_INFO_NAMED(name,...)
update
void update(const std::string &key, const XmlRpc::XmlRpcValue &v)
collision_detection::World::ObserverCallbackFn
boost::function< void(const ObjectConstPtr &, Action)> ObserverCallbackFn
ROS_FATAL_STREAM_NAMED
#define ROS_FATAL_STREAM_NAMED(name, args)
planning_scene_monitor::PlanningSceneMonitor::unlockSceneRead
void unlockSceneRead()
Unlock the scene from reading (multiple threads can lock for reading at the same time)
Definition: planning_scene_monitor.cpp:1010
planning_scene_monitor::PlanningSceneMonitor::DEFAULT_PLANNING_SCENE_WORLD_TOPIC
static const std::string DEFAULT_PLANNING_SCENE_WORLD_TOPIC
Definition: planning_scene_monitor.h:126
ROS_DEBUG_NAMED
#define ROS_DEBUG_NAMED(name,...)
planning_scene_monitor::PlanningSceneMonitor::root_nh_
ros::NodeHandle root_nh_
Definition: planning_scene_monitor.h:505
planning_scene_monitor::PlanningSceneMonitor::current_state_monitor_
CurrentStateMonitorPtr current_state_monitor_
Definition: planning_scene_monitor.h:549
ros::WallTime::now
static WallTime now()
planning_scene_monitor::PlanningSceneMonitor::checkFrameIgnored
bool checkFrameIgnored(const std::string &frame)
Definition: planning_scene_monitor.cpp:1511
planning_scene_monitor::PlanningSceneMonitor::stopPublishingPlanningScene
void stopPublishingPlanningScene()
Stop publishing the maintained planning scene.
Definition: planning_scene_monitor.cpp:349
planning_scene_monitor::PlanningSceneMonitor::excludeAttachedBodyFromOctree
void excludeAttachedBodyFromOctree(const moveit::core::AttachedBody *attached_body)
Definition: planning_scene_monitor.cpp:836
planning_scene_monitor::PlanningSceneMonitor::UPDATE_STATE
@ UPDATE_STATE
The state in the monitored scene was updated.
Definition: planning_scene_monitor.h:102
planning_scene_monitor::PlanningSceneMonitor::reconfigure_impl_
DynamicReconfigureImpl * reconfigure_impl_
Definition: planning_scene_monitor.h:618
planning_scene_monitor::PlanningSceneMonitor::queue_
ros::CallbackQueue queue_
Definition: planning_scene_monitor.h:506
planning_scene_monitor::PlanningSceneMonitor::stopSceneMonitor
void stopSceneMonitor()
Stop the scene monitor.
Definition: planning_scene_monitor.cpp:1045
planning_scene_monitor::PlanningSceneMonitor::stopWorldGeometryMonitor
void stopWorldGeometryMonitor()
Stop the world geometry monitor.
Definition: planning_scene_monitor.cpp:1154
planning_scene_monitor::PlanningSceneMonitor::DEFAULT_COLLISION_OBJECT_TOPIC
static const std::string DEFAULT_COLLISION_OBJECT_TOPIC
The name of the topic used by default for receiving collision objects in the world.
Definition: planning_scene_monitor.h:122
planning_scene_monitor::PlanningSceneMonitor::startStateMonitor
void startStateMonitor(const std::string &joint_states_topic=DEFAULT_JOINT_STATES_TOPIC, const std::string &attached_objects_topic=DEFAULT_ATTACHED_COLLISION_OBJECT_TOPIC)
Start the current state monitor.
Definition: planning_scene_monitor.cpp:1170
planning_scene_monitor::PlanningSceneMonitor::excludeRobotLinksFromOctree
void excludeRobotLinksFromOctree()
Definition: planning_scene_monitor.cpp:732
ros::WallTimer::setPeriod
void setPeriod(const WallDuration &period, bool reset=true)
planning_scene_monitor::PlanningSceneMonitor::getPlanningSceneServiceCallback
bool getPlanningSceneServiceCallback(moveit_msgs::GetPlanningScene::Request &req, moveit_msgs::GetPlanningScene::Response &res)
Definition: planning_scene_monitor.cpp:556
planning_scene_monitor::PlanningSceneMonitor::publish_planning_scene_
std::unique_ptr< boost::thread > publish_planning_scene_
Definition: planning_scene_monitor.h:528
ros::ServiceClient
ros::NodeHandle::hasParam
bool hasParam(const std::string &key) const
planning_scene_monitor.h
planning_scene_monitor::PlanningSceneMonitor::last_robot_state_update_wall_time_
ros::WallTime last_robot_state_update_wall_time_
Last time the state was updated from current_state_monitor_.
Definition: planning_scene_monitor.h:611
planning_scene_monitor::PlanningSceneMonitor::get_scene_service_
ros::ServiceServer get_scene_service_
Definition: planning_scene_monitor.h:543
ros::NodeHandle::getCallbackQueue
CallbackQueueInterface * getCallbackQueue() const
moveit::core::AttachedBodyCallback
boost::function< void(AttachedBody *body, bool attached)> AttachedBodyCallback
planning_scene_monitor::PlanningSceneMonitor::unlockSceneWrite
void unlockSceneWrite()
Lock the scene from writing (only one thread can lock for writing and no other thread can lock for re...
Definition: planning_scene_monitor.cpp:1024
planning_scene_monitor::PlanningSceneMonitor::robot_description_
std::string robot_description_
Definition: planning_scene_monitor.h:511
planning_scene_monitor::PlanningSceneMonitor::default_object_padd_
double default_object_padd_
default object padding
Definition: planning_scene_monitor.h:518
planning_scene_monitor::PlanningSceneMonitor::robot_model_
moveit::core::RobotModelConstPtr robot_model_
Definition: planning_scene_monitor.h:614
planning_scene_monitor::PlanningSceneMonitor::includeAttachedBodyInOctree
void includeAttachedBodyInOctree(const moveit::core::AttachedBody *attached_body)
Definition: planning_scene_monitor.cpp:858
planning_scene_monitor::PlanningSceneMonitor::stateUpdateTimerCallback
void stateUpdateTimerCallback(const ros::WallTimerEvent &event)
Definition: planning_scene_monitor.cpp:1241
ros::NodeHandle::subscribe
Subscriber subscribe(const std::string &topic, uint32_t queue_size, const boost::function< void(C)> &callback, const VoidConstPtr &tracked_object=VoidConstPtr(), const TransportHints &transport_hints=TransportHints())
ros::WallTime
planning_scene_monitor::PlanningSceneMonitor::setPlanningScenePublishingFrequency
void setPlanningScenePublishingFrequency(double hz)
Set the maximum frequency at which planning scenes are being published.
Definition: planning_scene_monitor.cpp:1360
planning_scene_monitor::PlanningSceneMonitor::default_robot_link_scale_
std::map< std::string, double > default_robot_link_scale_
default robot link scale
Definition: planning_scene_monitor.h:524
planning_scene_monitor::PlanningSceneMonitor::monitor_name_
std::string monitor_name_
The name of this scene monitor.
Definition: planning_scene_monitor.h:495
collision_detection::OccMapTree::ReadLock
boost::shared_lock< boost::shared_mutex > ReadLock
planning_scene_monitor::PlanningSceneMonitor::publish_planning_scene_frequency_
double publish_planning_scene_frequency_
Definition: planning_scene_monitor.h:529
XmlRpc::XmlRpcValue::getType
const Type & getType() const
ROS_WARN_THROTTLE_NAMED
#define ROS_WARN_THROTTLE_NAMED(period, name,...)
planning_scene_monitor::PlanningSceneMonitor
PlanningSceneMonitor Subscribes to the topic planning_scene.
Definition: planning_scene_monitor.h:93
tf2::transformToEigen
Eigen::Isometry3d transformToEigen(const geometry_msgs::Transform &t)
ros::NodeHandle::setCallbackQueue
void setCallbackQueue(CallbackQueueInterface *queue)
shapes::OCTREE
OCTREE
planning_scene_monitor::PlanningSceneMonitor::shape_handles_lock_
boost::recursive_mutex shape_handles_lock_
Definition: planning_scene_monitor.h:562
planning_scene_monitor::PlanningSceneMonitor::startWorldGeometryMonitor
void startWorldGeometryMonitor(const std::string &collision_objects_topic=DEFAULT_COLLISION_OBJECT_TOPIC, const std::string &planning_scene_world_topic=DEFAULT_PLANNING_SCENE_WORLD_TOPIC, const bool load_octomap_monitor=true)
Start the OccupancyMapMonitor and listening for:
Definition: planning_scene_monitor.cpp:1109
exceptions.h
ROS_WARN_STREAM_NAMED
#define ROS_WARN_STREAM_NAMED(name, args)
XmlRpc::XmlRpcValue::TypeArray
TypeArray
planning_scene_monitor::PlanningSceneMonitor::UPDATE_NONE
@ UPDATE_NONE
No update.
Definition: planning_scene_monitor.h:99
start
ROSCPP_DECL void start()
occupancy_map_monitor::ShapeHandle
unsigned int ShapeHandle
planning_scene_monitor::PlanningSceneMonitor::scene_
planning_scene::PlanningScenePtr scene_
Definition: planning_scene_monitor.h:497
planning_scene_monitor::PlanningSceneMonitor::newPlanningSceneWorldCallback
void newPlanningSceneWorldCallback(const moveit_msgs::PlanningSceneWorldConstPtr &world)
Callback for a new planning scene world.
Definition: planning_scene_monitor.cpp:679
planning_scene_monitor::PlanningSceneMonitor::nh_
ros::NodeHandle nh_
Last time the robot has moved.
Definition: planning_scene_monitor.h:504
planning_scene_monitor::PlanningSceneMonitor::DEFAULT_JOINT_STATES_TOPIC
static const std::string DEFAULT_JOINT_STATES_TOPIC
The name of the topic used by default for receiving joint states.
Definition: planning_scene_monitor.h:116
planning_scene_monitor::PlanningSceneMonitor::currentStateAttachedBodyUpdateCallback
void currentStateAttachedBodyUpdateCallback(moveit::core::AttachedBody *attached_body, bool just_attached)
Callback for a change for an attached object of the current state of the planning scene.
Definition: planning_scene_monitor.cpp:915
ros::WallTimerEvent
planning_scene_monitor::PlanningSceneMonitor::DEFAULT_PLANNING_SCENE_TOPIC
static const std::string DEFAULT_PLANNING_SCENE_TOPIC
The name of the topic used by default for receiving full planning scenes or planning scene diffs.
Definition: planning_scene_monitor.h:129
planning_scene_monitor::PlanningSceneMonitor::MONITORED_PLANNING_SCENE_TOPIC
static const std::string MONITORED_PLANNING_SCENE_TOPIC
Definition: planning_scene_monitor.h:136
ros::Time
planning_scene_monitor::PlanningSceneMonitor::includeRobotLinksInOctree
void includeRobotLinksInOctree()
Definition: planning_scene_monitor.cpp:768
planning_scene_monitor::PlanningSceneMonitor::waitForCurrentRobotState
bool waitForCurrentRobotState(const ros::Time &t, double wait_time=1.)
Wait for robot state to become more recent than time t.
Definition: planning_scene_monitor.cpp:946
DurationBase< WallDuration >::toNSec
int64_t toNSec() const
planning_scene_monitor::PlanningSceneMonitor::state_update_pending_
volatile bool state_update_pending_
True when we need to update the RobotState from current_state_monitor_.
Definition: planning_scene_monitor.h:593
planning_scene_monitor::PlanningSceneMonitor::attachObjectCallback
void attachObjectCallback(const moveit_msgs::AttachedCollisionObjectConstPtr &obj)
Callback for a new attached object msg.
Definition: planning_scene_monitor.cpp:718
tf_buffer
tf2_ros::Buffer * tf_buffer
planning_scene_monitor::PlanningSceneMonitor::startSceneMonitor
void startSceneMonitor(const std::string &scene_topic=DEFAULT_PLANNING_SCENE_TOPIC)
Start the scene monitor (ROS topic-based)
Definition: planning_scene_monitor.cpp:1031
std
planning_scene_monitor::PlanningSceneMonitor::newPlanningSceneCallback
void newPlanningSceneCallback(const moveit_msgs::PlanningSceneConstPtr &scene)
Definition: planning_scene_monitor.cpp:571
ros::ServiceClient::call
bool call(const MReq &req, MRes &resp, const std::string &service_md5sum)
moveit::core::AttachedBody::getShapes
const std::vector< shapes::ShapeConstPtr > & getShapes() const
planning_scene_monitor::PlanningSceneMonitor::planning_scene_subscriber_
ros::Subscriber planning_scene_subscriber_
Definition: planning_scene_monitor.h:535
planning_scene::PlanningScene::OCTOMAP_NS
static const MOVEIT_PLANNING_SCENE_EXPORT std::string OCTOMAP_NS
ros::ServiceServer::getService
std::string getService() const
planning_scene_monitor::PlanningSceneMonitor::includeWorldObjectsInOctree
void includeWorldObjectsInOctree()
Definition: planning_scene_monitor.cpp:811
moveit::tools::Profiler::ScopedBlock
ROS_WARN_NAMED
#define ROS_WARN_NAMED(name,...)
planning_scene_monitor::PlanningSceneMonitor::ignored_frames_
std::set< std::string > ignored_frames_
Definition: planning_scene_monitor.h:621
planning_scene_monitor::PlanningSceneMonitor::excludeAttachedBodiesFromOctree
void excludeAttachedBodiesFromOctree()
Definition: planning_scene_monitor.cpp:799
planning_scene_monitor::PlanningSceneMonitor::configureCollisionMatrix
void configureCollisionMatrix(const planning_scene::PlanningScenePtr &scene)
Configure the collision matrix for a particular scene.
Definition: planning_scene_monitor.cpp:1420
planning_scene_monitor::PlanningSceneMonitor::dt_state_update_
ros::WallDuration dt_state_update_
the amount of time to wait in between updates to the robot state
Definition: planning_scene_monitor.h:597
ros::NodeHandle::param
T param(const std::string &param_name, const T &default_val) const
planning_scene_monitor::PlanningSceneMonitor::UPDATE_GEOMETRY
@ UPDATE_GEOMETRY
The geometry of the scene was updated. This includes receiving new octomaps, collision objects,...
Definition: planning_scene_monitor.h:109
tf2_geometry_msgs.h
planning_scene_monitor::PlanningSceneMonitor::providePlanningSceneService
void providePlanningSceneService(const std::string &service_name=DEFAULT_PLANNING_SCENE_SERVICE)
Create an optional service for getting the complete planning scene This is useful for satisfying the ...
Definition: planning_scene_monitor.cpp:549
ros::Rate
planning_scene_monitor::PlanningSceneMonitor::getMonitoredTopics
void getMonitoredTopics(std::vector< std::string > &topics) const
Get the topic names that the monitor is listening to.
Definition: planning_scene_monitor.cpp:465
planning_scene_monitor::PlanningSceneMonitor::getUpdatedFrameTransforms
void getUpdatedFrameTransforms(std::vector< geometry_msgs::TransformStamped > &transforms)
Definition: planning_scene_monitor.cpp:1367
planning_scene_monitor::PlanningSceneMonitor::clearUpdateCallbacks
void clearUpdateCallbacks()
Clear the functions to be called when an update to the scene is received.
Definition: planning_scene_monitor.cpp:1354
planning_scene_monitor::PlanningSceneMonitor::clearOctomap
void clearOctomap()
Definition: planning_scene_monitor.cpp:576
planning_scene_monitor::PlanningSceneMonitor::UPDATE_SCENE
@ UPDATE_SCENE
The entire scene was updated.
Definition: planning_scene_monitor.h:112
DurationBase< WallDuration >::toSec
double toSec() const
collision_detection::CollisionPluginLoader::setupScene
void setupScene(ros::NodeHandle &nh, const planning_scene::PlanningScenePtr &scene)
Fetch plugin name from parameter server and activate the plugin for the given scene.
Definition: collision_plugin_loader.cpp:40
moveit::ConstructException
planning_scene_monitor::PlanningSceneMonitor::parent_scene_
planning_scene::PlanningScenePtr parent_scene_
Definition: planning_scene_monitor.h:499
profiler.h
ros::WallDuration
collision_detection::World::CREATE
CREATE
tf2::TransformException
planning_scene
planning_scene_monitor::PlanningSceneMonitor::requestPlanningSceneState
bool requestPlanningSceneState(const std::string &service_name=DEFAULT_PLANNING_SCENE_SERVICE)
Request a full planning scene state using a service call Be careful not to use this in conjunction wi...
Definition: planning_scene_monitor.cpp:516
planning_scene_monitor::PlanningSceneMonitor::startPublishingPlanningScene
void startPublishingPlanningScene(SceneUpdateType event, const std::string &planning_scene_topic=MONITORED_PLANNING_SCENE_TOPIC)
Start publishing the maintained planning scene. The first message set out is a complete planning scen...
Definition: planning_scene_monitor.cpp:363
planning_scene_monitor::PlanningSceneMonitor::monitorDiffs
void monitorDiffs(bool flag)
By default, the maintained planning scene does not reason about diffs. When the flag passed in is tru...
Definition: planning_scene_monitor.cpp:300
planning_scene_monitor::PlanningSceneMonitor::update_callbacks_
std::vector< boost::function< void(SceneUpdateType)> > update_callbacks_
Definition: planning_scene_monitor.h:566
planning_scene_monitor::PlanningSceneMonitor::UPDATE_TRANSFORMS
@ UPDATE_TRANSFORMS
The maintained set of fixed transforms in the monitored scene was updated.
Definition: planning_scene_monitor.h:105
ros::Duration
ros::NodeHandle::createWallTimer
WallTimer createWallTimer(WallDuration period, const WallTimerCallback &callback, bool oneshot=false, bool autostart=true) const
moveit::core::AttachedBody::getName
const std::string & getName() const
planning_scene_monitor::PlanningSceneMonitor::planning_scene_publisher_
ros::Publisher planning_scene_publisher_
Definition: planning_scene_monitor.h:527
t
geometry_msgs::TransformStamped t
planning_scene_monitor::PlanningSceneMonitor::link_shape_handles_
LinkShapeHandles link_shape_handles_
Definition: planning_scene_monitor.h:559
Transform.h
ros::WallTimer::stop
void stop()
planning_scene_monitor::PlanningSceneMonitor::includeWorldObjectInOctree
void includeWorldObjectInOctree(const collision_detection::World::ObjectConstPtr &obj)
Definition: planning_scene_monitor.cpp:898
XmlRpc::XmlRpcValue
planning_scene_monitor::PlanningSceneMonitor::includeAttachedBodiesInOctree
void includeAttachedBodiesInOctree()
Definition: planning_scene_monitor.cpp:783
planning_scene_monitor::PlanningSceneMonitor::scene_update_mutex_
boost::shared_mutex scene_update_mutex_
if diffs are monitored, this is the pointer to the parent scene
Definition: planning_scene_monitor.h:500
DurationBase< WallDuration >::isZero
bool isZero() const
ros::NodeHandle
planning_scene_monitor::PlanningSceneMonitor::PlanningSceneMonitor
PlanningSceneMonitor(const std::string &robot_description, const std::shared_ptr< tf2_ros::Buffer > &tf_buffer=std::shared_ptr< tf2_ros::Buffer >(), const std::string &name="")
Constructor.
Definition: planning_scene_monitor.cpp:151
planning_scene_monitor::PlanningSceneMonitor::shape_transform_cache_lookup_wait_time_
ros::Duration shape_transform_cache_lookup_wait_time_
the amount of time to wait when looking up transforms
Definition: planning_scene_monitor.h:602
ros::Time::now
static Time now()
planning_scene_monitor::PlanningSceneMonitor::DEFAULT_ATTACHED_COLLISION_OBJECT_TOPIC
static const std::string DEFAULT_ATTACHED_COLLISION_OBJECT_TOPIC
The name of the topic used by default for attached collision objects.
Definition: planning_scene_monitor.h:119
robot_model_loader.h
planning_scene_monitor::PlanningSceneMonitor::lockSceneWrite
void lockSceneWrite()
Lock the scene for writing (only one thread can lock for writing and no other thread can lock for rea...
Definition: planning_scene_monitor.cpp:1017


planning
Author(s): Ioan Sucan , Sachin Chitta
autogenerated on Thu Nov 21 2024 03:24:18