36#include "ompl/geometric/planners/informedtrees/eitstar/ReverseQueue.h"
40#include "ompl/geometric/planners/informedtrees/eitstar/Direction.h"
41#include "ompl/geometric/planners/informedtrees/eitstar/State.h"
50 const std::shared_ptr<const ompl::base::StateSpace> &space,
51 const bool isQueueCostOrdered)
52 : isQueueCostOrdered_(isQueueCostOrdered)
53 , objective_(objective)
55 , queue_(isQueueCostOrdered_ ? getCostComparisonOperator() : getEffortComparisonOperator())
71 if (!updateIfExists(edge))
75 const auto key2 = computeAdmissibleCostToComeToTarget(edge);
77 const auto key4 = computeInadmissibleSolutionEffort(edge);
80 const auto element = std::make_tuple(key1, key2, key3, key4, edge);
83 const auto elementPointer = queue_.insert(element);
86 edge.
source->asReverseVertex()->outgoingReverseQueueLookup_.emplace_back(elementPointer);
93 for (
const auto &edge : edges)
101 isQueueCostOrdered_ = isQueueCostOrdered;
105 throw std::runtime_error(
"Can't update ordering of queue if there are elements in it.");
107 if (isQueueCostOrdered_)
109 queue_.getComparisonOperator() = getCostComparisonOperator();
113 queue_.getComparisonOperator() = getEffortComparisonOperator();
119 if (
auto element = queue_.top())
121 return std::get<4>(element->data);
125 throw std::out_of_range(
"There are no elements to peek in the reverse queue.");
131 if (
auto element = queue_.top())
133 return std::get<2>(element->data);
137 throw std::out_of_range(
"There are no elements to peek in the reverse queue.");
141 bool ReverseQueue::updateIfExists(
const Edge &edge)
144 const auto &lookup = edge.
source->asReverseVertex()->outgoingReverseQueueLookup_;
145 const auto it = std::find_if(lookup.cbegin(), lookup.cend(), [&edge](
const auto &p)
146 { return std::get<4>(p->data).target->getId() == edge.target->getId(); });
149 if (it == lookup.cend())
156 std::get<1>((*it)->data) = computeAdmissibleCostToComeToTarget(edge);
158 std::get<3>((*it)->data) = computeInadmissibleSolutionEffort(edge);
167 return objective_->combineCosts(
168 objective_->combineCosts(edge.
source->getAdmissibleCostToGo(),
169 objective_->motionCostHeuristic(edge.
target->raw(), edge.
source->raw())),
170 edge.
target->getLowerBoundCostToCome());
176 edge.
source->getAdmissibleCostToGo(),
182 std::size_t edgeEffort = 0u;
189 const std::size_t fullSegmentCount =
190 space_->validSegmentCount(edge.
source->raw(), edge.
target->raw());
193 const std::size_t performedChecks = edge.
target->getIncomingCollisionCheckResolution(edge.
source);
196 assert(fullSegmentCount >= performedChecks);
199 edgeEffort = fullSegmentCount - performedChecks;
202 const unsigned int totalEffort =
203 edge.
source->getEstimatedEffortToGo() + edgeEffort + edge.
target->getLowerBoundEffortToCome();
205 if (std::numeric_limits<unsigned int>::max() - edgeEffort - edge.
source->getEstimatedEffortToGo() <
206 edge.
target->getLowerBoundEffortToCome())
208 return std::numeric_limits<unsigned int>::max();
214 std::function<bool(
const ReverseQueue::HeapElement &,
const ReverseQueue::HeapElement &)>
215 ReverseQueue::getCostComparisonOperator()
const
217 return [&objective = objective_](
const HeapElement &lhs,
const HeapElement &rhs)
219 if (objective->isCostEquivalentTo(std::get<0>(lhs), std::get<0>(rhs)))
221 if (objective->isCostEquivalentTo(std::get<1>(lhs), std::get<1>(rhs)))
223 return std::get<2>(lhs) < std::get<2>(rhs);
227 return objective->isCostBetterThan(std::get<1>(lhs), std::get<1>(rhs));
232 return objective->isCostBetterThan(std::get<0>(lhs), std::get<0>(rhs));
237 std::function<bool(
const ReverseQueue::HeapElement &,
const ReverseQueue::HeapElement &)>
238 ReverseQueue::getEffortComparisonOperator()
const
240 return [&objective = objective_](
const HeapElement &lhs,
const HeapElement &rhs)
242 if (std::get<2>(lhs) == std::get<2>(rhs))
244 if (std::get<3>(lhs) == std::get<3>(rhs))
246 if (objective->isCostEquivalentTo(std::get<0>(lhs), std::get<0>(rhs)))
248 return objective->isCostBetterThan(std::get<1>(lhs), std::get<1>(rhs));
252 return objective->isCostBetterThan(std::get<0>(lhs), std::get<0>(rhs));
257 return std::get<3>(lhs) < std::get<3>(rhs);
262 return std::get<2>(lhs) < std::get<2>(rhs);
267 unsigned int ReverseQueue::computeInadmissibleSolutionEffort(
const Edge &edge)
const
269 std::size_t edgeEffort = 0u;
270 if (edge.source->isWhitelisted(edge.target))
276 const std::size_t fullSegmentCount =
277 space_->validSegmentCount(edge.source->raw(), edge.target->raw());
280 const std::size_t performedChecks = edge.target->getIncomingCollisionCheckResolution(edge.source);
283 assert(fullSegmentCount >= performedChecks);
286 edgeEffort = fullSegmentCount - performedChecks;
289 if (std::numeric_limits<unsigned int>::max() - edgeEffort - edge.source->getEstimatedEffortToGo() <
290 edge.target->getInadmissibleEffortToCome())
292 return std::numeric_limits<unsigned int>::max();
296 return edge.source->getEstimatedEffortToGo() + edgeEffort + edge.target->getInadmissibleEffortToCome();
301 assert(!queue_.empty());
304 const auto element = queue_.top();
307 auto edge = std::get<4>(element->data);
310 assert(edge.source->hasReverseVertex());
316 auto &lookup = edge.source->asReverseVertex()->outgoingReverseQueueLookup_;
319 auto it = std::find(lookup.begin(), lookup.end(), element);
322 assert(it != lookup.end());
325 std::iter_swap(it, lookup.rbegin());
334 return std::get<0>(queue_.top()->data);
340 std::vector<HeapElement> contents;
341 queue_.getContent(contents);
342 for (
auto element : contents)
344 std::get<4>(element).source->asReverseVertex()->outgoingReverseQueueLookup_.clear();
351 std::vector<HeapElement> contents;
352 queue_.getContent(contents);
353 std::vector<Edge> edges;
354 edges.reserve(contents.size());
355 for (
const auto &element : contents)
357 edges.push_back(std::get<4>(element));
372 for (
const auto element : vertex->outgoingReverseQueueLookup_)
374 queue_.remove(element);
378 vertex->outgoingReverseQueueLookup_.clear();
void update(Element *element)
Update an element in the heap.
Definition of a cost value. Can represent the cost of a motion or the cost of a state.
virtual Cost motionCostHeuristic(const State *s1, const State *s2) const
Defines an admissible estimate on the optimal cost on the motion between states s1 and s2....
virtual Cost combineCosts(Cost c1, Cost c2) const
Get the cost that corresponds to combining the costs c1 and c2. Default implementation defines this c...
ReverseQueue(const std::shared_ptr< const ompl::base::OptimizationObjective > &objective, const std::shared_ptr< const ompl::base::StateSpace > &space, const bool isQueueCostOrdered)
Constructs the queue with the given optimization objective and state space.
ompl::base::Cost getLowerBoundOnOptimalSolutionCost() const
Returns a lower bound on the resolution-optimal solution cost.
void insertOrUpdate(const Edge &edge)
Inserts or updates an element in the queue.
void clear()
Clears the queue, i.e., deletes all elements from it.
unsigned int computeAdmissibleSolutionEffort(const Edge &edge) const
Returns the admissible total potential effort of an edge.
void rebuild()
Rebuilds the queue.
bool empty() const
Returns whether the queue is empty.
unsigned int peekEffort() const
Get the effort corresponding to the top edge of the queue.
void removeOutgoingEdges(const std::shared_ptr< Vertex > &vertex)
Removes the outgoing edges of a vertex from the queue.
void setCostQueueOrder(const bool isQueueCostOrdered)
Updates the queue ordering depending on the given suboptimality factor.
ompl::base::Cost computeAdmissibleSolutionCost(const Edge &edge) const
Returns the admissible total potential solution cost of an edge.
const Edge & peek() const
Get a reference to the top edge in the queue.
std::vector< Edge > getEdges() const
Copies all edges into a vector and returns the vector.
std::size_t size() const
Returns the number of elements in the queue.
Edge pop()
Returns and deletes the top element of the queue.
This namespace contains code that is specific to planning under geometric constraints.
Main namespace. Contains everything in this library.
A struct for basic edge data.
std::shared_ptr< State > source
The parent state of this edge.
std::shared_ptr< State > target
The child state of this edge.