Skip to content

Commit d1a6916

Browse files
authored
Stage::explainFailure() (#445)
... to facilitate spotting the stage causing a task to fail
1 parent ede7cb7 commit d1a6916

File tree

6 files changed

+36
-2
lines changed

6 files changed

+36
-2
lines changed

core/include/moveit/task_constructor/container.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ class ContainerBase : public Stage
7676

7777
virtual bool canCompute() const = 0;
7878
virtual void compute() = 0;
79+
void explainFailure(std::ostream& os) const override;
7980

8081
/// called by a (direct) child when a new solution becomes available
8182
virtual void onNewSolution(const SolutionBase& s) = 0;

core/include/moveit/task_constructor/stage.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,8 @@ class Stage
232232
/// Should we generate failure solutions? Note: Always report a failure!
233233
bool storeFailures() const;
234234

235+
virtual void explainFailure(std::ostream& os) const;
236+
235237
/// Get the stage's property map
236238
PropertyMap& properties();
237239
const PropertyMap& properties() const { return const_cast<Stage*>(this)->properties(); }

core/include/moveit/task_constructor/task.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,9 @@ class Task : protected WrapperBase
132132
/// print current task state (number of found solutions and propagated states) to std::cout
133133
void printState(std::ostream& os = std::cout) const;
134134

135+
/// print an explanation for a planning failure to os
136+
void explainFailure(std::ostream& os = std::cout) const override;
137+
135138
size_t numSolutions() const { return solutions().size(); }
136139
const ordered<SolutionBaseConstPtr>& solutions() const { return stages()->solutions(); }
137140
const std::list<SolutionBaseConstPtr>& failures() const { return stages()->failures(); }

core/src/container.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,20 @@ void ContainerBase::init(const moveit::core::RobotModelConstPtr& robot_model) {
446446
throw errors;
447447
}
448448

449+
void ContainerBase::explainFailure(std::ostream& os) const {
450+
for (const auto& stage : pimpl()->children()) {
451+
if (!stage->solutions().empty())
452+
continue; // skip deeper traversal, this stage produced solutions
453+
if (stage->numFailures()) {
454+
os << stage->name() << " (0/" << stage->numFailures() << ")";
455+
stage->explainFailure(os);
456+
os << std::endl;
457+
break;
458+
}
459+
stage->explainFailure(os); // recursively process children
460+
}
461+
}
462+
449463
std::ostream& operator<<(std::ostream& os, const ContainerBase& container) {
450464
ContainerBase::StageCallback processor = [&os](const Stage& stage, unsigned int depth) -> bool {
451465
os << std::string(2 * depth, ' ') << *stage.pimpl() << std::endl;
@@ -690,6 +704,7 @@ void SerialContainer::compute() {
690704
}
691705
}
692706

707+
693708
ParallelContainerBasePrivate::ParallelContainerBasePrivate(ParallelContainerBase* me, const std::string& name)
694709
: ContainerBasePrivate(me, name) {}
695710

core/src/stage.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,11 @@ bool Stage::storeFailures() const {
428428
return pimpl()->storeFailures();
429429
}
430430

431+
void Stage::explainFailure(std::ostream& os) const {
432+
if (!failures().empty())
433+
os << ": " << failures().front()->comment();
434+
}
435+
431436
PropertyMap& Stage::properties() {
432437
return pimpl()->properties_;
433438
}

core/src/task.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,9 +237,12 @@ moveit::core::MoveItErrorCode Task::plan(size_t max_solutions) {
237237
init();
238238

239239
// Print state and return success if there are solutions otherwise the input error_code
240-
const auto success_or = [this](const int32_t error_code) {
240+
const auto success_or = [this](const int32_t error_code) -> int32_t {
241+
if (numSolutions() > 0)
242+
return moveit::core::MoveItErrorCode::SUCCESS;
241243
printState();
242-
return numSolutions() > 0 ? moveit::core::MoveItErrorCode::SUCCESS : error_code;
244+
explainFailure();
245+
return error_code;
243246
};
244247
impl->preempt_requested_ = false;
245248
const double available_time = timeout();
@@ -313,5 +316,10 @@ const core::RobotModelConstPtr& Task::getRobotModel() const {
313316
void Task::printState(std::ostream& os) const {
314317
os << *stages();
315318
}
319+
320+
void Task::explainFailure(std::ostream& os) const {
321+
os << "Failing stage(s):\n";
322+
stages()->explainFailure(os);
323+
}
316324
} // namespace task_constructor
317325
} // namespace moveit

0 commit comments

Comments
 (0)