From b1f8a7e391b0e437920a1e5688b80bf69bccce6a Mon Sep 17 00:00:00 2001 From: Joseph Mirabel <jmirabel@laas.fr> Date: Wed, 27 Jan 2016 14:25:57 +0100 Subject: [PATCH] Update WaypointEdge to enable finer control of edge type. --- include/hpp/manipulation/graph/edge.hh | 29 +++--- src/graph/edge.cc | 130 ++++++++++++++----------- 2 files changed, 92 insertions(+), 67 deletions(-) diff --git a/include/hpp/manipulation/graph/edge.hh b/include/hpp/manipulation/graph/edge.hh index 8426a21..78158c3 100644 --- a/include/hpp/manipulation/graph/edge.hh +++ b/include/hpp/manipulation/graph/edge.hh @@ -227,18 +227,22 @@ namespace hpp { /// Return the inner waypoint. /// \param EdgeType is either Edge or WaypointEdge template <class EdgeType> - boost::shared_ptr <EdgeType> waypoint () const; + boost::shared_ptr <EdgeType> waypoint (const std::size_t index) const; /// Print the object in a stream. virtual std::ostream& dotPrint (std::ostream& os, dot::DrawingAttributes da = dot::DrawingAttributes ()) const; - /// Create inner waypoints. - /// \param depth the number of waypoints between from() and to() - /// minus 1. - /// \param bname basename used for naming. - /// \note inner edges are named bname + "_e" + pos - /// inner nodes are named bname + "_n" + pos - void createWaypoint (const unsigned int depth, const std::string& bname = "WaypointEdge"); + /// Set the number of waypoints + void nbWaypoints (const size_type number); + + std::size_t nbWaypoints () const + { + return waypoints_.size (); + } + + /// Set waypoint index with wEdge and wTo. + /// \param wTo is the destination node of wEdge + void setWaypoint (const std::size_t index, const EdgePtr_t wEdge, const NodePtr_t wTo); /// Get the node in which path after the waypoint is. NodePtr_t node () const; @@ -256,10 +260,13 @@ namespace hpp { virtual std::ostream& print (std::ostream& os) const; private: - typedef std::pair < EdgePtr_t, NodePtr_t > Waypoint; + typedef std::pair < EdgePtr_t, NodePtr_t > Waypoint_t; + typedef std::vector <Waypoint_t> Waypoints_t; + + Waypoints_t waypoints_; - Waypoint waypoint_; - mutable Configuration_t config_, result_; + mutable matrix_t configs_; + mutable Configuration_t result_; WaypointEdgeWkPtr_t wkPtr_; }; // class WaypointEdge diff --git a/src/graph/edge.cc b/src/graph/edge.cc index bcef230..1d8481e 100644 --- a/src/graph/edge.cc +++ b/src/graph/edge.cc @@ -95,9 +95,9 @@ namespace hpp { { Configuration_t q0 = path->initial (), q1 = path->end (); - const bool src_contains_q0 = waypoint_.second->contains (q0); + const bool src_contains_q0 = waypoints_.back().second->contains (q0); const bool dst_contains_q0 = to ()->contains (q0); - const bool src_contains_q1 = waypoint_.second->contains (q1); + const bool src_contains_q1 = waypoints_.back().second->contains (q1); const bool dst_contains_q1 = to ()->contains (q1); if (!( (src_contains_q0 && dst_contains_q1) @@ -287,7 +287,7 @@ namespace hpp { proj->rightHandSideFromConfig (qoffset); if (isShort_) q = qoffset; if (c->apply (q)) return true; - ::hpp::statistics::SuccessStatistics& ss = proj->statistics (); + const ::hpp::statistics::SuccessStatistics& ss = proj->statistics (); if (ss.nbFailure () > ss.nbSuccess ()) { hppDout (warning, c->name () << " fails often." << std::endl << ss); } else { @@ -318,91 +318,100 @@ namespace hpp { bool WaypointEdge::canConnect (ConfigurationIn_t q1, ConfigurationIn_t q2) const { - return waypoint_.first->canConnect (q1, q2) && Edge::canConnect (q1, q2); + /// TODO: This is not correct + return waypoints_.back().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; + core::PathPtr_t p; + core::PathVectorPtr_t pv = core::PathVector::create + (graph_.lock ()->robot ()->configSize (), + graph_.lock ()->robot ()->numberDof ()); // Many times, this will be called rigth after WaypointEdge::applyConstraints so config_ // already satisfies the constraints. - if (!result_.isApprox (q2)) config_ = q2; - if (!waypoint_.first->applyConstraints (q1, config_)) + bool useCache = result_.isApprox (q2); + if (!useCache) configs_.col (0) = q2; + + assert (waypoints_[0].first); + if (!waypoints_[0].first->applyConstraints (q1, configs_.col (0))) return false; - if (!waypoint_.first->build (pathToWaypoint, q1, config_)) + if (!waypoints_[0].first->build (p, q1, configs_.col (0))) return false; - core::PathVectorPtr_t pv = HPP_DYNAMIC_PTR_CAST (core::PathVector, pathToWaypoint); - if (!pv) { - pv = core::PathVector::create - (graph_.lock ()->robot ()->configSize (), - graph_.lock ()->robot ()->numberDof ()); - pv->appendPath (pathToWaypoint); + pv->appendPath (p); + + for (std::size_t i = 1; i < waypoints_.size (); ++i) { + assert (waypoints_[i].first); + if (!useCache) configs_.col (i) = q2; + if (!waypoints_[i].first->applyConstraints (configs_.col(i-1), configs_.col (i))) + return false; + if (!waypoints_[i].first->build (p, configs_.col(i-1), configs_.col (i))) + return false; + pv->appendPath (p); } - path = pv; - core::PathPtr_t end; - if (!Edge::build (end, config_, q2)) + if (!Edge::build (p, configs_.col (configs_.cols()-1), q2)) return false; - pv->appendPath (end); + pv->appendPath (p); + + path = pv; return true; } bool WaypointEdge::applyConstraints (ConfigurationIn_t qoffset, ConfigurationOut_t q) const { - assert (waypoint_.first); - config_ = q; - if (!waypoint_.first->applyConstraints (qoffset, config_)) { - q = config_; + assert (waypoints_[0].first); + configs_.col (0) = q; + if (!waypoints_[0].first->applyConstraints (qoffset, configs_.col (0))) { + q = configs_.col(0); return false; - } - bool success = Edge::applyConstraints (config_, q); + } + for (std::size_t i = 1; i < waypoints_.size (); ++i) { + assert (waypoints_[i].first); + configs_.col (i) = q; + if (!waypoints_[i].first->applyConstraints (configs_.col(i-1), configs_.col (i))) { + q = configs_.col(i); + return false; + } + } + bool success = Edge::applyConstraints (configs_.col (configs_.cols()-1), q); result_ = q; return success; } - void WaypointEdge::createWaypoint (const unsigned d, const std::string& bname) - { - std::ostringstream ss; - ss << bname << "_n" << d; - NodePtr_t node = Node::create (ss.str()); - node->parentGraph(graph_); - EdgePtr_t edge; - ss.str (std::string ()); ss.clear (); - ss << bname << "_e" << d; - if (d == 0) { - edge = Edge::create (ss.str (), graph_, from (), - node); - edge->isInNodeFrom (isInNodeFrom ()); - } else { - WaypointEdgePtr_t we = WaypointEdge::create - (ss.str (), graph_, from (), node); - we->createWaypoint (d-1, bname); - edge = we; - edge->isInNodeFrom (isInNodeFrom ()); - } - waypoint_ = Waypoint (edge, node); - config_ = Configuration_t(graph_.lock ()->robot ()->configSize ()); - result_ = Configuration_t(graph_.lock ()->robot ()->configSize ()); + void WaypointEdge::nbWaypoints (const size_type number) + { + waypoints_.resize (number); + const size_type nbDof = graph_.lock ()->robot ()->configSize (); + configs_ = matrix_t (nbDof, number); + result_ = Configuration_t (nbDof); + } + + void WaypointEdge::setWaypoint (const std::size_t index, const EdgePtr_t wEdge, const NodePtr_t wTo) + { + assert (index < waypoints_.size()); + waypoints_[index] = Waypoint_t (wEdge, wTo); } NodePtr_t WaypointEdge::node () const { - if (isInNodeFrom ()) return waypoint_.second; + if (isInNodeFrom ()) return waypoints_.back().second; else return to (); } template <> - EdgePtr_t WaypointEdge::waypoint <Edge> () const + EdgePtr_t WaypointEdge::waypoint <Edge> (const std::size_t index) const { - return waypoint_.first; + assert (index < waypoints_.size()); + return waypoints_[index].first; } template <> - WaypointEdgePtr_t WaypointEdge::waypoint <WaypointEdge> () const + WaypointEdgePtr_t WaypointEdge::waypoint <WaypointEdge> (const std::size_t index) const { - return HPP_DYNAMIC_PTR_CAST (WaypointEdge, waypoint_.first); + assert (index < waypoints_.size()); + return HPP_DYNAMIC_PTR_CAST (WaypointEdge, waypoints_[index].first); } std::ostream& WaypointEdge::print (std::ostream& os) const @@ -417,19 +426,28 @@ namespace hpp { { // First print the waypoint node, then the first edge. da ["style"]="dashed"; - waypoint_.second->dotPrint (os, da); + for (std::size_t i = 1; i < waypoints_.size (); ++i) + waypoints_[i].second->dotPrint (os, da); + da ["style"]="solid"; - waypoint_.first->dotPrint (os, da) << std::endl; + for (std::size_t i = 1; i < waypoints_.size (); ++i) + waypoints_[i].first->dotPrint (os, da) << std::endl; + da ["style"]="dotted"; da ["dir"] = "both"; da ["arrowtail"]="dot"; + // TODO: This is very ugly. There ought to be a better way of + // getting the real from() Node. + // We should be using Edge::dotPrint (...) instead of the following + // paragraph. da.insert ("shape", "onormal"); da.insertWithQuote ("label", name()); dot::Tooltip tp; tp.addLine ("Edge constains:"); populateTooltip (tp); da.insertWithQuote ("tooltip", tp.toStr()); da.insertWithQuote ("labeltooltip", tp.toStr()); - os << waypoint_.second->id () << " -> " << to()->id () << " " << da << ";"; + os << waypoints_.back().second->id () << " -> " << to()->id () << " " << da << ";"; + return os; } -- GitLab