-
Florent Lamiraux authoredFlorent Lamiraux authored
graph.cc 8.35 KiB
// 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/>.
#include "hpp/manipulation/graph/graph.hh"
#include <hpp/util/assertion.hh>
#include <hpp/manipulation/constraint-set.hh>
#include "hpp/manipulation/graph/state-selector.hh"
#include "hpp/manipulation/graph/state.hh"
#include "hpp/manipulation/graph/edge.hh"
#include "hpp/manipulation/graph/statistics.hh"
namespace hpp {
namespace manipulation {
namespace graph {
typedef constraints::Implicit Implicit;
typedef constraints::ImplicitPtr_t ImplicitPtr_t;
GraphPtr_t Graph::create(const std::string& name, DevicePtr_t robot,
const ProblemPtr_t& problem)
{
Graph* ptr = new Graph (name, problem);
GraphPtr_t shPtr (ptr);
ptr->init (shPtr, robot);
shPtr->createStateSelector (name);
return shPtr;
}
void Graph::init (const GraphWkPtr_t& weak, DevicePtr_t robot)
{
GraphComponent::init (weak);
robot_ = robot;
wkPtr_ = weak;
parentGraph(wkPtr_);
insertHistogram(graph::HistogramPtr_t (
new graph::StateHistogram (wkPtr_.lock()))
);
}
void Graph::initialize ()
{
hists_.clear ();
assert(components_.size() >= 1 && components_[0].lock() == wkPtr_.lock());
for (std::size_t i = 1; i < components_.size(); ++i)
components_[i].lock()->initialize();
constraintsAndComplements_.clear ();
isInit_ = true;
}
StateSelectorPtr_t Graph::createStateSelector (const std::string& name)
{
isInit_ = false;
stateSelector_ = StateSelector::create (name);
stateSelector_->parentGraph (wkPtr_);
return stateSelector_;
}
void Graph::stateSelector (StateSelectorPtr_t ns)
{
isInit_ = false;
stateSelector_ = ns;
stateSelector_->parentGraph (wkPtr_);
}
void Graph::maxIterations (size_type iterations)
{
isInit_ = false;
maxIterations_ = iterations;
}
size_type Graph::maxIterations () const
{
return maxIterations_;
}
void Graph::errorThreshold (const value_type& threshold)
{
isInit_ = false;
errorThreshold_ = threshold;
}
value_type Graph::errorThreshold () const
{
return errorThreshold_;
}
const DevicePtr_t& Graph::robot () const
{
return robot_;
}
void Graph::problem (const ProblemPtr_t& problem)
{
if (problem_ != problem) {
problem_ = problem;
setDirty();
}
}
const ProblemPtr_t& Graph::problem () const
{
return problem_;
}
StatePtr_t Graph::getState (ConfigurationIn_t config) const
{
if (!stateSelector_) throw std::runtime_error ("No StateSelector in Constraint Graph.");
return stateSelector_->getState (config);
}
StatePtr_t Graph::getState(RoadmapNodePtr_t coreNode) const
{
return stateSelector_->getState (coreNode);
}
Edges_t Graph::getEdges (const StatePtr_t& from, const StatePtr_t& to)
const
{
Edges_t edges;
for (Neighbors_t::const_iterator it = from->neighbors ().begin ();
it != from->neighbors ().end (); ++it) {
if (it->second->stateTo () == to)
edges.push_back (it->second);
}
return edges;
}
EdgePtr_t Graph::chooseEdge (RoadmapNodePtr_t from) const
{
return stateSelector_->chooseEdge (from);
}
void Graph::registerConstraints
(const ImplicitPtr_t& constraint,
const ImplicitPtr_t& complement,
const ImplicitPtr_t& both)
{
for (ConstraintsAndComplements_t::const_iterator it
(constraintsAndComplements_.begin ());
it != constraintsAndComplements_.end (); ++it) {
assert (it->constraint != constraint);
}
constraintsAndComplements_.push_back (ConstraintAndComplement_t
(constraint, complement, both));
}
bool Graph::isComplement (const ImplicitPtr_t& constraint,
const ImplicitPtr_t& complement,
ImplicitPtr_t& combinationOfBoth)
const
{
for (ConstraintsAndComplements_t::const_iterator it =
constraintsAndComplements_.begin ();
it != constraintsAndComplements_.end (); ++it) {
if ((it->constraint->functionPtr () == constraint->functionPtr ()) &&
(it->complement->functionPtr () == complement->functionPtr ())) {
combinationOfBoth = it->both;
return true;
}
}
return false;
}
const ConstraintsAndComplements_t& Graph::constraintsAndComplements ()
const
{
return constraintsAndComplements_;
}
ConstraintSetPtr_t Graph::configConstraint (const StatePtr_t& state) const
{
return state->configConstraint ();
}
bool Graph::getConfigErrorForState (ConfigurationIn_t config,
const StatePtr_t& state,
vector_t& error) const
{
return configConstraint (state)->isSatisfied (config, error);
}
bool Graph::getConfigErrorForEdge (ConfigurationIn_t config,
const EdgePtr_t& edge, vector_t& error) const
{
ConstraintSetPtr_t cs (pathConstraint (edge));
ConfigProjectorPtr_t cp (cs->configProjector ());
if (cp) cp->rightHandSideFromConfig (config);
return cs->isSatisfied (config, error);
}
bool Graph::getConfigErrorForEdgeTarget
(ConfigurationIn_t leafConfig, ConfigurationIn_t config,
const EdgePtr_t& edge, vector_t& error) const
{
ConstraintSetPtr_t cs (configConstraint (edge));
ConfigProjectorPtr_t cp (cs->configProjector ());
if (cp) cp->rightHandSideFromConfig (leafConfig);
return cs->isSatisfied (config, error);
}
bool Graph::getConfigErrorForEdgeLeaf
(ConfigurationIn_t leafConfig, ConfigurationIn_t config,
const EdgePtr_t& edge, vector_t& error) const
{
ConstraintSetPtr_t cs (pathConstraint (edge));
ConfigProjectorPtr_t cp (cs->configProjector ());
if (cp) cp->rightHandSideFromConfig (leafConfig);
return cs->isSatisfied (config, error);
}
ConstraintSetPtr_t Graph::configConstraint (const EdgePtr_t& edge) const
{
return edge->configConstraint ();
}
ConstraintSetPtr_t Graph::pathConstraint (const EdgePtr_t& edge) const
{
return edge->pathConstraint ();
}
GraphComponentWkPtr_t Graph::get(std::size_t id) const
{
if (id >= components_.size())
throw std::out_of_range ("ID out of range.");
return components_[id];
}
GraphComponents_t& Graph::components ()
{
return components_;
}
Graph::Graph (const std::string& name, const ProblemPtr_t& problem) :
GraphComponent (name), problem_ (problem)
{
}
std::ostream& Graph::dotPrint (std::ostream& os, dot::DrawingAttributes da) const
{
da.separator = "; ";
da.openSection = "\n";
da.closeSection = ";\n";
dot::Tooltip tp; tp.addLine ("Graph constains:");
populateTooltip (tp);
da.insertWithQuote ("tooltip", tp.toStr());
os << "digraph " << id() << " {" << da;
stateSelector_->dotPrint (os);
os << "}" << std::endl;
return os;
}
std::ostream& Graph::print (std::ostream& os) const
{
return GraphComponent::print (os) << std::endl << *stateSelector_;
}
} // namespace graph
} // namespace manipulation
} // namespace hpp