diff --git a/CMakeLists.txt b/CMakeLists.txt index 31ad63123cd7ec377642c3d401bcd3416a269f22..a054a8d2c8dcf440ddb74c30623317f052f11f5d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,6 +64,7 @@ SET (${PROJECT_NAME}_HEADERS include/hpp/manipulation/problem.hh include/hpp/manipulation/problem-solver.hh include/hpp/manipulation/device.hh + include/hpp/manipulation/weighed-distance.hh include/hpp/manipulation/constraint-set.hh include/hpp/manipulation/roadmap.hh include/hpp/manipulation/roadmap-node.hh diff --git a/include/hpp/manipulation/fwd.hh b/include/hpp/manipulation/fwd.hh index c9d1de0a240bf9c06f134b9966e83f22aaa2ee9c..9251a26b2c5b35b63d63f66b4ef80c02fbb1ce19 100644 --- a/include/hpp/manipulation/fwd.hh +++ b/include/hpp/manipulation/fwd.hh @@ -55,6 +55,8 @@ namespace hpp { typedef boost::shared_ptr <Roadmap> RoadmapPtr_t; HPP_PREDEF_CLASS (RoadmapNode); typedef RoadmapNode* RoadmapNodePtr_t; + HPP_PREDEF_CLASS (WeighedDistance); + typedef boost::shared_ptr<WeighedDistance> WeighedDistancePtr_t; typedef constraints::RelativeOrientation RelativeOrientation; typedef constraints::RelativePosition RelativePosition; typedef constraints::RelativeOrientationPtr_t RelativeOrientationPtr_t; diff --git a/include/hpp/manipulation/graph-path-validation.hh b/include/hpp/manipulation/graph-path-validation.hh index 6c3dfc9da18294dbbb15eba1573103a90fb7c58a..92642de15f2670a7c3799592a1c25a2091735cad 100644 --- a/include/hpp/manipulation/graph-path-validation.hh +++ b/include/hpp/manipulation/graph-path-validation.hh @@ -142,9 +142,11 @@ namespace hpp { private: /// Do validation regarding the constraint graph for PathVector - bool impl_validate (const PathVectorPtr_t& path, bool reverse, PathPtr_t& validPart); + bool impl_validate (const PathVectorPtr_t& path, bool reverse, + PathPtr_t& validPart, PathValidationReportPtr_t& report); /// Do validation regarding the constraint graph for Path - bool impl_validate (const PathPtr_t& path, bool reverse, PathPtr_t& validPart); + bool impl_validate (const PathPtr_t& path, bool reverse, + PathPtr_t& validPart, PathValidationReportPtr_t& report); /// The encapsulated PathValidation. PathValidationPtr_t pathValidation_; /// Pointer to the constraint graph. diff --git a/include/hpp/manipulation/graph-steering-method.hh b/include/hpp/manipulation/graph-steering-method.hh index eb5a132b3201e8fc7d05b9838749eb267f768596..22e8a6d206373e365db2a27b8cfa832055b8da19 100644 --- a/include/hpp/manipulation/graph-steering-method.hh +++ b/include/hpp/manipulation/graph-steering-method.hh @@ -20,12 +20,14 @@ # include <hpp/manipulation/config.hh> +# include "hpp/core/problem-solver.hh" // SteeringMethodBuilder_t # include <hpp/core/steering-method.hh> # include <hpp/core/weighed-distance.hh> # include <hpp/model/device.hh> # include "hpp/manipulation/fwd.hh" # include "hpp/manipulation/graph/fwd.hh" +# include "hpp/manipulation/problem.hh" namespace hpp { namespace manipulation { @@ -36,61 +38,73 @@ namespace hpp { class HPP_MANIPULATION_DLLAPI GraphSteeringMethod : public SteeringMethod { + typedef core::SteeringMethodBuilder_t SteeringMethodBuilder_t; + public: - /// Create instance and return shared pointer - static GraphSteeringMethodPtr_t create (const model::DevicePtr_t& robot); - - /// Create copy and return shared pointer - static GraphSteeringMethodPtr_t createCopy - (const GraphSteeringMethodPtr_t& other); - /// Copy instance and return shared pointer - virtual core::SteeringMethodPtr_t copy () const - { - return createCopy (weak_.lock ()); - } - /// \name Graph of constraints applicable to the robot. - /// \{ - - /// Set constraint graph - void constraintGraph (const graph::GraphPtr_t& graph) + /// Create instance and return shared pointer + /// \warning core::ProblemPtr_t will be casted to ProblemPtr_t + static GraphSteeringMethodPtr_t create + (const core::ProblemPtr_t& problem); + + template <typename T> + static GraphSteeringMethodPtr_t create + (const core::ProblemPtr_t& problem); + + /// Create instance and return shared pointer + static GraphSteeringMethodPtr_t create (const ProblemPtr_t& problem); + + /// Create copy and return shared pointer + static GraphSteeringMethodPtr_t createCopy + (const GraphSteeringMethodPtr_t& other); + + /// Copy instance and return shared pointer + virtual core::SteeringMethodPtr_t copy () const { - graph_ = graph; + return createCopy (weak_.lock ()); } - /// Get constraint graph - const graph::GraphPtr_t& constraintGraph () const + const core::SteeringMethodPtr_t& innerSteeringMethod () const { - return graph_; + return steeringMethod_; } - /// \} - const core::WeighedDistancePtr_t& distance () const; + void innerSteeringMethod (const core::SteeringMethodPtr_t& sm) + { + steeringMethod_ = sm; + } protected: /// Constructor - GraphSteeringMethod (const model::DevicePtr_t& robot); + GraphSteeringMethod (const ProblemPtr_t& problem); /// Copy constructor GraphSteeringMethod (const GraphSteeringMethod&); virtual PathPtr_t impl_compute (ConfigurationIn_t q1, ConfigurationIn_t q2) const; - void init (GraphSteeringMethodWkPtr_t weak) - { - core::SteeringMethod::init (weak); - weak_ = weak; - } + void init (GraphSteeringMethodWkPtr_t weak) + { + core::SteeringMethod::init (weak); + weak_ = weak; + } private: - /// A pointer to the graph of constraint. - graph::GraphPtr_t graph_; - /// Pointer to the Robot. - core::DeviceWkPtr_t robot_; - /// Metric in configuration space. - core::WeighedDistancePtr_t distance_; - /// Weak pointer to itself - GraphSteeringMethodWkPtr_t weak_; + /// A pointer to the problem + ProblemPtr_t problem_; + /// Weak pointer to itself + GraphSteeringMethodWkPtr_t weak_; + /// The encapsulated steering method + core::SteeringMethodPtr_t steeringMethod_; }; + + template <typename T> + GraphSteeringMethodPtr_t GraphSteeringMethod::create + (const core::ProblemPtr_t& problem) + { + GraphSteeringMethodPtr_t gsm = GraphSteeringMethod::create (problem); + gsm->innerSteeringMethod (T::create (problem)); + return gsm; + } /// \} } // namespace manipulation } // namespace hpp diff --git a/include/hpp/manipulation/graph/edge.hh b/include/hpp/manipulation/graph/edge.hh index 65098c2a962a1e0794f9a3e2a36b4fd881aea62d..4b5f32867a8e20d01064887f135d3ba5e49ead3f 100644 --- a/include/hpp/manipulation/graph/edge.hh +++ b/include/hpp/manipulation/graph/edge.hh @@ -18,7 +18,7 @@ # define HPP_MANIPULATION_GRAPH_EDGE_HH #include <hpp/core/constraint-set.hh> -#include <hpp/core/weighed-distance.hh> +#include <hpp/core/steering-method.hh> #include <hpp/core/path.hh> #include "hpp/manipulation/config.hh" @@ -65,7 +65,6 @@ namespace hpp { /// Create a new empty Edge. static EdgePtr_t create (const std::string& name, - const core::SteeringMethodPtr_t& steeringMethod, const GraphWkPtr_t& graph, const NodeWkPtr_t& from, const NodeWkPtr_t& to); @@ -74,7 +73,10 @@ namespace hpp { virtual bool applyConstraints (ConfigurationIn_t qoffset, ConfigurationOut_t q) const; - virtual bool build (core::PathPtr_t& path, ConfigurationIn_t q1, ConfigurationIn_t q2, const core::WeighedDistance& d) const; + virtual bool canConnect (ConfigurationIn_t q1, ConfigurationIn_t q2) const; + + virtual bool build (core::PathPtr_t& path, ConfigurationIn_t q1, + ConfigurationIn_t q2) const; /// Get the destination NodePtr_t to () const; @@ -97,7 +99,7 @@ namespace hpp { /// Get steering method associated to the edge. const core::SteeringMethodPtr_t& steeringMethod () const { - return steeringMethod_; + return steeringMethod_->get(); } /// Get direction of the path compare to the edge @@ -126,8 +128,7 @@ namespace hpp { const NodeWkPtr_t& to); /// Constructor - Edge (const std::string& name, - const core::SteeringMethodPtr_t& steeringMethod); + Edge (const std::string& name); /// Constraint to project a path. /// \return The initialized constraint. @@ -144,6 +145,7 @@ namespace hpp { private: typedef Cache < ConstraintSetPtr_t > Constraint_t; + typedef Cache < core::SteeringMethodPtr_t > SteeringMethod_t; /// See pathConstraint member function. Constraint_t* pathConstraints_; @@ -159,7 +161,7 @@ namespace hpp { bool isInNodeFrom_; /// Steering method used to create paths associated to the edge - core::SteeringMethodPtr_t steeringMethod_; + SteeringMethod_t* steeringMethod_; /// Weak pointer to itself. EdgeWkPtr_t wkPtr_; @@ -199,13 +201,14 @@ namespace hpp { /// Create a new WaypointEdge. static WaypointEdgePtr_t create (const std::string& name, - const core::SteeringMethodPtr_t& steeringMethod, const GraphWkPtr_t& graph, const NodeWkPtr_t& from, const NodeWkPtr_t& to); virtual bool direction (const core::PathPtr_t& path) const; - virtual bool build (core::PathPtr_t& path, ConfigurationIn_t q1, ConfigurationIn_t q2, const core::WeighedDistance& d) const; + virtual bool canConnect (ConfigurationIn_t q1, ConfigurationIn_t q2) const; + + virtual bool build (core::PathPtr_t& path, ConfigurationIn_t q1, ConfigurationIn_t q2) const; virtual bool applyConstraints (ConfigurationIn_t qoffset, ConfigurationOut_t q) const; @@ -229,9 +232,8 @@ namespace hpp { NodePtr_t node () const; protected: - WaypointEdge (const std::string& name, - const core::SteeringMethodPtr_t& steeringMethod) : - Edge (name, steeringMethod) + WaypointEdge (const std::string& name) : + Edge (name) { } /// Initialization of the object. @@ -259,7 +261,6 @@ namespace hpp { /// Create a new LevelSetEdge. static LevelSetEdgePtr_t create (const std::string& name, - const core::SteeringMethodPtr_t& steeringMethod, const GraphWkPtr_t& graph, const NodeWkPtr_t& from, const NodeWkPtr_t& to); @@ -287,8 +288,7 @@ namespace hpp { void init (const LevelSetEdgeWkPtr_t& weak, const GraphWkPtr_t& graph, const NodeWkPtr_t& from, const NodeWkPtr_t& to); - LevelSetEdge (const std::string& name, - const core::SteeringMethodPtr_t& steeringMethod); + LevelSetEdge (const std::string& name); /// Print the object in a stream. virtual std::ostream& print (std::ostream& os) const; diff --git a/include/hpp/manipulation/graph/graph.hh b/include/hpp/manipulation/graph/graph.hh index 3fb85bbefd7ea7f602876d023b50da494c09e274..86f1d0b5bd125a3598bac57e05a7b43e20247adb 100644 --- a/include/hpp/manipulation/graph/graph.hh +++ b/include/hpp/manipulation/graph/graph.hh @@ -45,9 +45,9 @@ namespace hpp { /// Create a new Graph. /// /// \param robot a manipulation robot - /// \param sm a steering method to create paths from edges + /// \param problem a pointer to the problem static GraphPtr_t create(const std::string& name, DevicePtr_t robot, - const core::SteeringMethodPtr_t& sm); + const ProblemPtr_t& problem); /// Create and insert a NodeSelector inside the graph. NodeSelectorPtr_t createNodeSelector (const std::string& name); @@ -119,7 +119,7 @@ namespace hpp { const DevicePtr_t& robot () const; /// Get the steering Method - const core::SteeringMethodPtr_t& steeringMethod () const; + const ProblemPtr_t& problem () const; /// Print the component in DOT language. virtual std::ostream& dotPrint (std::ostream& os, dot::DrawingAttributes da = dot::DrawingAttributes ()) const; @@ -130,8 +130,8 @@ namespace hpp { /// Constructor /// \param sm a steering method to create paths from edges - Graph (const std::string& name, const core::SteeringMethodPtr_t& sm) : - GraphComponent (name), steeringMethod_ (sm) + Graph (const std::string& name, const ProblemPtr_t& problem) : + GraphComponent (name), problem_ (problem) {} /// Print the object in a stream. @@ -160,7 +160,7 @@ namespace hpp { typedef std::map < EdgePtr_t, ConstraintSetPtr_t > MapFromEdge; typedef std::pair < EdgePtr_t, ConstraintSetPtr_t > PairEdgeConstraints; MapFromEdge cfgConstraintSetMapFromEdge_, pathConstraintSetMapFromEdge_; - core::SteeringMethodPtr_t steeringMethod_; + ProblemPtr_t problem_; value_type errorThreshold_; size_type maxIterations_; }; // Class Graph diff --git a/include/hpp/manipulation/graph/node.hh b/include/hpp/manipulation/graph/node.hh index c59d0280724d528d9a04ff722290ef954691d5e5..fb78a4caca5d31ee7dfa0e82ea3b8d779cc6c3f0 100644 --- a/include/hpp/manipulation/graph/node.hh +++ b/include/hpp/manipulation/graph/node.hh @@ -45,7 +45,6 @@ namespace hpp { public: typedef boost::function < EdgePtr_t (const std::string&, - const core::SteeringMethodPtr_t&, const GraphWkPtr_t&, const NodeWkPtr_t&, const NodeWkPtr_t&) > EdgeFactory; diff --git a/include/hpp/manipulation/manipulation-planner.hh b/include/hpp/manipulation/manipulation-planner.hh index d3acc285331ebadc8baf8e6ee6bceec7e35de811..429b7059f22358cdccf59b56d15ff7e7de06dca6 100644 --- a/include/hpp/manipulation/manipulation-planner.hh +++ b/include/hpp/manipulation/manipulation-planner.hh @@ -46,12 +46,12 @@ namespace hpp { /// One step of extension. /// - /// A set of constraints is choosen using the graph of constraints. - /// A constraint extension is done using a choosen set. + /// A set of constraints is chosen using the graph of constraints. + /// A constraint extension is done using a chosen set. /// virtual void oneStep (); - /// Extend a the configuration q_near toward q_rand. + /// Extend configuration q_near toward q_rand. /// \param q_near the configuration to be extended. /// \param q_rand the configuration toward extension is performed. /// \retval validPath the longest valid path (possibly of length 0), @@ -69,8 +69,12 @@ namespace hpp { void init (const ManipulationPlannerWkPtr_t& weak); private: - /// Try to connect configurations in a list. - void tryConnect (const core::Nodes_t nodes); + /// Try to connect nodes of the roadmap to other connected components. + /// \return the number of connection made. + std::size_t tryConnectToRoadmap (const core::Nodes_t nodes); + /// Try to connect nodes in a list between themselves. + /// \return the number of connection made. + std::size_t tryConnectNewNodes (const core::Nodes_t nodes); /// Configuration shooter ConfigurationShooterPtr_t shooter_; @@ -124,6 +128,8 @@ namespace hpp { void addFailure (TypeOfFailure t, const graph::EdgePtr_t& edge); + const value_type extendStep_; + mutable Configuration_t qProj_; }; /// \} diff --git a/include/hpp/manipulation/problem.hh b/include/hpp/manipulation/problem.hh index 3860f3afbf672ee7df7ad61d2cb59a52cff7e065..f7384192ae5d18935f89a34d44737c86acd3c0c2 100644 --- a/include/hpp/manipulation/problem.hh +++ b/include/hpp/manipulation/problem.hh @@ -19,11 +19,10 @@ # include <hpp/core/problem.hh> +# include "hpp/manipulation/fwd.hh" # include "hpp/manipulation/device.hh" # include "hpp/manipulation/graph/graph.hh" # include "hpp/manipulation/graph-path-validation.hh" -# include "hpp/manipulation/graph-steering-method.hh" -# include "hpp/manipulation/fwd.hh" namespace hpp { namespace manipulation { @@ -36,20 +35,10 @@ namespace hpp { typedef core::Problem Parent; /// Constructor - Problem (DevicePtr_t robot) : Parent (robot), - graph_(), steeringMethod_ (GraphSteeringMethod::create (robot)) - { - Parent::steeringMethod (steeringMethod_); - } + Problem (DevicePtr_t robot); /// Set the graph of constraints - void constraintGraph (const graph::GraphPtr_t& graph) - { - graph_ = graph; - steeringMethod_->constraintGraph (graph); - if (pathValidation ()) - pathValidation ()->constraintGraph (graph); - } + void constraintGraph (const graph::GraphPtr_t& graph); /// Get the graph of constraints graph::GraphPtr_t constraintGraph () const @@ -70,22 +59,14 @@ namespace hpp { } /// Get the path validation as a GraphPathValidation - GraphPathValidationPtr_t pathValidation () const - { - return HPP_DYNAMIC_PTR_CAST (GraphPathValidation, Parent::pathValidation()); - } + GraphPathValidationPtr_t pathValidation () const; /// Get the steering method as a GraphSteeringMethod - GraphSteeringMethodPtr_t steeringMethod () const - { - return steeringMethod_; - } + GraphSteeringMethodPtr_t steeringMethod () const; private: /// The graph of constraints graph::GraphPtr_t graph_; - /// Steering method - GraphSteeringMethodPtr_t steeringMethod_; }; // class Problem /// \} } // namespace manipulation diff --git a/include/hpp/manipulation/weighed-distance.hh b/include/hpp/manipulation/weighed-distance.hh new file mode 100644 index 0000000000000000000000000000000000000000..472a6d57540c81538f1af640acd3d22e53541871 --- /dev/null +++ b/include/hpp/manipulation/weighed-distance.hh @@ -0,0 +1,75 @@ +// Copyright (c) 2015 CNRS +// Authors: Joseph Mirabel +// +// 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_DISTANCE_HH +# define HPP_MANIPULATION_DISTANCE_HH + +# include <hpp/core/weighed-distance.hh> +# include <hpp/manipulation/fwd.hh> +# include <hpp/manipulation/graph/fwd.hh> +# include <hpp/manipulation/config.hh> + +namespace hpp { + namespace manipulation { + /// \addtogroup steering_method + /// \{ + + /// Class for distance between configurations + class HPP_MANIPULATION_DLLAPI WeighedDistance : public core::WeighedDistance + { + public: + static WeighedDistancePtr_t create (const DevicePtr_t& robot, + const graph::GraphPtr_t& graph); + + static WeighedDistancePtr_t createCopy + (const WeighedDistancePtr_t& distance); + + virtual core::DistancePtr_t clone () const; + + /// Set the graph of constraints + void constraintGraph (const graph::GraphPtr_t& graph) + { + graph_ = graph; + } + + /// Get the graph of constraints + graph::GraphPtr_t constraintGraph () const + { + return graph_; + } + + protected: + WeighedDistance (const DevicePtr_t& robot, const graph::GraphPtr_t graph); + + WeighedDistance (const WeighedDistance& distance); + + /// Derived class should implement this function + virtual value_type impl_distance ( + ConfigurationIn_t q1, ConfigurationIn_t q2) const; + virtual value_type impl_distance ( + core::NodePtr_t n1, core::NodePtr_t n2) const; + + void init (WeighedDistanceWkPtr_t self); + + private: + graph::GraphPtr_t graph_; + WeighedDistanceWkPtr_t weak_; + }; // class Distance + /// \} + } // namespace manipulation +} // namespace hpp +#endif // HPP_MANIPULATION_DISTANCE_HH diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b15985e242af674bee8d3e497671ee1edfee77fb..f5920d83a9f4aeecdc332ef17b73f18e7ec52cb3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -28,6 +28,8 @@ ADD_LIBRARY(${LIBRARY_NAME} SHARED constraint-set.cc roadmap-node.cc device.cc + weighed-distance.cc + problem.cc graph-path-validation.cc graph-steering-method.cc graph-optimizer.cc diff --git a/src/graph-path-validation.cc b/src/graph-path-validation.cc index 292dff7d9804f4aef07c1cb0a39423ba9fe1c487..46f24dc023f32a3096fc605aefacb34587ffa6a6 100644 --- a/src/graph-path-validation.cc +++ b/src/graph-path-validation.cc @@ -32,7 +32,8 @@ namespace hpp { const PathPtr_t& path, bool reverse, PathPtr_t& validPart) { assert (path); - bool success = impl_validate (path, reverse, validPart); + PathValidationReportPtr_t report; + bool success = impl_validate (path, reverse, validPart, report); assert (constraintGraph_); assert (constraintGraph_->getNode (validPart->initial ())); assert (constraintGraph_->getNode (validPart->end ())); @@ -44,19 +45,20 @@ namespace hpp { ValidationReport&) { assert (path); - return impl_validate (path, reverse, validPart); + PathValidationReportPtr_t report; + return impl_validate (path, reverse, validPart, report); } bool GraphPathValidation::validate (const PathPtr_t& path, bool reverse, PathPtr_t& validPart, - PathValidationReportPtr_t&) + PathValidationReportPtr_t& report) { assert (path); - return impl_validate (path, reverse, validPart); + return impl_validate (path, reverse, validPart, report); } - bool GraphPathValidation::impl_validate ( - const PathVectorPtr_t& path, bool reverse, PathPtr_t& validPart) + bool GraphPathValidation::impl_validate (const PathVectorPtr_t& path, + bool reverse, PathPtr_t& validPart, PathValidationReportPtr_t& report) { PathPtr_t validSubPart; if (reverse) { @@ -64,7 +66,7 @@ namespace hpp { assert (!reverse && "This has never been tested with reverse path"); for (long int i = path->numberPaths () - 1; i >= 0; i--) { // We should stop at the first non valid subpath. - if (!impl_validate (path->pathAtRank (i), true, validSubPart)) { + if (!impl_validate (path->pathAtRank (i), true, validSubPart, report)) { PathVectorPtr_t p = PathVector::create (path->outputSize(), path->outputDerivativeSize()); for (long int v = path->numberPaths () - 1; v > i; v--) @@ -78,7 +80,7 @@ namespace hpp { } else { for (size_t i = 0; i != path->numberPaths (); i++) { // We should stop at the first non valid subpath. - if (!impl_validate (path->pathAtRank (i), false, validSubPart)) { + if (!impl_validate (path->pathAtRank (i), false, validSubPart, report)) { PathVectorPtr_t p = PathVector::create (path->outputSize(), path->outputDerivativeSize()); for (size_t v = 0; v < i; v++) @@ -95,15 +97,14 @@ namespace hpp { return true; } - bool GraphPathValidation::impl_validate ( - const PathPtr_t& path, bool reverse, PathPtr_t& validPart) + bool GraphPathValidation::impl_validate (const PathPtr_t& path, + bool reverse, PathPtr_t& validPart, PathValidationReportPtr_t& report) { PathVectorPtr_t pathVector = HPP_DYNAMIC_PTR_CAST(PathVector, path); if (pathVector) - return impl_validate (pathVector, reverse, validPart); + return impl_validate (pathVector, reverse, validPart, report); PathPtr_t pathNoCollision; - PathValidationReportPtr_t report; if (pathValidation_->validate (path, reverse, pathNoCollision, report)) { validPart = path; return true; diff --git a/src/graph-steering-method.cc b/src/graph-steering-method.cc index 10f18719b287d18044f12201de1ac1049fc10100..381d301a69b2866fcb128ae008dd4d994d546023 100644 --- a/src/graph-steering-method.cc +++ b/src/graph-steering-method.cc @@ -16,6 +16,9 @@ #include "hpp/manipulation/graph-steering-method.hh" +#include <hpp/util/pointer.hh> + +#include <hpp/core/distance.hh> #include <hpp/core/straight-path.hh> #include "hpp/manipulation/graph/graph.hh" @@ -24,9 +27,18 @@ namespace hpp { namespace manipulation { GraphSteeringMethodPtr_t GraphSteeringMethod::create - (const model::DevicePtr_t& robot) + (const core::ProblemPtr_t& problem) + { + assert (dynamic_cast <const ProblemPtr_t> (problem) != NULL + && "Cast to const ProblemPtr_t failed"); + const ProblemPtr_t& p = static_cast <const ProblemPtr_t> (problem); + return create (p); + } + + GraphSteeringMethodPtr_t GraphSteeringMethod::create + (const ProblemPtr_t& problem) { - GraphSteeringMethod* ptr = new GraphSteeringMethod (robot); + GraphSteeringMethod* ptr = new GraphSteeringMethod (problem); GraphSteeringMethodPtr_t shPtr (ptr); ptr->init (shPtr); return shPtr; @@ -41,40 +53,34 @@ namespace hpp { return shPtr; } - GraphSteeringMethod::GraphSteeringMethod (const model::DevicePtr_t& robot) : - SteeringMethod (), graph_ (), robot_ (robot), - distance_ (core::WeighedDistance::create (robot)), weak_ () + GraphSteeringMethod::GraphSteeringMethod (const ProblemPtr_t& problem) : + SteeringMethod (problem), problem_ (problem), weak_ () { } GraphSteeringMethod::GraphSteeringMethod (const GraphSteeringMethod& other): - SteeringMethod (other), graph_ (other.graph_), robot_ (other.robot_), - distance_ (other.distance_) + SteeringMethod (other), problem_ (other.problem_) { } PathPtr_t GraphSteeringMethod::impl_compute (ConfigurationIn_t q1, ConfigurationIn_t q2) const { graph::Edges_t possibleEdges; + graph::Graph& graph = *problem_->constraintGraph (); try { - possibleEdges = graph_->getEdges (graph_->getNode (q1), graph_->getNode (q2)); + possibleEdges = graph.getEdges (graph.getNode (q1), graph.getNode (q2)); } catch (const std::logic_error& e) { hppDout (error, e.what ()); return PathPtr_t (); } PathPtr_t path; while (!possibleEdges.empty()) { - if (possibleEdges.back ()->build (path, q1, q2, *distance_)) { + if (possibleEdges.back ()->build (path, q1, q2)) { return path; } possibleEdges.pop_back (); } return PathPtr_t (); } - - const core::WeighedDistancePtr_t& GraphSteeringMethod::distance () const - { - return distance_; - } } // namespace manipulation } // namespace hpp diff --git a/src/graph/edge.cc b/src/graph/edge.cc index 84c6e4b874bd16bcb10e292b6d4ad53ef8ecf88a..1c2089f94d6c27c18424205f52b4539407ee7a15 100644 --- a/src/graph/edge.cc +++ b/src/graph/edge.cc @@ -18,7 +18,6 @@ #include <sstream> -#include <hpp/core/steering-method.hh> #include <hpp/core/path-vector.hh> #include <hpp/constraints/differentiable-function.hh> @@ -26,24 +25,26 @@ #include <hpp/util/pointer.hh> #include "hpp/manipulation/device.hh" +#include "hpp/manipulation/problem.hh" +#include "hpp/manipulation/graph-steering-method.hh" #include "hpp/manipulation/graph/statistics.hh" #include "hpp/manipulation/constraint-set.hh" namespace hpp { namespace manipulation { namespace graph { - Edge::Edge (const std::string& name, - const core::SteeringMethodPtr_t& steeringMethod) : + Edge::Edge (const std::string& name) : GraphComponent (name), isShort_ (false), pathConstraints_ (new Constraint_t()), configConstraints_ (new Constraint_t()), - steeringMethod_ (steeringMethod->copy ()) + steeringMethod_ (new SteeringMethod_t()) {} Edge::~Edge () { if (pathConstraints_ ) delete pathConstraints_; if (configConstraints_) delete configConstraints_; + if (steeringMethod_ ) delete steeringMethod_; } NodePtr_t Edge::to () const @@ -151,11 +152,10 @@ namespace hpp { } EdgePtr_t Edge::create (const std::string& name, - const core::SteeringMethodPtr_t& steeringMethod, const GraphWkPtr_t& graph, const NodeWkPtr_t& from, const NodeWkPtr_t& to) { - Edge* ptr = new Edge (name, steeringMethod); + Edge* ptr = new Edge (name); EdgePtr_t shPtr (ptr); ptr->init(shPtr, graph, from, to); return shPtr; @@ -226,7 +226,6 @@ namespace hpp { if (!*pathConstraints_) { ConstraintSetPtr_t pathConstraints (buildPathConstraint ()); pathConstraints_->set (pathConstraints); - steeringMethod_->constraints (pathConstraints); } return pathConstraints_->get (); } @@ -249,11 +248,27 @@ namespace hpp { node ()->insertLockedJoints (proj); constraint->edge (wkPtr_.lock ()); + + // Build steering method + steeringMethod_->set(g->problem()->steeringMethod() + ->innerSteeringMethod()->copy()); + steeringMethod_->get()->constraints (constraint); return constraint; } + bool Edge::canConnect (ConfigurationIn_t q1, ConfigurationIn_t q2) + const + { + ConstraintSetPtr_t constraints = pathConstraint (); + constraints->configProjector ()->rightHandSideFromConfig(q1); + if (!constraints->isSatisfied (q1) || !constraints->isSatisfied (q2)) { + return false; + } + return true; + } + bool Edge::build (core::PathPtr_t& path, ConfigurationIn_t q1, - ConfigurationIn_t q2, const core::WeighedDistance&) + ConfigurationIn_t q2) const { ConstraintSetPtr_t constraints = pathConstraint (); @@ -261,7 +276,7 @@ namespace hpp { if (!constraints->isSatisfied (q1) || !constraints->isSatisfied (q2)) { return false; } - path = (*steeringMethod_) (q1, q2); + path = (*steeringMethod_->get()) (q1, q2); return true; } @@ -290,12 +305,11 @@ namespace hpp { return false; } - WaypointEdgePtr_t WaypointEdge::create - (const std::string& name, const core::SteeringMethodPtr_t& steeringMethod, + WaypointEdgePtr_t WaypointEdge::create (const std::string& name, const GraphWkPtr_t& graph, const NodeWkPtr_t& from, const NodeWkPtr_t& to) { - WaypointEdge* ptr = new WaypointEdge (name, steeringMethod); + WaypointEdge* ptr = new WaypointEdge (name); WaypointEdgePtr_t shPtr (ptr); ptr->init(shPtr, graph, from, to); return shPtr; @@ -308,7 +322,13 @@ namespace hpp { wkPtr_ = weak; } - bool WaypointEdge::build (core::PathPtr_t& path, ConfigurationIn_t q1, ConfigurationIn_t q2, const core::WeighedDistance& d) const + bool WaypointEdge::canConnect (ConfigurationIn_t q1, ConfigurationIn_t q2) const + { + return waypoint_.first->canConnect (q1, q2) && Edge::canConnect (q1, q2); + } + + bool WaypointEdge::build (core::PathPtr_t& path, ConfigurationIn_t q1, + ConfigurationIn_t q2) const { assert (waypoint_.first); core::PathPtr_t pathToWaypoint; @@ -317,7 +337,7 @@ namespace hpp { if (!result_.isApprox (q2)) config_ = q2; if (!waypoint_.first->applyConstraints (q1, config_)) return false; - if (!waypoint_.first->build (pathToWaypoint, q1, config_, d)) + if (!waypoint_.first->build (pathToWaypoint, q1, config_)) return false; core::PathVectorPtr_t pv = HPP_DYNAMIC_PTR_CAST (core::PathVector, pathToWaypoint); if (!pv) { @@ -329,7 +349,7 @@ namespace hpp { path = pv; core::PathPtr_t end; - if (!Edge::build (end, config_, q2, d)) + if (!Edge::build (end, config_, q2)) return false; pv->appendPath (end); return true; @@ -358,12 +378,12 @@ namespace hpp { ss.str (std::string ()); ss.clear (); ss << bname << "_e" << d; if (d == 0) { - edge = Edge::create (ss.str (), steeringMethod (), graph_, from (), + edge = Edge::create (ss.str (), graph_, from (), node); edge->isInNodeFrom (isInNodeFrom ()); } else { WaypointEdgePtr_t we = WaypointEdge::create - (ss.str (), steeringMethod (), graph_, from (), node); + (ss.str (), graph_, from (), node); we->createWaypoint (d-1, bname); edge = we; edge->isInNodeFrom (isInNodeFrom ()); @@ -499,11 +519,10 @@ namespace hpp { } LevelSetEdgePtr_t LevelSetEdge::create - (const std::string& name, const core::SteeringMethodPtr_t& steeringMethod, - const GraphWkPtr_t& graph, const NodeWkPtr_t& from, - const NodeWkPtr_t& to) + (const std::string& name, const GraphWkPtr_t& graph, + const NodeWkPtr_t& from, const NodeWkPtr_t& to) { - LevelSetEdge* ptr = new LevelSetEdge (name, steeringMethod); + LevelSetEdge* ptr = new LevelSetEdge (name); LevelSetEdgePtr_t shPtr (ptr); ptr->init(shPtr, graph, from, to); return shPtr; @@ -592,9 +611,8 @@ namespace hpp { } LevelSetEdge::LevelSetEdge - (const std::string& name, - const core::SteeringMethodPtr_t& steeringMethod) : - Edge (name, steeringMethod), extraConstraints_ (new Constraint_t()) + (const std::string& name) : + Edge (name), extraConstraints_ (new Constraint_t()) { } diff --git a/src/graph/graph.cc b/src/graph/graph.cc index db6fa6e16276bab2478bd20ab2c8fa71bf2debcd..fc8385ec35615090cfc8401ac919bf15f6919e5b 100644 --- a/src/graph/graph.cc +++ b/src/graph/graph.cc @@ -27,9 +27,9 @@ namespace hpp { namespace manipulation { namespace graph { GraphPtr_t Graph::create(const std::string& name, DevicePtr_t robot, - const core::SteeringMethodPtr_t& sm) + const ProblemPtr_t& problem) { - Graph* ptr = new Graph (name, sm); + Graph* ptr = new Graph (name, problem); GraphPtr_t shPtr (ptr); ptr->init (shPtr, robot); return shPtr; @@ -80,9 +80,9 @@ namespace hpp { return robot_; } - const core::SteeringMethodPtr_t& Graph::steeringMethod () const + const ProblemPtr_t& Graph::problem () const { - return steeringMethod_; + return problem_; } NodePtr_t Graph::getNode (ConfigurationIn_t config) const diff --git a/src/graph/node.cc b/src/graph/node.cc index 6a1e3d855fe0b267351aa6a7d651d73d5adb1d37..598a43a755e9cf293eb8a25e79493a44ac5dbce2 100644 --- a/src/graph/node.cc +++ b/src/graph/node.cc @@ -53,8 +53,7 @@ namespace hpp { const Weight_t& w, const bool& isInNodeFrom, EdgeFactory create) { - EdgePtr_t newEdge = create(name, graph_.lock ()->steeringMethod (), - graph_, wkPtr_, to); + EdgePtr_t newEdge = create(name, graph_, wkPtr_, to); neighbors_.insert (newEdge, w); newEdge->isInNodeFrom (isInNodeFrom); return newEdge; diff --git a/src/manipulation-planner.cc b/src/manipulation-planner.cc index 1057f65469655aa5d8fc394a1a385345f541c839..fcb8dbbcba421315ce66223a3c0532620e907a26 100644 --- a/src/manipulation-planner.cc +++ b/src/manipulation-planner.cc @@ -26,6 +26,7 @@ #include <hpp/core/connected-component.hh> #include <hpp/core/path-projector.hh> #include <hpp/core/projection-error.hh> +#include <hpp/core/nearest-neighbor.hh> #include "hpp/manipulation/graph/statistics.hh" #include "hpp/manipulation/device.hh" @@ -154,12 +155,18 @@ namespace hpp { HPP_STOP_TIMECOUNTER(delayedEdges); // Try to connect the new nodes together - HPP_START_TIMECOUNTER(tryConnect); - tryConnect (newNodes); - HPP_STOP_TIMECOUNTER(tryConnect); + HPP_START_TIMECOUNTER(tryConnectNewNodes); + const std::size_t nbConn = tryConnectNewNodes (newNodes); + HPP_STOP_TIMECOUNTER(tryConnectNewNodes); + HPP_DISPLAY_LAST_TIMECOUNTER(tryConnectNewNodes); + if (nbConn == 0) { + HPP_START_TIMECOUNTER(tryConnectToRoadmap); + tryConnectToRoadmap (newNodes); + HPP_STOP_TIMECOUNTER(tryConnectToRoadmap); + HPP_DISPLAY_LAST_TIMECOUNTER(tryConnectToRoadmap); + } HPP_STOP_TIMECOUNTER(oneStep); HPP_DISPLAY_LAST_TIMECOUNTER(oneStep); - HPP_DISPLAY_LAST_TIMECOUNTER(tryConnect); HPP_DISPLAY_TIMECOUNTER(oneStep); HPP_DISPLAY_TIMECOUNTER(extend); HPP_DISPLAY_TIMECOUNTER(tryConnect); @@ -195,10 +202,9 @@ namespace hpp { return false; } HPP_STOP_TIMECOUNTER (applyConstraints); - GraphSteeringMethodPtr_t sm = problem_.steeringMethod(); core::PathPtr_t path; HPP_START_TIMECOUNTER (buildPath); - if (!edge->build (path, *q_near, qProj_, *(sm->distance ()))) { + if (!edge->build (path, *q_near, qProj_)) { HPP_STOP_TIMECOUNTER (buildPath); addFailure (STEERING_METHOD, edge); return false; @@ -235,12 +241,18 @@ namespace hpp { addFailure (PATH_VALIDATION, edge); validPath = fullValidPath; } else { - if (fullyValid) validPath = fullValidPath; + if (extendStep_ == 1 || fullyValid) validPath = fullValidPath; else { const value_type& length = fullValidPath->length(); const value_type& t_init = fullValidPath->timeRange ().first; - validPath = fullValidPath->extract - (core::interval_t(t_init, t_init + length * 0.5)); + try { + validPath = fullValidPath->extract + (core::interval_t(t_init, t_init + length * extendStep_)); + } catch (const core::projection_error& e) { + hppDout (error, e.what()); + addFailure (PATH_PROJECTION_SHORTER, edge); + return false; + } } extendStatistics_.addSuccess (); hppDout (info, "Extension:" << std::endl @@ -268,18 +280,30 @@ namespace hpp { hppDout (info, "Extension failed." << std::endl << extendStatistics_); } - inline void ManipulationPlanner::tryConnect (const core::Nodes_t nodes) + inline std::size_t ManipulationPlanner::tryConnectToRoadmap (const core::Nodes_t nodes) { const core::SteeringMethodPtr_t& sm (problem ().steeringMethod ()); core::PathValidationPtr_t pathValidation (problem ().pathValidation ()); PathProjectorPtr_t pathProjector (problem().pathProjector ()); core::PathPtr_t path, projPath, validPath; graph::GraphPtr_t graph = problem_.constraintGraph (); + bool connectSucceed = false; + std::size_t nbConnection = 0; + const std::size_t K = 7; + value_type distance; for (core::Nodes_t::const_iterator itn1 = nodes.begin (); - itn1 != nodes.end (); ++itn1) { + itn1 != nodes.end (); ++itn1) { ConfigurationPtr_t q1 ((*itn1)->configuration ()); - for (core::Nodes_t::const_iterator itn2 = boost::next (itn1); - itn2 != nodes.end (); ++itn2) { + connectSucceed = false; + for (core::ConnectedComponents_t::const_iterator itcc = + roadmap ()->connectedComponents ().begin (); + itcc != roadmap ()->connectedComponents ().end (); ++itcc) { + if (*itcc == (*itn1)->connectedComponent ()) + continue; + core::Nodes_t knearest = roadmap()->nearestNeighbor () + ->KnearestSearch (q1, *itcc, K, distance); + for (core::Nodes_t::const_iterator itn2 = knearest.begin (); + itn2 != knearest.end (); ++itn2) { bool _1to2 = (*itn1)->isOutNeighbor (*itn2); bool _2to1 = (*itn1)->isInNeighbor (*itn2); if (_1to2 && _2to1) { @@ -295,6 +319,7 @@ namespace hpp { } else projPath = path; PathValidationReportPtr_t report; if (pathValidation->validate (projPath, false, validPath, report)) { + nbConnection++; if (!_1to2) roadmap ()->addEdge (*itn1, *itn2, projPath); if (!_2to1) { core::interval_t timeRange = projPath->timeRange (); @@ -302,9 +327,58 @@ namespace hpp { (core::interval_t (timeRange.second, timeRange.first))); } + connectSucceed = true; + break; } + } + if (connectSucceed) break; + } + } + return nbConnection; + } + + inline std::size_t ManipulationPlanner::tryConnectNewNodes (const core::Nodes_t nodes) + { + const core::SteeringMethodPtr_t& sm (problem ().steeringMethod ()); + core::PathValidationPtr_t pathValidation (problem ().pathValidation ()); + PathProjectorPtr_t pathProjector (problem().pathProjector ()); + core::PathPtr_t path, projPath, validPath; + graph::GraphPtr_t graph = problem_.constraintGraph (); + std::size_t nbConnection = 0; + for (core::Nodes_t::const_iterator itn1 = nodes.begin (); + itn1 != nodes.end (); ++itn1) { + ConfigurationPtr_t q1 ((*itn1)->configuration ()); + for (core::Nodes_t::const_iterator itn2 = boost::next (itn1); + itn2 != nodes.end (); ++itn2) { + if ((*itn1)->connectedComponent () == (*itn2)->connectedComponent ()) + continue; + bool _1to2 = (*itn1)->isOutNeighbor (*itn2); + bool _2to1 = (*itn1)->isInNeighbor (*itn2); + if (_1to2 && _2to1) { + hppDout (info, "the two nodes are already connected"); + continue; + } + ConfigurationPtr_t q2 ((*itn2)->configuration ()); + assert (*q1 != *q2); + path = (*sm) (*q1, *q2); + if (!path) continue; + if (pathProjector) { + if (!pathProjector->apply (path, projPath)) continue; + } else projPath = path; + PathValidationReportPtr_t report; + if (pathValidation->validate (projPath, false, validPath, report)) { + nbConnection++; + if (!_1to2) roadmap ()->addEdge (*itn1, *itn2, projPath); + if (!_2to1) { + core::interval_t timeRange = projPath->timeRange (); + roadmap ()->addEdge (*itn2, *itn1, projPath->extract + (core::interval_t (timeRange.second, + timeRange.first))); + } + } } } + return nbConnection; } ManipulationPlanner::ManipulationPlanner (const Problem& problem, @@ -312,6 +386,7 @@ namespace hpp { core::PathPlanner (problem, roadmap), shooter_ (problem.configurationShooter()), problem_ (problem), roadmap_ (roadmap), + extendStep_ (1), qProj_ (problem.robot ()->configSize ()) {} diff --git a/src/path-optimization/config-optimization.cc b/src/path-optimization/config-optimization.cc index 74f026602c5e1926d2058dc3c2aa5fc6181df90e..ffa166338f9798c34c9ec8db5060efc20a2e417d 100644 --- a/src/path-optimization/config-optimization.cc +++ b/src/path-optimization/config-optimization.cc @@ -43,7 +43,7 @@ namespace hpp { /// path->end(). In that case, path->end () should be in edge->node(). /// (obviously, in this case, we have edge->isInNodeFrom_ = true) const bool reverseB = setB->edge ()->direction(before); - const bool reverseA = setA->edge ()->direction(after); + //const bool reverseA = setA->edge ()->direction(after); reverse = reverseB; diff --git a/src/problem-solver.cc b/src/problem-solver.cc index 9a9ed0de25122f3967e886856cdee4211c65adad..8772e0097366fa19ecd4aa361f208f7fb5b7365f 100644 --- a/src/problem-solver.cc +++ b/src/problem-solver.cc @@ -17,6 +17,8 @@ #include "hpp/manipulation/problem-solver.hh" +#include <boost/bind.hpp> + #include <hpp/util/pointer.hh> #include <hpp/util/debug.hh> @@ -29,17 +31,19 @@ #include <hpp/core/continuous-collision-checking/progressive.hh> #include <hpp/core/path-optimization/partial-shortcut.hh> #include <hpp/core/roadmap.hh> +#include <hpp/core/steering-method-straight.hh> +#include "hpp/manipulation/problem.hh" #include "hpp/manipulation/device.hh" #include "hpp/manipulation/handle.hh" #include "hpp/manipulation/graph/graph.hh" #include "hpp/manipulation/manipulation-planner.hh" -#include "hpp/manipulation/problem.hh" #include "hpp/manipulation/roadmap.hh" #include "hpp/manipulation/constraint-set.hh" #include "hpp/manipulation/graph-optimizer.hh" #include "hpp/manipulation/graph-path-validation.hh" #include "hpp/manipulation/graph-node-optimizer.hh" +#include "hpp/manipulation/graph-steering-method.hh" #include "hpp/manipulation/path-optimization/config-optimization.hh" namespace hpp { @@ -90,8 +94,13 @@ namespace hpp { GraphConfigOptimizationTraits <pathOptimization::ConfigOptimizationTraits> >); + using core::SteeringMethodBuilder_t; + add <SteeringMethodBuilder_t> ("Graph-SteeringMethodStraight", + GraphSteeringMethod::create <core::SteeringMethodStraight>); + pathPlannerType ("M-RRT"); pathValidationType ("Graph-Discretized", 0.05); + steeringMethodType ("Graph-SteeringMethodStraight"); } ProblemSolverPtr_t ProblemSolver::create () diff --git a/src/problem.cc b/src/problem.cc new file mode 100644 index 0000000000000000000000000000000000000000..7758f09ceeb9da50dd09f0bd1e2247d46469bd04 --- /dev/null +++ b/src/problem.cc @@ -0,0 +1,52 @@ +// Copyright (c) 2015, Joseph Mirabel +// Authors: Joseph Mirabel (joseph.mirabel@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/problem.hh> +#include <hpp/manipulation/weighed-distance.hh> +#include <hpp/manipulation/graph-steering-method.hh> + +namespace hpp { + namespace manipulation { + Problem::Problem (DevicePtr_t robot) + : Parent (robot), graph_() + { + Parent::steeringMethod (GraphSteeringMethod::create (this)); + distance (WeighedDistance::create (robot, graph_)); + } + + void Problem::constraintGraph (const graph::GraphPtr_t& graph) + { + graph_ = graph; + if (pathValidation ()) + pathValidation ()->constraintGraph (graph); + WeighedDistancePtr_t d = HPP_DYNAMIC_PTR_CAST (WeighedDistance, + distance ()); + if (d) d->constraintGraph (graph); + } + + GraphPathValidationPtr_t Problem::pathValidation () const + { + return HPP_DYNAMIC_PTR_CAST (GraphPathValidation, + Parent::pathValidation()); + } + + GraphSteeringMethodPtr_t Problem::steeringMethod () const + { + return HPP_DYNAMIC_PTR_CAST (GraphSteeringMethod, + Parent::steeringMethod()); + } + } // namespace manipulation +} // namespace hpp diff --git a/src/roadmap.cc b/src/roadmap.cc index 0458686bd953e7ef02c86ea489621822eb846cc8..2bc24768495ea70b96d3d9ed08ad8252891aaea8 100644 --- a/src/roadmap.cc +++ b/src/roadmap.cc @@ -17,6 +17,7 @@ #include "hpp/manipulation/roadmap.hh" #include <hpp/util/pointer.hh> +#include <hpp/core/distance.hh> #include <hpp/core/connected-component.hh> #include <hpp/manipulation/roadmap-node.hh> diff --git a/src/weighed-distance.cc b/src/weighed-distance.cc new file mode 100644 index 0000000000000000000000000000000000000000..4709eb4a1368a591596c061a30ef77236dc302a4 --- /dev/null +++ b/src/weighed-distance.cc @@ -0,0 +1,101 @@ +// Copyright (c) 2015, Joseph Mirabel +// Authors: Joseph Mirabel (joseph.mirabel@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/weighed-distance.hh> + +#include <hpp/util/debug.hh> + +#include <hpp/manipulation/roadmap-node.hh> +#include <hpp/manipulation/device.hh> +#include <hpp/manipulation/graph/graph.hh> +#include <hpp/manipulation/graph/edge.hh> + +namespace hpp { + namespace manipulation { + WeighedDistancePtr_t WeighedDistance::create + (const DevicePtr_t& robot, const graph::GraphPtr_t& graph) + { + WeighedDistance* ptr = new WeighedDistance (robot, graph); + WeighedDistancePtr_t shPtr (ptr); + ptr->init (shPtr); + return shPtr; + } + + WeighedDistancePtr_t WeighedDistance::createCopy + (const WeighedDistancePtr_t& distance) + { + WeighedDistance* ptr = new WeighedDistance (*distance); + WeighedDistancePtr_t shPtr (ptr); + ptr->init (shPtr); + return shPtr; + } + + core::DistancePtr_t WeighedDistance::clone () const + { + return createCopy (weak_.lock ()); + } + + WeighedDistance::WeighedDistance (const DevicePtr_t& robot, + const graph::GraphPtr_t graph) : + core::WeighedDistance (robot), graph_ (graph) + { + } + + WeighedDistance::WeighedDistance (const WeighedDistance& distance) : + core::WeighedDistance (distance), graph_ (distance.graph_) + { + } + + void WeighedDistance::init (WeighedDistanceWkPtr_t self) + { + weak_ = self; + } + + value_type WeighedDistance::impl_distance (ConfigurationIn_t q1, + ConfigurationIn_t q2) const + { + value_type d = core::WeighedDistance::impl_distance (q1, q2); + return d; + + // graph::Edges_t pes = graph_->getEdges + // (graph_->getNode (q1), graph_->getNode (q2)); + // while (!pes.empty ()) { + // if (pes.back ()->canConnect (q1, q2)) + // return d; + // pes.pop_back (); + // } + // return d + 100; + } + + value_type WeighedDistance::impl_distance (core::NodePtr_t n1, + core::NodePtr_t n2) const + { + Configuration_t& q1 = *n1->configuration(), + q2 = *n2->configuration(); + value_type d = core::WeighedDistance::impl_distance (q1, q2); + + graph::Edges_t pes = graph_->getEdges ( + graph_->getNode (static_cast <RoadmapNodePtr_t>(n1)), + graph_->getNode (static_cast <RoadmapNodePtr_t>(n2))); + while (!pes.empty ()) { + if (pes.back ()->canConnect (q1, q2)) + return d; + pes.pop_back (); + } + return d + 100; + } + } // namespace manipulation +} // namespace hpp