Directory: | ./ |
---|---|
File: | tests/util.hh |
Date: | 2025-05-05 12:19:30 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 29 | 35 | 82.9% |
Branches: | 37 | 92 | 40.2% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | // Copyright (c) 2017, Joseph Mirabel | ||
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 | #ifndef TEST_UTIL_HH | ||
30 | #define TEST_UTIL_HH | ||
31 | |||
32 | #define EIGEN_VECTOR_IS_APPROX(Va, Vb) \ | ||
33 | BOOST_CHECK_MESSAGE((Va).isApprox(Vb, test_precision), \ | ||
34 | "check " #Va ".isApprox(" #Vb \ | ||
35 | ") failed " \ | ||
36 | "[\n" \ | ||
37 | << (Va).transpose() << "\n!=\n" \ | ||
38 | << (Vb).transpose() << "\n]") | ||
39 | |||
40 | #define SE3CONFIG_IS_APPROX(Va, Vb) \ | ||
41 | { \ | ||
42 | BOOST_CHECK_MESSAGE((Va.head<3>()).isApprox(Vb.head<3>(), test_precision), \ | ||
43 | "check " #Va ".isApprox(" #Vb \ | ||
44 | ") failed " \ | ||
45 | "[\n" \ | ||
46 | << (Va).transpose() << "\n!=\n" \ | ||
47 | << (Vb).transpose() << "\n]"); \ | ||
48 | if ((Va.tail<4>().array() * Vb.tail<4>().array() > 0.01).any()) { \ | ||
49 | BOOST_CHECK_MESSAGE( \ | ||
50 | (Va.tail<4>()).isApprox(Vb.tail<4>(), test_precision), \ | ||
51 | "check " #Va ".isApprox(" #Vb \ | ||
52 | ") failed " \ | ||
53 | "[\n" \ | ||
54 | << (Va).transpose() << "\n!=\n" \ | ||
55 | << (Vb).transpose() << "\n]"); \ | ||
56 | } else { \ | ||
57 | BOOST_CHECK_MESSAGE( \ | ||
58 | (Va.tail<4>()).isApprox(-Vb.tail<4>(), test_precision), \ | ||
59 | "check " #Va ".isApprox(" #Vb \ | ||
60 | ") failed " \ | ||
61 | "[\n" \ | ||
62 | << (Va).transpose() << "\n!=\n" \ | ||
63 | << (Vb).transpose() << "\n]"); \ | ||
64 | } \ | ||
65 | } | ||
66 | |||
67 | #define EIGEN_VECTOR_IS_NOT_APPROX(Va, Vb) \ | ||
68 | BOOST_CHECK_MESSAGE(!Va.isApprox(Vb, test_precision), \ | ||
69 | "check !" #Va ".isApprox(" #Vb \ | ||
70 | ") failed " \ | ||
71 | "[\n" \ | ||
72 | << (Va).transpose() << "\n==\n" \ | ||
73 | << (Vb).transpose() << "\n]") | ||
74 | |||
75 | #define EIGEN_IS_APPROX(matrixA, matrixB) \ | ||
76 | BOOST_CHECK_MESSAGE(matrixA.isApprox(matrixB, test_precision), \ | ||
77 | "check " #matrixA ".isApprox(" #matrixB \ | ||
78 | ") failed " \ | ||
79 | "[\n" \ | ||
80 | << matrixA << "\n!=\n" \ | ||
81 | << matrixB << "\n]") | ||
82 | |||
83 | #define EIGEN_IS_NOT_APPROX(matrixA, matrixB) \ | ||
84 | BOOST_CHECK_MESSAGE(!matrixA.isApprox(matrixB, test_precision), \ | ||
85 | "check !" #matrixA ".isApprox(" #matrixB \ | ||
86 | ") failed " \ | ||
87 | "[\n" \ | ||
88 | << matrixA << "\n==\n" \ | ||
89 | << matrixB << "\n]") | ||
90 | |||
91 | #define SOLVER_CHECK_SOLVE(expr, expected) \ | ||
92 | { \ | ||
93 | hpp::constraints::solver::HierarchicalIterative::Status __status = expr; \ | ||
94 | BOOST_CHECK_MESSAGE( \ | ||
95 | __status == hpp::constraints::solver::HierarchicalIterative::expected, \ | ||
96 | "check " #expr " == " #expected " failed [" \ | ||
97 | << __status << " != " \ | ||
98 | << hpp::constraints::solver::HierarchicalIterative::expected \ | ||
99 | << "]"); \ | ||
100 | } | ||
101 | |||
102 | #include <boost/test/included/unit_test.hpp> | ||
103 | #include <hpp/constraints/differentiable-function.hh> | ||
104 | #include <hpp/constraints/fwd.hh> | ||
105 | #include <hpp/constraints/matrix-view.hh> | ||
106 | #include <hpp/pinocchio/device.hh> | ||
107 | #include <hpp/pinocchio/extra-config-space.hh> | ||
108 | #include <hpp/pinocchio/joint-collection.hh> | ||
109 | #include <hpp/pinocchio/joint.hh> | ||
110 | #include <hpp/pinocchio/util.hh> | ||
111 | #include <pinocchio/algorithm/joint-configuration.hpp> | ||
112 | #include <pinocchio/multibody/model.hpp> | ||
113 | |||
114 | 211 | void randomConfig(const hpp::pinocchio::DevicePtr_t& d, | |
115 | hpp::pinocchio::Configuration_t& q) { | ||
116 | using namespace hpp::constraints; | ||
117 | 211 | size_type extraDim = d->extraConfigSpace().dimension(); | |
118 | 211 | size_type offset = d->configSize() - extraDim; | |
119 | |||
120 | 211 | q.resize(d->configSize()); | |
121 |
2/4✓ Branch 4 taken 211 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 211 times.
✗ Branch 8 not taken.
|
211 | q.head(offset) = ::pinocchio::randomConfiguration(d->model()); |
122 | |||
123 | // Shoot extra configuration variables | ||
124 |
2/2✓ Branch 0 taken 303 times.
✓ Branch 1 taken 211 times.
|
514 | for (size_type i = 0; i < extraDim; ++i) { |
125 |
1/2✓ Branch 3 taken 303 times.
✗ Branch 4 not taken.
|
303 | value_type lower = d->extraConfigSpace().lower(i); |
126 |
1/2✓ Branch 3 taken 303 times.
✗ Branch 4 not taken.
|
303 | value_type upper = d->extraConfigSpace().upper(i); |
127 | 303 | value_type range = upper - lower; | |
128 |
3/6✓ Branch 0 taken 303 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 303 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 303 times.
|
303 | if ((range < 0) || (range == std::numeric_limits<double>::infinity())) { |
129 | ✗ | std::ostringstream oss; | |
130 | ✗ | oss << "Cannot uniformy sample extra config variable " << i | |
131 | ✗ | << ". min = " << lower << ", max = " << upper << std::endl; | |
132 | ✗ | throw std::runtime_error(oss.str()); | |
133 | } | ||
134 |
1/2✓ Branch 2 taken 303 times.
✗ Branch 3 not taken.
|
303 | q[offset + i] = lower + (upper - lower) * rand() / RAND_MAX; |
135 | } | ||
136 | 211 | } | |
137 | |||
138 | // This is an ugly fix to make BOOST_CHECK_EQUAL able to print segments_t | ||
139 | // when they are not equal. | ||
140 | namespace std { | ||
141 | ✗ | std::ostream& operator<<(std::ostream& os, | |
142 | hpp::constraints::BlockIndex::segments_t b) { | ||
143 | ✗ | return os << hpp::pretty_print(b); | |
144 | } | ||
145 | } // namespace std | ||
146 | |||
147 | class Quadratic : public hpp::constraints::DifferentiableFunction { | ||
148 | public: | ||
149 | typedef hpp::shared_ptr<Quadratic> Ptr_t; | ||
150 | typedef hpp::constraints::DifferentiableFunction DifferentiableFunction; | ||
151 | typedef hpp::constraints::matrix_t matrix_t; | ||
152 | typedef hpp::constraints::matrixOut_t matrixOut_t; | ||
153 | typedef hpp::constraints::vector_t vector_t; | ||
154 | typedef hpp::constraints::vectorIn_t vectorIn_t; | ||
155 | typedef hpp::constraints::LiegroupElementRef LiegroupElementRef; | ||
156 | typedef hpp::constraints::value_type value_type; | ||
157 | |||
158 | Quadratic(const matrix_t& _A, const vector_t& _b, const value_type& _c) | ||
159 | : hpp::constraints::DifferentiableFunction(_A.cols(), _A.cols(), 1, | ||
160 | "Quadratic"), | ||
161 | A(_A), | ||
162 | b(_b), | ||
163 | c(_c) { | ||
164 | check(); | ||
165 | } | ||
166 | |||
167 | 12 | Quadratic(const matrix_t& _A, const value_type& _c = 0) | |
168 | 12 | : hpp::constraints::DifferentiableFunction(_A.cols(), _A.cols(), 1, | |
169 | "Quadratic"), | ||
170 | 12 | A(_A), | |
171 |
2/4✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 12 times.
✗ Branch 6 not taken.
|
12 | b(vector_t::Zero(_A.rows())), |
172 |
3/6✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
✓ Branch 12 taken 12 times.
✗ Branch 13 not taken.
|
12 | c(_c) { |
173 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | check(); |
174 | 12 | } | |
175 | |||
176 | 12 | void check() const { | |
177 |
5/10✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
✓ Branch 9 taken 12 times.
✗ Branch 10 not taken.
✓ Branch 14 taken 12 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 12 times.
✗ Branch 18 not taken.
✗ Branch 22 not taken.
✓ Branch 23 taken 12 times.
|
12 | BOOST_REQUIRE(A.rows() == A.cols()); |
178 |
5/10✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
✓ Branch 9 taken 12 times.
✗ Branch 10 not taken.
✓ Branch 14 taken 12 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 12 times.
✗ Branch 18 not taken.
✗ Branch 22 not taken.
✓ Branch 23 taken 12 times.
|
12 | BOOST_REQUIRE(A.rows() == b.rows()); |
179 | 12 | } | |
180 | |||
181 | 346 | void impl_compute(LiegroupElementRef y, vectorIn_t x) const { | |
182 |
5/10✓ Branch 2 taken 346 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 346 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 346 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 346 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 346 times.
✗ Branch 16 not taken.
|
346 | y.vector()[0] = x.transpose() * A * x + b.dot(x) + c; |
183 | 346 | } | |
184 | |||
185 | 273 | void impl_jacobian(matrixOut_t J, vectorIn_t x) const { | |
186 |
6/12✓ Branch 2 taken 273 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 273 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 273 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 273 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 273 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 273 times.
✗ Branch 18 not taken.
|
273 | J.noalias() = 2 * x.transpose() * A + b.transpose(); |
187 | 273 | } | |
188 | |||
189 | matrix_t A; | ||
190 | vector_t b; | ||
191 | value_type c; | ||
192 | }; | ||
193 | |||
194 | #endif // TEST_UTIL_HH | ||
195 |