Parasol Planning Library (PPL)
ConnectorMethod.h
Go to the documentation of this file.
1 #ifndef PMPL_CONNECTION_METHOD_H_
2 #define PMPL_CONNECTION_METHOD_H_
3 
5 
9 #include "Utilities/Hash.h"
10 #include "Utilities/MPUtils.h"
11 #include "Utilities/MetricUtils.h"
12 
13 #include <iterator>
14 #include <set>
15 
16 
25 {
26  public:
27 
30 
34  typedef typename RoadmapType::VID VID;
36 
40 
41  typedef std::pair<VID, VID> ConnectionAttempt;
42  typedef std::unordered_set<ConnectionAttempt> ConnectionAttempts;
43  typedef std::unordered_map<void*, ConnectionAttempts> ConnectionAttemptsCache;
44 
45  template <typename AbstractRoadmapType>
46  using OutputIterator = std::back_insert_iterator<
47  std::vector<
48  typename AbstractRoadmapType::VP
49  >
50  >;
51 
55 
57 
58  ConnectorMethod(XMLNode& _node);
59 
60  virtual ~ConnectorMethod() = default;
61 
65 
66  virtual void Print(std::ostream& _os) const override;
67 
68  virtual void Initialize() override;
69 
73 
79  template <typename AbstractRoadmapType>
80  void Connect(AbstractRoadmapType* const _r,
81  const VertexSet* const _targetSet = nullptr,
82  OutputIterator<AbstractRoadmapType>* const _collision = nullptr);
83 
90  template <typename AbstractRoadmapType>
91  void Connect(AbstractRoadmapType* const _r, const VID _source,
92  const VertexSet* const _targetSet = nullptr,
93  OutputIterator<AbstractRoadmapType>* const _collision = nullptr);
94 
104  template <typename AbstractRoadmapType, typename InputIterator>
105  void Connect(AbstractRoadmapType* const _r,
106  InputIterator _sourceBegin, InputIterator _sourceEnd,
107  const VertexSet* const _targetSet = nullptr,
108  OutputIterator<AbstractRoadmapType>* const _collision = nullptr);
109 
112  bool IsRewiring() const noexcept;
113 
115 
116  protected:
117 
120 
128  virtual void ConnectImpl(RoadmapType* const _r, const VID _source,
129  const VertexSet* const _targetSet = nullptr,
130  OutputIterator<RoadmapType>* const _collision = nullptr);
131 
133  virtual void ConnectImpl(GroupRoadmapType* const _r, const VID _source,
134  const VertexSet* const _targetSet = nullptr,
135  OutputIterator<GroupRoadmapType>* const _collision = nullptr);
136 
139 
146  template <typename AbstractRoadmapType>
147  void ConnectNeighbors(
148  AbstractRoadmapType* const _r, const VID _source,
149  const std::vector<Neighbor>& _neighbors,
150  OutputIterator<AbstractRoadmapType>* const _collision = nullptr,
151  const bool _earlyQuit = false);
152 
159  bool ConnectNodes(RoadmapType* const _r, const VID _source,
160  const VID _target,
161  OutputIterator<RoadmapType>* const _collision = nullptr);
162 
169  bool ConnectNodes(GroupRoadmapType* const _r, const VID _source,
170  const VID _target,
171  OutputIterator<GroupRoadmapType>* const _collision = nullptr);
172 
178  template <typename AbstractRoadmapType>
179  bool DoNotCheck(AbstractRoadmapType* const _r, const VID _source,
180  const VID _target) const;
181 
185 
190  void CacheFailedConnection(void* const _map, const VID _source,
191  const VID _target) noexcept;
192 
199  bool IsCached(void* const _map, const VID _source, const VID _target) const
200  noexcept;
201 
204 
208 
210  std::string m_lpLabel;
211 
212  bool m_skipIfSameCC{true};
213  size_t m_maxFailures{0};
214  size_t m_failures{0};
215  bool m_oneWay{false};
216  bool m_rewiring{false};
217 
218  bool m_selfEdges{false};
219 
223  std::vector<Neighbor> m_neighborBuffer;
224 
226 
227 };
228 
229 
230 template <typename AbstractRoadmapType>
231 void
233 Connect(AbstractRoadmapType* const _r, const VertexSet* const _targetSet,
234  OutputIterator<AbstractRoadmapType>* const _collision) {
235  Connect(_r, _r->begin(), _r->end(), _targetSet, _collision);
236 }
237 
238 
239 template <typename AbstractRoadmapType>
240 void
242 Connect(AbstractRoadmapType* const _r, const VID _source,
243  const VertexSet* const _targetSet,
244  OutputIterator<AbstractRoadmapType>* const _collision)
245 {
246  const std::array<VID, 1> source{_source};
247  Connect(_r, source.begin(), source.end(), _targetSet, _collision);
248 }
249 
250 
251 template <typename AbstractRoadmapType, typename InputIterator>
252 void
254 Connect(AbstractRoadmapType* const _r,
255  InputIterator _sourceBegin, InputIterator _sourceEnd,
256  const VertexSet* const _targetSet,
257  OutputIterator<AbstractRoadmapType>* const _collision)
258 {
259  const std::string id = this->GetNameAndLabel() + "::Connect";
260  MethodTimer mt(this->GetStatClass(), id);
261  if(this->m_debug)
262  std::cout << id << std::endl;
263 
264  m_failures = 0;
265  for(auto iter = _sourceBegin; iter != _sourceEnd; ++iter) {
266  const VID sourceVID = _r->GetVID(iter);
267  if(this->m_debug)
268  std::cout << "\tAttempting connections from node "
269  << sourceVID << " at " << _r->GetVertex(sourceVID).PrettyPrint()
270  << std::endl;
271  ConnectImpl(_r, sourceVID, _targetSet, _collision);
272  }
273 }
274 
275 
276 template <typename AbstractRoadmapType>
277 void
279 ConnectNeighbors(AbstractRoadmapType* const _r, const VID _source,
280  const std::vector<Neighbor>& _neighbors,
281  OutputIterator<AbstractRoadmapType>* const _collision,
282  const bool _earlyQuit) {
283  // Try to connect _source to each neighbor.
284  for(const auto& neighbor : _neighbors) {
285  // Check if we have exceeded the failure limit.
287  if(this->m_debug)
288  std::cout << "\t\tFailures (" << m_failures << ") exceed threshold "
289  << "of " << m_maxFailures << ", stopping."
290  << std::endl;
291  return;
292  }
293 
294  // Attempt the next connection.
295  const VID target = neighbor.target;
296  if(this->m_debug)
297  std::cout << "\t\tAttempting connection from " << _source << " to "
298  << target << " at distance " << neighbor.distance << "."
299  << std::endl;
300 
301  // Check if this attempt should be skipped.
302  if(DoNotCheck(_r, _source, target))
303  continue;
304 
305  // Attempt connection with the local planner.
306  const bool connected = ConnectNodes(_r, _source, target, _collision);
307  m_failures += !connected;
308 
309  if(this->m_debug)
310  std::cout << "\t\t\tConnection " << (connected ? "succeeded" : "failed")
311  << "." << std::endl;
312 
313  // Quit early on success if requested.
314  if(_earlyQuit && connected)
315  return;
316  }
317 
318  //Connect vertices to themselves
319  //if(m_selfEdges) {
320  //this->ConnectNodes(_r, _source, _source, _collision);
321  //}
322 }
323 
324 
325 template <typename AbstractRoadmapType>
326 bool
328 DoNotCheck(AbstractRoadmapType* const _r, const VID _source, const VID _target)
329  const {
330  // Check that both VIDs are valid.
331  if(_source == INVALID_VID or _target == INVALID_VID) {
332  if(this->m_debug)
333  std::cout << "\t\t\tSkipping connection with invalid node "
334  << "(" << _source << ", " << _target << ")."
335  << std::endl;
336  return true;
337  }
338 
339  // Check for self-connection.
340  if(_source == _target and !m_selfEdges) {
341  if(this->m_debug)
342  std::cout << "\t\t\tSkipping self-connection "
343  << "(" << _source << ", " << _target << ")."
344  << std::endl;
345  return true;
346  }
347 
348  // Check for cached connection.
349  if(this->IsCached(_r, _source, _target)) {
350  if(this->m_debug)
351  std::cout << "\t\t\tSkipping cached failed connection "
352  << "(" << _source << ", " << _target << ")."
353  << std::endl;
354  return true;
355  }
356 
357  // Check if the edge already exists.
358  if(_r->IsEdge(_source, _target)) {
359  if(this->m_debug)
360  std::cout << "\t\t\tSkipping existing connection "
361  << "(" << _source << ", " << _target << ")."
362  << std::endl;
363  return true;
364  }
365 
366  // Check if the nodes are in the same connected component.
367  if(m_skipIfSameCC) {
368  auto ccTracker = _r->GetCCTracker();
369  if(!ccTracker)
370  throw RunTimeException(WHERE) << "A CCTracker is required for checking "
371  << "same CCs.";
372  const bool sameCC = ccTracker->InSameCC(_source, _target);
373  if(sameCC) {
374  if(this->m_debug)
375  std::cout << "\t\t\tSkipping connection "
376  << "(" << _source << ", " << _target << ")"
377  << " within the same connected component."
378  << std::endl;
379  return true;
380  }
381  }
382 
383  return false;
384 }
385 
386 #endif
#define INVALID_VID
Definition: GenericStateGraph.h:23
#define WHERE
Macro for retrieving info about file, function, and line number.
Definition: RuntimeUtils.h:32
Definition: ConnectorMethod.h:25
bool ConnectNodes(RoadmapType *const _r, const VID _source, const VID _target, OutputIterator< RoadmapType > *const _collision=nullptr)
Definition: ConnectorMethod.cpp:83
MPBaseObject::GroupCfgType GroupCfgType
Definition: ConnectorMethod.h:31
bool m_skipIfSameCC
Skip connections within the same CC?
Definition: ConnectorMethod.h:212
std::string m_lpLabel
Local Planner.
Definition: ConnectorMethod.h:210
virtual ~ConnectorMethod()=default
bool IsCached(void *const _map, const VID _source, const VID _target) const noexcept
Definition: ConnectorMethod.cpp:155
MPBaseObject::RoadmapType RoadmapType
Definition: ConnectorMethod.h:32
void Connect(AbstractRoadmapType *const _r, const VertexSet *const _targetSet=nullptr, OutputIterator< AbstractRoadmapType > *const _collision=nullptr)
Definition: ConnectorMethod.h:233
virtual void ConnectImpl(RoadmapType *const _r, const VID _source, const VertexSet *const _targetSet=nullptr, OutputIterator< RoadmapType > *const _collision=nullptr)
Definition: ConnectorMethod.cpp:65
ConnectorMethod()
Definition: ConnectorMethod.cpp:11
std::unordered_set< ConnectionAttempt > ConnectionAttempts
Definition: ConnectorMethod.h:42
bool m_rewiring
Does this connector delete edges?
Definition: ConnectorMethod.h:216
void ClearConnectionAttempts()
Clear the attempts cache.
Definition: ConnectorMethod.cpp:171
bool DoNotCheck(AbstractRoadmapType *const _r, const VID _source, const VID _target) const
Definition: ConnectorMethod.h:328
virtual void Print(std::ostream &_os) const override
Definition: ConnectorMethod.cpp:37
bool IsRewiring() const noexcept
Definition: ConnectorMethod.cpp:57
MPBaseObject::GroupRoadmapType GroupRoadmapType
Definition: ConnectorMethod.h:33
bool m_selfEdges
Indicates if roadmap vertices should have self-edges.
Definition: ConnectorMethod.h:218
bool m_oneWay
Create one-way edges or two-way?
Definition: ConnectorMethod.h:215
void ConnectNeighbors(AbstractRoadmapType *const _r, const VID _source, const std::vector< Neighbor > &_neighbors, OutputIterator< AbstractRoadmapType > *const _collision=nullptr, const bool _earlyQuit=false)
Definition: ConnectorMethod.h:279
std::pair< VID, VID > ConnectionAttempt
Definition: ConnectorMethod.h:41
RoadmapType::VID VID
Definition: ConnectorMethod.h:34
ConnectionAttemptsCache m_attemptsCache
All failed connection attempts.
Definition: ConnectorMethod.h:209
void CacheFailedConnection(void *const _map, const VID _source, const VID _target) noexcept
Definition: ConnectorMethod.cpp:147
size_t m_failures
Failures in this use.
Definition: ConnectorMethod.h:214
virtual void Initialize() override
Definition: ConnectorMethod.cpp:49
std::vector< Neighbor > m_neighborBuffer
Definition: ConnectorMethod.h:223
size_t m_maxFailures
Maximum allowed failures per use.
Definition: ConnectorMethod.h:213
RoadmapType::VertexSet VertexSet
Definition: ConnectorMethod.h:35
std::back_insert_iterator< std::vector< typename AbstractRoadmapType::VP > > OutputIterator
Definition: ConnectorMethod.h:50
std::unordered_map< void *, ConnectionAttempts > ConnectionAttemptsCache
Definition: ConnectorMethod.h:43
Definition: GenericStateGraph.h:67
STAPLGraph::vertex_descriptor VID
Definition: GenericStateGraph.h:83
std::unordered_set< VID > VertexSet
Definition: GenericStateGraph.h:86
Definition: GroupCfg.h:39
Definition: GroupRoadmap.h:25
Definition: MPBaseObject.h:46
std::string GetNameAndLabel() const
Get the unique string identifier for this object "m_name::m_label".
Definition: MPBaseObject.cpp:50
StatClass * GetStatClass() const noexcept
Get the current StatClass.
Definition: MPBaseObject.cpp:158
bool m_debug
Print debug info?
Definition: MPBaseObject.h:183
Definition: MetricUtils.h:124
Definition: XMLNode.h:27
Definition: Neighbors.h:13
Definition: PMPLExceptions.h:62