Skip to content

Commit 4ee7188

Browse files
authored
Rework Pruning (#221)
2 parents f2958a4 + b7f8093 commit 4ee7188

File tree

8 files changed

+481
-126
lines changed

8 files changed

+481
-126
lines changed

core/include/moveit/task_constructor/container.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ class ContainerBase : public Stage
7777

7878
/// called by a (direct) child when a new solution becomes available
7979
virtual void onNewSolution(const SolutionBase& s) = 0;
80+
/// called by a (direct) child when a solution failed
81+
virtual void onNewFailure(const Stage& child, const InterfaceState* from, const InterfaceState* to) = 0;
8082

8183
protected:
8284
ContainerBase(ContainerBasePrivate* impl);
@@ -95,8 +97,8 @@ class SerialContainer : public ContainerBase
9597
void compute() override;
9698

9799
protected:
98-
/// called by a (direct) child when a new solution becomes available
99100
void onNewSolution(const SolutionBase& s) override;
101+
void onNewFailure(const Stage& child, const InterfaceState* from, const InterfaceState* to) override;
100102

101103
protected:
102104
SerialContainer(SerialContainerPrivate* impl);
@@ -116,6 +118,7 @@ class ParallelContainerBase : public ContainerBase
116118
public:
117119
PRIVATE_CLASS(ParallelContainerBase)
118120
ParallelContainerBase(const std::string& name = "parallel container");
121+
void onNewFailure(const Stage& child, const InterfaceState* from, const InterfaceState* to) override;
119122

120123
protected:
121124
ParallelContainerBase(ParallelContainerBasePrivate* impl);

core/include/moveit/task_constructor/stage_p.h

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ class StagePrivate
144144
void spawn(InterfaceState&& state, const SolutionBasePtr& solution);
145145
void connect(const InterfaceState& from, const InterfaceState& to, const SolutionBasePtr& solution);
146146

147-
bool storeSolution(const SolutionBasePtr& solution);
147+
bool storeSolution(const SolutionBasePtr& solution, const InterfaceState* from, const InterfaceState* to);
148148
void newSolution(const SolutionBasePtr& solution);
149149
bool storeFailures() const { return introspection_ != nullptr; }
150150
void runCompute() {
@@ -157,6 +157,10 @@ class StagePrivate
157157
/** compute cost for solution through configured CostTerm */
158158
void computeCost(const InterfaceState& from, const InterfaceState& to, SolutionBase& solution);
159159

160+
/// Set ENABLED / DISABLED status of the solution tree starting from s into given direction
161+
template <Interface::Direction dir>
162+
static void setStatus(const InterfaceState* s, InterfaceState::Status status);
163+
160164
protected:
161165
// associated/owning Stage instance
162166
Stage* me_;
@@ -294,31 +298,53 @@ class ConnectingPrivate : public ComputeBasePrivate
294298
{
295299
friend class Connecting;
296300

297-
using StatePair = std::pair<Interface::const_iterator, Interface::const_iterator>;
298-
struct StatePairLess
301+
public:
302+
struct StatePair : std::pair<Interface::const_iterator, Interface::const_iterator>
299303
{
300-
bool operator()(const StatePair& x, const StatePair& y) const {
301-
return x.first->priority() + x.second->priority() < y.first->priority() + y.second->priority();
304+
using std::pair<Interface::const_iterator, Interface::const_iterator>::pair; // inherit base constructors
305+
bool operator<(const StatePair& rhs) const {
306+
return less(first->priority(), second->priority(), rhs.first->priority(), rhs.second->priority());
307+
}
308+
static inline bool less(const InterfaceState::Priority& lhsA, const InterfaceState::Priority& lhsB,
309+
const InterfaceState::Priority& rhsA, const InterfaceState::Priority& rhsB) {
310+
unsigned char lhs = (lhsA.enabled() << 1) | lhsB.enabled(); // combine bits into two-digit binary number
311+
unsigned char rhs = (rhsA.enabled() << 1) | rhsB.enabled();
312+
if (lhs == rhs) // if enabled status is identical
313+
return lhsA + lhsB < rhsA + rhsB; // compare the sums of both contributions
314+
// one of the states in each pair should be enabled
315+
assert(lhs != 0b00 && rhs != 0b00);
316+
// both states valid (b11)
317+
if (lhs == 0b11)
318+
return true;
319+
if (rhs == 0b11)
320+
return false;
321+
return lhs < rhs; // disabled states in 1st component go before disabled states in 2nd component
302322
}
303323
};
304324

305-
template <Interface::Direction other>
306-
inline StatePair make_pair(Interface::const_iterator first, Interface::const_iterator second);
307-
308-
public:
309325
inline ConnectingPrivate(Connecting* me, const std::string& name);
310326

311327
InterfaceFlags requiredInterface() const override;
312328
bool canCompute() const override;
313329
void compute() override;
314330

331+
// Check whether there are pending feasible states that could connect to source
332+
template <Interface::Direction dir>
333+
bool hasPendingOpposites(const InterfaceState* source) const;
334+
335+
std::ostream& printPendingPairs(std::ostream& os = std::cerr) const;
336+
315337
private:
338+
// Create a pair of Interface states for pending list, such that the order (start, end) is maintained
339+
template <Interface::Direction other>
340+
inline StatePair make_pair(Interface::const_iterator first, Interface::const_iterator second);
341+
316342
// get informed when new start or end state becomes available
317343
template <Interface::Direction other>
318344
void newState(Interface::iterator it, bool updated);
319345

320346
// ordered list of pending state pairs
321-
ordered<StatePair, StatePairLess> pending;
347+
ordered<StatePair> pending;
322348
};
323349
PIMPL_FUNCTIONS(Connecting)
324350
} // namespace task_constructor

core/include/moveit/task_constructor/storage.h

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -76,23 +76,42 @@ class InterfaceState
7676
{
7777
friend class SolutionBase; // addIncoming() / addOutgoing() should be called only by SolutionBase
7878
friend class Interface; // allow Interface to set owner_ and priority_
79+
friend class StagePrivate;
80+
7981
public:
82+
enum Status
83+
{
84+
ENABLED, // state is actively considered during planning
85+
DISABLED, // state is disabled because a required connected state failed
86+
DISABLED_FAILED, // state that failed, causing the whole partial solution to be disabled
87+
};
8088
/** InterfaceStates are ordered according to two values:
8189
* Depth of interlinked trajectory parts and accumulated trajectory costs along that path.
8290
* Preference ordering considers high-depth first and within same depth, minimal cost paths.
8391
*/
84-
struct Priority : public std::pair<unsigned int, double>
92+
struct Priority : std::tuple<Status, unsigned int, double>
8593
{
86-
Priority(unsigned int depth, double cost) : std::pair<unsigned int, double>(depth, cost) {}
94+
Priority(unsigned int depth, double cost, Status status = ENABLED)
95+
: std::tuple<Status, unsigned int, double>(status, depth, cost) {
96+
assert(std::isfinite(cost));
97+
}
98+
// Constructor copying depth and cost, but modifying its status
99+
Priority(const Priority& other, Status status) : Priority(other.depth(), other.cost(), status) {}
87100

88-
inline unsigned int depth() const { return this->first; }
89-
inline double cost() const { return this->second; }
101+
inline Status status() const { return std::get<0>(*this); }
102+
inline bool enabled() const { return std::get<0>(*this) == ENABLED; }
103+
inline unsigned int depth() const { return std::get<1>(*this); }
104+
inline double cost() const { return std::get<2>(*this); }
90105

91106
// add priorities
92107
Priority operator+(const Priority& other) const {
93-
return Priority(this->depth() + other.depth(), this->cost() + other.cost());
108+
return Priority(depth() + other.depth(), cost() + other.cost(), std::min(status(), other.status()));
94109
}
95-
bool operator<(const Priority& other) const;
110+
// comparison operators
111+
bool operator<(const Priority& rhs) const;
112+
inline bool operator>(const Priority& rhs) const { return rhs < *this; }
113+
inline bool operator<=(const Priority& rhs) const { return !(rhs < *this); }
114+
inline bool operator>=(const Priority& rhs) const { return !(*this < rhs); }
96115
};
97116
using Solutions = std::deque<SolutionBase*>;
98117

@@ -147,19 +166,20 @@ class Interface : public ordered<InterfaceState*>
147166
class iterator : public base_type::iterator
148167
{
149168
public:
150-
using base_type::iterator::iterator; // inherit base constructors
151169
iterator(base_type::iterator other) : base_type::iterator(other) {}
152170

153171
InterfaceState& operator*() const noexcept { return *base_type::iterator::operator*(); }
172+
154173
InterfaceState* operator->() const noexcept { return base_type::iterator::operator*(); }
155174
};
156175
class const_iterator : public base_type::const_iterator
157176
{
158177
public:
159-
using base_type::const_iterator::const_iterator; // inherit base constructors
160178
const_iterator(base_type::const_iterator other) : base_type::const_iterator(other) {}
179+
const_iterator(base_type::iterator other) : base_type::const_iterator(other) {}
161180

162181
const InterfaceState& operator*() const noexcept { return *base_type::const_iterator::operator*(); }
182+
163183
const InterfaceState* operator->() const noexcept { return base_type::const_iterator::operator*(); }
164184
};
165185

@@ -194,6 +214,9 @@ class Interface : public ordered<InterfaceState*>
194214
using base_type::remove_if;
195215
};
196216

217+
std::ostream& operator<<(std::ostream& os, const InterfaceState::Priority& prio);
218+
std::ostream& operator<<(std::ostream& os, const Interface& interface);
219+
197220
class CostTerm;
198221
class StagePrivate;
199222
class ContainerBasePrivate;
@@ -370,14 +393,26 @@ inline const InterfaceState* state<Interface::BACKWARD>(const SolutionBase& solu
370393

371394
/// Trait to retrieve outgoing (FORWARD) or incoming (BACKWARD) solution segments of a given state
372395
template <Interface::Direction dir>
373-
const InterfaceState::Solutions& trajectories(const InterfaceState* state);
396+
const InterfaceState::Solutions& trajectories(const InterfaceState& state);
397+
template <>
398+
inline const InterfaceState::Solutions& trajectories<Interface::FORWARD>(const InterfaceState& state) {
399+
return state.outgoingTrajectories();
400+
}
401+
template <>
402+
inline const InterfaceState::Solutions& trajectories<Interface::BACKWARD>(const InterfaceState& state) {
403+
return state.incomingTrajectories();
404+
}
405+
406+
/// Trait to retrieve opposite direction (FORWARD <-> BACKWARD)
407+
template <Interface::Direction dir>
408+
constexpr Interface::Direction opposite();
374409
template <>
375-
inline const InterfaceState::Solutions& trajectories<Interface::FORWARD>(const InterfaceState* state) {
376-
return state->outgoingTrajectories();
410+
inline constexpr Interface::Direction opposite<Interface::FORWARD>() {
411+
return Interface::BACKWARD;
377412
}
378413
template <>
379-
inline const InterfaceState::Solutions& trajectories<Interface::BACKWARD>(const InterfaceState* state) {
380-
return state->incomingTrajectories();
414+
inline constexpr Interface::Direction opposite<Interface::BACKWARD>() {
415+
return Interface::FORWARD;
381416
}
382417
} // namespace task_constructor
383418
} // namespace moveit

0 commit comments

Comments
 (0)