Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// 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-path-validation.hh"
namespace hpp {
namespace manipulation {
GraphPathValidationPtr_t GraphPathValidation::create (
const PathValidationPtr_t& pathValidation, const GraphPtr_t& graph)
{
GraphPathValidation* p = new GraphPathValidation (pathValidation, graph);
return GraphPathValidationPtr_t (p);
}
GraphPathValidation::GraphPathValidation (
const PathValidationPtr_t& pathValidation, const GraphPtr_t& graph) :
pathValidation_ (pathValidation), constraintGraph_ (graph)
{}
bool GraphPathValidation::validate (
const PathPtr_t& path, bool reverse, PathPtr_t& validPart)
{
PathPtr_t pathGraphValid;
bool graphValid = impl_validate (path, reverse, pathGraphValid);
bool collisionValid = pathValidation_->validate (pathGraphValid, reverse, validPart);
return graphValid && collisionValid;
}
bool GraphPathValidation::impl_validate (
const PathVectorPtr_t& path, bool reverse, PathPtr_t& validPart)
{
size_t start = 0,
end = path->numberPaths ();
int inc = 1;
if (reverse) {
std::swap (start, end);
inc = -1;
}
PathPtr_t validSubPart;
value_type timeOffset = path->timeRange().first;
for (size_t index = start; index != end; index += inc) {
// We should stop at the first non valid subpath.
if (!impl_validate (path->pathAtRank (index), reverse, validSubPart)) {
if (reverse)
validPart = path->extract (
std::make_pair (timeOffset + validSubPart->timeRange().first,
path->timeRange().second));
else
validPart = path->extract (
std::make_pair (path->timeRange().first,
timeOffset + validSubPart->timeRange().second));
return false;
}
timeOffset += path->pathAtRank (index)->length();
}
// Here, every subpath is valid.
validPart = path;
return true;
}
bool GraphPathValidation::impl_validate (
const PathPtr_t& path, bool reverse, PathPtr_t& validPart)
{
PathVectorPtr_t pathVector = HPP_DYNAMIC_PTR_CAST(PathVector, path);
if (pathVector)
return impl_validate (pathVector, reverse, validPart);
value_type tmin = path->timeRange ().first;
value_type tmax = path->timeRange ().second;
if (reverse)
std::swap (tmin, tmax);
const Path& configAt (*path);
graph::Nodes_t origNodes = constraintGraph_->getNode (configAt (tmin));
graph::Nodes_t destNodes = constraintGraph_->getNode (configAt (tmax));
std::vector <graph::Edges_t> possibleEdges (constraintGraph_->getEdge (origNodes, destNodes));
// We check for all of them if both nodes are on the same leaf.
ConstraintSetPtr_t constraints;
while (!possibleEdges.empty ()) {
constraints = constraintGraph_->pathConstraint (possibleEdges.back(), configAt (tmin));
// TODO: We need a quick way of checking that a configuration
// statisfies a constraint.
Configuration_t cfg = configAt (tmax);
if (constraints->apply(cfg) && ( cfg == configAt(tmax) )) {
validPart = path;
return true;
}
possibleEdges.pop_back();
}
validPart = path->extract (std::make_pair (tmin, tmin));
return false;
}
} // namespace manipulation
} // namespace hpp