GCC Code Coverage Report


Directory: ./
File: src/implicit.cc
Date: 2025-05-05 12:19:30
Exec Total Coverage
Lines: 126 143 88.1%
Branches: 101 226 44.7%

Line Branch Exec Source
1 // Copyright (c) 2015, 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/constraints/implicit.hh"
30
31 #include <boost/serialization/export.hpp>
32 #include <boost/serialization/vector.hpp>
33 #include <boost/serialization/weak_ptr.hpp>
34 #include <hpp/constraints/differentiable-function.hh>
35 #include <hpp/util/serialization.hh>
36 #include <pinocchio/serialization/eigen.hpp>
37
38 namespace hpp {
39 namespace constraints {
40 1165 bool Implicit::operator==(const Implicit& other) const {
41 1165 bool res = isEqual(other, true);
42 1165 return res;
43 }
44 9604 size_type computeParameterSize(const ComparisonTypes_t& comp) {
45 9604 size_type size = 0;
46
2/2
✓ Branch 1 taken 48716 times.
✓ Branch 2 taken 9604 times.
58320 for (std::size_t i = 0; i < comp.size(); ++i) {
47
2/2
✓ Branch 1 taken 25304 times.
✓ Branch 2 taken 23412 times.
48716 if (comp[i] == Equality) {
48 25304 ++size;
49 }
50 }
51 9604 return size;
52 }
53
54 void Implicit::rightHandSideFunction(const DifferentiableFunctionPtr_t& rhsF) {
55 if (rhsF) {
56 if (rhsF->inputSize() != 1 || rhsF->inputDerivativeSize() != 1) {
57 HPP_THROW(std::invalid_argument,
58 "Right hand side functions must take"
59 "only one real value as input. Got "
60 << rhsF->inputSize() << " and "
61 << rhsF->inputDerivativeSize());
62 }
63 if (*rhsF->outputSpace() != *function_->outputSpace()) {
64 HPP_THROW(std::invalid_argument,
65 "The right hand side function output"
66 " space ("
67 << *rhsF->outputSpace()
68 << ") differs from the function"
69 " output space ("
70 << *function_->outputSpace() << ").");
71 }
72 // Check that the right hand side is non-constant on all axis.
73 for (std::size_t i = 0; i < comparison_.size(); ++i) {
74 if (comparison_[i] != constraints::Equality) {
75 HPP_THROW(std::invalid_argument,
76 "The comparison type of implicit "
77 "constraint with right hand side function should be Equality "
78 "on all dimensions.");
79 }
80 }
81 }
82
83 rhsFunction_ = rhsF;
84 }
85
86 vectorIn_t Implicit::rightHandSideAt(const value_type& s) {
87 if (rhsFunction_) {
88 vector_t S(1);
89 S[0] = s;
90 rhsFunction_->value(output_, S);
91 }
92 return output_.vector();
93 }
94
95 size_type Implicit::parameterSize() const { return parameterSize_; }
96
97 12 size_type Implicit::rightHandSideSize() const {
98 12 return function_->outputSpace()->nq();
99 }
100 94136 const ComparisonTypes_t& Implicit::comparisonType() const {
101 94136 return comparison_;
102 }
103
104 6402 void Implicit::comparisonType(const ComparisonTypes_t& comp) {
105 6402 comparison_ = comp;
106 6402 parameterSize_ = computeParameterSize(comparison_);
107 6402 computeIndices();
108 6402 }
109
110 25931 void Implicit::setInactiveRowsToZero(vectorOut_t error) const {
111
1/2
✓ Branch 2 taken 25931 times.
✗ Branch 3 not taken.
25931 inactiveRows_.lview(error).setZero();
112 25931 }
113
114 3199 Implicit::Implicit(const DifferentiableFunctionPtr_t& function,
115 3199 ComparisonTypes_t comp, std::vector<bool> mask)
116 3199 : comparison_(comp),
117
2/4
✓ Branch 3 taken 3199 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 3199 times.
✗ Branch 7 not taken.
3199 rhs_(vector_t::Zero(function->outputSize())),
118
1/2
✓ Branch 1 taken 3199 times.
✗ Branch 2 not taken.
3199 parameterSize_(computeParameterSize(comparison_)),
119 3199 function_(function),
120
1/2
✓ Branch 1 taken 3199 times.
✗ Branch 2 not taken.
3199 mask_(mask),
121 3199 activeRows_(),
122
1/2
✓ Branch 1 taken 3199 times.
✗ Branch 2 not taken.
3199 inactiveRows_(),
123 3199 inequalityIndices_(),
124
1/2
✓ Branch 1 taken 3199 times.
✗ Branch 2 not taken.
3199 equalityIndices_(),
125
1/2
✓ Branch 3 taken 3199 times.
✗ Branch 4 not taken.
3199 output_(function->outputSpace()),
126
1/2
✓ Branch 8 taken 3199 times.
✗ Branch 9 not taken.
12796 logOutput_(function->outputSpace()->nv())
127
128 {
129 // This constructor used to set comparison types to Equality if an
130 // empty vector was given as input. Now you should provide the
131 // comparison type at construction.
132
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 3199 times.
3199 assert(function_->outputDerivativeSize() == (size_type)comparison_.size());
133
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 3199 times.
3199 assert(function_->outputDerivativeSize() == (size_type)mask.size());
134
1/2
✓ Branch 1 taken 3199 times.
✗ Branch 2 not taken.
3199 computeActiveRows();
135
1/2
✓ Branch 1 taken 3199 times.
✗ Branch 2 not taken.
3199 computeIndices();
136 3199 }
137
138 // Compute active rows
139 4253 void Implicit::computeActiveRows() {
140 4253 segments_t inactiveRows;
141
2/2
✓ Branch 1 taken 20459 times.
✓ Branch 2 taken 4253 times.
24712 for (std::size_t i = 0; i < mask_.size(); ++i) {
142
3/4
✓ Branch 1 taken 20459 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20426 times.
✓ Branch 5 taken 33 times.
20459 if (mask_[i])
143
1/2
✓ Branch 2 taken 20426 times.
✗ Branch 3 not taken.
20426 activeRows_.push_back(segment_t(i, 1));
144 else
145
1/2
✓ Branch 2 taken 33 times.
✗ Branch 3 not taken.
33 inactiveRows.push_back(segment_t(i, 1));
146 }
147
1/2
✓ Branch 1 taken 4253 times.
✗ Branch 2 not taken.
4253 Eigen::BlockIndex::shrink(activeRows_);
148
1/2
✓ Branch 1 taken 4253 times.
✗ Branch 2 not taken.
4253 Eigen::BlockIndex::shrink(inactiveRows);
149
2/4
✓ Branch 1 taken 4253 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4253 times.
✗ Branch 5 not taken.
4253 inactiveRows_ = Eigen::RowBlockIndices(inactiveRows);
150 4253 }
151
152 10655 void Implicit::computeIndices() {
153 10655 inequalityIndices_.clear();
154 10655 equalityIndices_.clearRows();
155
2/2
✓ Branch 1 taken 58861 times.
✓ Branch 2 taken 10655 times.
69516 for (std::size_t i = 0; i < comparison_.size(); ++i) {
156
6/6
✓ Branch 1 taken 58843 times.
✓ Branch 2 taken 18 times.
✓ Branch 4 taken 27 times.
✓ Branch 5 taken 58816 times.
✓ Branch 6 taken 45 times.
✓ Branch 7 taken 58816 times.
58861 if ((comparison_[i] == Superior) || (comparison_[i] == Inferior)) {
157
1/2
✓ Branch 1 taken 45 times.
✗ Branch 2 not taken.
45 inequalityIndices_.push_back((size_type)i);
158
2/2
✓ Branch 1 taken 31380 times.
✓ Branch 2 taken 27436 times.
58816 } else if (comparison_[i] == Equality) {
159
1/2
✓ Branch 1 taken 31380 times.
✗ Branch 2 not taken.
31380 equalityIndices_.addRow((size_type)i, 1);
160 }
161 }
162 10655 equalityIndices_.updateRows<true, true, true>();
163 10655 }
164
165 19 Implicit::Implicit(const Implicit& other)
166 19 : comparison_(other.comparison_),
167
1/2
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
19 rhs_(other.rhs_),
168 19 parameterSize_(other.parameterSize_),
169 19 function_(other.function_),
170 19 rhsFunction_(other.rhsFunction_),
171
1/2
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
19 mask_(other.mask_),
172
1/2
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
19 activeRows_(other.activeRows_),
173
1/2
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
19 inactiveRows_(other.inactiveRows_),
174
1/2
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
19 inequalityIndices_(other.inequalityIndices_),
175
1/2
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
19 equalityIndices_(other.equalityIndices_),
176
1/2
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
19 output_(other.output_),
177
1/2
✓ Branch 3 taken 19 times.
✗ Branch 4 not taken.
57 logOutput_(other.logOutput_)
178
179 19 {}
180
181 2190 bool Implicit::isEqual(const Implicit& other, bool swapAndTest) const {
182
2/2
✓ Branch 1 taken 80 times.
✓ Branch 2 taken 2110 times.
2190 if (comparison_ != other.comparison_) return false;
183
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 2110 times.
2110 if (rhs_.size() != other.rhs_.size()) return false;
184
5/6
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 2090 times.
✓ Branch 6 taken 20 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 20 times.
✓ Branch 9 taken 2090 times.
2110 if (function_ != other.function_ && *function_ != *other.function_)
185 20 return false;
186
2/2
✓ Branch 0 taken 1055 times.
✓ Branch 1 taken 1035 times.
2090 if (swapAndTest) return other.isEqual(*this, false);
187 1035 return true;
188 }
189
190 1066 ImplicitPtr_t Implicit::create(const DifferentiableFunctionPtr_t& function,
191 ComparisonTypes_t comp, std::vector<bool> mask) {
192
2/2
✓ Branch 1 taken 1053 times.
✓ Branch 2 taken 13 times.
1066 if (mask.empty()) {
193
1/2
✓ Branch 6 taken 1053 times.
✗ Branch 7 not taken.
1053 mask = std::vector<bool>(function->outputSpace()->nv(), true);
194 }
195
4/8
✓ Branch 1 taken 1066 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1066 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1066 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1066 times.
✗ Branch 11 not taken.
1066 Implicit* ptr = new Implicit(function, comp, mask);
196
1/2
✓ Branch 1 taken 1066 times.
✗ Branch 2 not taken.
1066 ImplicitPtr_t shPtr(ptr);
197 1066 ImplicitWkPtr_t wkPtr(shPtr);
198 1066 ptr->init(wkPtr);
199 2132 return shPtr;
200 1066 }
201
202 7 ImplicitPtr_t Implicit::createCopy(const ImplicitPtr_t& other) {
203
2/4
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 7 times.
✗ Branch 6 not taken.
7 Implicit* ptr = new Implicit(*other);
204
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 ImplicitPtr_t shPtr(ptr);
205 7 ImplicitWkPtr_t wkPtr(shPtr);
206 7 ptr->init(wkPtr);
207 14 return shPtr;
208 7 }
209
210
1/2
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
14 ImplicitPtr_t Implicit::copy() const { return createCopy(weak_.lock()); }
211
212 3606 void Implicit::rightHandSideFromConfig(ConfigurationIn_t config,
213 LiegroupElementRef rhs) {
214
2/4
✓ Branch 6 taken 3606 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 3606 times.
3606 assert(*rhs.space() == *function_->outputSpace());
215
2/4
✓ Branch 3 taken 3606 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 3606 times.
✗ Branch 7 not taken.
3606 function_->value(output_, config);
216 3606 logOutput_.setZero();
217
3/6
✓ Branch 2 taken 3606 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 3606 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 3606 times.
✗ Branch 9 not taken.
3606 equalityIndices_.lview(logOutput_) = equalityIndices_.rview(log(output_));
218 // rhs = exp(logOutput_)
219
2/4
✓ Branch 4 taken 3606 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3606 times.
✗ Branch 8 not taken.
3606 rhs = rhs.space()->exp(logOutput_);
220 3606 }
221
222 2101 bool Implicit::checkRightHandSide(LiegroupElementConstRef rhs) const {
223
1/2
✗ Branch 5 not taken.
✓ Branch 6 taken 2101 times.
2101 if (rhs.space() != function_->outputSpace()) return false;
224 2101 logOutput_ = log(rhs);
225
2/2
✓ Branch 1 taken 16601 times.
✓ Branch 2 taken 2101 times.
18702 for (std::size_t i = 0; i < comparison_.size(); ++i)
226
4/6
✓ Branch 1 taken 7000 times.
✓ Branch 2 taken 9601 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 7000 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 16601 times.
16601 if ((comparison_[i] != Equality) && (logOutput_[i] != 0)) return false;
227
228 2101 return true;
229 }
230
231 std::pair<JointConstPtr_t, JointConstPtr_t>
232 9 Implicit::doesConstrainRelPoseBetween(DeviceConstPtr_t robot) const {
233 std::pair<JointConstPtr_t, JointConstPtr_t> joints =
234
1/2
✓ Branch 3 taken 9 times.
✗ Branch 4 not taken.
9 function_->dependsOnRelPoseBetween(robot);
235 // check that the constraint fully constrains the relative pose
236
8/12
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 4 times.
✓ Branch 7 taken 5 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 2 times.
✓ Branch 10 taken 3 times.
✓ Branch 11 taken 9 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 6 times.
✓ Branch 15 taken 3 times.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
9 if (function_->outputSpace()->nv() != 6 || !checkAllRowsActive()) {
237 hppDout(
238 info, "Constraint "
239 << function_->name()
240 << " does not fully constrain the relative pose of joints");
241 6 return std::pair<JointConstPtr_t, JointConstPtr_t>(nullptr, nullptr);
242 }
243 3 return joints;
244 9 }
245
246 template <class Archive>
247 12 void Implicit::serialize(Archive& ar, const unsigned int version) {
248 (void)version;
249
1/2
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
12 ar& BOOST_SERIALIZATION_NVP(comparison_);
250
1/2
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
12 ar& BOOST_SERIALIZATION_NVP(rhs_);
251 if (!Archive::is_saving::value)
252 6 parameterSize_ = computeParameterSize(comparison_);
253
1/2
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
12 ar& BOOST_SERIALIZATION_NVP(function_);
254
1/2
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
12 ar& BOOST_SERIALIZATION_NVP(rhsFunction_);
255
1/2
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
12 ar& BOOST_SERIALIZATION_NVP(mask_);
256
1/2
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
12 ar& BOOST_SERIALIZATION_NVP(weak_);
257 if (!Archive::is_saving::value) {
258 6 computeActiveRows();
259 6 computeIndices();
260 }
261 }
262
263 HPP_SERIALIZATION_IMPLEMENT(Implicit);
264 } // namespace constraints
265 } // namespace hpp
266