Parasol Planning Library (PPL)
CompositeState.h
Go to the documentation of this file.
1 #ifndef PPL_COMPOSITE_STATE_H_
2 #define PPL_COMPOSITE_STATE_H_
3 
6 
8 #include "nonstd.h"
9 
10 #include <cstddef>
11 #include <iostream>
12 #include <vector>
13 
14 #include "Vector.h"
15 
16 class Robot;
17 class RobotGroup;
18 template <typename GraphType> class CompositeEdge;
19 
20 
25 template <typename GraphType>
27 
28  public:
29 
32 
33  typedef size_t VID;
34  typedef std::vector<VID> VIDSet;
35  typedef typename GraphType::CfgType CfgType;
36 
39 
40  typedef GraphType IndividualGraph;
41 
45 
48  explicit CompositeState(GroupGraphType* const _groupGraph = nullptr);
49 
53  explicit CompositeState(RobotGroup* const _group);
54 
58 
62  virtual bool operator==(const CompositeState& _other) const noexcept;
63 
67  virtual bool operator!=(const CompositeState& _other) const noexcept;
68 
73 
75  virtual size_t GetNumRobots() const noexcept;
76 
78  virtual const std::vector<Robot*>& GetRobots() const noexcept;
79 
82  virtual Robot* GetRobot(const size_t _index) const;
83 
89 
91  virtual GroupGraphType* GetGroupGraph() const noexcept;
92 
94  virtual void SetGroupGraph(GroupGraphType* _newGraph);
95 
100  virtual VID GetVID(const size_t _index) const noexcept;
101 
106  virtual VID GetVID(Robot* const _robot) const;
107 
113 
117  virtual void SetRobotCfg(Robot* const _robot, const VID _vid);
118 
122  virtual void SetRobotCfg(const size_t _index, const VID _vid);
123 
127  virtual void SetRobotCfg(Robot* const _robot, CfgType&& _cfg);
128 
132  virtual void SetRobotCfg(const size_t _index, CfgType&& _cfg);
133 
137  virtual CfgType& GetRobotCfg(Robot* const _robot);
138 
142  virtual CfgType& GetRobotCfg(const size_t _index);
143 
147  virtual const CfgType& GetRobotCfg(Robot* const _robot) const;
148 
152  virtual const CfgType& GetRobotCfg(const size_t _index) const;
153 
155  void ClearLocalCfgs();
156 
158 
159  protected:
160 
163 
166  virtual void VerifyIndex(const size_t _robotIndex) const noexcept;
167 
170  virtual bool IsLocalCfg(const size_t _robotIndex) const noexcept;
171 
173  virtual void InitializeLocalCfgs() noexcept;
174 
178 
180 
181  RobotGroup* m_group{nullptr};
182 
184 
185  std::vector<CfgType> m_localCfgs;
186 
188 
189 };
190 
191 template <typename GraphType>
192 std::ostream& operator<<(std::ostream&, const CompositeState<GraphType>&);
193 
194 /*------------------------------- Construction -------------------------------*/
195 
196 template <typename GraphType>
198 CompositeState(GroupGraphType* const _groupGraph) : m_groupMap(_groupGraph) {
199 
200  // If no group graph was given, this is a placeholder object.
201  if(!m_groupMap)
202  return;
203 
204  // Set the group to the one given in the composite graph.
206 
207  // Set the VID list to all invalid.
208  m_vids.resize(GetNumRobots(), INVALID_VID);
209 
210  // Initialize local configurations.
212 }
213 
214 
215 template <typename GraphType>
217 CompositeState(RobotGroup* const _group) : m_group(_group) {
218  // Set the VID list to all invalid.
219  m_vids.resize(GetNumRobots(), INVALID_VID);
220 
221  // Initialize local configurations.
223 }
224 
225 
226 /*--------------------------------- Equality ---------------------------------*/
227 
228 template <typename GraphType>
229 bool
231 operator==(const CompositeState<GraphType>& _other) const noexcept {
232  // If _other is for another group, these are not the same.
233  if(m_group != _other.m_group)
234  return false;
235 
236  // If _other is from another graph, these are not the same.
237  if(m_groupMap != _other.m_groupMap)
238  return false;
239 
240  // Else, compare VIDs if both are valid, or by-value other wise.
241  for(size_t i = 0; i < m_vids.size(); ++i) {
242  const VID thisVID = m_vids[i],
243  otherVID = _other.m_vids[i];
244 
245  if(thisVID != INVALID_VID and otherVID != INVALID_VID) {
246  if(thisVID != otherVID)
247  return false;
248  }
249  else if(GetRobotCfg(i) != _other.GetRobotCfg(i))
250  return false;
251  }
252 
253  return true;
254 }
255 
256 
257 template <typename GraphType>
258 bool
260 operator!=(const CompositeState<GraphType>& _other) const noexcept {
261  return !(*this == _other);
262 }
263 
264 /*---------------------------------- Robots ----------------------------------*/
265 
266 template <typename GraphType>
267 size_t
269 GetNumRobots() const noexcept {
270  return m_group ? m_group->Size() : 0;
271 }
272 
273 
274 template <typename GraphType>
275 const std::vector<Robot*>&
277 GetRobots() const noexcept {
278  return m_group->GetRobots();
279 }
280 
281 
282 template <typename GraphType>
283 Robot*
285 GetRobot(const size_t _index) const {
286  VerifyIndex(_index);
287 
288  Robot* const robot = m_group->GetRobot(_index);
289 
291  if(!robot)
292  throw RunTimeException(WHERE) << "Error! Robot pointer was null.";
293 
294  return robot;
295 }
296 
297 /*------------------------------ Graph Accessors -----------------------------*/
298 
299 template <typename GraphType>
302 GetGroupGraph() const noexcept {
303  return m_groupMap;
304 }
305 
306 template <typename GraphType>
307 void
309 SetGroupGraph(GroupGraphType* const _newGraph) {
310  // Check that groups are compatible.
311  if(m_group != _newGraph->GetGroup())
312  throw RunTimeException(WHERE) << "Trying to change graphs on incompatible "
313  << "groups!";
314 
315  // Set the group graph and set all vids to invalid.
316  m_groupMap = _newGraph;
317  m_vids.resize(GetNumRobots(), INVALID_VID);
318 }
319 
320 template <typename GraphType>
323 GetVID(const size_t _index) const noexcept {
324  VerifyIndex(_index);
325  return m_vids[_index];
326 }
327 
328 template <typename GraphType>
331 GetVID(Robot* const _robot) const {
332  const size_t index = m_groupMap->GetGroup()->GetGroupIndex(_robot);
333  return GetVID(index);
334 }
335 
336 /*------------------------ Individual States -------------------------*/
337 
338 template <typename GraphType>
339 void
341 SetRobotCfg(Robot* const _robot, const VID _vid) {
342  if(!m_groupMap)
343  throw RunTimeException(WHERE) << "Can't set a VID without a composite graph.";
344 
345  const size_t index = m_groupMap->GetGroup()->GetGroupIndex(_robot);
346  SetRobotCfg(index, _vid);
347 }
348 
349 
350 template <typename GraphType>
351 void
353 SetRobotCfg(const size_t _index, const VID _vid) {
354  if(!m_groupMap)
355  throw RunTimeException(WHERE) << "Can't set a VID without a composite graph.";
356 
357  VerifyIndex(_index);
358  m_vids[_index] = _vid;
359 }
360 
361 
362 template <typename GraphType>
363 void
365 SetRobotCfg(Robot* const _robot, CfgType&& _cfg) {
366  const size_t index = m_group->GetGroupIndex(_robot);
367  SetRobotCfg(index, std::move(_cfg));
368 }
369 
370 
371 template <typename GraphType>
372 void
374 SetRobotCfg(const size_t _index, CfgType&& _cfg) {
375  VerifyIndex(_index);
376 
377  m_localCfgs[_index] = std::move(_cfg);
378  m_vids[_index] = INVALID_VID;
379 }
380 
381 
382 template <typename GraphType>
383 void
385 ClearLocalCfgs() {
386  m_localCfgs.clear();
387 }
388 
389 
390 template <typename GraphType>
393 GetRobotCfg(Robot* const _robot) {
394  const size_t index = m_group->GetGroupIndex(_robot);
395  return GetRobotCfg(index);
396 }
397 
398 
399 template <typename GraphType>
402 GetRobotCfg(const size_t _index) {
403  VerifyIndex(_index);
404 
405  const VID vid = GetVID(_index);
406  if(vid != INVALID_VID)
407  return m_groupMap->GetIndividualGraph(_index)->GetVertex(vid);
408  else {
409  InitializeLocalCfgs();
410  return m_localCfgs[_index];
411  }
412 }
413 
414 
415 template <typename GraphType>
418 GetRobotCfg(Robot* const _robot) const {
419  const size_t index = m_group->GetGroupIndex(_robot);
420  return GetRobotCfg(index);
421 }
422 
423 
424 template <typename GraphType>
427 GetRobotCfg(const size_t _index) const {
428  VerifyIndex(_index);
429 
430  // If we have a valid VID for this robot, fetch its state from its
431  // individual graph.
432  const VID vid = GetVID(_index);
433  if(vid != INVALID_VID)
434  return m_groupMap->GetIndividualGraph(_index)->GetVertex(vid);
435 
436  try {
437  return m_localCfgs.at(_index);
438  }
439  catch(const std::out_of_range&) {
440  throw RunTimeException(WHERE) << "Requested configuration for robot "
441  << _index
442  << ", but no roadmap or local cfg exists.";
443  }
444 }
445 
446 /*----------------------------------------------------------------------------*/
447 
448 template <typename GraphType>
449 inline
450 void
452 VerifyIndex(const size_t _robotIndex) const noexcept {
453  if(_robotIndex >= GetNumRobots())
454  throw RunTimeException(WHERE) << "Requested data for robot " << _robotIndex
455  << ", but the group has only " << GetNumRobots()
456  << " robots.";
457 }
458 
459 /*----------------------------------------------------------------------------*/
460 
461 template <typename GraphType>
462 std::ostream&
463 operator<<(std::ostream& _os, const CompositeState<GraphType>& _compositeState) {
464  // Might not need to be hidden behind GROUP_MAP, but doing for consistency
465 #ifdef GROUP_MAP
466  _os << "0 ";
467 #endif
468 
469  // Loop through all robots in the group and print each one's state in order.
470  for(size_t i = 0; i < _compositeState.GetNumRobots(); ++i)
471  _os << _compositeState.GetRobotCfg(i);
472 
473  return _os;
474 }
475 
476 /*----------------------------------------------------------------------------*/
477 
478 template <typename GraphType>
479 bool
481 IsLocalCfg(const size_t _robotIndex) const noexcept {
482  // Only true if there is local data (meaning INVALID_VID is present)
483  return m_vids[_robotIndex] == INVALID_VID;
484 }
485 
486 
487 template <typename GraphType>
488 void
490 InitializeLocalCfgs() noexcept {
491  // We will assume the local cfgs are initialized if the container size is
492  // correct.
493  const size_t numRobots = GetNumRobots();
494  if(m_localCfgs.size() == numRobots)
495  return;
496 
497  m_localCfgs.clear();
498  m_localCfgs.resize(numRobots);
499 
500  for(size_t i = 0; i < numRobots; ++i)
501  m_localCfgs[i] = CfgType(this->GetRobot(i));
502 }
503 
504 /*----------------------------------------------------------------------------*/
505 
506 #endif
std::ostream & operator<<(std::ostream &, const CompositeState< GraphType > &)
Definition: CompositeState.h:463
#define INVALID_VID
Definition: GenericStateGraph.h:23
#define WHERE
Macro for retrieving info about file, function, and line number.
Definition: RuntimeUtils.h:32
Definition: CompositeEdge.h:23
Definition: CompositeGraph.h:27
virtual RobotGroup * GetGroup()
Get the robot group.
Definition: CompositeGraph.h:190
Definition: CompositeState.h:26
std::vector< CfgType > m_localCfgs
Individual states not in a map.
Definition: CompositeState.h:185
GraphType::CfgType CfgType
The indiv. graph vertex type.
Definition: CompositeState.h:35
std::vector< VID > VIDSet
A set of VIDs from indiv. graphs.
Definition: CompositeState.h:34
virtual void SetGroupGraph(GroupGraphType *_newGraph)
Set the composite graph that this composite state exists within.
Definition: CompositeState.h:309
CompositeEdge< GraphType > CompositeEdgeType
Definition: CompositeState.h:37
size_t VID
A VID in an individual graph.
Definition: CompositeState.h:33
virtual Robot * GetRobot(const size_t _index) const
Definition: CompositeState.h:285
GraphType IndividualGraph
Definition: CompositeState.h:40
virtual bool IsLocalCfg(const size_t _robotIndex) const noexcept
Definition: CompositeState.h:481
void ClearLocalCfgs()
Clear the Local Cfg information.
Definition: CompositeState.h:385
virtual void SetRobotCfg(Robot *const _robot, const VID _vid)
Definition: CompositeState.h:341
virtual void VerifyIndex(const size_t _robotIndex) const noexcept
Definition: CompositeState.h:452
virtual bool operator!=(const CompositeState &_other) const noexcept
Definition: CompositeState.h:260
virtual GroupGraphType * GetGroupGraph() const noexcept
Get the group graph this composite state is with respect to.
Definition: CompositeState.h:302
GroupGraphType * m_groupMap
The group graph.
Definition: CompositeState.h:179
virtual VID GetVID(const size_t _index) const noexcept
Definition: CompositeState.h:323
VIDSet m_vids
The individual VIDs in this aggregate state.
Definition: CompositeState.h:183
virtual const std::vector< Robot * > & GetRobots() const noexcept
Get the full vector of robot pointers.
Definition: CompositeState.h:277
virtual size_t GetNumRobots() const noexcept
Get the number of robots in this composite state.
Definition: CompositeState.h:269
virtual CfgType & GetRobotCfg(Robot *const _robot)
Definition: CompositeState.h:393
RobotGroup * m_group
The robot group for this state.
Definition: CompositeState.h:181
CompositeState(GroupGraphType *const _groupGraph=nullptr)
Definition: CompositeState.h:198
virtual bool operator==(const CompositeState &_other) const noexcept
Definition: CompositeState.h:231
virtual void InitializeLocalCfgs() noexcept
Initialize the set of local configurations if not already done.
Definition: CompositeState.h:490
CompositeGraph< CompositeState, CompositeEdgeType > GroupGraphType
Definition: CompositeState.h:38
A group of one or more robots.
Definition: RobotGroup.h:17
Definition: Robot.h:31
Definition: PMPLExceptions.h:62