Parasol Planning Library (PPL)
CompositeEdge.h
Go to the documentation of this file.
1 #ifndef PPL_COMPOSITE_EDGE_H_
2 #define PPL_COMPOSITE_EDGE_H_
3 
8 
9 #include "containers/sequential/graph/graph_util.h"
10 
11 #include <algorithm>
12 #include <iostream>
13 #include <vector>
14 
15 template <typename GraphType> class CompositeState;
16 
17 
22 template <typename GraphType>
24 
25  public:
26 
29 
30  typedef typename GraphType::CfgType IndividualCfg;
31  typedef typename GraphType::EdgeType IndividualEdge;
32 
33  typedef double EdgeWeight;
34  typedef stapl::edge_descriptor_impl<size_t> ED;
35 
38  typedef std::vector<CompositeStateType> CompositePath;
39 
43 
48  CompositeEdge(GroupGraphType* const & _g = nullptr, const double _w = 0.0,
49  const CompositePath& _intermediates = CompositePath());
50 
55  CompositeEdge(RobotGroup* const & _g, const double _w = 0.0,
56  const CompositePath& _intermediates = CompositePath());
57 
61 
64  virtual bool operator==(const CompositeEdge& _w) const noexcept;
65 
68  virtual bool operator!=(const CompositeEdge& _w) const noexcept;
69 
72  virtual bool operator<(const CompositeEdge& _other) const noexcept;
73 
77 
79  virtual EdgeWeight GetWeight() const noexcept;
80 
83  virtual void SetWeight(const EdgeWeight _w) noexcept;
84 
88 
91  void SetGroupGraph(GroupGraphType* const& _g);
92 
94  virtual void Clear() noexcept;
95 
97  CompositePath& GetIntermediates() noexcept;
98 
100  const CompositePath& GetIntermediates() const noexcept;
101 
103  const size_t GetNumIntermediates() noexcept;
104 
106  void SetIntermediates(const CompositePath& _cfgs);
107 
110  virtual void Write(std::ostream& _os) const;
111 
115 
119  virtual void SetEdge(Robot* const _robot, const ED _ed);
120 
124  void SetEdge(const size_t _robot, IndividualEdge&& _edge);
125 
129  void SetEdge(Robot* const _robot, IndividualEdge&& _edge);
130 
135  virtual IndividualEdge* GetEdge(Robot* const _robot);
136 
141  virtual const IndividualEdge* GetEdge(Robot* const _robot) const;
142 
147  virtual IndividualEdge* GetEdge(const size_t _robotIndex);
148 
153  virtual const IndividualEdge* GetEdge(const size_t _robotIndex) const;
154 
156  std::vector<IndividualEdge>& GetLocalEdges() noexcept;
157 
159  void ClearLocalEdges() noexcept;
160 
163  virtual std::vector<ED>& GetEdgeDescriptors() noexcept;
164 
166  virtual size_t GetNumRobots() const noexcept;
167 
170  virtual std::unordered_set<Robot*> GetActiveRobots();
171 
173  virtual void SetTimeSteps(size_t _timesteps);
174 
176  virtual size_t GetTimeSteps() const;
177 
181 
184  virtual CompositeEdge operator+(const CompositeEdge& _other) const ;
185 
187  virtual double Weight() const noexcept;
188 
193 
194  typedef typename std::vector<ED>::iterator iterator;
195  typedef typename std::vector<ED>::const_iterator const_iterator;
196 
197  virtual iterator begin() noexcept;
198  virtual iterator end() noexcept;
199 
200  virtual const_iterator begin() const noexcept;
201  virtual const_iterator end() const noexcept;
202 
204 
205  protected:
206 
209 
211 
212  RobotGroup* m_group{nullptr};
213 
215  double m_weight{std::numeric_limits<double>::infinity()};
216 
218 
219  std::vector<ED> m_edges;
220 
222  std::vector<IndividualEdge> m_localEdges;
223 
224  size_t m_timesteps;
225 
227 
228 };
229 
230 /*------------------------------- Construction -------------------------------*/
231 
232 template <typename GraphType>
234 CompositeEdge(GroupGraphType* const & _g, const double _w,
235  const CompositePath& _intermediates)
236  : m_groupMap(_g), m_group(_g->GetGroup()),
237  m_weight(_w) {
238 
239  m_intermediates.clear();
240  for(auto intermediate : _intermediates) {
241  m_intermediates.push_back(intermediate);
242  }
243 
244  if(m_groupMap) {
245  m_edges.resize(m_groupMap->GetGroup()->Size(), INVALID_ED);
246  m_localEdges.resize(m_groupMap->GetGroup()->Size());
247  }
248 }
249 
250 template <typename GraphType>
252 CompositeEdge(RobotGroup* const & _g, const double _w,
253  const CompositePath& _intermediates)
254  : m_group(_g), m_weight(_w), m_intermediates(_intermediates) {
255 
256  // Allocate space for local edges and set all edge descriptors to invalid.
257  m_localEdges.resize(m_group->Size());
258  m_edges.resize(m_group->Size(), INVALID_ED);
259 }
260 
261 /*------------------------- Misc Interface Functions -------------------------*/
262 
263 template <typename GraphType>
264 void
266 SetGroupGraph(GroupGraphType* const & _g) {
267  // The new composite graph must have the same group.
268  if(_g->GetGroup() != m_group)
269  throw RunTimeException(WHERE) << "The new composite graph must have the "
270  << "same robot group.";
271 
272  // Clear the edge descriptors since they do not correspond to the new graph.
273  m_edges.resize(m_group->Size(), INVALID_ED);
274 
275  m_groupMap = _g;
276 }
277 
278 template <typename GraphType>
281 GetIntermediates() noexcept {
282  return m_intermediates;
283 }
284 
285 
286 template <typename GraphType>
289 GetIntermediates() const noexcept {
290  return m_intermediates;
291 }
292 
293 
294 template <typename GraphType>
295 const size_t
297 GetNumIntermediates() noexcept {
298  return m_intermediates.size();
299 }
300 
301 
302 template <typename GraphType>
303 void
305 SetIntermediates(const CompositePath& _path) {
306  m_intermediates = _path;
307 }
308 
309 /*--------------------------- Ordering and Equality --------------------------*/
310 
311 template <typename GraphType>
312 bool
314 operator==(const CompositeEdge& _other) const noexcept {
315 
316  // Check that both edges correspond to the same group.
317  // If not, return false.
318  if(m_group != _other.m_group)
319  return false;
320 
321  // Check that both edges have a group map
322  // If neither do, return true
323  if(!m_groupMap and !_other.m_groupMap)
324  return true;
325 
326  // If only one does, return false
327  if(!m_groupMap or !_other.m_groupMap)
328  return false;
329 
330  // Ensure the edges are equal.
331  for(size_t i = 0; i < m_groupMap->GetGroup()->Size(); ++i) {
332  // If both descriptors are valid and equal, these edges are equal.
333  const auto& ed1 = m_edges[i],
334  & ed2 = _other.m_edges[i];
335  if(ed1 != INVALID_ED and ed2 != INVALID_ED and ed1 != ed2)
336  return false;
337 
338  // If either descriptor is invalid, one of the edges must be a local edge.
339  // In that case, these edges must compare value-equal.
340  const auto robot1 = m_groupMap->GetGroup()->GetRobot(i),
341  robot2 = _other.m_groupMap->GetGroup()->GetRobot(i);
342  if(*GetEdge(robot1) != *_other.GetEdge(robot2))
343  return false;
344  }
345 
346  return true;
347 }
348 
349 
350 template <typename GraphType>
351 bool
353 operator!=(const CompositeEdge& _other) const noexcept {
354  return !(*this == _other);
355 }
356 
357 
358 template <typename GraphType>
359 inline
360 bool
362 operator<(const CompositeEdge& _other) const noexcept {
363  return GetWeight() < _other.GetWeight();
364 }
365 
366 /*---------------------------- Roadmap Edge Weights --------------------------*/
367 
368 template <typename GraphType>
371 GetWeight() const noexcept {
372  return m_weight;
373 }
374 
375 
376 template <typename GraphType>
377 void
379 SetWeight(const EdgeWeight _w) noexcept {
380  m_weight = _w;
381 }
382 
383 /*------------------------- Misc Interface Functions -------------------------*/
384 
385 template <typename GraphType>
386 void
388 Clear() noexcept {
389  // Reset the initial state variables of this object:
390  m_weight = 0.;
391 }
392 
393 // Writes to a standard output stream all of the data for the edge, including
394 // control signals for nonholonomic robots.
395 // This function is symmetric with Write().
396 template <typename GraphType>
397 void
399 Write(std::ostream& _os) const {
400  // Write the intermediates of the composite edge.
401  _os << m_intermediates.size() << " ";
402  for(auto& cfg : m_intermediates)
403  _os << cfg;
404  _os << std::scientific << std::setprecision(16) << m_weight;
405 
406  // Clear scientific/precision options.
407  _os.unsetf(std::ios_base::floatfield);
408 }
409 
410 template <typename GraphType>
411 std::ostream&
412 operator<<(std::ostream& _os, const CompositeEdge<GraphType>& _w) {
413  _w.Write(_os);
414  return _os;
415 }
416 
417 /*-------------------------- Individual Local Plans --------------------------*/
418 
419 template <typename GraphType>
420 void
422 SetEdge(Robot* const _robot, const ED _ed) {
423  // Make sure that the composite graph has been set
424  if(!m_groupMap)
425  throw RunTimeException(WHERE) << "Can't set an edge descriptor without a "
426  << "composite graph.";
427 
428  const size_t index = m_groupMap->GetGroup()->GetGroupIndex(_robot);
429  m_edges[index] = _ed;
430 }
431 
432 
433 template <typename GraphType>
434 void
436 SetEdge(Robot* const _robot, IndividualEdge&& _edge) {
437  const size_t index = m_group->GetGroupIndex(_robot);
438  SetEdge(index, std::move(_edge));
439 }
440 
441 
442 template <typename GraphType>
443 void
445 SetEdge(const size_t robotIndex, IndividualEdge&& _edge) {
446  m_localEdges[robotIndex] = std::move(_edge);
447  m_edges[robotIndex] = INVALID_ED;
448 }
449 
450 
451 template <typename GraphType>
454 GetEdge(const size_t _robotIndex) {
455  return const_cast<IndividualEdge*>(GetEdge(m_group->GetRobot(_robotIndex)));
456 }
457 
458 
459 template <typename GraphType>
462 GetEdge(const size_t _robotIndex) const {
463  return GetEdge(m_group->GetRobot(_robotIndex));
464 }
465 
466 
467 template <typename GraphType>
470 GetEdge(Robot* const _robot) {
471  return const_cast<IndividualEdge*>(GetEdge(_robot));
472 }
473 
474 
475 template <typename GraphType>
478 GetEdge(Robot* const _robot) const {
479  const size_t index = m_group->GetGroupIndex(_robot);
480 
481  const ED& descriptor = m_edges.at(index);
482  if(descriptor != INVALID_ED)
483  return &m_groupMap->GetIndividualGraph(index)->GetEdge(descriptor.source(),
484  descriptor.target());
485 
486  try {
487  return &m_localEdges.at(index);
488  }
489  catch(const std::out_of_range&) {
490  throw RunTimeException(WHERE) << "Requested individual edge for robot "
491  << index << " (" << _robot << "), which is"
492  << " either stationary for this composite edge"
493  << "or not in the group.";
494  }
495 }
496 
497 
498 template <typename GraphType>
499 std::vector<typename CompositeEdge<GraphType>::ED>&
501 GetEdgeDescriptors() noexcept {
502  return m_edges;
503 }
504 
505 
506 template <typename GraphType>
507 std::vector<typename CompositeEdge<GraphType>::IndividualEdge>&
509 GetLocalEdges() noexcept {
510  return m_localEdges;
511 }
512 
513 
514 template <typename GraphType>
515 void
517 ClearLocalEdges() noexcept {
518  m_localEdges.clear();
519 }
520 
521 
522 template <typename GraphType>
523 size_t
525 GetNumRobots() const noexcept {
526  return m_group->Size();
527 }
528 
529 template <typename GraphType>
530 std::unordered_set<Robot*>
532 GetActiveRobots() {
533  // Note: this only works for non-local edges
534  std::unordered_set<Robot*> actives;
535 
536  for(size_t i = 0; i < m_edges.size(); ++i) {
537  if(m_edges[i] == INVALID_ED)
538  continue;
539 
540  auto roadmap = m_groupMap->GetIndividualGraph(i);
541 
542  typename GraphType::CEI ei;
543  typename GraphType::CVI vi;
544  roadmap->find_edge(m_edges[i], vi, ei);
545 
546  if(ei->source() != ei->target()) {
547  actives.insert(m_group->GetRobot(i));
548  }
549  }
550  return actives;
551 }
552 
553 template <typename GraphType>
554 void
556 SetTimeSteps(size_t _timesteps) {
557  m_timesteps = _timesteps;
558 }
559 
560 template <typename GraphType>
561 size_t
563 GetTimeSteps() const {
564  return m_timesteps;
565 }
566 
567 /*---------------------- stapl graph interface helpers -----------------------*/
568 
569 template <typename GraphType>
572 operator+(const CompositeEdge& _other) const {
573  if(!m_groupMap)
574  return CompositeEdge(m_group, m_weight + _other.m_weight);
575  else
576  return CompositeEdge(m_groupMap, m_weight + _other.m_weight);
577 }
578 
579 
580 template <typename GraphType>
581 double
583 Weight() const noexcept {
584  return GetWeight();
585 }
586 
587 /*-------------------------------- Iteration ---------------------------------*/
588 
589 template <typename GraphType>
592 begin() noexcept {
593  return m_edges.begin();
594 }
595 
596 
597 template <typename GraphType>
600 end() noexcept {
601  return m_edges.end();
602 }
603 
604 
605 template <typename GraphType>
608 begin() const noexcept {
609  return m_edges.begin();
610 }
611 
612 
613 template <typename GraphType>
616 end() const noexcept {
617  return m_edges.end();
618 }
619 
620 #endif
std::ostream & operator<<(std::ostream &_os, const CompositeEdge< GraphType > &_w)
Definition: CompositeEdge.h:412
#define INVALID_ED
Definition: CompositeGraph.h:11
#define WHERE
Macro for retrieving info about file, function, and line number.
Definition: RuntimeUtils.h:32
Definition: CompositeEdge.h:23
virtual size_t GetNumRobots() const noexcept
Get the number of robots given in this group local plan.
Definition: CompositeEdge.h:525
virtual void SetTimeSteps(size_t _timesteps)
Set the number of timesteps along this composite edge.
Definition: CompositeEdge.h:556
virtual std::unordered_set< Robot * > GetActiveRobots()
Definition: CompositeEdge.h:532
virtual void SetEdge(Robot *const _robot, const ED _ed)
Definition: CompositeEdge.h:422
RobotGroup * m_group
The robot group that this edge belongs to.
Definition: CompositeEdge.h:212
virtual bool operator==(const CompositeEdge &_w) const noexcept
Definition: CompositeEdge.h:314
GraphType::EdgeType IndividualEdge
Definition: CompositeEdge.h:31
std::vector< IndividualEdge > m_localEdges
Note that any edges added to m_localEdges must be valid and complete.
Definition: CompositeEdge.h:222
size_t m_timesteps
The number of timesteps along this edge.
Definition: CompositeEdge.h:224
CompositePath & GetIntermediates() noexcept
Get the composite state intermediates.
Definition: CompositeEdge.h:281
void SetIntermediates(const CompositePath &_cfgs)
Set the composite state intermediates.
Definition: CompositeEdge.h:305
std::vector< ED >::iterator iterator
Definition: CompositeEdge.h:194
virtual EdgeWeight GetWeight() const noexcept
Get the numeric weight for this edge.
Definition: CompositeEdge.h:371
virtual iterator begin() noexcept
Definition: CompositeEdge.h:592
virtual void Clear() noexcept
Reset the states of this object.
Definition: CompositeEdge.h:388
std::vector< CompositeStateType > CompositePath
Definition: CompositeEdge.h:38
virtual CompositeEdge operator+(const CompositeEdge &_other) const
Definition: CompositeEdge.h:572
void SetGroupGraph(GroupGraphType *const &_g)
Definition: CompositeEdge.h:266
double m_weight
The edge weight.
Definition: CompositeEdge.h:215
virtual double Weight() const noexcept
Get the weight of the plan.
Definition: CompositeEdge.h:583
std::vector< ED >::const_iterator const_iterator
Definition: CompositeEdge.h:195
GraphType::CfgType IndividualCfg
Definition: CompositeEdge.h:30
CompositeGraph< CompositeStateType, CompositeEdge > GroupGraphType
Definition: CompositeEdge.h:37
GroupGraphType * m_groupMap
The composite graph that this edge is in.
Definition: CompositeEdge.h:210
virtual std::vector< ED > & GetEdgeDescriptors() noexcept
Definition: CompositeEdge.h:501
virtual void Write(std::ostream &_os) const
Definition: CompositeEdge.h:399
std::vector< ED > m_edges
Descriptors of the individual edges.
Definition: CompositeEdge.h:219
CompositeState< GraphType > CompositeStateType
Definition: CompositeEdge.h:36
virtual IndividualEdge * GetEdge(Robot *const _robot)
Definition: CompositeEdge.h:470
CompositeEdge(GroupGraphType *const &_g=nullptr, const double _w=0.0, const CompositePath &_intermediates=CompositePath())
Definition: CompositeEdge.h:234
virtual void SetWeight(const EdgeWeight _w) noexcept
Definition: CompositeEdge.h:379
std::vector< IndividualEdge > & GetLocalEdges() noexcept
Get a vector of local edges in the plan.
Definition: CompositeEdge.h:509
const size_t GetNumIntermediates() noexcept
Get the number of composite intermediates along this edge.
Definition: CompositeEdge.h:297
double EdgeWeight
Definition: CompositeEdge.h:33
virtual bool operator<(const CompositeEdge &_other) const noexcept
Definition: CompositeEdge.h:362
stapl::edge_descriptor_impl< size_t > ED
Definition: CompositeEdge.h:34
virtual size_t GetTimeSteps() const
Get the number of timesteps along this composite edge.
Definition: CompositeEdge.h:563
virtual iterator end() noexcept
Definition: CompositeEdge.h:600
void ClearLocalEdges() noexcept
Clear all local edges in the plan.
Definition: CompositeEdge.h:517
CompositePath m_intermediates
Composite state intermediates.
Definition: CompositeEdge.h:217
virtual bool operator!=(const CompositeEdge &_w) const noexcept
Definition: CompositeEdge.h:353
Definition: CompositeGraph.h:27
virtual RobotGroup * GetGroup()
Get the robot group.
Definition: CompositeGraph.h:190
Definition: CompositeState.h:26
A group of one or more robots.
Definition: RobotGroup.h:17
size_t Size() const noexcept
Get the number of robots in the group.
Definition: RobotGroup.cpp:128
Definition: Robot.h:31
Definition: PMPLExceptions.h:62