38#include "ompl/geometric/planners/informedtrees/bitstar/Vertex.h"
47#include "ompl/util/Exception.h"
51#include "ompl/geometric/planners/informedtrees/bitstar/HelperFunctions.h"
53#include "ompl/geometric/planners/informedtrees/bitstar/IdGenerator.h"
55#include "ompl/geometric/planners/informedtrees/bitstar/CostHelper.h"
60#define TRACK_VERTEX_ID 0
63#define PRINT_VERTEX_CHANGE \
64 if (id_ == TRACK_VERTEX_ID) \
66 std::cout << "Vertex " << id_ << ": " << __func__ << "" << std::endl; \
70#define ASSERT_NOT_PRUNED \
71 if (this->isPruned_) \
73 std::cout << "Vertex " << id_ << ": " << __func__ << std::endl; \
74 throw ompl::Exception("Attempting to access a pruned vertex."); \
77#define PRINT_VERTEX_CHANGE
78#define ASSERT_NOT_PRUNED
86 std::once_flag g_IdInited;
88 boost::scoped_ptr<ompl::geometric::BITstar::IdGenerator> g_IdGenerator;
91 void initIdGenerator()
99 std::call_once(g_IdInited, &initIdGenerator);
100 return *g_IdGenerator;
110 BITstar::Vertex::Vertex(ompl::base::SpaceInformationPtr spaceInformation,
const CostHelper *
const costHelpPtr,
111 SearchQueue *
const queuePtr,
const std::shared_ptr<const unsigned int> &approximationId,
113 : id_(getIdGenerator().getNewId())
114 , si_(
std::move(spaceInformation))
115 , costHelpPtr_(
std::move(costHelpPtr))
116 , queuePtr_(queuePtr)
117 , state_(si_->allocState())
119 , edgeCost_(costHelpPtr_->infiniteCost())
120 , cost_(costHelpPtr_->infiniteCost())
121 , costAtExpansion_(costHelpPtr_->infiniteCost())
122 , currentSearchId_(queuePtr->getSearchId())
123 , currentApproximationId_(approximationId)
129 cost_ = costHelpPtr_->identityCost();
134 BITstar::Vertex::~Vertex()
139 si_->freeState(state_);
166 bool BITstar::Vertex::isRoot()
const
173 bool BITstar::Vertex::hasParent()
const
177 return static_cast<bool>(parentPtr_);
180 bool BITstar::Vertex::isInTree()
const
187 unsigned int BITstar::Vertex::getDepth()
const
194 throw ompl::Exception(
"Attempting to get the depth of a vertex that does not have a parent yet is not "
211 throw ompl::Exception(
"Attempting to access the parent of the root vertex.");
215 throw ompl::Exception(
"Attempting to access the parent of a vertex that does not have one.");
232 throw ompl::Exception(
"Attempting to access the parent of the root vertex.");
236 throw ompl::Exception(
"Attempting to access the parent of a vertex that does not have one.");
253 throw ompl::Exception(
"Attempting to add a parent to the root vertex, which cannot have a parent.");
257 throw ompl::Exception(
"Attempting to add a parent to a vertex that already has one.");
262 parentPtr_ = newParent;
265 edgeCost_ = edgeInCost;
268 this->updateCostAndDepth(
true);
271 void BITstar::Vertex::removeParent(
bool updateChildCosts)
280 throw ompl::Exception(
"Attempting to remove the parent of the root vertex, which cannot have a "
285 throw ompl::Exception(
"Attempting to remove the parent of a vertex that does not have a parent.");
293 this->updateCostAndDepth(updateChildCosts);
296 bool BITstar::Vertex::hasChildren()
const
300 return !children_.empty();
309 for (
const auto &child : children_)
315 throw ompl::Exception(
"A (weak) pointer to a child was found to have expired while collecting the "
316 "children of a vertex.");
321 children->push_back(child.lock());
331 for (
const auto &child : children_)
337 throw ompl::Exception(
"A (weak) pointer to a child was found to have expired while collecting the "
338 "children of a vertex.");
343 children->push_back(child.lock());
360 throw ompl::Exception(
"Attempted to add child that does not have a listed parent.");
364 throw ompl::Exception(
"Attempted to add someone else's child as mine.");
369 children_.push_back(child);
374 void BITstar::Vertex::removeChild(
const VertexPtr &child)
383 throw ompl::Exception(
"Attempted to remove a root vertex as a child.");
387 throw ompl::Exception(
"Attempted to remove a child that does not have a listed parent.");
391 throw ompl::Exception(
"Attempted to remove a child vertex from the wrong parent.");
401 for (
auto it = children_.begin(); it != children_.end(); ++it)
407 throw ompl::Exception(
"A (weak) pointer to a child was found to have expired while removing a "
408 "child from a vertex.");
413 if (it->lock()->getId() == child->
getId())
424 swapPopBack(it, &children_);
434 throw ompl::Exception(
"Attempting to remove a child vertex not present in the vector of children "
435 "stored in the (supposed) parent vertex.");
442 childIdBlacklist_.emplace(vertex->
getId());
447 childIdWhitelist_.emplace(vertex->
getId());
452 return childIdBlacklist_.find(vertex->
getId()) != childIdBlacklist_.end();
457 return childIdWhitelist_.find(vertex->
getId()) != childIdWhitelist_.end();
460 void BITstar::Vertex::clearBlacklist()
462 childIdBlacklist_.clear();
465 void BITstar::Vertex::clearWhitelist()
467 childIdWhitelist_.clear();
484 throw ompl::Exception(
"Attempting to access the incoming-edge cost of a vertex without a parent.");
491 bool BITstar::Vertex::isConsistent()
const
493 return cost_.
value() == costAtExpansion_.value();
496 bool BITstar::Vertex::isPruned()
const
501 bool BITstar::Vertex::isExpandedOnCurrentApproximation()
const
503 return expansionApproximationId_ == *currentApproximationId_;
506 bool BITstar::Vertex::isExpandedOnCurrentSearch()
const
508 return expansionSearchId_ == *currentSearchId_;
511 bool BITstar::Vertex::hasEverBeenExpandedAsRewiring()
const
513 return hasEverBeenExpandedAsRewiring_;
516 void BITstar::Vertex::registerExpansion()
519 costAtExpansion_ = cost_;
522 expansionApproximationId_ = *currentApproximationId_;
523 expansionSearchId_ = *currentSearchId_;
526 void BITstar::Vertex::registerRewiringExpansion()
528 hasEverBeenExpandedAsRewiring_ =
true;
531 void BITstar::Vertex::markPruned()
539 void BITstar::Vertex::markUnpruned()
551 this->clearLookupsIfOutdated();
555 if (element->data.second.first->getId() == id_)
557 throw ompl::Exception(
"Attempted to add a cyclic incoming queue edge.");
560 if (element->data.second.second->getId() != id_)
562 throw ompl::Exception(
"Attempted to add an incoming queue edge to the wrong vertex.");
565 for (
const auto &inEdge : edgeQueueInLookup_)
567 if (element->data.second.first->getId() == inEdge->data.second.first->getId())
569 throw ompl::Exception(
"Attempted to add a second edge to the queue from a single source vertex.");
575 edgeQueueInLookup_.push_back(element);
586 if (*currentApproximationId_ != lookupApproximationId_)
589 "Attempted to remove an incoming queue edge added under a different expansion id.");
598 for (
auto it = edgeQueueInLookup_.begin(); it != edgeQueueInLookup_.end(); ++it)
601 if ((*it)->data.second.first->getId() == element->data.second.first->getId())
618 throw ompl::Exception(
"Attempted to remove an edge not in the incoming lookup.");
624 BITstar::Vertex::removeFromEdgeQueueInLookup(
const SearchQueue::EdgeQueueElemPtrVector::const_iterator &element)
632 if (*currentApproximationId_ != lookupApproximationId_)
635 "Attempted to remove an incoming queue edge added under a different expansion id.");
644 void BITstar::Vertex::clearEdgeQueueInLookup()
648 edgeQueueInLookup_.clear();
651 BITstar::SearchQueue::EdgeQueueElemPtrVector::const_iterator BITstar::Vertex::edgeQueueInLookupConstBegin()
656 this->clearLookupsIfOutdated();
658 return edgeQueueInLookup_.cbegin();
661 BITstar::SearchQueue::EdgeQueueElemPtrVector::const_iterator BITstar::Vertex::edgeQueueInLookupConstEnd()
666 this->clearLookupsIfOutdated();
668 return edgeQueueInLookup_.cend();
671 unsigned int BITstar::Vertex::edgeQueueInLookupSize()
676 this->clearLookupsIfOutdated();
678 return edgeQueueInLookup_.size();
686 this->clearLookupsIfOutdated();
690 if (element->data.second.first->getId() != id_)
692 throw ompl::Exception(
"Attempted to add an outgoing queue edge to the wrong vertex.");
695 if (element->data.second.second->getId() == id_)
697 throw ompl::Exception(
"Attempted to add a cyclic outgoing queue edge.");
700 for (
const auto &outEdge : edgeQueueOutLookup_)
702 if (element->data.second.second->getId() == outEdge->data.second.second->getId())
704 throw ompl::Exception(
"Attempted to add a second edge to the queue to a single target vertex.");
710 edgeQueueOutLookup_.push_back(element);
721 if (*currentApproximationId_ != lookupApproximationId_)
724 "Attempted to remove an incoming queue edge added under a different expansion id.");
733 for (
auto it = edgeQueueOutLookup_.begin(); it != edgeQueueOutLookup_.end(); ++it)
736 if ((*it)->data.second.second->getId() == element->data.second.second->getId())
753 throw ompl::Exception(
"Attempted to remove an edge not in the outgoing lookup.");
758 void BITstar::Vertex::removeFromEdgeQueueOutLookup(
759 const SearchQueue::EdgeQueueElemPtrVector::const_iterator &element)
767 if (*currentApproximationId_ != lookupApproximationId_)
770 "Attempted to remove an outgoing queue edge added under a different expansion id.");
779 void BITstar::Vertex::clearEdgeQueueOutLookup()
783 edgeQueueOutLookup_.clear();
786 BITstar::SearchQueue::EdgeQueueElemPtrVector::const_iterator BITstar::Vertex::edgeQueueOutLookupConstBegin()
791 this->clearLookupsIfOutdated();
793 return edgeQueueOutLookup_.cbegin();
796 BITstar::SearchQueue::EdgeQueueElemPtrVector::const_iterator BITstar::Vertex::edgeQueueOutLookupConstEnd()
801 this->clearLookupsIfOutdated();
803 return edgeQueueOutLookup_.cend();
806 unsigned int BITstar::Vertex::edgeQueueOutLookupSize()
811 this->clearLookupsIfOutdated();
813 return edgeQueueOutLookup_.size();
816 void BITstar::Vertex::updateCostAndDepth(
bool cascadeUpdates )
824 cost_ = costHelpPtr_->identityCost();
827 else if (!this->hasParent())
830 cost_ = costHelpPtr_->infiniteCost();
837 if (this->hasChildren() && cascadeUpdates)
839 throw ompl::Exception(
"Attempting to update descendants' costs and depths of a vertex that does "
840 "not have a parent and is not root. This information would therefore be "
848 cost_ = costHelpPtr_->combineCosts(parentPtr_->getCost(), edgeCost_);
851 for (
const auto &edge : edgeQueueOutLookup_)
853 if (lookupApproximationId_ == *currentApproximationId_)
855 queuePtr_->update(edge);
860 depth_ = (parentPtr_->getDepth() + 1u);
867 for (
auto &child : children_)
873 throw ompl::Exception(
"A (weak) pointer to a child has was found to have expired while "
874 "updating the costs and depths of descendant vertices.");
879 child.lock()->updateCostAndDepth(
true);
885 void BITstar::Vertex::removeFromEdgeQueueInLookup(
const SearchQueue::EdgeQueueElemPtrVector::iterator &element)
889 VertexId parentId = (*element)->data.second.first->getId();
894 throw ompl::Exception(
"Attempted to remove a cyclic incoming queue edge.");
898 if ((*element)->data.second.second->getId() != id_)
900 throw ompl::Exception(
"Attempted to remove an incoming queue edge from the wrong vertex.");
904 if (edgeQueueInLookup_.empty())
906 throw ompl::Exception(
"Attempted to remove an incoming queue edge from a vertex with an empty list.");
911 for (
auto it = edgeQueueInLookup_.begin(); it != edgeQueueInLookup_.end() && !found; ++it)
913 found = ((*it)->data.second.first->getId() == parentId);
917 throw ompl::Exception(
"Attempted to remove an edge not in the incoming lookup.");
925 swapPopBack(element, &edgeQueueInLookup_);
929 for (
const auto &edgePtr : edgeQueueInLookup_)
931 if (edgePtr->data.second.first->getId() == parentId)
933 throw ompl::Exception(
"Failed to remove the designated edge in the incoming lookup.");
939 void BITstar::Vertex::removeFromEdgeQueueOutLookup(
const SearchQueue::EdgeQueueElemPtrVector::iterator &element)
943 VertexId childId = (*element)->data.second.second->getId();
946 if ((*element)->data.second.first->getId() != id_)
948 throw ompl::Exception(
"Attempted to remove an outgoing queue edge from the wrong vertex.");
953 throw ompl::Exception(
"Attempted to remove a cyclic outgoing queue edge.");
956 if (edgeQueueOutLookup_.empty())
958 throw ompl::Exception(
"Attempted to remove an outgoing queue edge from a vertex with an empty list.");
962 for (
auto it = edgeQueueOutLookup_.begin(); it != edgeQueueOutLookup_.end() && !found; ++it)
964 found = ((*it)->data.second.second->getId() == childId);
968 throw ompl::Exception(
"Attempted to remove an edge not in the outgoing lookup.");
976 swapPopBack(element, &edgeQueueOutLookup_);
980 for (
const auto &edgePtr : edgeQueueOutLookup_)
982 if (edgePtr->data.second.second->getId() == childId)
984 throw ompl::Exception(
"Failed to remove the designated edge in the outgoing lookup.");
990 void BITstar::Vertex::clearLookupsIfOutdated()
993 if (lookupApproximationId_ != *currentApproximationId_)
996 this->clearEdgeQueueInLookup();
997 this->clearEdgeQueueOutLookup();
1000 lookupApproximationId_ = *currentApproximationId_;
The exception type for ompl.
Definition of a cost value. Can represent the cost of a motion or the cost of a state.
double value() const
The value of the cost.
Definition of an abstract state.
A helper class to handle the various heuristic functions in one place.
An ID generator class for vertex IDs.
A queue of edges, sorted according to a sort key.
EdgeQueue::Element * EdgeQueueElemPtr
An element pointer into the edge queue binary heap.
bool hasParent() const
Returns whether this vertex has a parent.
void removeFromEdgeQueueOutLookup(const SearchQueue::EdgeQueueElemPtr &outEdge)
Remove an outgoing edge queue entry by value.
VertexConstPtr getParent() const
Get a const pointer to the parent of this vertex.
bool isRoot() const
Returns whether the vertex is the root of the search tree.
BITstar::VertexId getId() const
The (unique) vertex ID.
void removeFromEdgeQueueInLookup(const SearchQueue::EdgeQueueElemPtr &inEdge)
Remove an incoming edge queue entry by value to the member vector.
std::vector< VertexConstPtr > VertexConstPtrVector
A vector of shared pointers to const vertices.
std::vector< VertexPtr > VertexPtrVector
A vector of shared pointers to vertices.
std::shared_ptr< const Vertex > VertexConstPtr
A shared pointer to a const vertex.
std::shared_ptr< Vertex > VertexPtr
A shared pointer to a vertex.
unsigned int VertexId
The vertex id type.
This namespace contains code that is specific to planning under geometric constraints.
Main namespace. Contains everything in this library.