Skip to content
Snippets Groups Projects
roadmap.cc 5.14 KiB
Newer Older
// Copyright (c) 2014, LAAS-CNRS
// 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/>.

Joseph Mirabel's avatar
Joseph Mirabel committed
#include <hpp/manipulation/roadmap.hh>
Joseph Mirabel's avatar
Joseph Mirabel committed
#include <hpp/util/pointer.hh>
Joseph Mirabel's avatar
Joseph Mirabel committed

#include <hpp/core/edge.hh>
#include <hpp/core/distance.hh>
Joseph Mirabel's avatar
Joseph Mirabel committed
#include <hpp/manipulation/roadmap.hh>
#include <hpp/manipulation/roadmap-node.hh>
Joseph Mirabel's avatar
Joseph Mirabel committed
#include <hpp/manipulation/symbolic-component.hh>
Joseph Mirabel's avatar
Joseph Mirabel committed
#include <hpp/manipulation/connected-component.hh>
#include <hpp/manipulation/graph/node.hh>
#include <hpp/manipulation/graph/statistics.hh>
namespace hpp {
  namespace manipulation {
    Roadmap::Roadmap (const core::DistancePtr_t& distance, const core::DevicePtr_t& robot) :
      core::Roadmap (distance, robot), weak_ () {}

    RoadmapPtr_t Roadmap::create (const core::DistancePtr_t& distance, const core::DevicePtr_t& robot)
    {
      Roadmap* ptr = new Roadmap (distance, robot);
      RoadmapPtr_t shPtr (ptr);
      ptr->init(shPtr);
      return shPtr; 
    }

    void Roadmap::clear ()
    {
      Parent::clear ();
      Histograms_t::const_iterator it;
      for (it = histograms_.begin(); it != histograms_.end(); ++it)
      if (graph_) {
        const Histograms_t& hs = graph_->histograms();
        for (it = hs.begin(); it != hs.end(); ++it)
          (*it)->clear ();
      }
    }

    void Roadmap::push_node (const core::NodePtr_t& n)
    {
Joseph Mirabel's avatar
Joseph Mirabel committed
      const RoadmapNodePtr_t& node = 
        static_cast <const RoadmapNodePtr_t> (n);
      statInsert (node);
      symbolicCCs_.insert(node->symbolicComponent());
    void Roadmap::statInsert (const RoadmapNodePtr_t& n)
Joseph Mirabel's avatar
Joseph Mirabel committed
      Histograms_t::const_iterator it;
      for (it = histograms_.begin(); it != histograms_.end(); ++it)
      if (graph_) {
        const Histograms_t& hs = graph_->histograms();
        for (it = hs.begin(); it != hs.end(); ++it)
          (*it)->add (n);
      }
    void Roadmap::insertHistogram (const graph::HistogramPtr_t hist)
    {
      histograms_.push_back (hist);
      core::Nodes_t::const_iterator _node;
      for (_node = nodes().begin(); _node != nodes().end(); ++_node)
        hist->add (static_cast <const RoadmapNodePtr_t>(*_node));
Joseph Mirabel's avatar
Joseph Mirabel committed

    void Roadmap::constraintGraph (const graph::GraphPtr_t& graph)
    {
      graph_ = graph;
      // FIXME Add the current nodes() to the graph->histograms()
      // The main issue is that new histograms may be added to
      // graph->histograms() and this class will not know it.
    RoadmapNodePtr_t Roadmap::nearestNode (const ConfigurationPtr_t& configuration,
        const ConnectedComponentPtr_t& connectedComponent,
        const graph::NodePtr_t& node,
        value_type& minDistance) const
    {
      core::NodePtr_t result = NULL;
      minDistance = std::numeric_limits <value_type>::infinity ();
      const RoadmapNodes_t& roadmapNodes = connectedComponent->getRoadmapNodes (node);
      for (RoadmapNodes_t::const_iterator itNode = roadmapNodes.begin ();
          itNode != roadmapNodes.end (); ++itNode) {
        value_type d = (*distance()) (*(*itNode)->configuration (),
            *configuration);
        if (d < minDistance) {
          minDistance = d;
          result = *itNode;
        }
      }
      return static_cast <RoadmapNode*> (result);

    core::NodePtr_t Roadmap::createNode (const ConfigurationPtr_t& q) const
    {
      // call RoadmapNode constructor with new manipulation connected component
Joseph Mirabel's avatar
Joseph Mirabel committed
      RoadmapNodePtr_t node = new RoadmapNode (q, ConnectedComponent::create(weak_));
      SymbolicComponentPtr_t sc = WeighedSymbolicComponent::create (weak_.lock());
      node->symbolicComponent (sc);
      sc->setFirstNode(node);
      return node;

    graph::NodePtr_t Roadmap::getNode(RoadmapNodePtr_t node)
    {
      return graph_->getNode(node);
    }

Joseph Mirabel's avatar
Joseph Mirabel committed
    void Roadmap::addEdge (const core::EdgePtr_t& edge)
    {
      Parent::addEdge(edge);
      const RoadmapNodePtr_t& f = static_cast <const RoadmapNodePtr_t> (edge->from());
      const RoadmapNodePtr_t& t = static_cast <const RoadmapNodePtr_t> (edge->to());
      SymbolicComponentPtr_t scf = f->symbolicComponent();
      SymbolicComponentPtr_t sct = t->symbolicComponent();
      scf->canReach(sct);
      if (scf->canMerge(sct)) {
        if (scf->nodes().size() > sct->nodes().size()) {
          scf->merge(sct);
          symbolicCCs_.erase(sct);
        } else {
          sct->merge(scf);
          symbolicCCs_.erase(scf);
        }
      }
    }
  } // namespace manipulation
} // namespace hpp