Vertex.cpp
1 /*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2014, University of Toronto
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 * * Neither the name of the University of Toronto nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *********************************************************************/
34 
35 /* Authors: Jonathan Gammell */
36 
37 //My definition:
38 #include "ompl/geometric/planners/bitstar/datastructures/Vertex.h"
39 //The ID generator class, this is actually included via Vertex.h->BITstar.h, but to be clear.
40 #include "ompl/geometric/planners/bitstar/datastructures/IdGenerator.h"
41 
42 namespace ompl
43 {
44  namespace geometric
45  {
47  //Public functions:
49  : vId_(getIdGenerator().getNewId()),
50  si_(si),
51  opt_(opt),
52  state_( si_->allocState() ),
53  isRoot_(root),
54  isNew_(true),
55  hasBeenExpandedToSamples_(false),
56  hasBeenExpandedToVertices_(false),
57  isPruned_(false),
58  depth_(0u),
59  parentSPtr_( VertexPtr() ),
60  edgeCost_( opt_->infiniteCost() ),
61  cost_( opt_->infiniteCost() ),
62  childWPtrs_()
63  {
64  if (this->isRoot() == true)
65  {
66  cost_ = opt_->identityCost();
67  }
68  //No else, infinite by default
69  }
70 
71 
72 
74  {
75  //Free the state on destruction
76  si_->freeState(state_);
77  }
78 
79 
80 
82  {
83  this->assertNotPruned();
84  return vId_;
85  }
86 
87 
88 
90  {
91  this->assertNotPruned();
92 
93  return opt_;
94  }
95 
96 
97 
99  {
100  this->assertNotPruned();
101 
102  return state_;
103  }
104 
105 
106 
108  {
109  this->assertNotPruned();
110 
111  return state_;
112  }
113 
114 
115 
117  {
118  this->assertNotPruned();
119 
120  return isRoot_;
121  }
122 
123 
124 
126  {
127  this->assertNotPruned();
128 
129  return static_cast<bool>(parentSPtr_);
130  }
131 
132 
133 
135  {
136  //No need to assert, as the two other functions both do
137 
138  return this->isRoot() || this->hasParent();
139  }
140 
141 
142 
143  unsigned int BITstar::Vertex::getDepth() const
144  {
145  this->assertNotPruned();
146 
147  if (this->isRoot() == false && this->hasParent() == false)
148  {
149  throw ompl::Exception("Attempting to get the depth of a vertex that does not have a parent yet is not root.");
150  }
151 
152  return depth_;
153  }
154 
155 
156 
158  {
159  this->assertNotPruned();
160 
161  if (this->hasParent() == false)
162  {
163  if (this->isRoot() == true)
164  {
165  throw ompl::Exception("Attempting to access the parent of the root vertex.");
166  }
167  else
168  {
169  throw ompl::Exception("Attempting to access the parent of a vertex that does not have one.");
170  }
171  }
172 
173  return parentSPtr_;
174  }
175 
176 
177 
179  {
180  this->assertNotPruned();
181 
182  if (this->hasParent() == false)
183  {
184  if (this->isRoot() == true)
185  {
186  throw ompl::Exception("Attempting to access the parent of the root vertex.");
187  }
188  else
189  {
190  throw ompl::Exception("Attempting to access the parent of a vertex that does not have one.");
191  }
192  }
193 
194  return parentSPtr_;
195  }
196 
197 
198 
199  void BITstar::Vertex::addParent(const VertexPtr& newParent, const ompl::base::Cost& edgeInCost, bool updateChildCosts /*= true*/)
200  {
201  this->assertNotPruned();
202 
203  if (this->hasParent() == true)
204  {
205  throw ompl::Exception("Attempting to add a parent to a vertex that already has one.");
206  }
207  else if (this->isRoot() == true)
208  {
209  throw ompl::Exception("Attempting to add a parent to the root vertex, which cannot have a parent.");
210  }
211  //No else.
212 
213  //Store the parent
214  parentSPtr_ = newParent;
215 
216  //Store the edge cost
217  edgeCost_ = edgeInCost;
218 
219  //Update my cost
220  this->updateCostAndDepth(updateChildCosts);
221  }
222 
223 
224 
225  void BITstar::Vertex::removeParent(bool updateChildCosts /*= true*/)
226  {
227  this->assertNotPruned();
228 
229  if (this->hasParent() == false)
230  {
231  throw ompl::Exception("Attempting to remove the parent of a vertex that does not have a parent.");
232  }
233  else if (this->isRoot() == true)
234  {
235  throw ompl::Exception("Attempting to remove the parent of the root vertex, which cannot have a parent.");
236  }
237 
238  //Clear my parent
239  parentSPtr_.reset();
240 
241  //Update costs:
242  this->updateCostAndDepth(updateChildCosts);
243  }
244 
245 
246 
248  {
249  this->assertNotPruned();
250 
251  return !childWPtrs_.empty();
252  }
253 
254 
255 
256  void BITstar::Vertex::getChildrenConst(std::vector<VertexConstPtr>* children) const
257  {
258  this->assertNotPruned();
259 
260  children->clear();
261 
262  for (std::vector<VertexWeakPtr>::const_iterator cIter = childWPtrs_.begin(); cIter != childWPtrs_.end(); ++cIter)
263  {
264  //Check that the weak pointer hasn't expired
265  if (cIter->expired() == true)
266  {
267  throw ompl::Exception("A (weak) pointer to a child was found to have expired while calculating the children of a vertex.");
268  }
269  else
270  {
271  children->push_back(cIter->lock());
272  }
273  }
274  }
275 
276 
277 
278  void BITstar::Vertex::getChildren(std::vector<VertexPtr>* children)
279  {
280  this->assertNotPruned();
281 
282  children->clear();
283 
284  for (std::vector<VertexWeakPtr>::const_iterator cIter = childWPtrs_.begin(); cIter != childWPtrs_.end(); ++cIter)
285  {
286  //Check that the weak pointer hasn't expired
287  if (cIter->expired() == true)
288  {
289  throw ompl::Exception("A (weak) pointer to a child was found to have expired while calculating the children of a vertex.");
290  }
291  else
292  {
293  children->push_back(cIter->lock());
294  }
295  }
296  }
297 
298 
299 
300  void BITstar::Vertex::addChild(const VertexPtr& newChild, bool updateChildCosts /*= true*/)
301  {
302  this->assertNotPruned();
303 
304  //Push back the shared_ptr into the vector of weak_ptrs, this makes a weak_ptr copy
305  childWPtrs_.push_back(newChild);
306 
307  if (updateChildCosts == true)
308  {
309  newChild->updateCostAndDepth(true);
310  }
311  //No else, leave the costs out of date.
312  }
313 
314 
315 
316  void BITstar::Vertex::removeChild(VertexPtr oldChild, bool updateChildCosts /*= true*/)
317  {
318  this->assertNotPruned();
319 
320  //Variables
321  //Whether the child has been found (and then deleted);
322  bool foundChild;
323 
324  //Iterate over the list of children pointers until the child is found. Iterators make erase easier
325  foundChild = false;
326  for (std::vector<VertexWeakPtr>::iterator cIter = childWPtrs_.begin(); cIter != childWPtrs_.end() && foundChild == false; ++cIter)
327  {
328  //Check that the weak pointer hasn't expired
329  if (cIter->expired() == true)
330  {
331  throw ompl::Exception("A (weak) pointer to a child was found to have expired while removing a child from a vertex.");
332  }
333  //No else, weak pointer is valid
334 
335  //Check if this is the child we're looking for
336  if (cIter->lock() == oldChild)
337  {
338  //Remove the child from the vector
339  childWPtrs_.erase(cIter);
340 
341  //Mark as found
342  foundChild = true;
343 
344  //Update the child cost if appropriate
345  if (updateChildCosts == true)
346  {
347  oldChild->updateCostAndDepth(true);
348  }
349  //No else, leave the costs out of date.
350  }
351  //No else, move on
352  }
353 
354  //Throw if we did not find the child
355  if (foundChild == false)
356  {
357  throw ompl::Exception("Attempting to remove a child vertex not present in the list of children stored in the (supposed) parent vertex.");
358  }
359  //No else, we were successful
360  }
361 
362 
363 
365  {
366  this->assertNotPruned();
367 
368  return cost_;
369  }
370 
371 
372 
374  {
375  this->assertNotPruned();
376 
377  if (this->hasParent() == false)
378  {
379  throw ompl::Exception("Attempting to access the incoming-edge cost of a vertex without a parent.");
380  }
381 
382  return edgeCost_;
383  }
384 
385 
386 
388  {
389  this->assertNotPruned();
390 
391  return isNew_;
392  }
393 
394 
395 
397  {
398  this->assertNotPruned();
399 
400  isNew_ = true;
401  }
402 
403 
404 
406  {
407  this->assertNotPruned();
408 
409  isNew_ = false;
410  }
411 
412 
413 
415  {
416  this->assertNotPruned();
417 
418  return hasBeenExpandedToSamples_;
419  }
420 
421 
422 
424  {
425  this->assertNotPruned();
426 
427  hasBeenExpandedToSamples_ = true;
428  }
429 
430 
431 
433  {
434  this->assertNotPruned();
435 
436  hasBeenExpandedToSamples_ = false;
437  }
438 
439 
440 
442  {
443  this->assertNotPruned();
444 
445  return hasBeenExpandedToVertices_;
446  }
447 
448 
449 
451  {
452  this->assertNotPruned();
453 
454  hasBeenExpandedToVertices_ = true;
455  }
456 
457 
458 
460  {
461  this->assertNotPruned();
462 
463  hasBeenExpandedToVertices_ = false;
464  }
465 
466 
467 
469  {
470  return isPruned_;
471  }
472 
473 
474 
476  {
477  this->assertNotPruned();
478 
479  isPruned_ = true;
480  }
481 
482 
483 
485  {
486  isPruned_ = false;
487  }
489 
490 
491 
493  //Protected functions:
494  void BITstar::Vertex::updateCostAndDepth(bool cascadeUpdates /*= true*/)
495  {
496  this->assertNotPruned();
497 
498  if (this->isRoot() == true)
499  {
500  //Am I root? -- I don't really know how this would ever be called, but ok.
501  cost_ = opt_->identityCost();
502  depth_ = 0u;
503  }
504  else if (this->hasParent() == false)
505  {
506  //Am I disconnected?
507  cost_ = opt_->infiniteCost();
508 
509  //Set the depth to 0u, getDepth will throw in this condition
510  depth_ = 0u;
511 
512  //Assert that I have not been asked to cascade this bad data to my children:
513  if (this->hasChildren() == true && cascadeUpdates == true)
514  {
515  throw ompl::Exception("Attempting to update descendants' costs and depths of a vertex that does not have a parent and is not root. This information would therefore be gibberish.");
516  }
517  }
518  else
519  {
520  //I have a parent, so my cost is my parent cost + my edge cost to the parent
521  cost_ = opt_->combineCosts(parentSPtr_->getCost(), edgeCost_);
522 
523  //I am one more than my parent's depth:
524  depth_ = (parentSPtr_->getDepth() + 1u);
525  }
526 
527  //Am I updating my children?
528  if (cascadeUpdates == true)
529  {
530  //Now, iterate over my list of children and tell each one to update its own damn cost:
531  for (unsigned int i = 0u; i < childWPtrs_.size(); ++i)
532  {
533  //Check that it hasn't expired
534  if (childWPtrs_.at(i).expired() == true)
535  {
536  throw ompl::Exception("A (weak) pointer to a child has was found to have expired while updating the costs and depths of descendant vertices.");
537  }
538  //No else, weak pointer is valid
539 
540  //Get a lock and tell the child to update:
541  childWPtrs_.at(i).lock()->updateCostAndDepth(true);
542  }
543  }
544  //No else, do not update the children. I hope the caller knows what they're doing.
545  }
547 
548 
549 
551  //Private functions:
552  void BITstar::Vertex::assertNotPruned() const
553  {
554  if (isPruned_ == true)
555  {
556  std::cout << std::endl << "vId: " << vId_ << std::endl;
557  throw ompl::Exception("Attempting to access a pruned vertex.");
558  }
559  }
561  } // geometric
562 } // ompl
bool isNew() const
Returns true if the vertex is marked as new. Vertices are new until marked old.
Definition: Vertex.cpp:387
ompl::base::OptimizationObjectivePtr opt_
Optimization objective copied from ProblemDefinition.
Definition: BITstar.h:525
bool hasBeenExpandedToVertices() const
Returns true if the vertex has been expanded towards vertices.
Definition: Vertex.cpp:441
VertexConstPtr getParentConst() const
Get the parent of a vertex as a constant pointer.
Definition: Vertex.cpp:157
void markNew()
Mark the vertex as new.
Definition: Vertex.cpp:396
void markExpandedToSamples()
Mark the vertex as expanded towards samples.
Definition: Vertex.cpp:423
VertexPtr getParent()
Get the parent of a vertex as a mutable pointer.
Definition: Vertex.cpp:178
void updateCostAndDepth(bool cascadeUpdates=true)
Calculates the updated cost and depth of the current state, as well as calling all children's updateC...
Definition: Vertex.cpp:494
bool isRoot() const
Whether the vertex is root.
Definition: Vertex.cpp:116
bool hasParent() const
Get whether this vertex has a parent.
Definition: Vertex.cpp:125
bool isPruned() const
Whether the vertex has been pruned.
Definition: Vertex.cpp:468
ompl::base::State * state()
The state of a vertex as a mutable pointer.
Definition: Vertex.cpp:107
std::shared_ptr< const Vertex > VertexConstPtr
A constant vertex shared pointer.
Definition: BITstar.h:125
void addParent(const VertexPtr &newParent, const ompl::base::Cost &edgeInCost, bool updateChildCosts=true)
Set the parent of a vertex, cannot be used to replace a previous parent. Will update this vertex's co...
Definition: Vertex.cpp:199
bool hasChildren() const
Get whether this vertex has any children.
Definition: Vertex.cpp:247
void removeParent(bool updateChildCosts=true)
Remove the parent edge. Will update this vertex's cost, and can update the descendent costs...
Definition: Vertex.cpp:225
void markUnexpandedToVertices()
Mark the vertex as not expanded towards vertices.
Definition: Vertex.cpp:459
A shared pointer wrapper for ompl::base::SpaceInformation.
void markOld()
Mark the vertex as old.
Definition: Vertex.cpp:405
Definition of an abstract state.
Definition: State.h:50
ompl::base::OptimizationObjectivePtr getOpt() const
The optimization objective used by the vertex.
Definition: Vertex.cpp:89
void addChild(const VertexPtr &newChild, bool updateChildCosts=true)
Add a child vertex. Does not change this vertex's cost, and can update the child and its descendent c...
Definition: Vertex.cpp:300
void removeChild(VertexPtr oldChild, bool updateChildCosts=true)
Remove a child vertex. Does not change this vertex's cost, and can update the child and its descenden...
Definition: Vertex.cpp:316
unsigned int getDepth() const
Get the "depth" of the vertex from the root. A root vertex is at depth 0, a direct descendent of the ...
Definition: Vertex.cpp:143
void getChildrenConst(std::vector< VertexConstPtr > *children) const
Get the children of a vertex as constant pointers.
Definition: Vertex.cpp:256
The exception type for ompl.
Definition: Exception.h:47
A shared pointer wrapper for ompl::base::OptimizationObjective.
void markUnexpandedToSamples()
Mark the vertex as not expanded towards samples.
Definition: Vertex.cpp:432
bool hasBeenExpandedToSamples() const
Returns true if the vertex has been expanded towards samples.
Definition: Vertex.cpp:414
ompl::base::Cost getEdgeInCost() const
Get the incremental cost-to-come of a vertex.
Definition: Vertex.cpp:373
ompl::base::State const * stateConst() const
The state of a vertex as a constant pointer.
Definition: Vertex.cpp:98
bool isInTree() const
Get whether a vertex is "in the graph" or not. This returns true if the vertex is the graph root or i...
Definition: Vertex.cpp:134
SpaceInformationPtr si_
The space information for which planning is done.
Definition: Planner.h:398
void markUnpruned()
Mark the vertex as unpruned.
Definition: Vertex.cpp:484
BITstar::VertexId getId() const
The (unique) vertex ID.
Definition: Vertex.cpp:81
std::shared_ptr< Vertex > VertexPtr
A vertex shared pointer.
Definition: BITstar.h:120
Vertex(const ompl::base::SpaceInformationPtr &si, const ompl::base::OptimizationObjectivePtr &opt, bool root=false)
Constructor.
Definition: Vertex.cpp:48
Definition of a cost value. Can represent the cost of a motion or the cost of a state.
Definition: Cost.h:47
ompl::base::Cost getCost() const
Get the cost-to-come of a vertex. Return infinity if the edge is disconnected.
Definition: Vertex.cpp:364
void markExpandedToVertices()
Mark the vertex as expanded towards vertices.
Definition: Vertex.cpp:450
void markPruned()
Mark the vertex as pruned.
Definition: Vertex.cpp:475
unsigned int VertexId
The vertex id type.
Definition: BITstar.h:131
void getChildren(std::vector< VertexPtr > *children)
Get the children of a vertex as mutable pointers.
Definition: Vertex.cpp:278