Parasol Planning Library (PPL)
GroupRoadmap.h
Go to the documentation of this file.
1 #ifndef PMPL_GROUP_ROADMAP_H_
2 #define PMPL_GROUP_ROADMAP_H_
3 
7 
8 #include <containers/sequential/graph/algorithms/graph_input_output.h>
9 
10 #ifndef INVALID_ED
11 #define INVALID_ED ED{std::numeric_limits<size_t>::max(), std::numeric_limits<size_t>::max()}
12 #endif
13 
14 
24 template <typename Vertex, typename Edge>
25 class GroupRoadmap final : public CompositeGraph<Vertex, Edge> {
26 
27  public:
28 
31 
34 
35  typedef typename Vertex::IndividualGraph IndividualRoadmap;
36  typedef typename IndividualRoadmap::CfgType IndividualCfg;
37  typedef typename IndividualRoadmap::EdgeType IndividualEdge;
38  typedef typename BaseType::EID ED;
39 
44 
45  using typename BaseType::CVI;
46  using typename BaseType::VI;
47  using typename BaseType::EI;
48  using typename BaseType::VID;
49  using typename BaseType::STAPLGraph;
50 
54 
56  template <typename MPSolution>
57  GroupRoadmap(RobotGroup* const _g, MPSolution* const _solution);
58 
65 
66  GroupRoadmap(const GroupRoadmap&) = delete;
68 
69  GroupRoadmap& operator=(const GroupRoadmap&) = delete;
71 
75 
80  virtual VID AddVertex(const Vertex& _v) noexcept override;
81 
86  virtual ED AddEdge(const VID _source, const VID _target, const Edge& _w)
87  noexcept override;
88 
91  using BaseType::AddEdge;
92 
94 };
95 
96 /*------------------------------- Construction -------------------------------*/
97 
98 template <typename Vertex, typename Edge>
99 template <typename MPSolution>
101 GroupRoadmap(RobotGroup* const _g, MPSolution* const _solution) :
102  CompositeGraph<Vertex, Edge>(_g) {
103 
104  std::vector<IndividualRoadmap*> roadmaps;
105  for(Robot* const robot : *_g)
106  roadmaps.push_back(_solution->GetRoadmap(robot));
107 
108  this->m_graphs = roadmaps;
109 }
110 
111 /*-------------------------------- Modifiers ---------------------------------*/
112 
113 template <typename Vertex, typename Edge>
116 AddEdge(const VID _source, const VID _target, const Edge& _lp) noexcept {
117  if(_source == _target)
118  throw RunTimeException(WHERE) << "Tried to add edge between same VID "
119  << _source << ".";
120 
121  if(_lp.GetWeight() == 0 or _lp.GetWeight() == 0)
122  throw RunTimeException(WHERE) << "Tried to add zero weight edge!";
123 
124  // We need to adjust _lp, but we still want to override the base class
125  // function, so make a local copy of the edge.
126  Edge edge = _lp;
127 
128  // Vector of local edges, which are NOT already in individual roadmaps.
129  std::vector<IndividualEdge>& localEdges = edge.GetLocalEdges();
130 
131  // Vector of edge descriptors, which are edges already in individual roadmaps
132  std::vector<ED>& edgeDescriptors = edge.GetEdgeDescriptors();
133 
134  const Vertex& sourceCfg = this->GetVertex(_source),
135  & targetCfg = this->GetVertex(_target);
136 
137  size_t numInactiveRobots = 0;
138 
139  // First, make sure all the local edges are in the individual roadmaps.
140  for(size_t i = 0; i < edgeDescriptors.size(); ++i) {
141  auto roadmap = this->m_graphs[i];
142 
143  const VID individualSourceVID = sourceCfg.GetVID(i),
144  individualTargetVID = targetCfg.GetVID(i);
145 
146  // If they are the same, it means this is an inactive robot. Record the
147  // number of these that occur so that we can ensure SOME robot(s) moved.
148  if(individualSourceVID == individualTargetVID) {
149  ++numInactiveRobots;
150  continue;
151  }
152 
153  // Assert that the individual vertices exist.
154  const bool verticesExist =
155  roadmap->find_vertex(individualSourceVID) != roadmap->end() and
156  roadmap->find_vertex(individualTargetVID) != roadmap->end();
157  if(!verticesExist)
158  throw RunTimeException(WHERE, "Cannot add edge for non-existent vertices.");
159 
160  // If we received a valid edge descriptor, it must agree with the individual
161  // VIDs, and the individual edge must exist.
162  const bool edgeExists = roadmap->IsEdge(individualSourceVID,
163  individualTargetVID);
164  if(edgeDescriptors[i] != INVALID_ED) {
165  if(!edgeExists)
166  throw RunTimeException(WHERE) << "Expected edge (" << individualSourceVID
167  << ", " << individualTargetVID << ") does "
168  << "not exist for robot "
169  << roadmap->GetRobot()->GetLabel() << ".";
170 
171  const bool consistent = edgeDescriptors[i].source() == individualSourceVID
172  and edgeDescriptors[i].target() == individualTargetVID;
173  if(!consistent)
174  throw RunTimeException(WHERE) << "Edge descriptors are not consistent. "
175  << "Fetched from group cfg: ("
176  << individualSourceVID << ", "
177  << individualTargetVID << "), fetched from "
178  << "group edge: ("
179  << edgeDescriptors[i].source() << ", "
180  << edgeDescriptors[i].target() << ").";
181  }
182  // If not, assert that the edge to be added does not already exist and then
183  // add it.
184  else {
185  /*
186  if(edgeExists)
187  std::cerr << "\nGroupRoadmap::AddEdge: robot " << i
188  << "'s individual edge (" << individualSourceVID << ", "
189  << individualTargetVID << ") already exists, "
190  << "not adding to its roadmap." << std::endl;
191  */
192 
193  // NOTE: If you are getting a seg fault here, it's most likely due to not
194  // calling GroupLPOutput::SetIndividualEdges() before calling this!
195  roadmap->AddEdge(individualSourceVID, individualTargetVID, localEdges[i]);
196  edgeDescriptors[i] = ED(individualSourceVID, individualTargetVID);
197  }
198  }
199 
200  if(numInactiveRobots >= this->GetNumRobots())
201  throw RunTimeException(WHERE) << "No robots were moved in this edge!";
202 
203  // Now all of the individual edges are in the local maps. Clear out the local
204  // copies in edge before we add it to the group map.
205  edge.ClearLocalEdges();
206  const auto edgeDescriptor = this->add_edge(_source, _target, edge);
207  const bool notNew = edgeDescriptor.id() == INVALID_EID;
208 
209  if(notNew) {
210  /*
211  std::cerr << "\nGroupRoadmap::AddEdge: edge (" << _source << ", "
212  << _target << ") already exists, not adding."
213  << std::endl;
214  */
215  return INVALID_ED;
216  }
217  else {
218  // Find the edge iterator.
219  VI vi;
220  EI ei;
221  this->find_edge(edgeDescriptor, vi, ei);
222 
223  // Execute post-add hooks.
224  this->ExecuteAddEdgeHooks(ei);
225 
226  this->m_predecessors[_target].insert(_source);
227  ++this->m_timestamp;
228 
229  return edgeDescriptor;
230  }
231 }
232 
233 
234 template <typename Vertex, typename Edge>
237 AddVertex(const Vertex& _v) noexcept {
238  Vertex cfg = _v; // Will be a copy of the const Vertex
239  // Check that the group map is correct, if not, try and change it.
240  if((GroupRoadmapType*)_v.GetGroupRoadmap() != this) {
241  std::cerr << "GroupRoadmap::AddVertex: Warning! Group roadmap "
242  << "doesn't match this, attempting to exchange the roadmap..."
243  << std::endl;
244  cfg.SetGroupRoadmap(this);
245  }
246 
247  // Find the vertex and ensure it does not already exist.
248  CVI vi;
249  if(this->IsVertex(cfg, vi)) {
250  std::cerr << "\nGroupRoadmap::AddVertex: vertex " << vi->descriptor()
251  << " already in graph"
252  << std::endl;
253  return vi->descriptor();
254  }
255 
256  // Add each vid to individual roadmaps if not already present.
257  for(size_t i = 0; i < this->m_group->Size(); ++i) {
258  auto roadmap = this->GetIndividualGraph(i);
259  auto robot = roadmap->GetRobot();
260  VID individualVID = cfg.GetVID(i);
261 
262  // If the vid is invalid, we must add the local cfg.
263  if(individualVID == INVALID_VID) {
264  individualVID =roadmap->AddVertex(cfg.GetRobotCfg(i));
265  cfg.SetRobotCfg(robot, individualVID);
266  }
267  // If the vid was valid, make sure it exists.
268  else if(roadmap->find_vertex(individualVID) == roadmap->end())
269  throw RunTimeException(WHERE) << "Individual vertex " << individualVID
270  << " does not exist!";
271  }
272 
273  // The vertex does not exist. Add it now.
274  const VID vid = this->add_vertex(cfg);
275  this->m_predecessors[vid];
276  this->m_allVIDs.insert(vid);
277  ++this->m_timestamp;
278 
279  // Execute post-add hooks.
280  this->ExecuteAddVertexHooks(this->find_vertex(vid));
281 
282  return vid;
283 }
284 
285 /*----------------------------------------------------------------------------*/
286 
287 #endif
#define INVALID_VID
Definition: GenericStateGraph.h:23
#define INVALID_EID
Definition: GenericStateGraph.h:27
#define INVALID_ED
Definition: GroupRoadmap.h:11
#define WHERE
Macro for retrieving info about file, function, and line number.
Definition: RuntimeUtils.h:32
Definition: CompositeGraph.h:27
virtual EID AddEdge(const VID _source, const VID _target, const Edge &_w) noexcept
Definition: GenericStateGraph.h:698
BaseType::vertex_descriptor vertex_descriptor
Definition: CompositeGraph.h:44
BaseType::EID ED
Definition: CompositeGraph.h:38
STAPLGraph::vertex_descriptor VID
Definition: GenericStateGraph.h:83
STAPLGraph::const_vertex_iterator CVI
Definition: GenericStateGraph.h:91
STAPLGraph::vertex_iterator VI
Definition: GenericStateGraph.h:89
STAPLGraph::adj_edge_iterator EI
Definition: GenericStateGraph.h:90
stapl::sequential::graph< stapl::DIRECTED, stapl::NONMULTIEDGES, Vertex, Edge > STAPLGraph
Definition: GenericStateGraph.h:80
std::vector< IndividualGraph * > m_graphs
The individual graphs.
Definition: CompositeGraph.h:165
BaseType::edge_descriptor edge_descriptor
Definition: CompositeGraph.h:42
BaseType::vertex_iterator vertex_iterator
Definition: CompositeGraph.h:43
BaseType::adj_edge_iterator adj_edge_iterator
Definition: CompositeGraph.h:41
STAPLGraph::vertex_descriptor VID
Definition: GenericStateGraph.h:83
STAPLGraph::const_vertex_iterator CVI
Definition: GenericStateGraph.h:91
STAPLGraph::vertex_iterator VI
Definition: GenericStateGraph.h:89
STAPLGraph::edge_descriptor EID
Definition: GenericStateGraph.h:84
STAPLGraph::adj_edge_iterator EI
Definition: GenericStateGraph.h:90
Definition: GroupRoadmap.h:25
virtual EID AddEdge(const VID _source, const VID _target, const Edge &_w) noexcept
Definition: GenericStateGraph.h:698
STAPLGraph::vertex_descriptor VID
Definition: GenericStateGraph.h:83
Vertex::IndividualGraph IndividualRoadmap
Definition: GroupRoadmap.h:35
GroupRoadmap(RobotGroup *const _g, MPSolution *const _solution)
Construct a group roadmap.
Definition: GroupRoadmap.h:101
CompositeGraph< Vertex, Edge > BaseType
Definition: GroupRoadmap.h:32
GroupRoadmap< Vertex, Edge > GroupRoadmapType
Definition: GroupRoadmap.h:33
virtual VID AddVertex(const Vertex &_v) noexcept override
Definition: GroupRoadmap.h:237
BaseType::vertex_descriptor vertex_descriptor
Definition: GroupRoadmap.h:43
BaseType::vertex_iterator vertex_iterator
Definition: GroupRoadmap.h:42
BaseType::adj_edge_iterator adj_edge_iterator
Definition: GroupRoadmap.h:40
GroupRoadmap(const GroupRoadmap &)=delete
IndividualRoadmap::EdgeType IndividualEdge
Definition: GroupRoadmap.h:37
IndividualRoadmap::CfgType IndividualCfg
Definition: GroupRoadmap.h:36
BaseType::edge_descriptor edge_descriptor
Definition: GroupRoadmap.h:41
GroupRoadmap(GroupRoadmap &&)=delete
GroupRoadmap & operator=(const GroupRoadmap &)=delete
GroupRoadmap & operator=(GroupRoadmap &&)=delete
BaseType::EID ED
Definition: GroupRoadmap.h:38
A group of one or more robots.
Definition: RobotGroup.h:17
Definition: Robot.h:31
Definition: PMPLExceptions.h:62