graph.cpp
Go to the documentation of this file.
1 
29 #include <boost/graph/directed_graph.hpp> // A subclass to provide reasonable arguments to adjacency_list for a typical directed graph
30 #include <boost/graph/depth_first_search.hpp>
31 #include <boost/graph/breadth_first_search.hpp>
32 #include <boost/graph/adj_list_serialize.hpp>
33 #include <boost/graph/dijkstra_shortest_paths.hpp>
34 #include <boost/graph/undirected_graph.hpp>
35 #include <boost/graph/copy.hpp>
36 #include <boost/serialization/access.hpp>
37 #include <boost/serialization/base_object.hpp>
38 #include <boost/serialization/nvp.hpp>
39 #include <boost/serialization/shared_ptr.hpp>
40 #include <boost/serialization/split_member.hpp>
41 #include <fstream>
42 #include <console_bridge/console.h>
43 #if (BOOST_VERSION >= 107400) && (BOOST_VERSION < 107500)
44 #include <boost/serialization/library_version_type.hpp>
45 #endif
46 #include <boost/serialization/unordered_map.hpp>
47 #include <boost/serialization/utility.hpp>
49 
54 #include <tesseract_common/utils.h>
55 
56 namespace tesseract_scene_graph
57 {
58 struct cycle_detector : public boost::dfs_visitor<>
59 {
60  cycle_detector(bool& ascyclic) : ascyclic_(ascyclic) {}
61 
62  template <class e, class g>
63  void back_edge(e, g&)
64  {
65  ascyclic_ = false;
66  }
67 
68 protected:
69  bool& ascyclic_; // NOLINT(cppcoreguidelines-avoid-const-or-ref-data-members)
70 };
71 
72 struct tree_detector : public boost::dfs_visitor<>
73 {
74  tree_detector(bool& tree) : tree_(tree) {}
75 
76  template <class u, class g>
77  void discover_vertex(u vertex, const g& graph)
78  {
79  auto num_in_edges = static_cast<int>(boost::in_degree(vertex, graph));
80 
81  if (num_in_edges > 1)
82  {
83  tree_ = false;
84  return;
85  }
86 
87  // Check if more that one root exist
88  if (num_in_edges == 0 && found_root_)
89  {
90  tree_ = false;
91  return;
92  }
93 
94  if (num_in_edges == 0)
95  found_root_ = true;
96 
97  // Check if not vertex is unused.
98  if (num_in_edges == 0 && boost::out_degree(vertex, graph) == 0)
99  {
100  tree_ = false;
101  return;
102  }
103  }
104 
105  template <class e, class g>
106  void back_edge(e, const g&)
107  {
108  tree_ = false;
109  }
110 
111 protected:
112  bool& tree_; // NOLINT(cppcoreguidelines-avoid-const-or-ref-data-members)
113  bool found_root_{ false };
114 };
115 
116 struct children_detector : public boost::default_bfs_visitor
117 {
118  children_detector(std::vector<std::string>& children) : children_(children) {}
119 
120  template <class u, class g>
121  void discover_vertex(u vertex, const g& graph)
122  {
123  children_.push_back(boost::get(boost::vertex_link, graph)[vertex]->getName());
124  }
125 
126 protected:
127  std::vector<std::string>& children_; // NOLINT(cppcoreguidelines-avoid-const-or-ref-data-members)
128 };
129 
130 struct adjacency_detector : public boost::default_bfs_visitor
131 {
132  adjacency_detector(std::unordered_map<std::string, std::string>& adjacency_map,
133  std::map<SceneGraph::Vertex, boost::default_color_type>& color_map,
134  const std::string& base_link_name,
135  const std::vector<std::string>& terminate_on_links)
136  : adjacency_map_(adjacency_map)
137  , color_map_(color_map)
138  , base_link_name_(base_link_name)
139  , terminate_on_links_(terminate_on_links)
140  {
141  }
142 
143  template <class u, class g>
144  void examine_vertex(u vertex, const g& graph)
145  {
146  for (auto vd : boost::make_iterator_range(adjacent_vertices(vertex, graph)))
147  {
148  std::string adj_link = boost::get(boost::vertex_link, graph)[vd]->getName();
149  if (std::find(terminate_on_links_.begin(), terminate_on_links_.end(), adj_link) != terminate_on_links_.end())
150  color_map_[vd] = boost::default_color_type::black_color;
151  }
152  }
153 
154  template <class u, class g>
155  void discover_vertex(u vertex, const g& graph)
156  {
157  std::string adj_link = boost::get(boost::vertex_link, graph)[vertex]->getName();
158  adjacency_map_[adj_link] = base_link_name_;
159  }
160 
161 protected:
162  // NOLINTNEXTLINE(cppcoreguidelines-avoid-const-or-ref-data-members)
163  std::unordered_map<std::string, std::string>& adjacency_map_;
164  // NOLINTNEXTLINE(cppcoreguidelines-avoid-const-or-ref-data-members)
165  std::map<SceneGraph::Vertex, boost::default_color_type>& color_map_;
166  const std::string& base_link_name_; // NOLINT(cppcoreguidelines-avoid-const-or-ref-data-members)
167  const std::vector<std::string>& terminate_on_links_; // NOLINT(cppcoreguidelines-avoid-const-or-ref-data-members)
168 };
169 
170 using UGraph =
171  boost::adjacency_list<boost::listS, boost::listS, boost::undirectedS, VertexProperty, EdgeProperty, GraphProperty>;
172 
174 {
176  : vertex_all_map1(get(boost::vertex_all, g1)), vertex_all_map2(get(boost::vertex_all, g2))
177  {
178  }
179 
180  template <typename Vertex1, typename Vertex2>
181  void operator()(const Vertex1& v1, Vertex2& v2) const
182  {
183  boost::put(vertex_all_map2, v2, get(vertex_all_map1, v1));
184  }
185  typename boost::property_map<Graph, boost::vertex_all_t>::const_type vertex_all_map1;
186  mutable typename boost::property_map<UGraph, boost::vertex_all_t>::type vertex_all_map2;
187 };
188 
189 SceneGraph::SceneGraph(const std::string& name) : acm_(std::make_shared<tesseract_common::AllowedCollisionMatrix>())
190 {
191  boost::set_property(static_cast<Graph&>(*this), boost::graph_name, name);
192 }
193 
195  : Graph(other) // Graph does not have a move constructor
196  , link_map_(std::move(other.link_map_))
197  , joint_map_(std::move(other.joint_map_))
198  , acm_(std::move(other.acm_))
199 {
200  rebuildLinkAndJointMaps();
201 }
202 
204 {
205  Graph::operator=(other); // Graph does not have move assignment operator
206 
207  link_map_ = std::move(other.link_map_);
208  joint_map_ = std::move(other.joint_map_);
209  acm_ = std::move(other.acm_);
210 
211  rebuildLinkAndJointMaps();
212 
213  return *this;
214 }
215 
217 {
218  auto cloned_graph = std::make_unique<SceneGraph>();
219 
220  for (auto& link : getLinks())
221  {
222  cloned_graph->addLink(link->clone(link->getName()));
223  cloned_graph->setLinkVisibility(link->getName(), getLinkVisibility(link->getName()));
224  cloned_graph->setLinkCollisionEnabled(link->getName(), getLinkCollisionEnabled(link->getName()));
225  }
226 
227  for (auto& joint : getJoints())
228  cloned_graph->addJoint(joint->clone(joint->getName()));
229 
230  cloned_graph->getAllowedCollisionMatrix()->insertAllowedCollisionMatrix(*getAllowedCollisionMatrix());
231 
232  cloned_graph->setName(getName());
233  cloned_graph->setRoot(getRoot());
234 
235  return cloned_graph;
236 }
237 
239 {
240  Graph::clear();
241  link_map_.clear();
242  joint_map_.clear();
243  acm_->clearAllowedCollisions();
244 }
245 
246 void SceneGraph::setName(const std::string& name)
247 {
248  boost::set_property(static_cast<Graph&>(*this), boost::graph_name, name);
249 }
250 
251 const std::string& SceneGraph::getName() const
252 {
253  return boost::get_property(static_cast<const Graph&>(*this), boost::graph_name);
254 }
255 
256 bool SceneGraph::setRoot(const std::string& name)
257 {
258  auto found = link_map_.find(name);
259 
260  if (found == link_map_.end())
261  return false;
262 
263  boost::set_property(static_cast<Graph&>(*this), boost::graph_root, name);
264 
265  return true;
266 }
267 
268 const std::string& SceneGraph::getRoot() const
269 {
270  return boost::get_property(static_cast<const Graph&>(*this), boost::graph_root);
271 }
272 
273 bool SceneGraph::addLink(const Link& link, bool replace_allowed)
274 {
275  auto link_ptr = std::make_shared<tesseract_scene_graph::Link>(link.clone());
276  return addLinkHelper(link_ptr, replace_allowed);
277 }
278 
279 bool SceneGraph::addLink(const Link& link, const Joint& joint)
280 {
281  if (getLink(link.getName()) != nullptr)
282  {
283  CONSOLE_BRIDGE_logWarn("Tried to add link (%s) with same name as an existing link.", link.getName().c_str());
284  return false;
285  }
286 
287  if (getJoint(joint.getName()) != nullptr)
288  {
289  CONSOLE_BRIDGE_logWarn("Tried to add joint (%s) with same name as an existing joint.", joint.getName().c_str());
290  return false;
291  }
292 
293  if (!addLinkHelper(std::make_shared<Link>(link.clone())))
294  return false; // LCOV_EXCL_LINE
295 
296  if (!addJointHelper(std::make_shared<Joint>(joint.clone())))
297  return false; // LCOV_EXCL_LINE
298 
299  return true;
300 }
301 
302 bool SceneGraph::addLinkHelper(const std::shared_ptr<Link>& link_ptr, bool replace_allowed)
303 {
304  auto found = link_map_.find(link_ptr->getName());
305  bool link_exists = (found != link_map_.end());
306  if (link_exists && !replace_allowed)
307  return false;
308 
309  if (link_exists && replace_allowed)
310  { // replacing an existing link
311  found->second.first = link_ptr;
312  boost::property_map<Graph, boost::vertex_link_t>::type param = get(boost::vertex_link, static_cast<Graph&>(*this));
313  param[found->second.second] = link_ptr;
314  }
315  else
316  { // Adding a new link
317  // Set default visibility and collision enabled to true
318  boost::property<boost::vertex_link_visible_t, bool, boost::property<boost::vertex_link_collision_enabled_t, bool>>
319  data(true, true);
320  VertexProperty info(link_ptr, data);
321  Vertex v = boost::add_vertex(info, static_cast<Graph&>(*this));
322  link_map_[link_ptr->getName()] = std::make_pair(link_ptr, v);
323 
324  // First link added set as root
325  if (link_map_.size() == 1)
326  setRoot(link_ptr->getName());
327  }
328 
329  return true;
330 }
331 
332 std::shared_ptr<const Link> SceneGraph::getLink(const std::string& name) const
333 {
334  auto found = link_map_.find(name);
335  if (found == link_map_.end())
336  return nullptr;
337 
338  return found->second.first;
339 }
340 
341 std::vector<std::shared_ptr<const Link>> SceneGraph::getLinks() const
342 {
343  std::vector<Link::ConstPtr> links;
344  links.reserve(link_map_.size());
345  for (const auto& link : link_map_)
346  links.push_back(link.second.first);
347 
348  return links;
349 }
350 
351 std::vector<std::shared_ptr<const Link>> SceneGraph::getLeafLinks() const
352 {
353  std::vector<Link::ConstPtr> links;
354  links.reserve(link_map_.size());
355  for (const auto& link : link_map_)
356  {
357  if (boost::out_degree(link.second.second, *this) == 0)
358  links.push_back(link.second.first);
359  }
360 
361  return links;
362 }
363 
364 bool SceneGraph::removeLink(const std::string& name, bool recursive)
365 {
366  auto found = link_map_.find(name);
367  if (found == link_map_.end())
368  {
369  CONSOLE_BRIDGE_logWarn("Tried to remove link (%s) from scene graph that does not exist.", name.c_str());
370  return false;
371  }
372 
373  std::vector<std::string> adjacent_link_names = getAdjacentLinkNames(name);
374 
375  // Need to remove all inbound and outbound edges first
376  Vertex vertex = getVertex(name);
377  boost::clear_vertex(vertex, *this);
378 
379  // rebuild joint_map
380  joint_map_.clear();
381  Graph::edge_iterator ei, ei_end;
382  for (boost::tie(ei, ei_end) = boost::edges(*this); ei != ei_end; ++ei)
383  {
384  Edge e = *ei;
385  Joint::Ptr joint = boost::get(boost::edge_joint, *this)[e];
386  joint_map_[joint->getName()] = std::make_pair(joint, e);
387  }
388 
389  // Now remove vertex
390  boost::remove_vertex(found->second.second, static_cast<Graph&>(*this));
391  link_map_.erase(name);
392 
393  // Need to remove any reference to link in allowed collision matrix
395 
396  if (recursive)
397  {
398  for (const auto& link_name : adjacent_link_names)
399  {
400  if (getInboundJoints(link_name).empty())
401  removeLink(link_name, true);
402  }
403  }
404 
405  return true;
406 }
407 
408 bool SceneGraph::moveLink(const Joint& joint)
409 {
410  if (link_map_.find(joint.child_link_name) == link_map_.end())
411  {
412  CONSOLE_BRIDGE_logWarn("Tried to move link (%s) in scene graph that does not exist.",
413  joint.child_link_name.c_str());
414  return false;
415  }
416 
417  if (link_map_.find(joint.parent_link_name) == link_map_.end())
418  {
419  CONSOLE_BRIDGE_logWarn("Tried to move link (%s) in scene graph that parent link (%s) which does not exist.",
420  joint.child_link_name.c_str(),
421  joint.parent_link_name.c_str());
422  return false;
423  }
424 
425  std::vector<tesseract_scene_graph::Joint::ConstPtr> joints = getInboundJoints(joint.child_link_name);
426  for (const auto& joint : joints)
427  removeJoint(joint->getName());
428 
429  return addJoint(joint);
430 }
431 
432 void SceneGraph::setLinkVisibility(const std::string& name, bool visibility)
433 {
434  boost::property_map<Graph, boost::vertex_link_visible_t>::type param =
435  get(boost::vertex_link_visible, static_cast<Graph&>(*this));
436  param[getVertex(name)] = visibility;
437 }
438 
439 bool SceneGraph::getLinkVisibility(const std::string& name) const
440 {
441  boost::property_map<Graph, boost::vertex_link_visible_t>::const_type param =
442  get(boost::vertex_link_visible, static_cast<const Graph&>(*this));
443  return param[getVertex(name)];
444 }
445 
446 void SceneGraph::setLinkCollisionEnabled(const std::string& name, bool enabled)
447 {
448  boost::property_map<Graph, boost::vertex_link_collision_enabled_t>::type param =
449  get(boost::vertex_link_collision_enabled, static_cast<Graph&>(*this));
450  param[getVertex(name)] = enabled;
451 }
452 
453 bool SceneGraph::getLinkCollisionEnabled(const std::string& name) const
454 {
455  boost::property_map<Graph, boost::vertex_link_collision_enabled_t>::const_type param =
456  get(boost::vertex_link_collision_enabled, static_cast<const Graph&>(*this));
457  return param[getVertex(name)];
458 }
459 
460 bool SceneGraph::addJoint(const Joint& joint)
461 {
462  auto joint_ptr = std::make_shared<tesseract_scene_graph::Joint>(joint.clone());
463  return addJointHelper(joint_ptr);
464 }
465 
466 bool SceneGraph::addJointHelper(const std::shared_ptr<Joint>& joint_ptr)
467 {
468  auto parent = link_map_.find(joint_ptr->parent_link_name);
469  auto child = link_map_.find(joint_ptr->child_link_name);
470  auto found = joint_map_.find(joint_ptr->getName());
471 
472  if (parent == link_map_.end())
473  {
474  CONSOLE_BRIDGE_logWarn("Parent link (%s) does not exist in scene graph.", joint_ptr->parent_link_name.c_str());
475  return false;
476  }
477 
478  if (child == link_map_.end())
479  {
480  CONSOLE_BRIDGE_logWarn("Child link (%s) does not exist in scene graph.", joint_ptr->child_link_name.c_str());
481  return false;
482  }
483 
484  if (found != joint_map_.end())
485  {
486  CONSOLE_BRIDGE_logWarn("Joint with name (%s) already exists in scene graph.", joint_ptr->getName().c_str());
487  return false;
488  }
489 
490  if ((joint_ptr->type != JointType::FIXED) && (joint_ptr->type != JointType::FLOATING) &&
491  (joint_ptr->type != JointType::CONTINUOUS) && joint_ptr->limits == nullptr)
492  {
493  CONSOLE_BRIDGE_logWarn("Joint with name (%s) requires limits because it is not of type fixed, floating or "
494  "continuous.",
495  joint_ptr->getName().c_str());
496  return false;
497  }
498 
499  // Need to set limits for continuous joints. TODO: This may not be required
500  // by the optimization library but may be nice to have
501  if (joint_ptr->type == tesseract_scene_graph::JointType::CONTINUOUS)
502  {
503  if (joint_ptr->limits == nullptr)
504  {
505  joint_ptr->limits = std::make_shared<JointLimits>(-4 * M_PI, 4 * M_PI, 0, 2, 1, 1000);
506  }
507  else if (tesseract_common::almostEqualRelativeAndAbs(joint_ptr->limits->lower, joint_ptr->limits->upper, 1e-5))
508  {
509  joint_ptr->limits->lower = -4 * M_PI;
510  joint_ptr->limits->upper = +4 * M_PI;
511  }
512  }
513 
514  double d = joint_ptr->parent_to_joint_origin_transform.translation().norm();
515 
516  EdgeProperty info(joint_ptr, d);
517  std::pair<Edge, bool> e =
518  boost::add_edge(parent->second.second, child->second.second, info, static_cast<Graph&>(*this));
519  assert(e.second == true);
520  joint_map_[joint_ptr->getName()] = std::make_pair(joint_ptr, e.first);
521 
522  return true;
523 }
524 
525 std::shared_ptr<const Joint> SceneGraph::getJoint(const std::string& name) const
526 {
527  auto found = joint_map_.find(name);
528  if (found == joint_map_.end())
529  return nullptr;
530 
531  return found->second.first;
532 }
533 
534 bool SceneGraph::removeJoint(const std::string& name, bool recursive)
535 {
536  auto found = joint_map_.find(name);
537  if (found == joint_map_.end())
538  return false;
539 
540  if (!recursive)
541  {
542  boost::remove_edge(found->second.second, static_cast<Graph&>(*this));
543  joint_map_.erase(name);
544  }
545  else
546  {
547  if (getInboundJoints(found->second.first->child_link_name).size() == 1)
548  {
549  std::string child_link_name = found->second.first->child_link_name;
550  removeLink(child_link_name, true);
551  }
552  }
553 
554  return true;
555 }
556 
557 bool SceneGraph::moveJoint(const std::string& name, const std::string& parent_link)
558 {
559  auto found_joint = joint_map_.find(name);
560  auto found_parent_link = link_map_.find(parent_link);
561 
562  if (found_joint == joint_map_.end())
563  {
564  CONSOLE_BRIDGE_logWarn("Tried to move Joint with name (%s) which does not exist in scene graph.", name.c_str());
565  return false;
566  }
567 
568  if (found_parent_link == link_map_.end())
569  {
570  CONSOLE_BRIDGE_logWarn("Tried to move Joint with name (%s) to parent link (%s) which does not exist in scene "
571  "graph.",
572  name.c_str(),
573  parent_link.c_str());
574  return false;
575  }
576 
577  Joint::Ptr joint = found_joint->second.first;
578  if (!removeJoint(name))
579  return false;
580 
581  joint->parent_link_name = parent_link;
582  return addJointHelper(joint);
583 }
584 
585 std::vector<std::shared_ptr<const Joint>> SceneGraph::getJoints() const
586 {
587  std::vector<Joint::ConstPtr> joints;
588  joints.reserve(joint_map_.size());
589  for (const auto& joint : joint_map_)
590  joints.push_back(joint.second.first);
591 
592  return joints;
593 }
594 
595 std::vector<std::shared_ptr<const Joint>> SceneGraph::getActiveJoints() const
596 {
597  std::vector<Joint::ConstPtr> joints;
598  joints.reserve(joint_map_.size());
599  for (const auto& joint : joint_map_)
600  {
601  if ((joint.second.first->type != JointType::FIXED) && (joint.second.first->type != JointType::FLOATING))
602  joints.push_back(joint.second.first);
603  }
604 
605  return joints;
606 }
607 
608 bool SceneGraph::changeJointOrigin(const std::string& name, const Eigen::Isometry3d& new_origin)
609 {
610  auto found = joint_map_.find(name);
611 
612  if (found == joint_map_.end())
613  {
614  CONSOLE_BRIDGE_logWarn("Tried to change Joint origin with name (%s) which does not exist in scene graph.",
615  name.c_str());
616  return false;
617  }
618 
619  // Update transform associated with the joint
620  Joint::Ptr joint = found->second.first;
621  joint->parent_to_joint_origin_transform = new_origin;
622 
623  // Update the edge value associated with the joint
624  Edge e = getEdge(name);
625  double d = joint->parent_to_joint_origin_transform.translation().norm();
626  boost::put(boost::edge_weight_t(), *this, e, d);
627 
628  return true;
629 }
630 
631 bool SceneGraph::changeJointLimits(const std::string& name, const JointLimits& limits)
632 {
633  auto found = joint_map_.find(name);
634 
635  if (found == joint_map_.end())
636  {
637  CONSOLE_BRIDGE_logWarn("Tried to change Joint limit with name (%s) which does not exist in scene graph.",
638  name.c_str());
639  return false;
640  }
641 
642  if (found->second.first->type == JointType::FIXED || found->second.first->type == JointType::FLOATING)
643  {
644  CONSOLE_BRIDGE_logWarn("Tried to change Joint limits for a fixed or floating joint type.", name.c_str());
645  return false;
646  }
647 
648  if (found->second.first->limits == nullptr)
649  found->second.first->limits = std::make_shared<JointLimits>();
650 
651  found->second.first->limits->lower = limits.lower;
652  found->second.first->limits->upper = limits.upper;
653  found->second.first->limits->effort = limits.effort;
654  found->second.first->limits->velocity = limits.velocity;
655  found->second.first->limits->acceleration = limits.acceleration;
656  found->second.first->limits->jerk = limits.jerk;
657 
658  return true;
659 }
660 
661 bool SceneGraph::changeJointPositionLimits(const std::string& name, double lower, double upper)
662 {
663  auto found = joint_map_.find(name);
664 
665  if (found == joint_map_.end())
666  {
667  CONSOLE_BRIDGE_logWarn("Tried to change Joint Position limits with name (%s) which does not exist in scene graph.",
668  name.c_str());
669  return false;
670  }
671 
672  if (found->second.first->type == JointType::FIXED || found->second.first->type == JointType::FLOATING)
673  {
674  CONSOLE_BRIDGE_logWarn("Tried to change Joint Position limits for a fixed or floating joint type.", name.c_str());
675  return false;
676  }
677 
678  found->second.first->limits->lower = lower;
679  found->second.first->limits->upper = upper;
680 
681  return true;
682 }
683 
684 bool SceneGraph::changeJointVelocityLimits(const std::string& name, double limit)
685 {
686  auto found = joint_map_.find(name);
687 
688  if (found == joint_map_.end())
689  {
690  CONSOLE_BRIDGE_logWarn("Tried to change Joint Velocity limit with name (%s) which does not exist in scene graph.",
691  name.c_str());
692  return false;
693  }
694 
695  if (found->second.first->type == JointType::FIXED || found->second.first->type == JointType::FLOATING)
696  {
697  CONSOLE_BRIDGE_logWarn("Tried to change Joint Velocity limit for a fixed or floating joint type.", name.c_str());
698  return false;
699  }
700 
701  found->second.first->limits->velocity = limit;
702  return true;
703 }
704 
705 bool SceneGraph::changeJointAccelerationLimits(const std::string& name, double limit)
706 {
707  auto found = joint_map_.find(name);
708 
709  if (found == joint_map_.end())
710  {
711  CONSOLE_BRIDGE_logWarn("Tried to change Joint Acceleration limit with name (%s) which does not exist in scene "
712  "graph.",
713  name.c_str());
714  return false;
715  }
716 
717  if (found->second.first->type == JointType::FIXED || found->second.first->type == JointType::FLOATING)
718  {
719  CONSOLE_BRIDGE_logWarn("Tried to change Joint Acceleration limit for a fixed or floating joint type.",
720  name.c_str());
721  return false;
722  }
723 
724  if (found->second.first->limits == nullptr)
725  found->second.first->limits = std::make_shared<JointLimits>();
726 
727  found->second.first->limits->acceleration = limit;
728 
729  return true;
730 }
731 
732 bool SceneGraph::changeJointJerkLimits(const std::string& name, double limit)
733 {
734  auto found = joint_map_.find(name);
735 
736  if (found == joint_map_.end())
737  {
738  CONSOLE_BRIDGE_logWarn("Tried to change Joint Jerk limit with name (%s) which does not exist in scene "
739  "graph.",
740  name.c_str());
741  return false;
742  }
743 
744  if (found->second.first->type == JointType::FIXED || found->second.first->type == JointType::FLOATING)
745  {
746  CONSOLE_BRIDGE_logWarn("Tried to change Joint Jerk limit for a fixed or floating joint type.", name.c_str());
747  return false;
748  }
749 
750  if (found->second.first->limits == nullptr)
751  found->second.first->limits = std::make_shared<JointLimits>();
752 
753  found->second.first->limits->jerk = limit;
754 
755  return true;
756 }
757 
758 std::shared_ptr<const JointLimits> SceneGraph::getJointLimits(const std::string& name)
759 {
760  auto found = joint_map_.find(name);
761 
762  if (found == joint_map_.end())
763  {
764  CONSOLE_BRIDGE_logWarn("SceneGraph::getJointLimits tried to find Joint with name (%s) which does not exist in "
765  "scene graph.",
766  name.c_str());
767  return nullptr;
768  }
769  return found->second.first->limits;
770 }
771 
772 void SceneGraph::setAllowedCollisionMatrix(std::shared_ptr<tesseract_common::AllowedCollisionMatrix> acm)
773 {
774  acm_ = std::move(acm);
775 }
776 
777 void SceneGraph::addAllowedCollision(const std::string& link_name1,
778  const std::string& link_name2,
779  const std::string& reason)
780 {
781  acm_->addAllowedCollision(link_name1, link_name2, reason);
782 }
783 
784 void SceneGraph::removeAllowedCollision(const std::string& link_name1, const std::string& link_name2)
785 {
786  acm_->removeAllowedCollision(link_name1, link_name2);
787 }
788 
789 void SceneGraph::removeAllowedCollision(const std::string& link_name) { acm_->removeAllowedCollision(link_name); }
790 
791 void SceneGraph::clearAllowedCollisions() { acm_->clearAllowedCollisions(); }
792 
793 bool SceneGraph::isCollisionAllowed(const std::string& link_name1, const std::string& link_name2) const
794 {
795  return acm_->isCollisionAllowed(link_name1, link_name2);
796 }
797 
798 std::shared_ptr<const tesseract_common::AllowedCollisionMatrix> SceneGraph::getAllowedCollisionMatrix() const
799 {
800  return acm_;
801 }
802 
803 std::shared_ptr<tesseract_common::AllowedCollisionMatrix> SceneGraph::getAllowedCollisionMatrix() { return acm_; }
804 
805 std::shared_ptr<const Link> SceneGraph::getSourceLink(const std::string& joint_name) const
806 {
807  Edge e = getEdge(joint_name);
808  Vertex v = boost::source(e, *this);
809  return boost::get(boost::vertex_link, *this)[v];
810 }
811 
812 std::shared_ptr<const Link> SceneGraph::getTargetLink(const std::string& joint_name) const
813 {
814  Edge e = getEdge(joint_name);
815  Vertex v = boost::target(e, *this);
816  return boost::get(boost::vertex_link, *this)[v];
817 }
818 
819 std::vector<std::shared_ptr<const Joint>> SceneGraph::getInboundJoints(const std::string& link_name) const
820 {
821  std::vector<Joint::ConstPtr> joints;
822  Vertex vertex = getVertex(link_name);
823 
824  // Get incoming edges
825  auto num_in_edges = static_cast<int>(boost::in_degree(vertex, *this));
826  if (num_in_edges == 0) // The root of the tree will have not incoming edges
827  return joints;
828 
829  boost::graph_traits<Graph>::in_edge_iterator ei, ei_end;
830  for (boost::tie(ei, ei_end) = boost::in_edges(vertex, *this); ei != ei_end; ++ei)
831  {
832  SceneGraph::Edge e = *ei;
833  joints.push_back(boost::get(boost::edge_joint, *this)[e]);
834  }
835 
836  return joints;
837 }
838 
839 std::vector<std::shared_ptr<const Joint>> SceneGraph::getOutboundJoints(const std::string& link_name) const
840 {
841  std::vector<Joint::ConstPtr> joints;
842  Vertex vertex = getVertex(link_name);
843 
844  // Get incoming edges
845  auto num_out_edges = static_cast<int>(boost::out_degree(vertex, *this));
846  if (num_out_edges == 0)
847  return joints;
848 
849  boost::graph_traits<Graph>::out_edge_iterator eo, eo_end;
850  for (boost::tie(eo, eo_end) = boost::out_edges(vertex, *this); eo != eo_end; ++eo)
851  {
852  SceneGraph::Edge e = *eo;
853  joints.push_back(boost::get(boost::edge_joint, *this)[e]);
854  }
855 
856  return joints;
857 }
858 
859 bool SceneGraph::isEmpty() const { return link_map_.empty(); }
860 
862 {
863  const auto& graph = static_cast<const Graph&>(*this);
864  bool acyclic = true;
865 
866  std::map<Vertex, size_t> index_map;
867  boost::associative_property_map<std::map<Vertex, size_t>> prop_index_map(index_map);
868 
869  int c = 0;
870  Graph::vertex_iterator i, iend;
871  for (boost::tie(i, iend) = boost::vertices(graph); i != iend; ++i, ++c)
872  boost::put(prop_index_map, *i, c);
873 
874  cycle_detector vis(acyclic);
875  boost::depth_first_search(static_cast<const Graph&>(*this), boost::visitor(vis).vertex_index_map(prop_index_map));
876  return acyclic;
877 }
878 
879 bool SceneGraph::isTree() const
880 {
881  const auto& graph = static_cast<const Graph&>(*this);
882  bool tree = true;
883 
884  std::map<Vertex, size_t> index_map;
885  boost::associative_property_map<std::map<Vertex, size_t>> prop_index_map(index_map);
886 
887  int c = 0;
888  Graph::vertex_iterator i, iend;
889  for (boost::tie(i, iend) = boost::vertices(graph); i != iend; ++i, ++c)
890  boost::put(prop_index_map, *i, c);
891 
892  tree_detector vis(tree);
893  boost::depth_first_search(static_cast<const Graph&>(*this), boost::visitor(vis).vertex_index_map(prop_index_map));
894  return tree;
895 }
896 
897 std::vector<std::string> SceneGraph::getAdjacentLinkNames(const std::string& name) const
898 {
899  std::vector<std::string> link_names;
900  Vertex v = getVertex(name);
901  for (auto* vd : boost::make_iterator_range(adjacent_vertices(v, *this)))
902  link_names.push_back(boost::get(boost::vertex_link, *this)[vd]->getName());
903 
904  return link_names;
905 }
906 
907 std::vector<std::string> SceneGraph::getInvAdjacentLinkNames(const std::string& name) const
908 {
909  std::vector<std::string> link_names;
910  Vertex v = getVertex(name);
911  for (auto* vd : boost::make_iterator_range(inv_adjacent_vertices(v, *this)))
912  link_names.push_back(boost::get(boost::vertex_link, *this)[vd]->getName());
913 
914  return link_names;
915 }
916 
917 std::vector<std::string> SceneGraph::getLinkChildrenNames(const std::string& name) const
918 {
919  Vertex v = getVertex(name);
920  std::vector<std::string> child_link_names = getLinkChildrenHelper(v);
921 
922  // This always includes the start vertex, so must remove
923  child_link_names.erase(child_link_names.begin());
924  return child_link_names;
925 }
926 
927 std::vector<std::string> SceneGraph::getJointChildrenNames(const std::string& name) const
928 {
929  const auto& graph = static_cast<const Graph&>(*this);
930  Edge e = getEdge(name);
931  Vertex v = boost::target(e, graph);
932  return getLinkChildrenHelper(v); // NOLINT
933 }
934 
935 std::vector<std::string> SceneGraph::getJointChildrenNames(const std::vector<std::string>& names) const
936 {
937  std::set<std::string> link_names;
938  for (const auto& name : names)
939  {
940  std::vector<std::string> joint_children = getJointChildrenNames(name);
941  link_names.insert(joint_children.begin(), joint_children.end());
942  }
943 
944  return std::vector<std::string>{ link_names.begin(), link_names.end() };
945 }
946 
947 std::unordered_map<std::string, std::string>
948 SceneGraph::getAdjacencyMap(const std::vector<std::string>& link_names) const
949 {
950  std::map<Vertex, size_t> index_map;
951  boost::associative_property_map<std::map<Vertex, size_t>> prop_index_map(index_map);
952 
953  std::map<Vertex, boost::default_color_type> color_map;
954  boost::associative_property_map<std::map<Vertex, boost::default_color_type>> prop_color_map(color_map);
955 
956  int c = 0;
957  Graph::vertex_iterator i, iend;
958  for (boost::tie(i, iend) = boost::vertices(*this); i != iend; ++i, ++c)
959  boost::put(prop_index_map, *i, c);
960 
961  std::unordered_map<std::string, std::string> adjacency_map;
962  for (const auto& link_name : link_names)
963  {
964  Vertex start_vertex = getVertex(link_name);
965  adjacency_detector vis(adjacency_map, color_map, link_name, link_names);
966 
967  // NOLINTNEXTLINE
968  boost::breadth_first_search(
969  *this,
970  start_vertex,
971  boost::visitor(vis).root_vertex(start_vertex).vertex_index_map(prop_index_map).color_map(prop_color_map));
972  }
973 
974  return adjacency_map;
975 }
976 
977 void SceneGraph::saveDOT(const std::string& path) const
978 {
979  std::ofstream dot_file(path);
980  if (!dot_file.is_open())
981  {
982  throw std::runtime_error("Failed to open file: " + path);
983  }
984 
985  dot_file << "digraph D {\n"
986  << " rankdir=LR\n"
987  << " size=\"4,3\"\n"
988  << " ratio=\"fill\"\n"
989  << " edge[style=\"bold\"]\n"
990  << " node[shape=\"circle\"]\n";
991 
992  const auto& graph = static_cast<const Graph&>(*this);
993  Graph::edge_iterator ei, ei_end;
994  for (boost::tie(ei, ei_end) = boost::edges(graph); ei != ei_end; ++ei)
995  {
996  Edge e = *ei;
997  Vertex u = boost::source(e, graph);
998  Vertex v = boost::target(e, graph);
999  Joint::ConstPtr joint = boost::get(boost::edge_joint, graph)[e];
1000 
1001  dot_file << '"' << boost::get(boost::vertex_link, graph)[u]->getName() << '"' << " -> " << '"'
1002  << boost::get(boost::vertex_link, graph)[v]->getName() << '"' << "[label=\"" << joint->getName() << "\n("
1003  << joint->type << ")\", color=\"black\"]";
1004  }
1005  dot_file << "}";
1006 }
1007 
1008 ShortestPath SceneGraph::getShortestPath(const std::string& root, const std::string& tip) const
1009 {
1010  // Must copy to undirected graph because order does not matter for creating kinematics chains.
1011 
1012  // Copy Graph
1013  UGraph graph;
1014 
1015  std::map<Graph::vertex_descriptor, size_t> index_map;
1016  boost::associative_property_map<std::map<Graph::vertex_descriptor, size_t>> prop_index_map(index_map);
1017 
1018  {
1019  int c = 0;
1020  Graph::vertex_iterator i, iend;
1021  for (boost::tie(i, iend) = boost::vertices(*this); i != iend; ++i, ++c)
1022  boost::put(prop_index_map, *i, c);
1023  }
1024 
1025  ugraph_vertex_copier v_copier(*this, graph);
1026  boost::copy_graph(*this, graph, boost::vertex_index_map(prop_index_map).vertex_copy(v_copier));
1027 
1028  // Search Graph
1029  UGraph::vertex_descriptor s_root = getVertex(root);
1030  UGraph::vertex_descriptor s_tip = getVertex(tip);
1031 
1032  auto prop_weight_map = boost::get(boost::edge_weight, graph);
1033 
1034  std::map<UGraph::vertex_descriptor, UGraph::vertex_descriptor> predicessor_map;
1035  boost::associative_property_map<std::map<UGraph::vertex_descriptor, UGraph::vertex_descriptor>> prop_predicessor_map(
1036  predicessor_map);
1037 
1038  std::map<UGraph::vertex_descriptor, double> distance_map;
1039  boost::associative_property_map<std::map<UGraph::vertex_descriptor, double>> prop_distance_map(distance_map);
1040 
1041  std::map<UGraph::vertex_descriptor, size_t> u_index_map;
1042  boost::associative_property_map<std::map<UGraph::vertex_descriptor, size_t>> u_prop_index_map(u_index_map);
1043 
1044  { // Populate index map
1045  int c = 0;
1046  UGraph::vertex_iterator i, iend;
1047  for (boost::tie(i, iend) = boost::vertices(graph); i != iend; ++i, ++c)
1048  {
1049  std::string name = boost::get(boost::vertex_link, graph)[*i]->getName();
1050  if (name == root)
1051  s_root = *i;
1052 
1053  if (name == tip)
1054  s_tip = *i;
1055 
1056  boost::put(u_prop_index_map, *i, c);
1057  }
1058  }
1059 
1060  dijkstra_shortest_paths(graph,
1061  s_root,
1062  prop_predicessor_map,
1063  prop_distance_map,
1064  prop_weight_map,
1065  u_prop_index_map,
1066  std::less<>(),
1067  boost::closed_plus<double>(),
1068  (std::numeric_limits<double>::max)(),
1069  0,
1070  boost::default_dijkstra_visitor());
1071 
1072  ShortestPath path;
1073  path.links.reserve(predicessor_map.size());
1074  path.joints.reserve(predicessor_map.size());
1075  path.active_joints.reserve(predicessor_map.size());
1076  // We want to start at the destination and work our way back to the source
1077  for (Vertex u = predicessor_map[s_tip]; // Start by setting 'u' to the destination node's predecessor
1078  u != s_tip; // Keep tracking the path until we get to the source
1079  s_tip = u, u = predicessor_map[s_tip]) // Set the current vertex to the current predecessor, and the predecessor
1080  // to one level up
1081  {
1082  path.links.push_back(boost::get(boost::vertex_link, graph)[s_tip]->getName());
1083  const Joint::ConstPtr& joint = boost::get(boost::edge_joint, graph)[boost::edge(u, s_tip, graph).first];
1084 
1085  path.joints.push_back(joint->getName());
1086  if (joint->type != JointType::FIXED && joint->type != JointType::FLOATING)
1087  path.active_joints.push_back(joint->getName());
1088  }
1089  path.links.push_back(root);
1090  std::reverse(path.links.begin(), path.links.end());
1091  std::reverse(path.joints.begin(), path.joints.end());
1092  std::reverse(path.active_joints.begin(), path.active_joints.end());
1093 
1094 #ifndef NDEBUG
1095  CONSOLE_BRIDGE_logDebug("distances and parents:");
1096  UGraph::vertex_iterator vi, vend;
1097  for (boost::tie(vi, vend) = boost::vertices(graph); vi != vend; ++vi)
1098  {
1099  CONSOLE_BRIDGE_logDebug("distance(%s) = %f, parent(%s) = %s",
1100  boost::get(boost::vertex_link, graph)[*vi]->getName().c_str(),
1101  distance_map[*vi],
1102  boost::get(boost::vertex_link, graph)[*vi]->getName().c_str(),
1103  boost::get(boost::vertex_link, graph)[predicessor_map[*vi]]->getName().c_str());
1104  }
1105 #endif
1106  return path;
1107 }
1108 
1109 SceneGraph::Vertex SceneGraph::getVertex(const std::string& name) const
1110 {
1111  auto found = link_map_.find(name);
1112  if (found == link_map_.end())
1113  throw std::runtime_error("SceneGraph, vertex with name '" + name + "' does not exist!");
1114 
1115  return found->second.second;
1116 }
1117 
1118 SceneGraph::Edge SceneGraph::getEdge(const std::string& name) const
1119 {
1120  auto found = joint_map_.find(name);
1121  if (found == joint_map_.end())
1122  throw std::runtime_error("SceneGraph, edge with name '" + name + "' does not exist!");
1123 
1124  return found->second.second;
1125 }
1126 
1128 namespace
1129 {
1130 tesseract_scene_graph::Link clone_prefix(const tesseract_scene_graph::Link::ConstPtr& link, const std::string& prefix)
1131 {
1132  return link->clone(prefix + link->getName());
1133 }
1134 
1136  const std::string& prefix)
1137 {
1138  auto ret = joint->clone(prefix + joint->getName());
1139  ret.child_link_name = prefix + joint->child_link_name;
1140  ret.parent_link_name = prefix + joint->parent_link_name;
1141  return ret;
1142 }
1143 
1145 clone_prefix(const tesseract_common::AllowedCollisionMatrix::ConstPtr& acm, const std::string& prefix)
1146 {
1147  if (prefix.empty())
1148  return std::make_shared<tesseract_common::AllowedCollisionMatrix>(*acm);
1149 
1150  auto new_acm = std::make_shared<tesseract_common::AllowedCollisionMatrix>();
1151  for (const auto& entry : acm->getAllAllowedCollisions())
1152  new_acm->addAllowedCollision(prefix + entry.first.first, prefix + entry.first.second, entry.second);
1153 
1154  return new_acm;
1155 }
1156 } // namespace
1157 
1158 bool SceneGraph::insertSceneGraph(const tesseract_scene_graph::SceneGraph& scene_graph, const std::string& prefix)
1159 {
1160  bool is_empty = isEmpty();
1161 
1162  // Verify that link names are unique
1163  for (const auto& link : scene_graph.getLinks())
1164  {
1165  if (link_map_.find(prefix + link->getName()) != link_map_.end())
1166  {
1167  CONSOLE_BRIDGE_logError("Failed to add inserted graph, link names are not unique: %s",
1168  (prefix + link->getName()).c_str());
1169  return false;
1170  }
1171  }
1172 
1173  // Verify that joint names are unique
1174  for (const auto& joint : scene_graph.getJoints())
1175  {
1176  if (joint_map_.find(prefix + joint->getName()) != joint_map_.end())
1177  {
1178  CONSOLE_BRIDGE_logError("Failed to add inserted graph, joint names are not unique: %s",
1179  (prefix + joint->getName()).c_str());
1180  return false;
1181  }
1182  }
1183 
1184  for (const auto& link : scene_graph.getLinks())
1185  {
1186  auto new_link = std::make_shared<Link>(clone_prefix(link, prefix));
1187  bool res = addLinkHelper(new_link);
1188  if (!res)
1189  {
1190  CONSOLE_BRIDGE_logError("Failed to add inserted graph link: %s", link->getName().c_str());
1191  return false;
1192  }
1193 
1194  // Set link collision enabled and visibility
1195  setLinkCollisionEnabled(new_link->getName(), scene_graph.getLinkCollisionEnabled(link->getName()));
1196  setLinkVisibility(new_link->getName(), scene_graph.getLinkVisibility(link->getName()));
1197  }
1198 
1199  for (const auto& joint : scene_graph.getJoints())
1200  {
1201  auto new_joint = std::make_shared<Joint>(clone_prefix(joint, prefix));
1202  bool res = addJointHelper(new_joint);
1203  if (!res)
1204  {
1205  CONSOLE_BRIDGE_logError("Failed to add inserted graph joint: %s", joint->getName().c_str());
1206  return false;
1207  }
1208  }
1209 
1210  acm_->insertAllowedCollisionMatrix(*clone_prefix(scene_graph.getAllowedCollisionMatrix(), prefix));
1211 
1212  // If the this graph was empty to start we will set the root link to the same as the inserted one.
1213  if (is_empty)
1214  setRoot(scene_graph.getRoot());
1215 
1216  return true;
1217 }
1218 
1220  const Joint& joint,
1221  const std::string& prefix)
1222 {
1223  std::string parent_link = joint.parent_link_name;
1224  std::string child_link = joint.child_link_name;
1225 
1226  // Assumes the joint already contains the prefix in the parent and child link names
1227  if (!prefix.empty())
1228  child_link.erase(0, prefix.length());
1229 
1230  if (getLink(parent_link) == nullptr || scene_graph.getLink(child_link) == nullptr)
1231  {
1232  CONSOLE_BRIDGE_logError("Failed to add inserted graph, provided joint link names do not exist in inserted graph!");
1233  return false;
1234  }
1235 
1236  if (getJoint(joint.getName()) != nullptr)
1237  {
1238  CONSOLE_BRIDGE_logError("Failed to add inserted graph, provided joint name %s already exists!",
1239  joint.getName().c_str());
1240  return false;
1241  }
1242 
1243  if (!insertSceneGraph(scene_graph, prefix))
1244  return false;
1245 
1246  return addJointHelper(std::make_shared<Joint>(joint.clone()));
1247 }
1248 
1250 {
1251  link_map_.clear();
1252  joint_map_.clear();
1253 
1254  { // Rebuild link map
1255  Graph::vertex_iterator i, iend;
1256  for (boost::tie(i, iend) = boost::vertices(*this); i != iend; ++i)
1257  {
1258  Link::Ptr link = boost::get(boost::vertex_link, *this)[*i];
1259  link_map_[link->getName()] = std::make_pair(link, *i);
1260  }
1261  }
1262 
1263  { // Rebuild joint map
1264  Graph::edge_iterator i, iend;
1265  for (boost::tie(i, iend) = boost::edges(*this); i != iend; ++i)
1266  {
1267  Joint::Ptr joint = boost::get(boost::edge_joint, *this)[*i];
1268  joint_map_[joint->getName()] = std::make_pair(joint, *i);
1269  }
1270  }
1271 }
1272 
1273 std::vector<std::string> SceneGraph::getLinkChildrenHelper(Vertex start_vertex) const
1274 {
1275  const auto& graph = static_cast<const Graph&>(*this);
1276  std::vector<std::string> child_link_names;
1277 
1278  std::map<Vertex, size_t> index_map;
1279  boost::associative_property_map<std::map<Vertex, size_t>> prop_index_map(index_map);
1280 
1281  std::map<Vertex, boost::default_color_type> color_map;
1282  boost::associative_property_map<std::map<Vertex, boost::default_color_type>> prop_color_map(color_map);
1283 
1284  int c = 0;
1285  Graph::vertex_iterator i, iend;
1286  for (boost::tie(i, iend) = boost::vertices(graph); i != iend; ++i, ++c)
1287  boost::put(prop_index_map, *i, c);
1288 
1289  children_detector vis(child_link_names);
1290  // NOLINTNEXTLINE
1291  boost::breadth_first_search(
1292  graph,
1293  start_vertex,
1294  boost::visitor(vis).root_vertex(start_vertex).vertex_index_map(prop_index_map).color_map(prop_color_map));
1295 
1296  return child_link_names;
1297 }
1298 
1299 bool SceneGraph::operator==(const SceneGraph& rhs) const
1300 {
1301  using namespace tesseract_common;
1302  // Currently these only compare the Link/Joint.
1303  auto link_pair_equal = [](const std::pair<const Link::Ptr, Vertex>& v1, const std::pair<Link::Ptr, Vertex>& v2) {
1304  return pointersEqual(v1.first, v2.first);
1305  };
1306  auto joint_pair_equal = [](const std::pair<const Joint::Ptr, Edge>& v1, const std::pair<Joint::Ptr, Edge>& v2) {
1307  return pointersEqual(v1.first, v2.first);
1308  };
1309 
1310  bool equal = true;
1311  equal &= pointersEqual(acm_, rhs.acm_);
1312  equal &= isIdenticalMap<std::unordered_map<std::string, std::pair<Link::Ptr, Vertex>>, std::pair<Link::Ptr, Vertex>>(
1313  link_map_, rhs.link_map_, link_pair_equal);
1314  equal &= isIdenticalMap<std::unordered_map<std::string, std::pair<Joint::Ptr, Edge>>, std::pair<Joint::Ptr, Edge>>(
1315  joint_map_, rhs.joint_map_, joint_pair_equal);
1316 
1317  return equal;
1318 }
1319 bool SceneGraph::operator!=(const SceneGraph& rhs) const { return !operator==(rhs); }
1320 
1321 template <class Archive>
1322 void SceneGraph::save(Archive& ar, const unsigned int /*version*/) const
1323 {
1324  using namespace boost::serialization;
1325  ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(Graph);
1326  ar& BOOST_SERIALIZATION_NVP(acm_);
1327 }
1328 
1329 template <class Archive>
1330 void SceneGraph::load(Archive& ar, const unsigned int /*version*/)
1331 {
1332  using namespace boost::serialization;
1333  ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(Graph);
1334  ar& BOOST_SERIALIZATION_NVP(acm_);
1335 
1337 }
1338 
1339 template <class Archive>
1340 void SceneGraph::serialize(Archive& ar, const unsigned int version)
1341 {
1342  boost::serialization::split_member(ar, *this, version);
1343 }
1344 
1345 std::ostream& operator<<(std::ostream& os, const ShortestPath& path)
1346 {
1347  os << "Links:"
1348  << "\n";
1349  for (const auto& l : path.links)
1350  os << " " << l << "\n";
1351 
1352  os << "Joints:"
1353  << "\n";
1354  for (const auto& j : path.joints)
1355  os << " " << j << "\n";
1356 
1357  os << "Active Joints:"
1358  << "\n";
1359  for (const auto& j : path.active_joints)
1360  os << " " << j << "\n";
1361  return os;
1362 }
1363 
1364 } // namespace tesseract_scene_graph
1365 
1367 BOOST_CLASS_EXPORT_IMPLEMENT(tesseract_scene_graph::SceneGraph)
tesseract_scene_graph::SceneGraph::link_map_
std::unordered_map< std::string, std::pair< std::shared_ptr< Link >, Vertex > > link_map_
Definition: graph.h:591
tesseract_scene_graph::cycle_detector::cycle_detector
cycle_detector(bool &ascyclic)
Definition: graph.cpp:60
tesseract_scene_graph::Graph
boost::adjacency_list< boost::listS, boost::listS, boost::bidirectionalS, VertexProperty, EdgeProperty, GraphProperty > Graph
Definition: graph.h:108
boost::edge_joint
@ edge_joint
Definition: graph.h:65
tesseract_scene_graph::SceneGraph::getLinkChildrenHelper
std::vector< std::string > getLinkChildrenHelper(Vertex start_vertex) const
Get the children of a vertex starting with start_vertex.
Definition: graph.cpp:1273
tesseract_scene_graph::ugraph_vertex_copier::operator()
void operator()(const Vertex1 &v1, Vertex2 &v2) const
Definition: graph.cpp:181
tesseract_scene_graph::SceneGraph::save
void save(Archive &ar, const unsigned int version) const
Definition: graph.cpp:1322
tesseract_scene_graph::SceneGraph::setRoot
bool setRoot(const std::string &name)
Sets the root link name (aka. World Coordinate Frame)
Definition: graph.cpp:256
tesseract_scene_graph::adjacency_detector::color_map_
std::map< SceneGraph::Vertex, boost::default_color_type > & color_map_
Definition: graph.cpp:165
tesseract_common
allowed_collision_matrix.h
tesseract_scene_graph::JointType::FLOATING
@ FLOATING
tesseract_scene_graph::SceneGraph::getLinkCollisionEnabled
bool getLinkCollisionEnabled(const std::string &name) const
Get whether a link should be considered during collision checking.
Definition: graph.cpp:453
tesseract_scene_graph::SceneGraph::Vertex
SceneGraph::vertex_descriptor Vertex
Definition: graph.h:132
tesseract_scene_graph::adjacency_detector::adjacency_detector
adjacency_detector(std::unordered_map< std::string, std::string > &adjacency_map, std::map< SceneGraph::Vertex, boost::default_color_type > &color_map, const std::string &base_link_name, const std::vector< std::string > &terminate_on_links)
Definition: graph.cpp:132
tesseract_scene_graph::SceneGraph::clone
SceneGraph::UPtr clone() const
Clone the scene graph.
Definition: graph.cpp:216
tesseract_scene_graph::SceneGraph::saveDOT
void saveDOT(const std::string &path) const
Saves Graph as Graph Description Language (DOT)
Definition: graph.cpp:977
tesseract_scene_graph::SceneGraph::setLinkCollisionEnabled
void setLinkCollisionEnabled(const std::string &name, bool enabled)
Set whether a link should be considered during collision checking.
Definition: graph.cpp:446
tesseract_scene_graph::SceneGraph::changeJointVelocityLimits
bool changeJointVelocityLimits(const std::string &name, double limit)
Changes the velocity limits associated with a joint.
Definition: graph.cpp:684
tesseract_scene_graph::SceneGraph::getLinks
std::vector< std::shared_ptr< const Link > > getLinks() const
Get a vector links in the scene graph.
Definition: graph.cpp:341
tesseract_scene_graph::SceneGraph::changeJointLimits
bool changeJointLimits(const std::string &name, const JointLimits &limits)
Changes the limits of a joint. The JointLimits::Ptr remains the same, but the values passed in are as...
Definition: graph.cpp:631
tesseract_scene_graph::Joint::clone
Joint clone() const
Clone the joint keeping the name.
Definition: joint.cpp:275
tesseract_scene_graph::SceneGraph::isTree
bool isTree() const
Determine if the graph is a tree.
Definition: graph.cpp:879
utils.h
tesseract_scene_graph::adjacency_detector::adjacency_map_
std::unordered_map< std::string, std::string > & adjacency_map_
Definition: graph.cpp:163
tesseract_scene_graph::SceneGraph::changeJointPositionLimits
bool changeJointPositionLimits(const std::string &name, double lower, double upper)
Changes the position limits associated with a joint.
Definition: graph.cpp:661
tesseract_scene_graph::ShortestPath::active_joints
std::vector< std::string > active_joints
A list of active joints along the shortest path.
Definition: graph.h:122
tesseract_scene_graph::SceneGraph::getJoints
std::vector< std::shared_ptr< const Joint > > getJoints() const
Get a vector of joints in the scene graph.
Definition: graph.cpp:585
boost::vertex_link
@ vertex_link
Definition: graph.h:53
tesseract_scene_graph::ugraph_vertex_copier::vertex_all_map1
boost::property_map< Graph, boost::vertex_all_t >::const_type vertex_all_map1
Definition: graph.cpp:185
boost::vertex_link_collision_enabled
@ vertex_link_collision_enabled
Definition: graph.h:61
tesseract_scene_graph::SceneGraph::getAllowedCollisionMatrix
std::shared_ptr< const tesseract_common::AllowedCollisionMatrix > getAllowedCollisionMatrix() const
Get the allowed collision matrix.
Definition: graph.cpp:798
tesseract_scene_graph::adjacency_detector::examine_vertex
void examine_vertex(u vertex, const g &graph)
Definition: graph.cpp:144
tesseract_scene_graph::SceneGraph::addAllowedCollision
void addAllowedCollision(const std::string &link_name1, const std::string &link_name2, const std::string &reason)
Disable collision between two collision objects.
Definition: graph.cpp:777
tesseract_scene_graph::SceneGraph::getJointLimits
std::shared_ptr< const JointLimits > getJointLimits(const std::string &name)
Gets the limits of the joint specified by name.
Definition: graph.cpp:758
tesseract_common::almostEqualRelativeAndAbs
bool almostEqualRelativeAndAbs(const Eigen::Ref< const Eigen::VectorXd > &v1, const Eigen::Ref< const Eigen::VectorXd > &v2, const Eigen::Ref< const Eigen::VectorXd > &max_diff, const Eigen::Ref< const Eigen::VectorXd > &max_rel_diff)
pointersEqual
bool pointersEqual(const std::shared_ptr< T > &p1, const std::shared_ptr< T > &p2)
tesseract_scene_graph::adjacency_detector::discover_vertex
void discover_vertex(u vertex, const g &graph)
Definition: graph.cpp:155
tesseract_scene_graph::ugraph_vertex_copier
Definition: graph.cpp:173
tesseract_scene_graph::tree_detector::found_root_
bool found_root_
Definition: graph.cpp:113
tesseract_scene_graph::adjacency_detector::base_link_name_
const std::string & base_link_name_
Definition: graph.cpp:166
tesseract_scene_graph::SceneGraph::Edge
SceneGraph::edge_descriptor Edge
Definition: graph.h:133
boost
TESSERACT_COMMON_IGNORE_WARNINGS_PUSH
#define TESSERACT_COMMON_IGNORE_WARNINGS_PUSH
tesseract_scene_graph::EdgeProperty
boost::property< boost::edge_joint_t, std::shared_ptr< Joint >, boost::property< boost::edge_weight_t, double > > EdgeProperty
EdgeProperty.
Definition: graph.h:105
tesseract_scene_graph::SceneGraph::moveJoint
bool moveJoint(const std::string &name, const std::string &parent_link)
Move joint to new parent link.
Definition: graph.cpp:557
tesseract_scene_graph::tree_detector::back_edge
void back_edge(e, const g &)
Definition: graph.cpp:106
tesseract_scene_graph::ugraph_vertex_copier::ugraph_vertex_copier
ugraph_vertex_copier(const Graph &g1, UGraph &g2)
Definition: graph.cpp:175
tesseract_scene_graph::SceneGraph
Definition: graph.h:125
tesseract_scene_graph::Joint::ConstPtr
std::shared_ptr< const Joint > ConstPtr
Definition: joint.h:278
tesseract_scene_graph::adjacency_detector::terminate_on_links_
const std::vector< std::string > & terminate_on_links_
Definition: graph.cpp:167
tesseract_scene_graph::SceneGraph::getOutboundJoints
std::vector< std::shared_ptr< const Joint > > getOutboundJoints(const std::string &link_name) const
Get outbound joints for a link.
Definition: graph.cpp:839
tesseract_scene_graph::SceneGraph::operator==
bool operator==(const SceneGraph &rhs) const
Definition: graph.cpp:1299
tesseract_scene_graph::SceneGraph::addLink
bool addLink(const Link &link, bool replace_allowed=false)
Adds a link to the graph.
Definition: graph.cpp:273
tesseract_scene_graph::SceneGraph::addJointHelper
bool addJointHelper(const std::shared_ptr< Joint > &joint_ptr)
Adds joint to the graph.
Definition: graph.cpp:466
tesseract_scene_graph::tree_detector
Definition: graph.cpp:72
tesseract_scene_graph::cycle_detector::ascyclic_
bool & ascyclic_
Definition: graph.cpp:69
tesseract_scene_graph::SceneGraph::UPtr
std::unique_ptr< SceneGraph > UPtr
Definition: graph.h:137
joint.h
tesseract_scene_graph::SceneGraph::getAdjacentLinkNames
std::vector< std::string > getAdjacentLinkNames(const std::string &name) const
Get a vector of adjacent link names provided a link name.
Definition: graph.cpp:897
tesseract_scene_graph::SceneGraph::getName
const std::string & getName() const
Sets the graph name.
Definition: graph.cpp:251
tesseract_scene_graph::SceneGraph::getInvAdjacentLinkNames
std::vector< std::string > getInvAdjacentLinkNames(const std::string &name) const
Geta a vectpr pf inverse adjacent link names provided a link name.
Definition: graph.cpp:907
tesseract_scene_graph::SceneGraph::removeAllowedCollision
void removeAllowedCollision(const std::string &link_name1, const std::string &link_name2)
Remove disabled collision pair from allowed collision matrix.
Definition: graph.cpp:784
tesseract_scene_graph::children_detector::discover_vertex
void discover_vertex(u vertex, const g &graph)
Definition: graph.cpp:121
tesseract_scene_graph::UGraph
boost::adjacency_list< boost::listS, boost::listS, boost::undirectedS, VertexProperty, EdgeProperty, GraphProperty > UGraph
Definition: graph.cpp:171
tesseract_scene_graph::SceneGraph::isCollisionAllowed
bool isCollisionAllowed(const std::string &link_name1, const std::string &link_name2) const
Check if two links are allowed to be in collision.
Definition: graph.cpp:793
tesseract_scene_graph::SceneGraph::removeJoint
bool removeJoint(const std::string &name, bool recursive=false)
Removes a joint from the graph.
Definition: graph.cpp:534
tesseract_common::AllowedCollisionMatrix::Ptr
std::shared_ptr< AllowedCollisionMatrix > Ptr
tesseract_scene_graph::JointLimits::upper
double upper
Definition: joint.h:108
tesseract_scene_graph::SceneGraph::acm_
std::shared_ptr< tesseract_common::AllowedCollisionMatrix > acm_
Definition: graph.h:593
tesseract_scene_graph::SceneGraph::changeJointOrigin
bool changeJointOrigin(const std::string &name, const Eigen::Isometry3d &new_origin)
Changes the "origin" transform of the joint and recomputes the associated edge.
Definition: graph.cpp:608
tesseract_scene_graph::SceneGraph::moveLink
bool moveLink(const Joint &joint)
Move link defined by provided joint This deletes all inbound joints on the parent link defined by the...
Definition: graph.cpp:408
tesseract_scene_graph::cycle_detector::back_edge
void back_edge(e, g &)
Definition: graph.cpp:63
tesseract_scene_graph::VertexProperty
boost::property< boost::vertex_link_t, std::shared_ptr< Link >, boost::property< boost::vertex_link_visible_t, bool, boost::property< boost::vertex_link_collision_enabled_t, bool > >> VertexProperty
Defines the boost graph vertex property.
Definition: graph.h:97
tesseract_scene_graph::JointLimits::jerk
double jerk
Definition: joint.h:112
tesseract_common::AllowedCollisionMatrix::ConstPtr
std::shared_ptr< const AllowedCollisionMatrix > ConstPtr
tesseract_scene_graph::Joint::child_link_name
std::string child_link_name
Definition: joint.h:307
tesseract_scene_graph::SceneGraph::getEdge
Edge getEdge(const std::string &name) const
Get the graph edge by name.
Definition: graph.cpp:1118
tesseract_scene_graph::SceneGraph::getShortestPath
ShortestPath getShortestPath(const std::string &root, const std::string &tip) const
Get the shortest path between two links.
Definition: graph.cpp:1008
tesseract_scene_graph::ugraph_vertex_copier::vertex_all_map2
boost::property_map< UGraph, boost::vertex_all_t >::type vertex_all_map2
Definition: graph.cpp:186
tesseract_scene_graph::SceneGraph::addJoint
bool addJoint(const Joint &joint)
Adds joint to the graph.
Definition: graph.cpp:460
tesseract_scene_graph::SceneGraph::setAllowedCollisionMatrix
void setAllowedCollisionMatrix(std::shared_ptr< tesseract_common::AllowedCollisionMatrix > acm)
Set the allowed collision matrix.
Definition: graph.cpp:772
serialization.h
tesseract_scene_graph::SceneGraph::getInboundJoints
std::vector< std::shared_ptr< const Joint > > getInboundJoints(const std::string &link_name) const
Get inbound joints for a link.
Definition: graph.cpp:819
TESSERACT_SERIALIZE_SAVE_LOAD_ARCHIVES_INSTANTIATE
#define TESSERACT_SERIALIZE_SAVE_LOAD_ARCHIVES_INSTANTIATE(Type)
tesseract_scene_graph::SceneGraph::getLinkVisibility
bool getLinkVisibility(const std::string &name) const
Get a given links visibility setting.
Definition: graph.cpp:439
tesseract_scene_graph::SceneGraph::getSourceLink
std::shared_ptr< const Link > getSourceLink(const std::string &joint_name) const
Get the source link (parent link) for a joint.
Definition: graph.cpp:805
boost::graph_root
@ graph_root
Definition: graph.h:69
tesseract_scene_graph::SceneGraph::getJointChildrenNames
std::vector< std::string > getJointChildrenNames(const std::string &name) const
Get all children link names for a given joint name.
Definition: graph.cpp:927
boost::serialization
tesseract_scene_graph::SceneGraph::insertSceneGraph
bool insertSceneGraph(const tesseract_scene_graph::SceneGraph &scene_graph, const std::string &prefix="")
Merge a graph into the current graph.
Definition: graph.cpp:1158
tesseract_scene_graph::JointLimits::acceleration
double acceleration
Definition: joint.h:111
tesseract_scene_graph::tree_detector::tree_
bool & tree_
Definition: graph.cpp:112
tesseract_scene_graph::SceneGraph::load
void load(Archive &ar, const unsigned int version)
Definition: graph.cpp:1330
tesseract_scene_graph::SceneGraph::getActiveJoints
std::vector< std::shared_ptr< const Joint > > getActiveJoints() const
Get a vector of active joints in the scene graph.
Definition: graph.cpp:595
tesseract_scene_graph::SceneGraph::getTargetLink
std::shared_ptr< const Link > getTargetLink(const std::string &joint_name) const
Get the target link (child link) for a joint.
Definition: graph.cpp:812
tesseract_scene_graph::cycle_detector
Definition: graph.cpp:58
tesseract_scene_graph::ShortestPath
Holds the shortest path information.
Definition: graph.h:113
tesseract_scene_graph::JointLimits
Definition: joint.h:92
tesseract_scene_graph::children_detector::children_detector
children_detector(std::vector< std::string > &children)
Definition: graph.cpp:118
tesseract_scene_graph::ShortestPath::joints
std::vector< std::string > joints
A list of joints along the shortest path.
Definition: graph.h:119
boost::vertex_link_visible
@ vertex_link_visible
Definition: graph.h:57
tesseract_scene_graph::SceneGraph::addLinkHelper
bool addLinkHelper(const std::shared_ptr< Link > &link_ptr, bool replace_allowed=false)
Adds a link to the graph.
Definition: graph.cpp:302
tesseract_scene_graph::JointType::CONTINUOUS
@ CONTINUOUS
tesseract_scene_graph::Joint
Definition: joint.h:272
tesseract_scene_graph::tree_detector::tree_detector
tree_detector(bool &tree)
Definition: graph.cpp:74
graph.h
A basic scene graph using boost.
tesseract_scene_graph::SceneGraph::clearAllowedCollisions
void clearAllowedCollisions()
Remove all allowed collisions.
Definition: graph.cpp:791
tesseract_scene_graph::SceneGraph::isEmpty
bool isEmpty() const
Check if the graph is empty.
Definition: graph.cpp:859
TESSERACT_COMMON_IGNORE_WARNINGS_POP
#define TESSERACT_COMMON_IGNORE_WARNINGS_POP
tesseract_scene_graph::children_detector::children_
std::vector< std::string > & children_
Definition: graph.cpp:127
tesseract_scene_graph::SceneGraph::setName
void setName(const std::string &name)
Sets the graph name.
Definition: graph.cpp:246
tesseract_scene_graph::SceneGraph::operator!=
bool operator!=(const SceneGraph &rhs) const
Definition: graph.cpp:1319
tesseract_scene_graph::SceneGraph::getRoot
const std::string & getRoot() const
Gets the root link name (aka. World Coordinate Frame)
Definition: graph.cpp:268
tesseract_scene_graph::SceneGraph::getJoint
std::shared_ptr< const Joint > getJoint(const std::string &name) const
Get a joint in the graph.
Definition: graph.cpp:525
tesseract_scene_graph::operator<<
std::ostream & operator<<(std::ostream &os, const ShortestPath &path)
Definition: graph.cpp:1345
tesseract_scene_graph::SceneGraph::changeJointJerkLimits
bool changeJointJerkLimits(const std::string &name, double limit)
Changes the jerk limits associated with a joint.
Definition: graph.cpp:732
tesseract_scene_graph::SceneGraph::getLeafLinks
std::vector< std::shared_ptr< const Link > > getLeafLinks() const
Get a vector leaf links in the scene graph.
Definition: graph.cpp:351
tesseract_scene_graph::SceneGraph::removeLink
bool removeLink(const std::string &name, bool recursive=false)
Removes a link from the graph.
Definition: graph.cpp:364
tesseract_scene_graph::SceneGraph::joint_map_
std::unordered_map< std::string, std::pair< std::shared_ptr< Joint >, Edge > > joint_map_
Definition: graph.h:592
tesseract_scene_graph::JointLimits::effort
double effort
Definition: joint.h:109
tesseract_scene_graph::SceneGraph::rebuildLinkAndJointMaps
void rebuildLinkAndJointMaps()
The rebuild the link and joint map by extraction information from the graph.
Definition: graph.cpp:1249
tesseract_scene_graph::SceneGraph::setLinkVisibility
void setLinkVisibility(const std::string &name, bool visibility)
Set a links visibility.
Definition: graph.cpp:432
tesseract_scene_graph::SceneGraph::serialize
void serialize(Archive &ar, const unsigned int version)
Definition: graph.cpp:1340
tesseract_scene_graph::Joint::Ptr
std::shared_ptr< Joint > Ptr
Definition: joint.h:277
tesseract_scene_graph::SceneGraph::changeJointAccelerationLimits
bool changeJointAccelerationLimits(const std::string &name, double limit)
Changes the acceleration limits associated with a joint.
Definition: graph.cpp:705
tesseract_scene_graph::SceneGraph::getLink
std::shared_ptr< const Link > getLink(const std::string &name) const
Get a link in the graph.
Definition: graph.cpp:332
tesseract_scene_graph::Joint::getName
const std::string & getName() const
Definition: joint.cpp:259
tesseract_scene_graph::ShortestPath::links
std::vector< std::string > links
a list of links along the shortest path
Definition: graph.h:116
tesseract_scene_graph::children_detector
Definition: graph.cpp:116
tesseract_scene_graph::JointLimits::velocity
double velocity
Definition: joint.h:110
tesseract_scene_graph::SceneGraph::getAdjacencyMap
std::unordered_map< std::string, std::string > getAdjacencyMap(const std::vector< std::string > &link_names) const
Create mapping between links in the scene to the provided links if they are directly affected if the ...
Definition: graph.cpp:948
tesseract_scene_graph::SceneGraph::getVertex
Vertex getVertex(const std::string &name) const
Get the graph vertex by name.
Definition: graph.cpp:1109
tesseract_scene_graph::adjacency_detector
Definition: graph.cpp:130
macros.h
tesseract_scene_graph::JointLimits::lower
double lower
Definition: joint.h:107
tesseract_scene_graph::tree_detector::discover_vertex
void discover_vertex(u vertex, const g &graph)
Definition: graph.cpp:77
tesseract_scene_graph
Definition: fwd.h:32
tesseract_scene_graph::SceneGraph::isAcyclic
bool isAcyclic() const
Determine if the graph contains cycles.
Definition: graph.cpp:861
tesseract_scene_graph::SceneGraph::SceneGraph
SceneGraph(const std::string &name="")
Definition: graph.cpp:189
tesseract_scene_graph::Joint::parent_link_name
std::string parent_link_name
Definition: joint.h:311
tesseract_scene_graph::SceneGraph::operator=
SceneGraph & operator=(const SceneGraph &other)=delete
tesseract_scene_graph::JointType::FIXED
@ FIXED
tesseract_scene_graph::SceneGraph::clear
void clear()
Clear the scene graph.
Definition: graph.cpp:238
tesseract_scene_graph::SceneGraph::getLinkChildrenNames
std::vector< std::string > getLinkChildrenNames(const std::string &name) const
Get all children for a given link name.
Definition: graph.cpp:917


tesseract_scene_graph
Author(s): Levi Armstrong
autogenerated on Sun May 18 2025 03:01:49