From 45c41f47e631430ee292b88cdcbb7886b59db624 Mon Sep 17 00:00:00 2001 From: Florent Lamiraux <florent@laas.fr> Date: Tue, 21 Sep 2021 14:39:14 +0000 Subject: [PATCH] [StatesPathFinder] Refactor - Use parent implementation for method solve, - reimplement tryToConnectInitAndGoals, - remove InStatePath class and call core::DiffusingPlanner instead. - optimize paths on sub-manifolds with random shortcut and insert path in roadmap. --- CMakeLists.txt | 2 - .../path-planner/in-state-path.hh | 135 --------- .../path-planner/states-path-finder.hh | 46 +-- src/path-planner/in-state-path.cc | 232 -------------- src/path-planner/states-path-finder.cc | 283 +++++++----------- src/problem-solver.cc | 2 - 6 files changed, 128 insertions(+), 572 deletions(-) delete mode 100644 include/hpp/manipulation/path-planner/in-state-path.hh delete mode 100644 src/path-planner/in-state-path.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 0272208..3519603 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -82,7 +82,6 @@ SET(${PROJECT_NAME}_HEADERS include/hpp/manipulation/path-planner/end-effector-trajectory.hh include/hpp/manipulation/path-planner/states-path-finder.hh - include/hpp/manipulation/path-planner/in-state-path.hh include/hpp/manipulation/problem-target/state.hh @@ -126,7 +125,6 @@ SET(${PROJECT_NAME}_SOURCES src/path-planner/end-effector-trajectory.cc src/path-planner/states-path-finder.cc - src/path-planner/in-state-path.cc src/problem-target/state.cc diff --git a/include/hpp/manipulation/path-planner/in-state-path.hh b/include/hpp/manipulation/path-planner/in-state-path.hh deleted file mode 100644 index 4395ed6..0000000 --- a/include/hpp/manipulation/path-planner/in-state-path.hh +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright (c) 2021, Joseph Mirabel -// Authors: Joseph Mirabel (joseph.mirabel@laas.fr), -// Florent Lamiraux (florent.lamiraux@laas.fr) -// Alexandre Thiault (athiault@laas.fr) -// -// This file is part of hpp-manipulation. -// hpp-manipulation is free software: you can redistribute it -// and/or modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation, either version -// 3 of the License, or (at your option) any later version. -// -// hpp-manipulation is distributed in the hope that it will be -// useful, but WITHOUT ANY WARRANTY; without even the implied warranty -// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Lesser Public License for more details. You should have -// received a copy of the GNU Lesser General Public License along with -// hpp-manipulation. If not, see <http://www.gnu.org/licenses/>. - -#ifndef HPP_MANIPULATION_PATH_PLANNER_IN_STATE_PATH_HH -# define HPP_MANIPULATION_PATH_PLANNER_IN_STATE_PATH_HH - -# include <hpp/core/path-planner.hh> -# include <hpp/core/config-projector.hh> -# include <hpp/core/collision-validation.hh> -# include <hpp/core/joint-bound-validation.hh> - -# include <hpp/manipulation/config.hh> -# include <hpp/manipulation/fwd.hh> -# include <hpp/manipulation/problem.hh> -# include <hpp/manipulation/steering-method/graph.hh> - -namespace hpp { - namespace manipulation { - namespace pathPlanner { - /// \addtogroup path_planner - /// \{ - - /// - /// Path planner designed to build a path between two configurations - /// on the same leaf of a given state graph edge - class HPP_MANIPULATION_DLLAPI InStatePath : public core::PathPlanner - { - public: - virtual ~InStatePath() - {} - - static InStatePathPtr_t create ( - const core::ProblemConstPtr_t& problem); - - static InStatePathPtr_t createWithRoadmap ( - const core::ProblemConstPtr_t& problem, - const core::RoadmapPtr_t& roadmap); - - InStatePathPtr_t copy () const; - - void maxIterPlanner(const unsigned long& maxiter); - void timeOutPlanner(const double& timeout); - void resetRoadmap(const bool& resetroadmap); - void plannerType(const std::string& plannertype); - void addOptimizerType(const std::string& opttype); - void resetOptimizerTypes(); - - /// Set the edge along which q_init and q_goal will be linked. - /// Use setEdge before setInit and setGoal. - void setEdge (const graph::EdgePtr_t& edge); - void setInit (const ConfigurationPtr_t& q); - void setGoal (const ConfigurationPtr_t& q); - - virtual void oneStep() - {} - virtual core::PathVectorPtr_t solve(); - - const core::RoadmapPtr_t& leafRoadmap() const; - void mergeLeafRoadmapWith(const core::RoadmapPtr_t& roadmap) const; - - protected: - InStatePath (const core::ProblemConstPtr_t& problem, - const core::RoadmapPtr_t& roadmap) : - PathPlanner(problem), - problem_ (HPP_STATIC_PTR_CAST(const manipulation::Problem, problem)), - leafRoadmap_(roadmap), - constraints_(), weak_() - { - const core::DevicePtr_t& robot = problem_->robot(); - leafProblem_ = core::Problem::create(robot); - leafProblem_->setParameter - ("kPRM*/numberOfNodes", core::Parameter((size_type) 2000)); - leafProblem_->clearConfigValidations(); - leafProblem_->addConfigValidation(core::CollisionValidation::create(robot)); - leafProblem_->addConfigValidation(core::JointBoundValidation::create(robot)); - for (const core::CollisionObjectPtr_t & obs: problem_->collisionObstacles()) { - leafProblem_->addObstacle(obs); - } - leafProblem_->pathProjector(problem->pathProjector()); - } - - InStatePath (const InStatePath& other) : - PathPlanner(other.problem_), - problem_(other.problem_), leafProblem_(other.leafProblem_), - leafRoadmap_ (other.leafRoadmap_), - constraints_(other.constraints_), - weak_ () - {} - - void init (InStatePathWkPtr_t weak) - { - weak_ = weak; - } - - private: - - // a pointer to the problem used to create the InStatePath instance - ProblemConstPtr_t problem_; - // a new problem created for this InStatePath instance - core::ProblemPtr_t leafProblem_; - core::RoadmapPtr_t leafRoadmap_; - ConstraintSetPtr_t constraints_; - - double timeOutPathPlanning_ = 0; - unsigned long maxIterPathPlanning_ = 0; - bool resetRoadmap_ = true; - std::string plannerType_ = "BiRRT*"; - std::vector<std::string> optimizerTypes_; - - /// Weak pointer to itself - InStatePathWkPtr_t weak_; - - }; // class InStatePath - /// \} - - } // namespace pathPlanner - } // namespace manipulation -} // namespace hpp - -#endif // HPP_MANIPULATION_STEERING_METHOD_CROSS_STATE_OPTIMIZATION_HH diff --git a/include/hpp/manipulation/path-planner/states-path-finder.hh b/include/hpp/manipulation/path-planner/states-path-finder.hh index 288414d..9fd0db9 100644 --- a/include/hpp/manipulation/path-planner/states-path-finder.hh +++ b/include/hpp/manipulation/path-planner/states-path-finder.hh @@ -114,11 +114,6 @@ namespace hpp { StatesPathFinderPtr_t copy () const; - core::ProblemConstPtr_t problem() const - { - return problem_; - } - /// create a vector of configurations between two configurations /// \return a Configurations_t from q1 to q2 if found. An empty /// vector if a path could not be built. @@ -139,34 +134,20 @@ namespace hpp { int solveStep(std::size_t wp); Configuration_t configSolved (std::size_t wp) const; - /// Step 7 of the algorithm - core::PathVectorPtr_t pathFromConfigList (std::size_t i) const; - /// deletes from memory the latest working states list, which is used to /// resume finding solutions from that list in case of failure at a /// later step. void reset(); - core::PathVectorPtr_t buildPath (ConfigurationIn_t q1, ConfigurationIn_t q2); virtual void startSolve(); virtual void oneStep(); - virtual core::PathVectorPtr_t solve (); + /// Do nothing + virtual void tryConnectInitAndGoals (); protected: StatesPathFinder (const core::ProblemConstPtr_t& problem, - const core::RoadmapPtr_t&) : - PathPlanner(problem), - problem_ (HPP_STATIC_PTR_CAST(const manipulation::Problem, problem)), - sameRightHandSide_ (), weak_ () - { - gatherGraphConstraints (); - } - - StatesPathFinder (const StatesPathFinder& other) : - PathPlanner(other.problem_), - problem_ (other.problem_), constraints_ (), index_ (other.index_), - sameRightHandSide_ (other.sameRightHandSide_), weak_ () - {} + const core::RoadmapPtr_t&); + StatesPathFinder (const StatesPathFinder& other); void init (StatesPathFinderWkPtr_t weak) { @@ -201,7 +182,7 @@ namespace hpp { bool solveOptimizationProblem (); /// Step 6 of the algorithm - core::Configurations_t buildConfigList () const; + core::Configurations_t getConfigList () const; /// Functions used in assert statements bool checkWaypointRightHandSide (std::size_t ictr, std::size_t jslv) const; @@ -214,30 +195,31 @@ namespace hpp { /// A pointer to the manipulation problem ProblemConstPtr_t problem_; + /// Path planning problem in each leaf. + core::ProblemPtr_t inStateProblem_; /// Vector of parameterizable edge numerical constraints NumericalConstraints_t constraints_; - /// Map of indexes in constraints_ + /// Map of indices in constraints_ std::map < std::string, std::size_t > index_; /// associative map that stores pairs of constraints of the form /// (constraint, constraint/hold) std::map <ImplicitPtr_t, ImplicitPtr_t> sameRightHandSide_; - mutable OptimizationData* optData_ = nullptr; + mutable OptimizationData* optData_; + /// Index of the sequence of states std::size_t idxSol_ = 0; graph::Edges_t lastBuiltTransitions_; - bool skipColAnalysis_ = false; + bool skipColAnalysis_; // Variables used across several calls to oneStep ConfigurationPtr_t q1_, q2_; core::Configurations_t configList_; - std::size_t idxConfigList_ = 0; - size_type nTryConfigList_ = 0; - InStatePathPtr_t planner_; - core::PathVectorPtr_t solution_; - bool solved_ = false, interrupt_ = false; + std::size_t idxConfigList_; + size_type nTryConfigList_; + bool solved_, interrupt_; /// Weak pointer to itself StatesPathFinderWkPtr_t weak_; diff --git a/src/path-planner/in-state-path.cc b/src/path-planner/in-state-path.cc deleted file mode 100644 index 69c065c..0000000 --- a/src/path-planner/in-state-path.cc +++ /dev/null @@ -1,232 +0,0 @@ -// Copyright (c) 2021, Joseph Mirabel -// Authors: Joseph Mirabel (joseph.mirabel@laas.fr), -// Florent Lamiraux (florent.lamiraux@laas.fr) -// Alexandre Thiault (athiault@laas.fr) -// -// This file is part of hpp-manipulation. -// hpp-manipulation is free software: you can redistribute it -// and/or modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation, either version -// 3 of the License, or (at your option) any later version. -// -// hpp-manipulation is distributed in the hope that it will be -// useful, but WITHOUT ANY WARRANTY; without even the implied warranty -// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Lesser Public License for more details. You should have -// received a copy of the GNU Lesser General Public License along with -// hpp-manipulation. If not, see <http://www.gnu.org/licenses/>. - -#include <hpp/manipulation/path-planner/in-state-path.hh> - -#include <hpp/util/exception-factory.hh> - -#include <hpp/pinocchio/configuration.hh> - -#include <hpp/core/path-vector.hh> -#include <hpp/core/roadmap.hh> -#include <hpp/core/edge.hh> - -#include <hpp/core/bi-rrt-planner.hh> -#include <hpp/core/path-planner/k-prm-star.hh> -#include <hpp/core/diffusing-planner.hh> - -#include <hpp/core/path-optimizer.hh> -#include <hpp/core/path-optimization/random-shortcut.hh> -#include <hpp/core/path-optimization/simple-shortcut.hh> -#include <hpp/core/path-optimization/partial-shortcut.hh> -#include <hpp/core/path-optimization/simple-time-parameterization.hh> -#include <hpp/manipulation/path-optimization/random-shortcut.hh> - -#include <hpp/manipulation/graph/edge.hh> -#include <hpp/manipulation/roadmap.hh> - - -namespace hpp { - namespace manipulation { - namespace pathPlanner { - - InStatePathPtr_t InStatePath::create ( - const core::ProblemConstPtr_t& problem) - { - InStatePath* ptr; - RoadmapPtr_t r = Roadmap::create(problem->distance(), problem->robot()); - try { - ProblemConstPtr_t p(HPP_DYNAMIC_PTR_CAST(const Problem, problem)); - ptr = new InStatePath (p, r); - } catch (std::exception&) { - throw std::invalid_argument - ("The problem must be of type hpp::manipulation::Problem."); - } - InStatePathPtr_t shPtr (ptr); - ptr->init (shPtr); - return shPtr; - } - - InStatePathPtr_t InStatePath::createWithRoadmap ( - const core::ProblemConstPtr_t& problem, - const core::RoadmapPtr_t& roadmap) - { - InStatePath* ptr; - core::RoadmapPtr_t r2 = roadmap; - RoadmapPtr_t r; - try { - ProblemConstPtr_t p(HPP_DYNAMIC_PTR_CAST(const Problem, problem)); - r = HPP_DYNAMIC_PTR_CAST (Roadmap, r2); - ptr = new InStatePath (p, r); - } catch (std::exception&) { - if (!r) - throw std::invalid_argument - ("The roadmap must be of type hpp::manipulation::Roadmap."); - else - throw std::invalid_argument - ("The problem must be of type hpp::manipulation::Problem."); - } - InStatePathPtr_t shPtr (ptr); - ptr->init (shPtr); - return shPtr; - } - - InStatePathPtr_t InStatePath::copy () const - { - InStatePath *ptr = new InStatePath(*this); - InStatePathPtr_t shPtr(ptr); - ptr->init(shPtr); - return shPtr; - } - - void InStatePath::maxIterPlanner(const unsigned long& maxiter) - { - maxIterPathPlanning_ = maxiter; - } - - void InStatePath::timeOutPlanner(const double& timeout) - { - timeOutPathPlanning_ = timeout; - } - - void InStatePath::resetRoadmap(const bool& resetroadmap) - { - resetRoadmap_ = resetroadmap; - } - - void InStatePath::plannerType(const std::string& plannertype) - { - plannerType_ = plannertype; - } - - void InStatePath::addOptimizerType(const std::string& opttype) - { - optimizerTypes_.push_back(opttype); - } - - void InStatePath::resetOptimizerTypes() - { - optimizerTypes_.clear(); - } - - void InStatePath::setEdge (const graph::EdgePtr_t& edge) - { - constraints_ = edge->pathConstraint(); - leafProblem_->pathValidation(edge->pathValidation()); - leafProblem_->constraints(constraints_); - leafProblem_->steeringMethod(edge->steeringMethod()); - } - - void InStatePath::setInit (const ConfigurationPtr_t& qinit) - { - if (!constraints_) - throw std::logic_error("Use setEdge before setInit and setGoal"); - constraints_->configProjector()->rightHandSideFromConfig(*qinit); - leafProblem_->initConfig(qinit); - leafProblem_->resetGoalConfigs(); - } - - void InStatePath::setGoal (const ConfigurationPtr_t& qgoal) - { - if (!constraints_) - throw std::logic_error("Use setEdge before setInit and setGoal"); - ConfigurationPtr_t qgoalc (new Configuration_t (*qgoal)); - constraints_->apply(*qgoalc); - assert((*qgoal-*qgoalc).isZero()); - leafProblem_->resetGoalConfigs(); - leafProblem_->addGoalConfig(qgoal); - } - - core::PathVectorPtr_t InStatePath::solve() - { - if (!constraints_) - throw std::logic_error("Use setEdge, setInit and setGoal before solve"); - if (resetRoadmap_ || !leafRoadmap_) - leafRoadmap_ = core::Roadmap::create (leafProblem_->distance(), problem_->robot()); - - core::PathPlannerPtr_t planner; - // TODO: BiRRT* does not work properly: - // - discontinuities due to an algorithmic mistake involving qProj_ - // - not using path projectors, it should - if (plannerType_ == "kPRM*") - planner = core::pathPlanner::kPrmStar::createWithRoadmap(leafProblem_, leafRoadmap_); - else if (plannerType_ == "DiffusingPlanner") - planner = core::DiffusingPlanner::createWithRoadmap(leafProblem_, leafRoadmap_); - else if (plannerType_ == "BiRRT*") - planner = core::BiRRTPlanner::createWithRoadmap(leafProblem_, leafRoadmap_); - else { - hppDout(warning, "Unknown planner type specified. Setting to default DiffusingPlanner"); - planner = core::DiffusingPlanner::createWithRoadmap(leafProblem_, leafRoadmap_); - } - if (maxIterPathPlanning_) - planner->maxIterations(maxIterPathPlanning_); - if (timeOutPathPlanning_) - planner->timeOut(timeOutPathPlanning_); - if (!maxIterPathPlanning_ && !timeOutPathPlanning_) - planner->stopWhenProblemIsSolved(true); - core::PathVectorPtr_t path = planner->solve(); - - for (const std::string& optType: optimizerTypes_) { - namespace manipOpt = pathOptimization; - namespace coreOpt = core::pathOptimization; - PathOptimizerPtr_t optimizer; - if (optType == "RandomShortcut") - optimizer = coreOpt::RandomShortcut::create(problem_); - else if (optType == "SimpleShortcut") - optimizer = coreOpt::SimpleShortcut::create(problem_); - else if (optType == "PartialShortcut") - optimizer = coreOpt::PartialShortcut::create(problem_); - else if (optType == "SimpleTimeParameterization") - optimizer = coreOpt::SimpleTimeParameterization::create(problem_); - else if (optType == "Graph-RandomShortcut") - optimizer = manipOpt::RandomShortcut::create(problem_); - else - continue; - try { - path = optimizer->optimize(path); - } catch (const hpp::Exception& e) { - hppDout(info, "could not optimize " << e.what()); - } - } - return path; - } - - const core::RoadmapPtr_t& InStatePath::leafRoadmap() const - { - return leafRoadmap_; - } - - void InStatePath::mergeLeafRoadmapWith(const core::RoadmapPtr_t& roadmap) const { - std::map<core::NodePtr_t, core::NodePtr_t> cNode; - for (const core::NodePtr_t& node: leafRoadmap_->nodes()) { - cNode[node] = roadmap->addNode(node->configuration()); - } - for (const core::EdgePtr_t& edge: leafRoadmap_->edges()) { - if (edge->path()->length() == 0) - assert (edge->from() == edge->to()); - else - roadmap->addEdges( - cNode[edge->from()], cNode[edge->to()], edge->path()); - } - // TODO this is inefficient because the roadmap recomputes the connected - // component at every step. A merge function should be added in roadmap.cc - } - - } // namespace pathPlanner - } // namespace manipulation -} // namespace hpp diff --git a/src/path-planner/states-path-finder.cc b/src/path-planner/states-path-finder.cc index 92cde65..1cb04b6 100644 --- a/src/path-planner/states-path-finder.cc +++ b/src/path-planner/states-path-finder.cc @@ -35,11 +35,17 @@ #include <hpp/constraints/solver/by-substitution.hh> #include <hpp/constraints/explicit.hh> +#include <hpp/core/diffusing-planner.hh> #include <hpp/core/path-vector.hh> #include <hpp/core/path-planning-failed.hh> +#include <hpp/core/path-projector/progressive.hh> #include <hpp/core/configuration-shooter.hh> #include <hpp/core/collision-validation.hh> #include <hpp/core/collision-validation-report.hh> +#include <hpp/core/problem-target.hh> +#include <hpp/core/path-optimization/random-shortcut.hh> + +#include <hpp/manipulation/constraint-set.hh> #include <hpp/manipulation/graph/edge.hh> #include <hpp/manipulation/graph/state.hh> @@ -63,10 +69,45 @@ namespace hpp { using graph::LockedJoints_t; using graph::segments_t; + static void displayRoadmap(const core::RoadmapPtr_t& roadmap) + { + unsigned i=0; + for (auto cc : roadmap->connectedComponents()){ + hppDout(info, " CC " << i); ++i; + for (auto n : cc->nodes()) { + hppDout(info, pinocchio::displayConfig(*(n->configuration()))); + } + } + } + + StatesPathFinder::StatesPathFinder(const core::ProblemConstPtr_t& problem, + const core::RoadmapPtr_t& roadmap) : + PathPlanner(problem, roadmap), + problem_ (HPP_STATIC_PTR_CAST(const manipulation::Problem, problem)), + constraints_(), index_(), sameRightHandSide_(), optData_(0x0), + idxSol_(0), lastBuiltTransitions_(), skipColAnalysis_(false), + q1_(0x0), q2_(0x0), configList_(), idxConfigList_(0), + nTryConfigList_(0), solved_(false), interrupt_(false), + weak_() + { + gatherGraphConstraints (); + inStateProblem_ = core::Problem::create(problem_->robot()); + core::PathProjectorPtr_t pathProjector + (core::pathProjector::Progressive::create + (inStateProblem_, 1e-2)); + inStateProblem_->pathProjector(pathProjector); + } + + StatesPathFinder::StatesPathFinder (const StatesPathFinder& other) : + PathPlanner(other.problem_), + problem_ (other.problem_), constraints_ (), index_ (other.index_), + sameRightHandSide_ (other.sameRightHandSide_), weak_ () + {} StatesPathFinderPtr_t StatesPathFinder::create ( const core::ProblemConstPtr_t& problem) { + hppDout(info, ""); StatesPathFinder* ptr; RoadmapPtr_t r = Roadmap::create(problem->distance(), problem->robot()); try { @@ -86,20 +127,16 @@ namespace hpp { const core::RoadmapPtr_t& roadmap) { StatesPathFinder* ptr; - core::RoadmapPtr_t r2 = roadmap; // unused - RoadmapPtr_t r; - try { - ProblemConstPtr_t p(HPP_DYNAMIC_PTR_CAST(const Problem, problem)); - r = HPP_DYNAMIC_PTR_CAST (Roadmap, r2); - ptr = new StatesPathFinder (p, r); - } catch (std::exception&) { - if (!r) - throw std::invalid_argument - ("The roadmap must be of type hpp::manipulation::Roadmap."); - else - throw std::invalid_argument - ("The problem must be of type hpp::manipulation::Problem."); - } + ProblemConstPtr_t p = HPP_DYNAMIC_PTR_CAST (const Problem, problem); + RoadmapPtr_t r = HPP_DYNAMIC_PTR_CAST (Roadmap, roadmap); + if (!r) + throw std::invalid_argument + ("The roadmap must be of type hpp::manipulation::Roadmap."); + if (!p) + throw std::invalid_argument + ("The problem must be of type hpp::manipulation::Problem."); + + ptr = new StatesPathFinder (p, r); StatesPathFinderPtr_t shPtr (ptr); ptr->init (shPtr); return shPtr; @@ -325,7 +362,7 @@ namespace hpp { std::vector <bool> isTargetWaypoint; // Waypoints lying in each intermediate state matrix_t waypoint; - Configuration_t q1, q2; + const Configuration_t q1, q2; core::DevicePtr_t robot; // Matrix specifying for each constraint and each waypoint how // the right hand side is initialized in the solver. @@ -466,7 +503,7 @@ namespace hpp { std::ostringstream oss1; oss1.precision (2); std::ostringstream oss2; oss2.precision (2); oss1 << constraints_ [i]->function ().name () << " & "; - + oss1 << "$\\left(\\begin{array}{c} "; for (std::size_t k=0; k<mask.size (); ++k) { oss1 << mask[k] << "\\\\ "; @@ -622,7 +659,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]-> @@ -631,7 +668,7 @@ namespace hpp { const Solver_t& otherSolver = transitions [j+1]-> pathConstraint ()->configProjector ()->solver (); for (std::size_t i = 0; i < constraints_.size (); i++) { - if (d.M_status(i, j-1) == OptimizationData::ABSENT && + if (d.M_status(i, j-1) == OptimizationData::ABSENT && d.M_status(i, j) == OptimizationData::EQUAL_TO_GOAL && !contains(d.solvers[j], constraints_[i]) && otherSolver.contains(constraints_[i])) { @@ -796,7 +833,7 @@ namespace hpp { if (!ok) { hppDout(info, "Analysis found a collision at WP " << wp); return false; - } + } hppDout(info, "Analysis at WP " << wp << " passed after " << tries << " solve tries"); } return true; @@ -884,14 +921,14 @@ namespace hpp { return 3; } return 0; - } + } return 1; } std::string StatesPathFinder::displayConfigsSolved() const { const OptimizationData& d = *optData_; std::ostringstream oss; - oss << "configs = [" << std::endl; + oss << "configs = [" << std::endl; oss << " " << pinocchio::displayConfig(d.q1) << ", # 0" << std::endl; for (size_type j = 0; j < d.waypoint.cols(); j++) oss << " " << pinocchio::displayConfig(d.waypoint.col(j)) << ", # " << j+1 << std::endl; @@ -938,7 +975,7 @@ namespace hpp { wp--; // backtrack: try a new solution for the latest waypoint } while (wp>1 && d.isTargetWaypoint[wp-1]); } - + // Completely reset a solution when too many tries have failed if (wp > 1 && nFails >= nFailsMax) { for (std::size_t k = 2; k <= d.solvers.size(); k++) @@ -982,12 +1019,13 @@ namespace hpp { } displayConfigsSolved(); - displayRhsMatrix (); + // displayRhsMatrix (); return true; } - core::Configurations_t StatesPathFinder::buildConfigList () const + // Get list of configurations from solution of optimization problem + core::Configurations_t StatesPathFinder::getConfigList () const { OptimizationData& d = *optData_; core::Configurations_t pv; @@ -1002,6 +1040,9 @@ namespace hpp { return pv; } + // Loop over all the possible paths in the constraint graph between + // the states of the initial configuration and of the final configurations + // and compute waypoint configurations in each state. core::Configurations_t StatesPathFinder::computeConfigList ( ConfigurationIn_t q1, ConfigurationIn_t q2) { @@ -1038,8 +1079,8 @@ namespace hpp { if (buildOptimizationProblem (transitions)) { lastBuiltTransitions_ = transitions; if (skipColAnalysis_ || analyseOptimizationProblem (transitions)) { - if (solveOptimizationProblem ()) { - core::Configurations_t path = buildConfigList (); + if (solveOptimizationProblem ()) { + core::Configurations_t path = getConfigList (); hppDout (warning, " Solution " << idxSol << ": solved configurations list"); return path; } else { @@ -1062,39 +1103,6 @@ namespace hpp { return empty_path; } - core::PathVectorPtr_t StatesPathFinder::pathFromConfigList (std::size_t i) const - { - hppDout(info, "calling StatesPathFinder::pathFromConfigList for transition " << i); - try { - const Edges_t& transitions = lastBuiltTransitions_; - InStatePathPtr_t planner = InStatePath::create(problem_); - planner->addOptimizerType("Graph-RandomShortcut"); - planner->plannerType("DiffusingPlanner"); - planner->maxIterPlanner(problem_->getParameter - ("StatesPathFinder/innerPlannerMaxIterations").intValue()); - planner->timeOutPlanner(problem_->getParameter - ("StatesPathFinder/innerPlannerTimeOut").floatValue()); - planner->resetRoadmap(true); - ConfigurationPtr_t q1 (new Configuration_t (configSolved(i))); - ConfigurationPtr_t q2 (new Configuration_t (configSolved(i+1))); - hppDout(info, 3); - planner->setEdge(transitions[i]); - hppDout(info, 4); - planner->setInit(q1); - planner->setGoal(q2); - hppDout(info, "calling InStatePath::computePath for transition " << i); - return planner->solve(); - } catch(const core::path_planning_failed&(e)) { - std::ostringstream oss; - oss << "Error " << e.what() << "\n"; - oss << "Solution \"latest\":\nFailed to build path at edge " << i << ": "; - oss << lastBuiltTransitions_[i]->pathConstraint()->name(); - hppDout(warning, oss.str()); - core::PathVectorPtr_t empty; - return empty; - } - } - void StatesPathFinder::reset() { idxSol_ = 0; if (optData_) { @@ -1106,121 +1114,77 @@ namespace hpp { nTryConfigList_ = 0; } - core::PathVectorPtr_t StatesPathFinder::buildPath (ConfigurationIn_t q1, ConfigurationIn_t q2) - { - reset(); - size_type nTry = 0; - size_type nTryMax = problem_->getParameter - ("StatesPathFinder/maxTriesBuildPath").intValue(); - - InStatePathPtr_t planner = InStatePath::create(problem_); - planner->addOptimizerType("Graph-RandomShortcut"); - planner->plannerType("DiffusingPlanner"); - planner->maxIterPlanner(problem_->getParameter - ("StatesPathFinder/innerPlannerMaxIterations").intValue()); - planner->timeOutPlanner(problem_->getParameter - ("StatesPathFinder/innerPlannerTimeOut").floatValue()); - planner->resetRoadmap(true); - - while (true) { - skipColAnalysis_ = (nTryConfigList_ >= 1); // already passed, don't redo it - core::Configurations_t configList = computeConfigList(q1, q2); - if (configList.size() <= 1) {// max depth reached - reset(); - continue; - } - const Edges_t& transitions = lastBuiltTransitions_; - std::size_t i = 0; - try { - core::PathVectorPtr_t ans = core::PathVector::create ( - problem()->robot()->configSize(), problem()->robot()->numberDof()); - for (i = 0; i < configList.size()-1; i++) { - ConfigurationPtr_t q1 (new Configuration_t (configSolved(i))); - ConfigurationPtr_t q2 (new Configuration_t (configSolved(i+1))); - planner->setEdge(transitions[i]); - planner->setInit(q1); - planner->setGoal(q2); - hppDout(info, "calling InStatePath::solve for transition " << i); - ans->concatenate(planner->solve()); - } - hppDout(warning, "Solution " << idxSol_ << ": Success" - << "\n-----------------------------------------------"); - return ans; - } catch(const core::path_planning_failed&(e)) { - std::ostringstream oss; - oss << "Error " << e.what() << "\n"; - oss << "Solution " << idxSol_ << ": Failed to build path at edge " << i << ": "; - oss << lastBuiltTransitions_[i]->name(); - hppDout(warning, oss.str()); - - // Retry nTryMax times to build another solution for the same states list - if (++nTry >= nTryMax) { - nTry = 0; - idxSol_++; - } - } - } - core::PathVectorPtr_t empty; - return empty; - } - void StatesPathFinder::startSolve () { + PathPlanner::startSolve(); assert(problem_); q1_ = problem_->initConfig(); assert(q1_); core::Configurations_t q2s = problem_->goalConfigs(); - assert(q2s.size()); + if (q2s.size() != 1) { + std::ostringstream os; + os << "StatesPathFinder accept one and only one goal configuration, "; + os << q2s.size() << " provided."; + throw std::logic_error(os.str().c_str()); + } q2_ = q2s[0]; reset(); - - planner_ = InStatePath::create(problem_); - planner_->addOptimizerType("Graph-RandomShortcut"); - planner_->plannerType("DiffusingPlanner"); - planner_->maxIterPlanner(problem_->getParameter - ("StatesPathFinder/innerPlannerMaxIterations").intValue()); - planner_->timeOutPlanner(problem_->getParameter - ("StatesPathFinder/innerPlannerTimeOut").floatValue()); - planner_->resetRoadmap(true); } void StatesPathFinder::oneStep () { if (idxConfigList_ == 0) { - solution_ = core::PathVector::create ( - problem()->robot()->configSize(), problem()->robot()->numberDof()); skipColAnalysis_ = (nTryConfigList_ >= 1); // already passed, don't redo it configList_ = computeConfigList(*q1_, *q2_); - roadmap()->clear(); if (configList_.size() <= 1) { // max depth reached reset(); - return; + throw core::path_planning_failed("Maximal depth reached."); } } + ConfigurationPtr_t q1, q2; try { const Edges_t& transitions = lastBuiltTransitions_; - ConfigurationPtr_t q1 (new Configuration_t (configSolved(idxConfigList_))); - ConfigurationPtr_t q2 (new Configuration_t (configSolved(idxConfigList_+1))); - planner_->setEdge(transitions[idxConfigList_]); - planner_->setInit(q1); - planner_->setGoal(q2); - - hppDout(info, "calling InStatePath::solve for transition " << idxConfigList_); - - core::PathVectorPtr_t aux = planner_->solve(); - for (std::size_t r = 0; r < aux->numberPaths()-1; r++) - assert(aux->pathAtRank(r)->end() == aux->pathAtRank(r+1)->initial()); - solution_->concatenate(aux); - planner_->mergeLeafRoadmapWith(roadmap()); - + q1 = ConfigurationPtr_t(new Configuration_t(configSolved + (idxConfigList_))); + q2 = ConfigurationPtr_t(new Configuration_t(configSolved + (idxConfigList_+1))); + const graph::EdgePtr_t& edge(transitions[idxConfigList_]); + // Copy edge constraints + core::ConstraintSetPtr_t constraints(HPP_DYNAMIC_PTR_CAST( + 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); + + core::PathPlannerPtr_t inStatePlanner + (core::DiffusingPlanner::create(inStateProblem_)); + core::PathOptimizerPtr_t inStateOptimizer + (core::pathOptimization::RandomShortcut::create(inStateProblem_)); + inStatePlanner->maxIterations(problem_->getParameter + ("StatesPathFinder/innerPlannerMaxIterations").intValue()); + inStatePlanner->timeOut(problem_->getParameter + ("StatesPathFinder/innerPlannerTimeOut").floatValue()); + hppDout(info, "calling InStatePlanner_.solve for transition " + << idxConfigList_); + + core::PathVectorPtr_t path = inStatePlanner->solve(); + for (std::size_t r = 0; r < path->numberPaths()-1; r++) + assert(path->pathAtRank(r)->end() == + path->pathAtRank(r+1)->initial()); + roadmap()->merge(inStatePlanner->roadmap()); + // core::PathVectorPtr_t opt = inStateOptimizer->optimize(path); + // roadmap()->insertPathVector(opt, true); idxConfigList_++; if (idxConfigList_ == configList_.size()-1) { hppDout(warning, "Solution " << idxSol_ << ": Success" << "\n-----------------------------------------------"); - //solution_ = aux; - solved_ = true; } } catch(const core::path_planning_failed&(e)) { @@ -1241,28 +1205,9 @@ namespace hpp { } } - core::PathVectorPtr_t StatesPathFinder::solve () - { - namespace bpt = boost::posix_time; - - interrupt_ = false; - solved_ = false; - unsigned long int nIter (0); - startSolve (); - if (interrupt_) throw core::path_planning_failed("Interruption"); - while (!solved_) { - // Execute one step - hppStartBenchmark(ONE_STEP); - oneStep (); - hppStopBenchmark(ONE_STEP); - hppDisplayBenchmark(ONE_STEP); - - ++nIter; - //solved = problem()->target()->reached (roadmap()); - if (interrupt_) throw core::path_planning_failed("Interruption"); - } - return solution_; - } + void StatesPathFinder::tryConnectInitAndGoals() + { + } std::vector<std::string> StatesPathFinder::constraintNamesFromSolverAtWaypoint (std::size_t wp) diff --git a/src/problem-solver.cc b/src/problem-solver.cc index f923dc2..d2c1b4c 100644 --- a/src/problem-solver.cc +++ b/src/problem-solver.cc @@ -122,8 +122,6 @@ namespace hpp { pathPlanners.add ("M-RRT", ManipulationPlanner::create); pathPlanners.add ("EndEffectorTrajectory", pathPlanner::EndEffectorTrajectory::createWithRoadmap); pathPlanners.add ("StatesPathFinder", pathPlanner::StatesPathFinder::createWithRoadmap); - pathPlanners.add ("InStatePath", pathPlanner::InStatePath::createWithRoadmap); - pathValidations.add ("Graph-Discretized" , createDiscretizedCollisionGraphPathValidation); pathValidations.add ("Graph-DiscretizedCollision" , createDiscretizedCollisionGraphPathValidation); pathValidations.add ("Graph-DiscretizedJointBound" , createDiscretizedJointBoundGraphPathValidation); -- GitLab