GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
// Copyright (c) 2017-2020, CNRS INRIA |
||
2 |
// Authors: Joseph Mirabel (joseph.mirabel@laas.fr) |
||
3 |
// |
||
4 |
|||
5 |
#include "pinocchio/multibody/liegroup/liegroup.hpp" |
||
6 |
#include "pinocchio/multibody/liegroup/liegroup-collection.hpp" |
||
7 |
#include "pinocchio/multibody/liegroup/liegroup-generic.hpp" |
||
8 |
#include "pinocchio/multibody/liegroup/cartesian-product-variant.hpp" |
||
9 |
|||
10 |
#include "pinocchio/multibody/joint/joint-generic.hpp" |
||
11 |
|||
12 |
#include <boost/test/unit_test.hpp> |
||
13 |
#include <boost/utility/binary.hpp> |
||
14 |
#include <boost/algorithm/string.hpp> |
||
15 |
#include <boost/mpl/vector.hpp> |
||
16 |
|||
17 |
#define EIGEN_VECTOR_IS_APPROX(Va, Vb, precision) \ |
||
18 |
BOOST_CHECK_MESSAGE((Va).isApprox(Vb, precision), \ |
||
19 |
"check " #Va ".isApprox(" #Vb ") failed " \ |
||
20 |
"[\n" << (Va).transpose() << "\n!=\n" << (Vb).transpose() << "\n]") |
||
21 |
#define EIGEN_MATRIX_IS_APPROX(Va, Vb, precision) \ |
||
22 |
BOOST_CHECK_MESSAGE((Va).isApprox(Vb, precision), \ |
||
23 |
"check " #Va ".isApprox(" #Vb ") failed " \ |
||
24 |
"[\n" << (Va) << "\n!=\n" << (Vb) << "\n]") |
||
25 |
|||
26 |
using namespace pinocchio; |
||
27 |
|||
28 |
#define VERBOSE false |
||
29 |
#define IFVERBOSE if(VERBOSE) |
||
30 |
|||
31 |
namespace pinocchio { |
||
32 |
template<typename Derived> |
||
33 |
std::ostream& operator<< (std::ostream& os, const LieGroupBase<Derived>& lg) |
||
34 |
{ |
||
35 |
return os << lg.name(); |
||
36 |
} |
||
37 |
template<typename LieGroupCollection> |
||
38 |
std::ostream& operator<< (std::ostream& os, const LieGroupGenericTpl<LieGroupCollection>& lg) |
||
39 |
{ |
||
40 |
return os << lg.name(); |
||
41 |
} |
||
42 |
} // namespace pinocchio |
||
43 |
|||
44 |
template <typename T> |
||
45 |
28640 |
void test_lie_group_methods (T & jmodel, typename T::JointDataDerived &) |
|
46 |
{ |
||
47 |
typedef typename LieGroup<T>::type LieGroupType; |
||
48 |
typedef double Scalar; |
||
49 |
|||
50 |
28640 |
const Scalar prec = Eigen::NumTraits<Scalar>::dummy_precision(); |
|
51 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗ |
28640 |
BOOST_TEST_MESSAGE ("Testing Joint over " << jmodel.shortname()); |
52 |
typedef typename T::ConfigVector_t ConfigVector_t; |
||
53 |
typedef typename T::TangentVector_t TangentVector_t; |
||
54 |
|||
55 |
✓✗✓✗ ✓✗ |
28640 |
ConfigVector_t q1(ConfigVector_t::Random (jmodel.nq())); |
56 |
✓✗✓✗ ✓✗ |
28640 |
TangentVector_t q1_dot(TangentVector_t::Random (jmodel.nv())); |
57 |
✓✗✓✗ ✓✗ |
28640 |
ConfigVector_t q2(ConfigVector_t::Random (jmodel.nq())); |
58 |
|||
59 |
✓✓✓✗ ✓✗✓✗ ✓✗✗✗ |
28640 |
static ConfigVector_t Ones(ConfigVector_t::Ones(jmodel.nq())); |
60 |
28640 |
const Scalar u = 0.3; |
|
61 |
// pinocchio::Inertia::Matrix6 Ia(pinocchio::Inertia::Random().matrix()); |
||
62 |
// bool update_I = false; |
||
63 |
|||
64 |
✓✗✓✗ ✓✗ |
28640 |
q1 = LieGroupType().randomConfiguration(-Ones, Ones); |
65 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
28640 |
BOOST_CHECK(LieGroupType().isNormalized(q1)); |
66 |
|||
67 |
✓✗ | 28640 |
typename T::JointDataDerived jdata = jmodel.createData(); |
68 |
|||
69 |
// Check integrate |
||
70 |
✓✗ | 28640 |
jmodel.calc(jdata, q1, q1_dot); |
71 |
✓✗ | 28640 |
SE3 M1 = jdata.M; |
72 |
✓✗ | 28640 |
Motion v1(jdata.v); |
73 |
|||
74 |
✓✗✓✗ |
28640 |
q2 = LieGroupType().integrate(q1,q1_dot); |
75 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
28640 |
BOOST_CHECK(LieGroupType().isNormalized(q2)); |
76 |
✓✗ | 28640 |
jmodel.calc(jdata,q2); |
77 |
✓✗ | 28640 |
SE3 M2 = jdata.M; |
78 |
|||
79 |
28640 |
double tol_test = 1e2; |
|
80 |
✓✗✓✓ |
28640 |
if(jmodel.shortname() == "JointModelPlanar") |
81 |
2040 |
tol_test = 5e4; |
|
82 |
|||
83 |
✓✗✓✗ |
28640 |
const SE3 M2_exp = M1*exp6(v1); |
84 |
|||
85 |
✓✗✓✓ |
28640 |
if(jmodel.shortname() != "JointModelSphericalZYX") |
86 |
{ |
||
87 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
26600 |
BOOST_CHECK_MESSAGE(M2.isApprox(M2_exp), std::string("Error when integrating1 " + jmodel.shortname())); |
88 |
} |
||
89 |
|||
90 |
// Check integrate when the same vector is passed as input and output |
||
91 |
✓✗✓✗ ✓✗ |
28640 |
ConfigVector_t qTest(ConfigVector_t::Random (jmodel.nq())); |
92 |
✓✗✓✗ ✓✗ |
28640 |
TangentVector_t qTest_dot(TangentVector_t::Random (jmodel.nv())); |
93 |
✓✗✓✗ ✓✗ |
28640 |
ConfigVector_t qResult(ConfigVector_t::Random (jmodel.nq())); |
94 |
✓✗✓✗ ✓✗ |
28640 |
qTest = LieGroupType().randomConfiguration(-Ones, Ones); |
95 |
✓✗✓✗ |
28640 |
qResult = LieGroupType().integrate(qTest, qTest_dot); |
96 |
✓✗✓✗ |
28640 |
LieGroupType().integrate(qTest, qTest_dot, qTest); |
97 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
28640 |
BOOST_CHECK_MESSAGE(LieGroupType().isNormalized(qTest), |
98 |
std::string("Normalization error when integrating with same input and output " + jmodel.shortname())); |
||
99 |
|||
100 |
✓✗✓✗ |
28640 |
SE3 MTest, MResult; |
101 |
{ |
||
102 |
✓✗ | 28640 |
typename T::JointDataDerived jdata = jmodel.createData(); |
103 |
✓✗ | 28640 |
jmodel.calc(jdata, qTest); |
104 |
✓✗ | 28640 |
MTest = jdata.M; |
105 |
} |
||
106 |
{ |
||
107 |
✓✗ | 28640 |
typename T::JointDataDerived jdata = jmodel.createData(); |
108 |
✓✗ | 28640 |
jmodel.calc(jdata, qResult); |
109 |
✓✗ | 28640 |
MResult = jdata.M; |
110 |
} |
||
111 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
28640 |
BOOST_CHECK_MESSAGE(MTest.isApprox(MResult), |
112 |
std::string("Inconsistent value when integrating with same input and output " + jmodel.shortname())); |
||
113 |
|||
114 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
28640 |
BOOST_CHECK_MESSAGE(qTest.isApprox(qResult,prec), |
115 |
std::string("Inconsistent value when integrating with same input and output " + jmodel.shortname())); |
||
116 |
|||
117 |
// Check the reversability of integrate |
||
118 |
✓✗✓✗ ✓✗ |
28640 |
ConfigVector_t q3 = LieGroupType().integrate(q2,-q1_dot); |
119 |
✓✗ | 28640 |
jmodel.calc(jdata,q3); |
120 |
✓✗ | 28640 |
SE3 M3 = jdata.M; |
121 |
|||
122 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
28640 |
BOOST_CHECK_MESSAGE(M3.isApprox(M1), std::string("Error when integrating back " + jmodel.shortname())); |
123 |
|||
124 |
// Check interpolate |
||
125 |
✓✗✓✗ |
28640 |
ConfigVector_t q_interpolate = LieGroupType().interpolate(q1,q2,0.); |
126 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
28640 |
BOOST_CHECK_MESSAGE(q_interpolate.isApprox(q1), std::string("Error when interpolating " + jmodel.shortname())); |
127 |
|||
128 |
✓✗✓✗ |
28640 |
q_interpolate = LieGroupType().interpolate(q1,q2,1.); |
129 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
28640 |
BOOST_CHECK_MESSAGE(q_interpolate.isApprox(q2,tol_test*prec), std::string("Error when interpolating " + jmodel.shortname())); |
130 |
|||
131 |
✓✗✓✓ |
28640 |
if(jmodel.shortname() != "JointModelSphericalZYX") |
132 |
{ |
||
133 |
✓✗✓✗ |
26600 |
q_interpolate = LieGroupType().interpolate(q1,q2,u); |
134 |
✓✗ | 26600 |
jmodel.calc(jdata,q_interpolate); |
135 |
✓✗ | 26600 |
SE3 M_interpolate = jdata.M; |
136 |
|||
137 |
✓✗✓✗ ✓✗ |
26600 |
SE3 M_interpolate_expected = M1*exp6(u*v1); |
138 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
26600 |
BOOST_CHECK_MESSAGE(M_interpolate_expected.isApprox(M_interpolate,1e4*prec), std::string("Error when interpolating " + jmodel.shortname())); |
139 |
} |
||
140 |
|||
141 |
// Check that difference between two equal configuration is exactly 0 |
||
142 |
✓✗✓✗ |
28640 |
TangentVector_t zero = LieGroupType().difference(q1,q1); |
143 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
28640 |
BOOST_CHECK_MESSAGE (zero.isZero(), std::string ("Error: difference between two equal configurations is not 0.")); |
144 |
✓✗✓✗ |
28640 |
zero = LieGroupType().difference(q2,q2); |
145 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
28640 |
BOOST_CHECK_MESSAGE (zero.isZero(), std::string ("Error: difference between two equal configurations is not 0.")); |
146 |
|||
147 |
// Check difference |
||
148 |
// TODO(jcarpent): check the increase of tolerance. |
||
149 |
|||
150 |
|||
151 |
✓✗✓✗ |
28640 |
TangentVector_t vdiff = LieGroupType().difference(q1,q2); |
152 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
28640 |
BOOST_CHECK_MESSAGE(vdiff.isApprox(q1_dot,tol_test*prec), std::string("Error when differentiating " + jmodel.shortname())); |
153 |
|||
154 |
// Check distance |
||
155 |
✓✗✓✗ |
28640 |
Scalar dist = LieGroupType().distance(q1,q2); |
156 |
✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
28640 |
BOOST_CHECK_MESSAGE(dist > 0., "distance - wrong results"); |
157 |
✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
28640 |
BOOST_CHECK_SMALL(math::fabs(dist-q1_dot.norm()), tol_test*prec); |
158 |
|||
159 |
✓✗ | 57280 |
std::string error_prefix("LieGroup"); |
160 |
✓✗✓✗ ✓✗ |
28640 |
error_prefix += " on joint " + jmodel.shortname(); |
161 |
|||
162 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
28640 |
BOOST_CHECK_MESSAGE(jmodel.nq() == LieGroupType::NQ, std::string(error_prefix + " - nq ")); |
163 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
28640 |
BOOST_CHECK_MESSAGE(jmodel.nv() == LieGroupType::NV, std::string(error_prefix + " - nv ")); |
164 |
|||
165 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
28640 |
BOOST_CHECK_MESSAGE |
166 |
(jmodel.nq() == |
||
167 |
LieGroupType().randomConfiguration(-1 * Ones, Ones).size(), |
||
168 |
std::string(error_prefix + " - RandomConfiguration dimensions ")); |
||
169 |
|||
170 |
✓✗✓✗ |
28640 |
ConfigVector_t q_normalize(ConfigVector_t::Random()); |
171 |
✓✗ | 57280 |
Eigen::VectorXd q_normalize_ref(q_normalize); |
172 |
✓✗✓✓ |
28640 |
if(jmodel.shortname() == "JointModelSpherical") |
173 |
{ |
||
174 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
2040 |
BOOST_CHECK_MESSAGE(!LieGroupType().isNormalized(q_normalize_ref), std::string(error_prefix + " - !isNormalized ")); |
175 |
✓✗✓✗ |
2040 |
q_normalize_ref /= q_normalize_ref.norm(); |
176 |
} |
||
177 |
✓✗✓✓ |
26600 |
else if(jmodel.shortname() == "JointModelFreeFlyer") |
178 |
{ |
||
179 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
2040 |
BOOST_CHECK_MESSAGE(!LieGroupType().isNormalized(q_normalize_ref), std::string(error_prefix + " - !isNormalized ")); |
180 |
✓✗✓✗ ✓✗✓✗ |
2040 |
q_normalize_ref.template tail<4>() /= q_normalize_ref.template tail<4>().norm(); |
181 |
} |
||
182 |
✓✗✓✗ ✓✓ |
24560 |
else if(boost::algorithm::istarts_with(jmodel.shortname(),"JointModelRUB")) |
183 |
{ |
||
184 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
6120 |
BOOST_CHECK_MESSAGE(!LieGroupType().isNormalized(q_normalize_ref), std::string(error_prefix + " - !isNormalized ")); |
185 |
✓✗✓✗ |
6120 |
q_normalize_ref /= q_normalize_ref.norm(); |
186 |
} |
||
187 |
✓✗✓✓ |
18440 |
else if(jmodel.shortname() == "JointModelPlanar") |
188 |
{ |
||
189 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
2040 |
BOOST_CHECK_MESSAGE(!LieGroupType().isNormalized(q_normalize_ref), std::string(error_prefix + " - !isNormalized ")); |
190 |
✓✗✓✗ ✓✗✓✗ |
2040 |
q_normalize_ref.template tail<2>() /= q_normalize_ref.template tail<2>().norm(); |
191 |
} |
||
192 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
28640 |
BOOST_CHECK_MESSAGE(LieGroupType().isNormalized(q_normalize_ref), std::string(error_prefix + " - isNormalized ")); |
193 |
✓✗✓✗ |
28640 |
LieGroupType().normalize(q_normalize); |
194 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
28640 |
BOOST_CHECK_MESSAGE(q_normalize.isApprox(q_normalize_ref), std::string(error_prefix + " - normalize ")); |
195 |
28640 |
} |
|
196 |
|||
197 |
struct TestJoint{ |
||
198 |
|||
199 |
template <typename T> |
||
200 |
560 |
void operator()(const T ) const |
|
201 |
{ |
||
202 |
✓✗ | 560 |
T jmodel; |
203 |
✓✗ | 560 |
jmodel.setIndexes(0,0,0); |
204 |
✓✗ | 560 |
typename T::JointDataDerived jdata = jmodel.createData(); |
205 |
|||
206 |
✓✓ | 29120 |
for (int i = 0; i <= 50; ++i) |
207 |
{ |
||
208 |
✓✗ | 28560 |
test_lie_group_methods(jmodel, jdata); |
209 |
} |
||
210 |
560 |
} |
|
211 |
|||
212 |
20 |
void operator()(const pinocchio::JointModelRevoluteUnaligned & ) const |
|
213 |
{ |
||
214 |
✓✗ | 20 |
pinocchio::JointModelRevoluteUnaligned jmodel(1.5, 1., 0.); |
215 |
✓✗ | 20 |
jmodel.setIndexes(0,0,0); |
216 |
✓✗ | 20 |
pinocchio::JointModelRevoluteUnaligned::JointDataDerived jdata = jmodel.createData(); |
217 |
|||
218 |
✓✗ | 20 |
test_lie_group_methods(jmodel, jdata); |
219 |
20 |
} |
|
220 |
|||
221 |
20 |
void operator()(const pinocchio::JointModelPrismaticUnaligned & ) const |
|
222 |
{ |
||
223 |
✓✗ | 20 |
pinocchio::JointModelPrismaticUnaligned jmodel(1.5, 1., 0.); |
224 |
✓✗ | 20 |
jmodel.setIndexes(0,0,0); |
225 |
✓✗ | 20 |
pinocchio::JointModelPrismaticUnaligned::JointDataDerived jdata = jmodel.createData(); |
226 |
|||
227 |
✓✗ | 20 |
test_lie_group_methods(jmodel, jdata); |
228 |
20 |
} |
|
229 |
|||
230 |
}; |
||
231 |
|||
232 |
struct LieGroup_Jdifference{ |
||
233 |
template <typename T> |
||
234 |
320 |
void operator()(const T ) const |
|
235 |
{ |
||
236 |
typedef typename T::ConfigVector_t ConfigVector_t; |
||
237 |
typedef typename T::TangentVector_t TangentVector_t; |
||
238 |
typedef typename T::JacobianMatrix_t JacobianMatrix_t; |
||
239 |
typedef typename T::Scalar Scalar; |
||
240 |
|||
241 |
✓✗ | 320 |
T lg; |
242 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
320 |
BOOST_TEST_MESSAGE (lg.name()); |
243 |
✓✓✓✗ ✓✓✓✗ |
1600 |
ConfigVector_t q[2], q_dv[2]; |
244 |
✓✗ | 320 |
q[0] = lg.random(); |
245 |
✓✗ | 320 |
q[1] = lg.random(); |
246 |
✓✗✓✗ ✓✗ |
320 |
TangentVector_t va, vb, dv; |
247 |
✓✓✓✗ |
960 |
JacobianMatrix_t J[2]; |
248 |
✓✗ | 320 |
dv.setZero(); |
249 |
|||
250 |
✓✗ | 320 |
lg.difference (q[0], q[1], va); |
251 |
✓✗ | 320 |
lg.template dDifference<ARG0> (q[0], q[1], J[0]); |
252 |
✓✗ | 320 |
lg.template dDifference<ARG1> (q[0], q[1], J[1]); |
253 |
|||
254 |
320 |
const Scalar eps = 1e-6; |
|
255 |
✓✓ | 960 |
for (int k = 0; k < 2; ++k) { |
256 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
640 |
BOOST_TEST_MESSAGE ("Checking J" << k << '\n' << J[k]); |
257 |
✓✗ | 640 |
q_dv[0] = q[0]; |
258 |
✓✗ | 640 |
q_dv[1] = q[1]; |
259 |
// Check J[k] |
||
260 |
✓✗✓✓ |
2640 |
for (int i = 0; i < dv.size(); ++i) |
261 |
{ |
||
262 |
✓✗ | 2000 |
dv[i] = eps; |
263 |
✓✗ | 2000 |
lg.integrate (q[k], dv, q_dv[k]); |
264 |
✓✗ | 2000 |
lg.difference (q_dv[0], q_dv[1], vb); |
265 |
|||
266 |
// vb - va ~ J[k] * dv |
||
267 |
✓✗✓✗ |
2000 |
TangentVector_t J_dv = J[k].col(i); |
268 |
✓✗✓✗ ✓✗ |
2000 |
TangentVector_t vb_va = (vb - va) / eps; |
269 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
2000 |
EIGEN_VECTOR_IS_APPROX (vb_va, J_dv, 1e-2); |
270 |
✓✗ | 2000 |
dv[i] = 0; |
271 |
} |
||
272 |
} |
||
273 |
|||
274 |
✓✗✓✗ |
320 |
specificTests(lg); |
275 |
320 |
} |
|
276 |
|||
277 |
template <typename T> |
||
278 |
240 |
void specificTests(const T ) const |
|
279 |
240 |
{} |
|
280 |
|||
281 |
template <typename Scalar, int Options> |
||
282 |
20 |
void specificTests(const SpecialEuclideanOperationTpl<3,Scalar,Options>) const |
|
283 |
{ |
||
284 |
typedef SE3Tpl<Scalar> SE3; |
||
285 |
typedef SpecialEuclideanOperationTpl<3,Scalar,Options> LG_t; |
||
286 |
typedef typename LG_t::ConfigVector_t ConfigVector_t; |
||
287 |
typedef typename LG_t::JacobianMatrix_t JacobianMatrix_t; |
||
288 |
typedef typename LG_t::ConstQuaternionMap_t ConstQuaternionMap_t; |
||
289 |
|||
290 |
✓✗ | 20 |
LG_t lg; |
291 |
|||
292 |
✓✓✓✗ |
60 |
ConfigVector_t q[2]; |
293 |
✓✗ | 20 |
q[0] = lg.random(); |
294 |
✓✗ | 20 |
q[1] = lg.random(); |
295 |
|||
296 |
✓✗✓✗ ✓✗✓✗ |
20 |
ConstQuaternionMap_t quat0(q[0].template tail<4>().data()), quat1(q[1].template tail<4>().data()); |
297 |
✓✓✓✗ |
60 |
JacobianMatrix_t J[2]; |
298 |
|||
299 |
✓✗ | 20 |
lg.template dDifference<ARG0> (q[0], q[1], J[0]); |
300 |
✓✗ | 20 |
lg.template dDifference<ARG1> (q[0], q[1], J[1]); |
301 |
|||
302 |
✓✗✓✗ ✓✗✓✗ ✓✗ |
20 |
SE3 om0 (typename SE3::Quaternion (q[0].template tail<4>()).matrix(), q[0].template head<3>()), |
303 |
✓✗✓✗ ✓✗✓✗ ✓✗ |
20 |
om1 (typename SE3::Quaternion (q[1].template tail<4>()).matrix(), q[1].template head<3>()), |
304 |
✓✗ | 20 |
_1m2 (om1.actInv (om0)) ; |
305 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
20 |
EIGEN_MATRIX_IS_APPROX (J[1] * _1m2.toActionMatrix(), - J[0], 1e-8); |
306 |
|||
307 |
// Test against SE3::Interpolate |
||
308 |
20 |
const Scalar u = 0.3; |
|
309 |
✓✗ | 20 |
ConfigVector_t q_interp = lg.interpolate(q[0],q[1],u); |
310 |
✓✗✓✗ |
20 |
ConstQuaternionMap_t quat_interp(q_interp.template tail<4>().data()); |
311 |
|||
312 |
✓✗✓✗ |
20 |
SE3 M0(quat0,q[0].template head<3>()); |
313 |
✓✗✓✗ |
20 |
SE3 M1(quat1,q[1].template head<3>()); |
314 |
|||
315 |
✓✗ | 20 |
SE3 M_u = SE3::Interpolate(M0,M1,u); |
316 |
✓✗✓✗ |
20 |
SE3 M_interp(quat_interp,q_interp.template head<3>()); |
317 |
|||
318 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
20 |
BOOST_CHECK(M_u.isApprox(M_interp)); |
319 |
20 |
} |
|
320 |
|||
321 |
template <typename Scalar, int Options> |
||
322 |
20 |
void specificTests(const CartesianProductOperation< |
|
323 |
VectorSpaceOperationTpl<3,Scalar,Options>, |
||
324 |
SpecialOrthogonalOperationTpl<3,Scalar,Options> |
||
325 |
>) const |
||
326 |
{ |
||
327 |
typedef SE3Tpl<Scalar> SE3; |
||
328 |
typedef CartesianProductOperation< |
||
329 |
VectorSpaceOperationTpl<3,Scalar,Options>, |
||
330 |
SpecialOrthogonalOperationTpl<3,Scalar,Options> |
||
331 |
> LG_t; |
||
332 |
typedef typename LG_t::ConfigVector_t ConfigVector_t; |
||
333 |
typedef typename LG_t::JacobianMatrix_t JacobianMatrix_t; |
||
334 |
|||
335 |
✓✗ | 20 |
LG_t lg; |
336 |
|||
337 |
✓✓✓✗ |
60 |
ConfigVector_t q[2]; |
338 |
✓✗ | 20 |
q[0] = lg.random(); |
339 |
✓✗ | 20 |
q[1] = lg.random(); |
340 |
✓✓✓✗ |
60 |
JacobianMatrix_t J[2]; |
341 |
|||
342 |
✓✗ | 20 |
lg.template dDifference<ARG0> (q[0], q[1], J[0]); |
343 |
✓✗ | 20 |
lg.template dDifference<ARG1> (q[0], q[1], J[1]); |
344 |
|||
345 |
typename SE3::Matrix3 |
||
346 |
✓✗✓✗ ✓✗ |
20 |
oR0 (typename SE3::Quaternion (q[0].template tail<4>()).matrix()), |
347 |
✓✗✓✗ ✓✗ |
20 |
oR1 (typename SE3::Quaternion (q[1].template tail<4>()).matrix()); |
348 |
✓✗✓✗ |
20 |
JacobianMatrix_t X (JacobianMatrix_t::Identity()); |
349 |
✓✗✓✗ ✓✗✓✗ |
20 |
X.template bottomRightCorner<3,3>() = oR1.transpose() * oR0; |
350 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
20 |
EIGEN_MATRIX_IS_APPROX (J[1] * X, - J[0], 1e-8); |
351 |
20 |
} |
|
352 |
}; |
||
353 |
|||
354 |
template<bool around_identity> |
||
355 |
struct LieGroup_Jintegrate{ |
||
356 |
template <typename T> |
||
357 |
336 |
void operator()(const T ) const |
|
358 |
{ |
||
359 |
typedef typename T::ConfigVector_t ConfigVector_t; |
||
360 |
typedef typename T::TangentVector_t TangentVector_t; |
||
361 |
typedef typename T::JacobianMatrix_t JacobianMatrix_t; |
||
362 |
typedef typename T::Scalar Scalar; |
||
363 |
|||
364 |
✓✗ | 336 |
T lg; |
365 |
✓✗ | 336 |
ConfigVector_t q = lg.random(); |
366 |
✓✗✓✗ ✓✗ |
336 |
TangentVector_t v, dq, dv; |
367 |
if(around_identity) |
||
368 |
✓✗ | 16 |
v.setZero(); |
369 |
else |
||
370 |
✓✗ | 320 |
v.setRandom(); |
371 |
|||
372 |
✓✗ | 336 |
dq.setZero(); |
373 |
✓✗ | 336 |
dv.setZero(); |
374 |
|||
375 |
✓✗ | 336 |
ConfigVector_t q_v = lg.integrate (q, v); |
376 |
|||
377 |
✓✗✓✗ |
336 |
JacobianMatrix_t Jq, Jv; |
378 |
✓✗ | 336 |
lg.dIntegrate_dq (q, v, Jq); |
379 |
✓✗ | 336 |
lg.dIntegrate_dv (q, v, Jv); |
380 |
|||
381 |
336 |
const Scalar eps = 1e-6; |
|
382 |
✓✗✓✓ |
1386 |
for (int i = 0; i < v.size(); ++i) |
383 |
{ |
||
384 |
✓✗✓✗ |
1050 |
dq[i] = dv[i] = eps; |
385 |
✓✗ | 1050 |
ConfigVector_t q_dq = lg.integrate (q, dq); |
386 |
|||
387 |
✓✗ | 1050 |
ConfigVector_t q_dq_v = lg.integrate (q_dq, v); |
388 |
✓✗✓✗ |
1050 |
TangentVector_t Jq_dq = Jq.col(i); |
389 |
// q_dv_v - q_v ~ Jq dv |
||
390 |
✓✗✓✗ ✓✗ |
1050 |
TangentVector_t dI_dq = lg.difference (q_v, q_dq_v) / eps; |
391 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
1050 |
EIGEN_VECTOR_IS_APPROX (dI_dq, Jq_dq, 1e-2); |
392 |
|||
393 |
✓✗✓✗ ✓✗ |
1050 |
ConfigVector_t q_v_dv = lg.integrate (q, (v+dv).eval()); |
394 |
✓✗✓✗ |
1050 |
TangentVector_t Jv_dv = Jv.col(i); |
395 |
// q_v_dv - q_v ~ Jv dv |
||
396 |
✓✗✓✗ ✓✗ |
1050 |
TangentVector_t dI_dv = lg.difference (q_v, q_v_dv) / eps; |
397 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
1050 |
EIGEN_VECTOR_IS_APPROX (dI_dv, Jv_dv, 1e-2); |
398 |
|||
399 |
✓✗✓✗ |
1050 |
dq[i] = dv[i] = 0; |
400 |
} |
||
401 |
336 |
} |
|
402 |
}; |
||
403 |
|||
404 |
struct LieGroup_JintegrateJdifference{ |
||
405 |
template <typename T> |
||
406 |
320 |
void operator()(const T ) const |
|
407 |
{ |
||
408 |
typedef typename T::ConfigVector_t ConfigVector_t; |
||
409 |
typedef typename T::TangentVector_t TangentVector_t; |
||
410 |
typedef typename T::JacobianMatrix_t JacobianMatrix_t; |
||
411 |
|||
412 |
✓✗ | 320 |
T lg; |
413 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
320 |
BOOST_TEST_MESSAGE (lg.name()); |
414 |
✓✗✓✓ ✗✓✗ |
320 |
ConfigVector_t qa, qb (lg.nq()); |
415 |
✓✗ | 320 |
qa = lg.random(); |
416 |
✓✓✗✓ ✗ |
320 |
TangentVector_t v (lg.nv()); |
417 |
✓✗ | 320 |
v.setRandom (); |
418 |
✓✗ | 320 |
lg.integrate(qa, v, qb); |
419 |
|||
420 |
✓✗✓✗ |
320 |
JacobianMatrix_t Jd_qb, Ji_v; |
421 |
|||
422 |
✓✗ | 320 |
lg.template dDifference<ARG1> (qa, qb, Jd_qb); |
423 |
✓✗ | 320 |
lg.template dIntegrate <ARG1> (qa, v , Ji_v ); |
424 |
|||
425 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
320 |
BOOST_CHECK_MESSAGE ((Jd_qb * Ji_v).isIdentity(), |
426 |
"Jd_qb\n" << |
||
427 |
Jd_qb << '\n' << |
||
428 |
"* Ji_v\n" << |
||
429 |
Ji_v << '\n' << |
||
430 |
"!= Identity\n" << |
||
431 |
Jd_qb * Ji_v << '\n'); |
||
432 |
320 |
} |
|
433 |
}; |
||
434 |
|||
435 |
struct LieGroup_JintegrateCoeffWise |
||
436 |
{ |
||
437 |
template <typename T> |
||
438 |
320 |
void operator()(const T ) const |
|
439 |
{ |
||
440 |
typedef typename T::ConfigVector_t ConfigVector_t; |
||
441 |
typedef typename T::TangentVector_t TangentVector_t; |
||
442 |
typedef typename T::Scalar Scalar; |
||
443 |
|||
444 |
✓✗ | 320 |
T lg; |
445 |
✓✗ | 320 |
ConfigVector_t q = lg.random(); |
446 |
✓✓✗✓ ✓✗✓✗ |
320 |
TangentVector_t dv(TangentVector_t::Zero(lg.nv())); |
447 |
|||
448 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
320 |
BOOST_TEST_MESSAGE (lg.name()); |
449 |
typedef Eigen::Matrix<Scalar,T::NQ,T::NV> JacobianCoeffs; |
||
450 |
✓✗✓✓ ✗✓✓✗ ✓✗ |
320 |
JacobianCoeffs Jintegrate(JacobianCoeffs::Zero(lg.nq(),lg.nv())); |
451 |
✓✗ | 320 |
lg.integrateCoeffWiseJacobian(q,Jintegrate); |
452 |
✓✗✓✓ ✗✓✓✗ ✓✗ |
320 |
JacobianCoeffs Jintegrate_fd(JacobianCoeffs::Zero(lg.nq(),lg.nv())); |
453 |
|||
454 |
320 |
const Scalar eps = 1e-8; |
|
455 |
✓✓✓✓ |
1320 |
for (int i = 0; i < lg.nv(); ++i) |
456 |
{ |
||
457 |
✓✗ | 1000 |
dv[i] = eps; |
458 |
✓✓✗✓ ✓✗✓✗ |
1000 |
ConfigVector_t q_next(ConfigVector_t::Zero(lg.nq())); |
459 |
✓✗ | 1000 |
lg.integrate(q, dv,q_next); |
460 |
✓✗✓✗ ✓✗✓✗ |
1000 |
Jintegrate_fd.col(i) = (q_next - q)/eps; |
461 |
|||
462 |
✓✗ | 1000 |
dv[i] = 0; |
463 |
} |
||
464 |
|||
465 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
320 |
EIGEN_MATRIX_IS_APPROX(Jintegrate, Jintegrate_fd, sqrt(eps)); |
466 |
320 |
} |
|
467 |
}; |
||
468 |
|||
469 |
BOOST_AUTO_TEST_SUITE ( BOOST_TEST_MODULE ) |
||
470 |
|||
471 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗ |
4 |
BOOST_AUTO_TEST_CASE ( test_all ) |
472 |
{ |
||
473 |
typedef boost::variant< JointModelRX, JointModelRY, JointModelRZ, JointModelRevoluteUnaligned |
||
474 |
, JointModelSpherical, JointModelSphericalZYX |
||
475 |
, JointModelPX, JointModelPY, JointModelPZ |
||
476 |
, JointModelPrismaticUnaligned |
||
477 |
, JointModelFreeFlyer |
||
478 |
, JointModelPlanar |
||
479 |
, JointModelTranslation |
||
480 |
, JointModelRUBX, JointModelRUBY, JointModelRUBZ |
||
481 |
> Variant; |
||
482 |
✓✓ | 42 |
for (int i = 0; i < 20; ++i) |
483 |
✓✗ | 40 |
boost::mpl::for_each<Variant::types>(TestJoint()); |
484 |
|||
485 |
// FIXME JointModelComposite does not work. |
||
486 |
// boost::mpl::for_each<JointModelVariant::types>(TestJoint()); |
||
487 |
|||
488 |
2 |
} |
|
489 |
|||
490 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗ |
4 |
BOOST_AUTO_TEST_CASE ( Jdifference ) |
491 |
{ |
||
492 |
typedef double Scalar; |
||
493 |
enum { Options = 0 }; |
||
494 |
|||
495 |
typedef boost::mpl::vector< VectorSpaceOperationTpl<1,Scalar,Options> |
||
496 |
, VectorSpaceOperationTpl<2,Scalar,Options> |
||
497 |
, SpecialOrthogonalOperationTpl<2,Scalar,Options> |
||
498 |
, SpecialOrthogonalOperationTpl<3,Scalar,Options> |
||
499 |
, SpecialEuclideanOperationTpl<2,Scalar,Options> |
||
500 |
, SpecialEuclideanOperationTpl<3,Scalar,Options> |
||
501 |
, CartesianProductOperation< |
||
502 |
VectorSpaceOperationTpl<2,Scalar,Options>, |
||
503 |
SpecialOrthogonalOperationTpl<2,Scalar,Options> |
||
504 |
> |
||
505 |
, CartesianProductOperation< |
||
506 |
VectorSpaceOperationTpl<3,Scalar,Options>, |
||
507 |
SpecialOrthogonalOperationTpl<3,Scalar,Options> |
||
508 |
> |
||
509 |
> Types; |
||
510 |
✓✓ | 42 |
for (int i = 0; i < 20; ++i) |
511 |
✓✗ | 40 |
boost::mpl::for_each<Types>(LieGroup_Jdifference()); |
512 |
2 |
} |
|
513 |
|||
514 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗ |
4 |
BOOST_AUTO_TEST_CASE ( Jintegrate ) |
515 |
{ |
||
516 |
typedef double Scalar; |
||
517 |
enum { Options = 0 }; |
||
518 |
|||
519 |
typedef boost::mpl::vector< VectorSpaceOperationTpl<1,Scalar,Options> |
||
520 |
, VectorSpaceOperationTpl<2,Scalar,Options> |
||
521 |
, SpecialOrthogonalOperationTpl<2,Scalar,Options> |
||
522 |
, SpecialOrthogonalOperationTpl<3,Scalar,Options> |
||
523 |
, SpecialEuclideanOperationTpl<2,Scalar,Options> |
||
524 |
, SpecialEuclideanOperationTpl<3,Scalar,Options> |
||
525 |
, CartesianProductOperation< |
||
526 |
VectorSpaceOperationTpl<2,Scalar,Options>, |
||
527 |
SpecialOrthogonalOperationTpl<2,Scalar,Options> |
||
528 |
> |
||
529 |
, CartesianProductOperation< |
||
530 |
VectorSpaceOperationTpl<3,Scalar,Options>, |
||
531 |
SpecialOrthogonalOperationTpl<3,Scalar,Options> |
||
532 |
> |
||
533 |
> Types; |
||
534 |
✓✓ | 42 |
for (int i = 0; i < 20; ++i) |
535 |
✓✗ | 40 |
boost::mpl::for_each<Types>(LieGroup_Jintegrate<false>()); |
536 |
|||
537 |
// Around identity |
||
538 |
✓✗ | 2 |
boost::mpl::for_each<Types>(LieGroup_Jintegrate<true>()); |
539 |
2 |
} |
|
540 |
|||
541 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗ |
4 |
BOOST_AUTO_TEST_CASE ( Jintegrate_Jdifference ) |
542 |
{ |
||
543 |
typedef double Scalar; |
||
544 |
enum { Options = 0 }; |
||
545 |
|||
546 |
typedef boost::mpl::vector< VectorSpaceOperationTpl<1,Scalar,Options> |
||
547 |
, VectorSpaceOperationTpl<2,Scalar,Options> |
||
548 |
, SpecialOrthogonalOperationTpl<2,Scalar,Options> |
||
549 |
, SpecialOrthogonalOperationTpl<3,Scalar,Options> |
||
550 |
, SpecialEuclideanOperationTpl<2,Scalar,Options> |
||
551 |
, SpecialEuclideanOperationTpl<3,Scalar,Options> |
||
552 |
, CartesianProductOperation< |
||
553 |
VectorSpaceOperationTpl<2,Scalar,Options>, |
||
554 |
SpecialOrthogonalOperationTpl<2,Scalar,Options> |
||
555 |
> |
||
556 |
, CartesianProductOperation< |
||
557 |
VectorSpaceOperationTpl<3,Scalar,Options>, |
||
558 |
SpecialOrthogonalOperationTpl<3,Scalar,Options> |
||
559 |
> |
||
560 |
> Types; |
||
561 |
✓✓ | 42 |
for (int i = 0; i < 20; ++i) |
562 |
✓✗ | 40 |
boost::mpl::for_each<Types>(LieGroup_JintegrateJdifference()); |
563 |
2 |
} |
|
564 |
|||
565 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗ |
4 |
BOOST_AUTO_TEST_CASE(JintegrateCoeffWise) |
566 |
{ |
||
567 |
typedef double Scalar; |
||
568 |
enum { Options = 0 }; |
||
569 |
|||
570 |
typedef boost::mpl::vector< VectorSpaceOperationTpl<1,Scalar,Options> |
||
571 |
, VectorSpaceOperationTpl<2,Scalar,Options> |
||
572 |
, SpecialOrthogonalOperationTpl<2,Scalar,Options> |
||
573 |
, SpecialOrthogonalOperationTpl<3,Scalar,Options> |
||
574 |
, SpecialEuclideanOperationTpl<2,Scalar,Options> |
||
575 |
, SpecialEuclideanOperationTpl<3,Scalar,Options> |
||
576 |
, CartesianProductOperation< |
||
577 |
VectorSpaceOperationTpl<2,Scalar,Options>, |
||
578 |
SpecialOrthogonalOperationTpl<2,Scalar,Options> |
||
579 |
> |
||
580 |
, CartesianProductOperation< |
||
581 |
VectorSpaceOperationTpl<3,Scalar,Options>, |
||
582 |
SpecialOrthogonalOperationTpl<3,Scalar,Options> |
||
583 |
> |
||
584 |
> Types; |
||
585 |
✓✓ | 42 |
for (int i = 0; i < 20; ++i) |
586 |
✓✗ | 40 |
boost::mpl::for_each<Types>(LieGroup_JintegrateCoeffWise()); |
587 |
|||
588 |
{ |
||
589 |
typedef SpecialEuclideanOperationTpl<3,Scalar,Options> LieGroup; |
||
590 |
typedef LieGroup::ConfigVector_t ConfigVector_t; |
||
591 |
✓✗ | 2 |
LieGroup lg; |
592 |
|||
593 |
✓✗ | 2 |
ConfigVector_t q = lg.random(); |
594 |
// TangentVector_t dv(TangentVector_t::Zero(lg.nv())); |
||
595 |
|||
596 |
typedef Eigen::Matrix<Scalar,LieGroup::NQ,LieGroup::NV> JacobianCoeffs; |
||
597 |
✓✗✓✗ |
2 |
JacobianCoeffs Jintegrate(JacobianCoeffs::Zero(lg.nq(),lg.nv())); |
598 |
✓✗ | 2 |
lg.integrateCoeffWiseJacobian(q,Jintegrate); |
599 |
|||
600 |
|||
601 |
|||
602 |
} |
||
603 |
2 |
} |
|
604 |
|||
605 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗ |
4 |
BOOST_AUTO_TEST_CASE ( test_vector_space ) |
606 |
{ |
||
607 |
typedef VectorSpaceOperationTpl<3,double> VSO_t; |
||
608 |
✓✗ | 2 |
VSO_t::ConfigVector_t q, |
609 |
✓✗✓✗ |
2 |
lo(VSO_t::ConfigVector_t::Constant(-std::numeric_limits<double>::infinity())), |
610 |
// lo(VSO_t::ConfigVector_t::Constant( 0)), |
||
611 |
// up(VSO_t::ConfigVector_t::Constant( std::numeric_limits<double>::infinity())); |
||
612 |
✓✗✓✗ |
2 |
up(VSO_t::ConfigVector_t::Constant( 0)); |
613 |
|||
614 |
2 |
bool error = false; |
|
615 |
try { |
||
616 |
✓✗✗✓ |
2 |
VSO_t ().randomConfiguration(lo, up, q); |
617 |
2 |
} catch (const std::runtime_error&) { |
|
618 |
2 |
error = true; |
|
619 |
} |
||
620 |
✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
2 |
BOOST_CHECK_MESSAGE(error, "Random configuration between infinite bounds should return an error"); |
621 |
2 |
} |
|
622 |
|||
623 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗ |
4 |
BOOST_AUTO_TEST_CASE ( test_size ) |
624 |
{ |
||
625 |
// R^1: neutral = [0] |
||
626 |
✓✗ | 2 |
VectorSpaceOperationTpl <1,double> vs1; |
627 |
✓✗ | 4 |
Eigen::VectorXd neutral; |
628 |
✓✗ | 2 |
neutral.resize (1); |
629 |
✓✗ | 2 |
neutral.setZero (); |
630 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
2 |
BOOST_CHECK (vs1.nq () == 1); |
631 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
2 |
BOOST_CHECK (vs1.nv () == 1); |
632 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
2 |
BOOST_CHECK (vs1.name () == "R^1"); |
633 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
2 |
BOOST_CHECK (vs1.neutral () == neutral); |
634 |
// R^2: neutral = [0, 0] |
||
635 |
✓✗ | 2 |
VectorSpaceOperationTpl <2,double> vs2; |
636 |
✓✗ | 2 |
neutral.resize (2); |
637 |
✓✗ | 2 |
neutral.setZero (); |
638 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
2 |
BOOST_CHECK (vs2.nq () == 2); |
639 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
2 |
BOOST_CHECK (vs2.nv () == 2); |
640 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
2 |
BOOST_CHECK (vs2.name () == "R^2"); |
641 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
2 |
BOOST_CHECK (vs2.neutral () == neutral); |
642 |
// R^3: neutral = [0, 0, 0] |
||
643 |
✓✗ | 2 |
VectorSpaceOperationTpl <3,double> vs3; |
644 |
✓✗ | 2 |
neutral.resize (3); |
645 |
✓✗ | 2 |
neutral.setZero (); |
646 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
2 |
BOOST_CHECK (vs3.nq () == 3); |
647 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
2 |
BOOST_CHECK (vs3.nv () == 3); |
648 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
2 |
BOOST_CHECK (vs3.name () == "R^3"); |
649 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
2 |
BOOST_CHECK (vs3.neutral () == neutral); |
650 |
// SO(2): neutral = [1, 0] |
||
651 |
✓✗ | 2 |
SpecialOrthogonalOperationTpl<2,double> so2; |
652 |
✓✗✓✗ ✓✗ |
2 |
neutral.resize (2); neutral [0] = 1; neutral [1] = 0; |
653 |
✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
2 |
BOOST_CHECK (so2.nq () == 2); |
654 |
✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
2 |
BOOST_CHECK (so2.nv () == 1); |
655 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
2 |
BOOST_CHECK (so2.name () == "SO(2)"); |
656 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
2 |
BOOST_CHECK (so2.neutral () == neutral); |
657 |
// SO(3): neutral = [0, 0, 0, 1] |
||
658 |
✓✗ | 2 |
SpecialOrthogonalOperationTpl<3,double> so3; |
659 |
✓✗✓✗ |
2 |
neutral.resize (4); neutral.setZero (); |
660 |
✓✗ | 2 |
neutral [3] = 1; |
661 |
✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
2 |
BOOST_CHECK (so3.nq () == 4); |
662 |
✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
2 |
BOOST_CHECK (so3.nv () == 3); |
663 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
2 |
BOOST_CHECK (so3.name () == "SO(3)"); |
664 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
2 |
BOOST_CHECK (so3.neutral () == neutral); |
665 |
// SE(2): neutral = [0, 0, 1, 0] |
||
666 |
✓✗ | 2 |
SpecialEuclideanOperationTpl <2,double> se2; |
667 |
✓✗✓✗ |
2 |
neutral.resize (4); neutral.setZero (); |
668 |
✓✗ | 2 |
neutral [2] = 1; |
669 |
✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
2 |
BOOST_CHECK (se2.nq () == 4); |
670 |
✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
2 |
BOOST_CHECK (se2.nv () == 3); |
671 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
2 |
BOOST_CHECK (se2.name () == "SE(2)"); |
672 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
2 |
BOOST_CHECK (se2.neutral () == neutral); |
673 |
// SE(3): neutral = [0, 0, 0, 0, 0, 0, 1] |
||
674 |
✓✗ | 2 |
SpecialEuclideanOperationTpl <3,double> se3; |
675 |
✓✗✓✗ |
2 |
neutral.resize (7); neutral.setZero (); |
676 |
✓✗ | 2 |
neutral [6] = 1; |
677 |
✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
2 |
BOOST_CHECK (se3.nq () == 7); |
678 |
✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
2 |
BOOST_CHECK (se3.nv () == 6); |
679 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
2 |
BOOST_CHECK (se3.name () == "SE(3)"); |
680 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
2 |
BOOST_CHECK (se3.neutral () == neutral); |
681 |
// R^2 x SO(2): neutral = [0, 0, 1, 0] |
||
682 |
CartesianProductOperation <VectorSpaceOperationTpl <2,double>, |
||
683 |
✓✗ | 2 |
SpecialOrthogonalOperationTpl <2,double> > r2xso2; |
684 |
✓✗✓✗ |
2 |
neutral.resize (4); neutral.setZero (); |
685 |
✓✗ | 2 |
neutral [2] = 1; |
686 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
2 |
BOOST_CHECK (r2xso2.nq () == 4); |
687 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
2 |
BOOST_CHECK (r2xso2.nv () == 3); |
688 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
2 |
BOOST_CHECK (r2xso2.name () == "R^2*SO(2)"); |
689 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
2 |
BOOST_CHECK (r2xso2.neutral () == neutral); |
690 |
// R^3 x SO(3): neutral = [0, 0, 0, 0, 0, 0, 1] |
||
691 |
CartesianProductOperation <VectorSpaceOperationTpl <3,double>, |
||
692 |
✓✗ | 2 |
SpecialOrthogonalOperationTpl <3,double> > r3xso3; |
693 |
✓✗✓✗ |
2 |
neutral.resize (7); neutral.setZero (); |
694 |
✓✗ | 2 |
neutral [6] = 1; |
695 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
2 |
BOOST_CHECK (r3xso3.nq () == 7); |
696 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
2 |
BOOST_CHECK (r3xso3.nv () == 6); |
697 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
2 |
BOOST_CHECK (r3xso3.name () == "R^3*SO(3)"); |
698 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
2 |
BOOST_CHECK (r3xso3.neutral () == neutral); |
699 |
2 |
} |
|
700 |
|||
701 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗ |
4 |
BOOST_AUTO_TEST_CASE(test_dim_computation) |
702 |
{ |
||
703 |
2 |
int dim = eval_set_dim<1,1>::value ; |
|
704 |
✓✗✓✗ ✓✗✓✗ ✗✓ |
2 |
BOOST_CHECK(dim == 2); |
705 |
2 |
dim = eval_set_dim<Eigen::Dynamic,1>::value; |
|
706 |
✓✗✓✗ ✓✗✓✗ ✗✓ |
2 |
BOOST_CHECK(dim == Eigen::Dynamic); |
707 |
2 |
dim = eval_set_dim<1,Eigen::Dynamic>::value; |
|
708 |
✓✗✓✗ ✓✗✓✗ ✗✓ |
2 |
BOOST_CHECK(dim == Eigen::Dynamic); |
709 |
2 |
} |
|
710 |
|||
711 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗ |
4 |
BOOST_AUTO_TEST_CASE (small_distance_test) |
712 |
{ |
||
713 |
✓✗ | 2 |
SpecialOrthogonalOperationTpl <3,double> so3; |
714 |
✓✗ | 4 |
Eigen::VectorXd q1(so3.nq()); |
715 |
✓✗ | 4 |
Eigen::VectorXd q2(so3.nq()); |
716 |
✓✗✓✗ ✓✗✓✗ |
2 |
q1 << 0,0,-0.1953711450011105244,0.9807293794421349169; |
717 |
✓✗✓✗ ✓✗✓✗ |
2 |
q2 << 0,0,-0.19537114500111049664,0.98072937944213492244; |
718 |
|||
719 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
2 |
BOOST_CHECK_MESSAGE (so3.distance(q1,q2) > 0., |
720 |
"SO3 small distance - wrong results"); |
||
721 |
2 |
} |
|
722 |
|||
723 |
template<typename LieGroupCollection> |
||
724 |
struct TestLieGroupVariantVisitor |
||
725 |
{ |
||
726 |
|||
727 |
typedef LieGroupGenericTpl<LieGroupCollection> LieGroupGeneric; |
||
728 |
typedef typename LieGroupGeneric::ConfigVector_t ConfigVector_t; |
||
729 |
typedef typename LieGroupGeneric::TangentVector_t TangentVector_t; |
||
730 |
|||
731 |
template<typename Derived> |
||
732 |
16 |
void operator() (const LieGroupBase<Derived> & lg) const |
|
733 |
{ |
||
734 |
✓✗ | 32 |
LieGroupGenericTpl<LieGroupCollection> lg_generic(lg.derived()); |
735 |
✓✗ | 16 |
test(lg,lg_generic); |
736 |
16 |
} |
|
737 |
|||
738 |
template<typename Derived> |
||
739 |
16 |
static void test(const LieGroupBase<Derived> & lg, |
|
740 |
const LieGroupGenericTpl<LieGroupCollection> & lg_generic) |
||
741 |
{ |
||
742 |
✓✗✓✗ ✓✗✓✓ ✗✓✓✗ ✓✓✗✓ ✗✗✓✗ ✓ |
16 |
BOOST_CHECK(lg.nq() == nq(lg_generic)); |
743 |
✓✗✓✗ ✓✗✓✓ ✗✓✓✗ ✓✓✗✓ ✗✗✓✗ ✓ |
16 |
BOOST_CHECK(lg.nv() == nv(lg_generic)); |
744 |
|||
745 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
16 |
BOOST_CHECK(lg.name() == name(lg_generic)); |
746 |
|||
747 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓✓ |
16 |
BOOST_CHECK(lg.neutral() == neutral(lg_generic)); |
748 |
|||
749 |
typedef typename LieGroupGeneric::ConfigVector_t ConfigVectorGeneric; |
||
750 |
typedef typename LieGroupGeneric::TangentVector_t TangentVectorGeneric; |
||
751 |
|||
752 |
✓✗✓✗ |
32 |
ConfigVector_t q0 = lg.random(); |
753 |
✓✓✗✓ ✓✗✓✗ |
32 |
TangentVector_t v = TangentVector_t::Random(lg.nv()); |
754 |
✓✓✗✓ ✗ |
32 |
ConfigVector_t qout_ref(lg.nq()); |
755 |
✓✗ | 16 |
lg.integrate(q0, v, qout_ref); |
756 |
|||
757 |
✓✓✗✓ ✗ |
32 |
ConfigVectorGeneric qout(lg.nq()); |
758 |
✓✗✓✗ ✓✗ |
16 |
integrate(lg_generic, ConfigVectorGeneric(q0), TangentVectorGeneric(v), qout); |
759 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
16 |
BOOST_CHECK(qout.isApprox(qout_ref)); |
760 |
|||
761 |
✓✗✓✗ |
32 |
ConfigVector_t q1 (nq(lg_generic)); |
762 |
✓✗ | 16 |
random (lg_generic, q1); |
763 |
✓✗ | 16 |
difference(lg_generic, q0, q1, v); |
764 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
16 |
BOOST_CHECK_EQUAL(lg.distance(q0, q1), distance (lg_generic, q0, q1)); |
765 |
|||
766 |
✓✗✓✗ |
32 |
ConfigVector_t q2(nq(lg_generic)); |
767 |
✓✗ | 16 |
random(lg_generic, q2); |
768 |
✓✗ | 16 |
normalize(lg_generic, q2); |
769 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
16 |
BOOST_CHECK(isNormalized(lg_generic, q2)); |
770 |
16 |
} |
|
771 |
}; |
||
772 |
|||
773 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗ |
4 |
BOOST_AUTO_TEST_CASE(test_liegroup_variant) |
774 |
{ |
||
775 |
✓✗ | 2 |
boost::mpl::for_each<LieGroupCollectionDefault::LieGroupVariant::types>(TestLieGroupVariantVisitor<LieGroupCollectionDefault>()); |
776 |
2 |
} |
|
777 |
|||
778 |
template<typename Lg1, typename Lg2> |
||
779 |
1 |
void test_liegroup_variant_equal(Lg1 lg1, Lg2 lg2) |
|
780 |
{ |
||
781 |
typedef LieGroupGenericTpl<LieGroupCollectionDefault> LieGroupGeneric; |
||
782 |
✓✗✓✗ ✓✗✓✗ ✗✓ |
1 |
BOOST_CHECK_EQUAL(LieGroupGeneric(lg1), LieGroupGeneric(lg2)); |
783 |
1 |
} |
|
784 |
|||
785 |
template<typename Lg1, typename Lg2> |
||
786 |
1 |
void test_liegroup_variant_not_equal(Lg1 lg1, Lg2 lg2) |
|
787 |
{ |
||
788 |
typedef LieGroupGenericTpl<LieGroupCollectionDefault> LieGroupGeneric; |
||
789 |
✓✗✓✗ ✓✗✓✗ ✗✓ |
1 |
BOOST_CHECK_PREDICATE( std::not_equal_to<LieGroupGeneric>(), |
790 |
(LieGroupGeneric(lg1))(LieGroupGeneric(lg2)) ); |
||
791 |
1 |
} |
|
792 |
|||
793 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗ |
4 |
BOOST_AUTO_TEST_CASE(test_liegroup_variant_comparison) |
794 |
{ |
||
795 |
✓✗ | 2 |
test_liegroup_variant_equal( |
796 |
✓✗ | 2 |
VectorSpaceOperationTpl<1, double>(), |
797 |
2 |
VectorSpaceOperationTpl<Eigen::Dynamic, double>(1)); |
|
798 |
✓✗ | 2 |
test_liegroup_variant_not_equal( |
799 |
✓✗ | 2 |
VectorSpaceOperationTpl<1, double>(), |
800 |
2 |
VectorSpaceOperationTpl<Eigen::Dynamic, double>(2)); |
|
801 |
2 |
} |
|
802 |
|||
803 |
BOOST_AUTO_TEST_SUITE_END () |
Generated by: GCOVR (Version 4.2) |