From 13c5ef9d80f14e03ebe1e7f094adbd65891d50f9 Mon Sep 17 00:00:00 2001 From: Le Quang Anh <43576719+Toefinder@users.noreply.github.com> Date: Fri, 4 Feb 2022 17:55:34 +0100 Subject: [PATCH] [WIP] [StatesPathFinder] Solve when goal is a set of constraints --- .../path-planner/states-path-finder.hh | 9 +- src/path-planner/states-path-finder.cc | 109 ++++++++++++++++-- 2 files changed, 106 insertions(+), 12 deletions(-) diff --git a/include/hpp/manipulation/path-planner/states-path-finder.hh b/include/hpp/manipulation/path-planner/states-path-finder.hh index e0fad8a9..9cde92f2 100644 --- a/include/hpp/manipulation/path-planner/states-path-finder.hh +++ b/include/hpp/manipulation/path-planner/states-path-finder.hh @@ -78,7 +78,7 @@ namespace hpp { /// - method analyseOptimizationProblem loops over the waypoint solvers, /// tests what happens when solving each waypoint after initializing /// only the right hand sides that are equal to the initial or goal - /// configuraion, and detects if a collision is certain to block any attemps + /// configuration, and detects if a collision is certain to block any attemps /// to solve the problem in the solveOptimizationProblem step. /// - method solveOptimizationProblem tries to solve for each waypoint after /// initializing the right hand sides with the proper values, backtracking @@ -119,6 +119,12 @@ namespace hpp { /// vector if a path could not be built. core::Configurations_t computeConfigList (ConfigurationIn_t q1, ConfigurationIn_t q2); + /// create a vector of configurations from initial configuration + /// to a configuration satisfying the goal constraints, when goal + /// is defined as a set of constraints + /// \return a Configurations_t from q1 to q2 if found. An empty + /// vector if a path could not be built. + core::Configurations_t computeConfigList (ConfigurationIn_t q1); // access functions for Python interface std::vector<std::string> constraintNamesFromSolverAtWaypoint @@ -216,6 +222,7 @@ namespace hpp { // Constraints defining the goal NumericalConstraints_t goalConstraints_; + bool goalDefinedByConstraints_; // Variables used across several calls to oneStep ConfigurationPtr_t q1_, q2_; core::Configurations_t configList_; diff --git a/src/path-planner/states-path-finder.cc b/src/path-planner/states-path-finder.cc index 62819f76..398e2a20 100644 --- a/src/path-planner/states-path-finder.cc +++ b/src/path-planner/states-path-finder.cc @@ -16,12 +16,14 @@ // received a copy of the GNU Lesser General Public License along with // hpp-manipulation. If not, see <http://www.gnu.org/licenses/>. +#define HPP_DEBUG #include <hpp/manipulation/path-planner/states-path-finder.hh> #include <map> #include <queue> #include <vector> +#include <hpp/util/debug.hh> #include <hpp/util/exception-factory.hh> #include <hpp/util/timer.hh> @@ -679,7 +681,7 @@ namespace hpp { } ++index; } // for (NumericalConstraints_t::const_iterator it - // displayStatusMatrix (transitions); + displayStatusMatrix (transitions); // Fill solvers with target constraints of transition for (std::size_t j = 0; j < d.N; ++j) { d.solvers [j] = transitions [j]-> @@ -1066,6 +1068,7 @@ namespace hpp { core::Configurations_t StatesPathFinder::computeConfigList ( ConfigurationIn_t q1, ConfigurationIn_t q2) { + assert (!goalDefinedByConstraints_); const graph::GraphPtr_t& graph(problem_->constraintGraph ()); GraphSearchData d; d.s1 = graph->getState (q1); @@ -1123,6 +1126,70 @@ namespace hpp { return empty_path; } + // Loop over all the possible paths in the constraint graph starting from + // the states of the initial configuration and with increasing lengths, + // apply goal constraints on the end node and try to project configurations + core::Configurations_t StatesPathFinder::computeConfigList ( + ConfigurationIn_t q1) + { + assert (goalDefinedByConstraints_); + const graph::GraphPtr_t& graph(problem_->constraintGraph ()); + GraphSearchData d; + d.s1 = graph->getState (q1); + d.s2 = graph->getState (q2); // TODO: fix this + d.maxDepth = problem_->getParameter + ("StatesPathFinder/maxDepth").intValue(); + + // Find + d.queue1.push (d.addInitState()); + std::size_t idxSol = (d.s1 == d.s2 ? 1 : 0); + if (idxSol_ < idxSol) idxSol_ = idxSol; + + bool maxDepthReached; + while (!(maxDepthReached = findTransitions (d))) { // mut + Edges_t transitions = getTransitionList (d, idxSol); // const, const + while (! transitions.empty()) { + if (idxSol >= idxSol_) { +#ifdef HPP_DEBUG + std::ostringstream ss; + ss << " Trying solution " << idxSol << ": \n\t"; + for (std::size_t j = 0; j < transitions.size(); ++j) + ss << transitions[j]->name() << ", \n\t"; + hppDout (info, ss.str()); +#endif // HPP_DEBUG + if (optData_) { + delete optData_; + optData_ = nullptr; + } + optData_ = new OptimizationData (problem(), q1, q2, transitions); + + if (buildOptimizationProblem (transitions)) { + lastBuiltTransitions_ = transitions; + if (skipColAnalysis_ || analyseOptimizationProblem (transitions)) { + if (solveOptimizationProblem ()) { + core::Configurations_t path = getConfigList (); + hppDout (warning, " Solution " << idxSol << ": solved configurations list"); + return path; + } else { + hppDout (info, " Failed solution " << idxSol << " at step 5 (solve opt pb)"); + } + } else { + hppDout (info, " Failed solution " << idxSol << " at step 4 (analyse opt pb)"); + } + } else { + hppDout (info, " Failed solution " << idxSol << " at step 3 (build opt pb)"); + } + } // if (idxSol >= idxSol_) + transitions = getTransitionList(d, ++idxSol); + if (idxSol_ < idxSol) idxSol_ = idxSol; + } + } + core::Configurations_t empty_path; + ConfigurationPtr_t q (new Configuration_t (q1)); + empty_path.push_back(q); + return empty_path; + } + void StatesPathFinder::reset() { idxSol_ = 0; if (optData_) { @@ -1146,6 +1213,7 @@ namespace hpp { GoalConfigurationsPtr_t goalConfigs (HPP_DYNAMIC_PTR_CAST(GoalConfigurations, target)); if (goalConfigs){ + goalDefinedByConstraints_ = false; core::Configurations_t q2s = goalConfigs->configurations(); if (q2s.size() != 1) { std::ostringstream os; @@ -1155,10 +1223,17 @@ namespace hpp { throw std::logic_error(os.str().c_str()); } q2_ = q2s[0]; - } - TaskTargetPtr_t taskTarget(HPP_DYNAMIC_PTR_CAST(TaskTarget,target)); - if(taskTarget){ + } else { + TaskTargetPtr_t taskTarget(HPP_DYNAMIC_PTR_CAST(TaskTarget,target)); + if(!taskTarget){ + std::ostringstream os; + os << "StatesPathFinder only accept goal defined as " + "either a configuration or a set of constraints."; + throw std::logic_error(os.str().c_str()); + } + goalDefinedByConstraints_ = true; goalConstraints_ = taskTarget->constraints(); + hppDout(info, "goal defined as a set of constraints"); } reset(); } @@ -1167,7 +1242,14 @@ namespace hpp { { if (idxConfigList_ == 0) { skipColAnalysis_ = (nTryConfigList_ >= 1); // already passed, don't redo it - configList_ = computeConfigList(*q1_, *q2_); + // TODO: accommodate when goal is a set of constraints + assert(q1_); + if (!goalDefinedByConstraints_) { + assert(q2_); + configList_ = computeConfigList(*q1_, *q2_); + } else { + configList_ = computeConfigList(*q1_); + } if (configList_.size() <= 1) { // max depth reached reset(); throw core::path_planning_failed("Maximal depth reached."); @@ -1187,12 +1269,17 @@ namespace hpp { core::ConstraintSet, edge->pathConstraint()->copy())); // Initialize right hand side constraints->configProjector()->rightHandSideFromConfig(*q1); - assert(constraints->isSatisfied(*q2)); - inStateProblem_->constraints(constraints); - inStateProblem_->pathValidation(edge->pathValidation()); - inStateProblem_->initConfig(q1); - inStateProblem_->resetGoalConfigs(); - inStateProblem_->addGoalConfig(q2); + if (!goalDefinedByConstraints_) { + assert(constraints->isSatisfied(*q2)); + inStateProblem_->constraints(constraints); + inStateProblem_->pathValidation(edge->pathValidation()); + inStateProblem_->initConfig(q1); + inStateProblem_->resetGoalConfigs(); + inStateProblem_->addGoalConfig(q2); + } else { + // TODO: algorithm when the goal is a set of constraints + hppDout(warning, "Not implemented for goal as a set of constraints"); + } core::PathPlannerPtr_t inStatePlanner (core::DiffusingPlanner::create(inStateProblem_)); -- GitLab