GCC Code Coverage Report


Directory: ./
File: src/graph/validation.cc
Date: 2025-05-07 11:07:45
Exec Total Coverage
Lines: 0 105 0.0%
Branches: 0 243 0.0%

Line Branch Exec Source
1 // Copyright (c) 2019, LAAS-CNRS
2 // Authors: Joseph Mirabel (joseph.mirabel@laas.fr)
3 //
4
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // 1. Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //
12 // 2. Redistributions in binary form must reproduce the above copyright
13 // notice, this list of conditions and the following disclaimer in the
14 // documentation and/or other materials provided with the distribution.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
27 // DAMAGE.
28
29 #include "hpp/manipulation/graph/validation.hh"
30
31 #include <hpp/constraints/differentiable-function.hh>
32 #include <hpp/core/collision-validation-report.hh>
33 #include <hpp/core/collision-validation.hh>
34 #include <hpp/core/configuration-shooter.hh>
35 #include <hpp/core/relative-motion.hh>
36 #include <hpp/util/indent.hh>
37 #include <sstream>
38
39 #include "hpp/manipulation/graph/edge.hh"
40 #include "hpp/manipulation/graph/state-selector.hh"
41 #include "hpp/manipulation/graph/state.hh"
42 #include "hpp/manipulation/problem.hh"
43
44 namespace hpp {
45 namespace manipulation {
46 namespace graph {
47 ✗ bool stateAIncludedInStateB(const StatePtr_t& A, const StatePtr_t& B) {
48 ✗ const NumericalConstraints_t& Ancs = A->numericalConstraints();
49 ✗ const NumericalConstraints_t& Bncs = B->numericalConstraints();
50 ✗ for (NumericalConstraints_t::const_iterator _nc = Bncs.begin();
51 ✗ _nc != Bncs.end(); ++_nc)
52 ✗ if (std::find(Ancs.begin(), Ancs.end(), *_nc) == Ancs.end()) return false;
53 ✗ return true;
54 }
55
56 ✗ std::ostream& Validation::print(std::ostream& os) const {
57 ✗ for (std::size_t i = 0; i < warnings_.size(); ++i) {
58 ✗ os << "Warning " << i << " ("
59 ✗ << (warnings_[i].first ? warnings_[i].first->name() : "no component")
60 ✗ << ')' << incendl << warnings_[i].second << decendl;
61 }
62 ✗ for (std::size_t i = 0; i < errors_.size(); ++i) {
63 ✗ os << "Error " << i << " ("
64 ✗ << (errors_[i].first ? errors_[i].first->name() : "no component") << ')'
65 ✗ << incendl << errors_[i].second << decendl;
66 }
67 ✗ return os;
68 }
69
70 ✗ bool Validation::validate(const GraphComponentPtr_t& comp) {
71 ✗ if (HPP_DYNAMIC_PTR_CAST(State, comp))
72 ✗ return validateState(HPP_DYNAMIC_PTR_CAST(State, comp));
73 ✗ else if (HPP_DYNAMIC_PTR_CAST(Edge, comp))
74 ✗ return validateEdge(HPP_DYNAMIC_PTR_CAST(Edge, comp));
75 ✗ else if (HPP_DYNAMIC_PTR_CAST(Graph, comp))
76 ✗ return validateGraph(HPP_DYNAMIC_PTR_CAST(Graph, comp));
77 else
78 ✗ return true;
79 }
80
81 ✗ bool Validation::validateState(const StatePtr_t& state) {
82 ✗ bool success = true;
83
84 // 1. Check that all the constraint are not parameterizable.
85 ✗ const NumericalConstraints_t& ncs = state->numericalConstraints();
86 ✗ for (NumericalConstraints_t::const_iterator _nc = ncs.begin();
87 ✗ _nc != ncs.end(); ++_nc)
88 ✗ if ((*_nc)->parameterSize() > 0) {
89 ✗ std::ostringstream oss;
90 ✗ oss << incindent << "Constraint " << (*_nc)->function().name()
91 << " has a varying right hand side while constraints of a state must"
92 ✗ " have a constant one.";
93 ✗ addError(state, oss.str());
94 }
95
96 // 2. try to generate a configuration in this state.
97 bool projOk;
98 ✗ Configuration_t q;
99 ✗ std::size_t i, Nrand = 100;
100
101 ✗ for (i = 0; i < Nrand; i++) {
102 ✗ problem_->configurationShooter()->shoot(q);
103 ✗ projOk = state->configConstraint()->apply(q);
104 ✗ if (projOk) break;
105 }
106 ✗ if (!projOk) {
107 ✗ std::ostringstream oss;
108 ✗ oss << incindent << "Failed to apply the constraints to " << Nrand
109 ✗ << "random configurations.";
110 ✗ addError(state, oss.str());
111 ✗ return false;
112 }
113 ✗ if (4 * i > 3 * Nrand) {
114 ✗ std::ostringstream oss;
115 ✗ oss << incindent << "Success rate of constraint projection is " << i / Nrand
116 ✗ << '.';
117 ✗ addWarning(state, oss.str());
118 ✗ oss.clear();
119 }
120
121 // 3. check the collision pairs which will be disabled because of the
122 // constraint.
123 core::CollisionValidationPtr_t colValidation(
124 ✗ core::CollisionValidation::create(problem_->robot()));
125 ✗ for (std::size_t i = 0; i < problem_->collisionObstacles().size(); ++i)
126 ✗ colValidation->addObstacle(problem_->collisionObstacles()[i]);
127 ✗ colValidation->computeAllContacts(true);
128
129 typedef core::RelativeMotion RelativeMotion;
130 RelativeMotion::matrix_type relMotion =
131 ✗ RelativeMotion::matrix(problem_->robot());
132 ✗ RelativeMotion::fromConstraint(relMotion, problem_->robot(),
133 ✗ state->configConstraint());
134
135 // Invert the relative motions.
136 hppDout(info, "Relative motion matrix:\n" << relMotion);
137 ✗ for (size_type r = 0; r < relMotion.rows(); ++r)
138 ✗ for (size_type c = 0; c < r; ++c) {
139 ✗ if (relMotion(r, c) != relMotion(c, r)) {
140 hppDout(error, "Relative motion matrix not symmetric.");
141 }
142 ✗ switch (relMotion(r, c)) {
143 ✗ case RelativeMotion::Constrained:
144 ✗ relMotion(r, c) = relMotion(c, r) = RelativeMotion::Unconstrained;
145 ✗ break;
146 ✗ case RelativeMotion::Parameterized:
147 case RelativeMotion::Unconstrained:
148 ✗ relMotion(r, c) = relMotion(c, r) = RelativeMotion::Constrained;
149 ✗ break;
150 ✗ default:
151 ✗ throw std::logic_error("Relative motion not understood");
152 }
153 }
154 hppDout(info, "Relative motion matrix:\n" << relMotion);
155
156 ✗ colValidation->filterCollisionPairs(relMotion);
157 ✗ core::ValidationReportPtr_t colReport;
158 ✗ bool colOk = colValidation->validate(q, colReport);
159
160 ✗ if (!colOk) {
161 ✗ std::ostringstream oss;
162 ✗ oss << incindent
163 << "The following collision pairs will always "
164 ✗ "collide."
165 ✗ << incendl << *colReport << decindent;
166 ✗ addError(state, oss.str());
167 ✗ if (HPP_DYNAMIC_PTR_CAST(core::CollisionValidationReport, colReport)) {
168 std::pair<std::string, std::string> names =
169 ✗ HPP_DYNAMIC_PTR_CAST(core::CollisionValidationReport, colReport)
170 ✗ ->getObjectNames();
171 ✗ addCollision(state, names.first, names.second);
172 }
173 ✗ success = false;
174 }
175
176 ✗ return success;
177 }
178
179 ✗ bool Validation::validateEdge(const EdgePtr_t&) { return true; }
180
181 ✗ bool Validation::validateGraph(const GraphPtr_t& graph) {
182 ✗ if (!graph) return false;
183 ✗ bool success = true;
184
185 ✗ for (std::size_t i = 1; i < graph->nbComponents(); ++i)
186 ✗ if (!validate(graph->get(i).lock())) success = false;
187
188 // Check that no state is included in a state which has a higher priority.
189 ✗ States_t states = graph->stateSelector()->getStates();
190 ✗ for (States_t::const_iterator _state = states.begin(); _state != states.end();
191 ✗ ++_state) {
192 ✗ for (States_t::const_iterator _stateHO = states.begin(); _stateHO != _state;
193 ✗ ++_stateHO) {
194 ✗ if (stateAIncludedInStateB(*_state, *_stateHO)) {
195 ✗ std::ostringstream oss;
196 ✗ oss << "State " << (*_state)->name() << " is included in state "
197 ✗ << (*_stateHO)->name() << " but the latter has a higher priority.";
198 ✗ addError(*_state, oss.str());
199 ✗ success = false;
200 }
201 }
202 }
203
204 ✗ return success;
205 }
206 } // namespace graph
207 } // namespace manipulation
208 } // namespace hpp
209