Directory: | ./ |
---|---|
File: | include/pinocchio/multibody/liegroup/special-orthogonal.hpp |
Date: | 2025-02-12 21:03:38 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 253 | 285 | 88.8% |
Branches: | 254 | 869 | 29.2% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | // | ||
2 | // Copyright (c) 2016-2021 CNRS INRIA | ||
3 | // | ||
4 | |||
5 | #ifndef __pinocchio_multibody_liegroup_special_orthogonal_operation_hpp__ | ||
6 | #define __pinocchio_multibody_liegroup_special_orthogonal_operation_hpp__ | ||
7 | |||
8 | #include <limits> | ||
9 | |||
10 | #include "pinocchio/spatial/explog.hpp" | ||
11 | #include "pinocchio/math/quaternion.hpp" | ||
12 | #include "pinocchio/multibody/liegroup/liegroup-base.hpp" | ||
13 | #include "pinocchio/utils/static-if.hpp" | ||
14 | |||
15 | namespace pinocchio | ||
16 | { | ||
17 | template<int Dim, typename Scalar, int Options = 0> | ||
18 | struct SpecialOrthogonalOperationTpl | ||
19 | { | ||
20 | }; | ||
21 | |||
22 | template<int Dim, typename Scalar, int Options> | ||
23 | struct traits<SpecialOrthogonalOperationTpl<Dim, Scalar, Options>> | ||
24 | { | ||
25 | }; | ||
26 | |||
27 | template<typename _Scalar, int _Options> | ||
28 | struct traits<SpecialOrthogonalOperationTpl<2, _Scalar, _Options>> | ||
29 | { | ||
30 | typedef _Scalar Scalar; | ||
31 | enum | ||
32 | { | ||
33 | Options = _Options, | ||
34 | NQ = 2, | ||
35 | NV = 1 | ||
36 | }; | ||
37 | }; | ||
38 | |||
39 | template<typename _Scalar, int _Options> | ||
40 | struct traits<SpecialOrthogonalOperationTpl<3, _Scalar, _Options>> | ||
41 | { | ||
42 | typedef _Scalar Scalar; | ||
43 | enum | ||
44 | { | ||
45 | Options = _Options, | ||
46 | NQ = 4, | ||
47 | NV = 3 | ||
48 | }; | ||
49 | }; | ||
50 | |||
51 | template<typename _Scalar, int _Options> | ||
52 | struct SpecialOrthogonalOperationTpl<2, _Scalar, _Options> | ||
53 | : public LieGroupBase<SpecialOrthogonalOperationTpl<2, _Scalar, _Options>> | ||
54 | { | ||
55 | PINOCCHIO_LIE_GROUP_TPL_PUBLIC_INTERFACE(SpecialOrthogonalOperationTpl); | ||
56 | typedef Eigen::Matrix<Scalar, 2, 2> Matrix2; | ||
57 | typedef typename Eigen::NumTraits<Scalar>::Real RealScalar; | ||
58 | |||
59 | template<typename Matrix2Like> | ||
60 | 20243 | static typename Matrix2Like::Scalar log(const Eigen::MatrixBase<Matrix2Like> & R) | |
61 | { | ||
62 | typedef typename Matrix2Like::Scalar Scalar; | ||
63 | EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Matrix2Like, 2, 2); | ||
64 | |||
65 |
1/2✓ Branch 1 taken 20243 times.
✗ Branch 2 not taken.
|
20243 | const Scalar tr = R.trace(); |
66 | |||
67 |
3/8✓ Branch 0 taken 5 times.
✓ Branch 1 taken 20238 times.
✓ Branch 3 taken 5 times.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
20243 | static const Scalar PI_value = PI<Scalar>(); |
68 | |||
69 | using internal::if_then_else; | ||
70 |
0/6✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
|
40486 | Scalar theta = if_then_else( |
71 | ✗ | internal::GT, tr, Scalar(2), | |
72 | ✗ | Scalar(0), // then | |
73 |
1/2✓ Branch 1 taken 20243 times.
✗ Branch 2 not taken.
|
20243 | if_then_else( |
74 | ✗ | internal::LT, tr, Scalar(-2), | |
75 |
1/2✓ Branch 1 taken 20243 times.
✗ Branch 2 not taken.
|
20243 | if_then_else( |
76 |
1/6✓ Branch 1 taken 20243 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
|
20243 | internal::GE, R(1, 0), Scalar(0), PI_value, |
77 | ✗ | static_cast<Scalar>(-PI_value)), // then | |
78 |
1/2✓ Branch 1 taken 20243 times.
✗ Branch 2 not taken.
|
20243 | if_then_else( |
79 | internal::GT, tr, | ||
80 | ✗ | static_cast<Scalar>(Scalar(2) - Scalar(1e-2)), // TODO: change value | |
81 |
2/12✓ Branch 1 taken 20243 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20243 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
|
20243 | static_cast<Scalar>(asin((R(1, 0) - R(0, 1)) / Scalar(2))), // then |
82 |
1/2✓ Branch 1 taken 20243 times.
✗ Branch 2 not taken.
|
20243 | if_then_else( |
83 |
1/6✓ Branch 1 taken 20243 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
|
20243 | internal::GE, R(1, 0), Scalar(0), |
84 | ✗ | static_cast<Scalar>(acos(tr / Scalar(2))), // then | |
85 |
1/8✓ Branch 1 taken 20243 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
20243 | static_cast<Scalar>(-acos(tr / Scalar(2))))))); |
86 | |||
87 | // const bool pos = (R (1, 0) > Scalar(0)); | ||
88 | // if (tr > Scalar(2)) theta = Scalar(0); // acos((3-1)/2) | ||
89 | // else if (tr < Scalar(-2)) theta = (pos ? PI_value : -PI_value); // acos((-1-1)/2) | ||
90 | // Around 0, asin is numerically more stable than acos because | ||
91 | // acos(x) = PI/2 - x and asin(x) = x (the precision of x is not lost in PI/2). | ||
92 | // else if (tr > Scalar(2) - 1e-2) theta = asin ((R(1,0) - R(0,1)) / Scalar(2)); | ||
93 | // else theta = (pos ? acos (tr/Scalar(2)) : -acos(tr/Scalar(2))); | ||
94 |
2/13✓ Branch 1 taken 20243 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 20107 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
|
20243 | assert(check_expression_if_real<Scalar>(theta == theta) && "theta is NaN"); // theta != NaN |
95 | // assert ((cos (theta) * R(0,0) + sin (theta) * R(1,0) > 0) && | ||
96 | // (cos (theta) * R(1,0) - sin (theta) * R(0,0) < 1e-6)); | ||
97 | 20243 | return theta; | |
98 | } | ||
99 | |||
100 | template<typename Matrix2Like> | ||
101 | 130 | static typename Matrix2Like::Scalar Jlog(const Eigen::MatrixBase<Matrix2Like> &) | |
102 | { | ||
103 | typedef typename Matrix2Like::Scalar Scalar; | ||
104 | EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Matrix2Like, 2, 2); | ||
105 | 130 | return Scalar(1); | |
106 | } | ||
107 | |||
108 | /// Get dimension of Lie Group vector representation | ||
109 | /// | ||
110 | /// For instance, for SO(3), the dimension of the vector representation is | ||
111 | /// 4 (quaternion) while the dimension of the tangent space is 3. | ||
112 | 39809 | static Index nq() | |
113 | { | ||
114 | 39809 | return NQ; | |
115 | } | ||
116 | |||
117 | /// Get dimension of Lie Group tangent space | ||
118 | 14641 | static Index nv() | |
119 | { | ||
120 | 14641 | return NV; | |
121 | } | ||
122 | |||
123 | 12 | static ConfigVector_t neutral() | |
124 | { | ||
125 | 12 | ConfigVector_t n; | |
126 |
2/8✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
12 | n << Scalar(1), Scalar(0); |
127 | 12 | return n; | |
128 | } | ||
129 | |||
130 | 170 | static std::string name() | |
131 | { | ||
132 |
1/2✓ Branch 2 taken 170 times.
✗ Branch 3 not taken.
|
170 | return std::string("SO(2)"); |
133 | } | ||
134 | |||
135 | template<class ConfigL_t, class ConfigR_t, class Tangent_t> | ||
136 | 25238 | static void difference_impl( | |
137 | const Eigen::MatrixBase<ConfigL_t> & q0, | ||
138 | const Eigen::MatrixBase<ConfigR_t> & q1, | ||
139 | const Eigen::MatrixBase<Tangent_t> & d) | ||
140 | { | ||
141 |
1/2✓ Branch 1 taken 12619 times.
✗ Branch 2 not taken.
|
25238 | Matrix2 R; // R0.transpose() * R1; |
142 |
3/10✓ Branch 1 taken 12619 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12619 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12619 times.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
|
25238 | R(0, 0) = R(1, 1) = q0.dot(q1); |
143 |
5/18✓ Branch 1 taken 12619 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12619 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12619 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 12619 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 12619 times.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
|
25238 | R(1, 0) = q0(0) * q1(1) - q0(1) * q1(0); |
144 |
2/8✓ Branch 1 taken 12619 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12619 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
25238 | R(0, 1) = -R(1, 0); |
145 |
2/6✓ Branch 1 taken 12619 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 12619 times.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
25238 | PINOCCHIO_EIGEN_CONST_CAST(Tangent_t, d)[0] = log(R); |
146 | 25238 | } | |
147 | |||
148 | template<ArgumentPosition arg, class ConfigL_t, class ConfigR_t, class JacobianOut_t> | ||
149 | 260 | static void dDifference_impl( | |
150 | const Eigen::MatrixBase<ConfigL_t> & q0, | ||
151 | const Eigen::MatrixBase<ConfigR_t> & q1, | ||
152 | const Eigen::MatrixBase<JacobianOut_t> & J) | ||
153 | { | ||
154 |
1/2✓ Branch 1 taken 130 times.
✗ Branch 2 not taken.
|
260 | Matrix2 R; // R0.transpose() * R1; |
155 |
3/10✓ Branch 1 taken 130 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 130 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 130 times.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
|
260 | R(0, 0) = R(1, 1) = q0.dot(q1); |
156 |
5/18✓ Branch 1 taken 130 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 130 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 130 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 130 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 130 times.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
|
260 | R(1, 0) = q0(0) * q1(1) - q0(1) * q1(0); |
157 |
2/8✓ Branch 1 taken 130 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 130 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
260 | R(0, 1) = -R(1, 0); |
158 | |||
159 |
0/2✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
260 | Scalar w(Jlog(R)); |
160 |
0/4✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
260 | PINOCCHIO_EIGEN_CONST_CAST(JacobianOut_t, J).coeffRef(0, 0) = ((arg == ARG0) ? -w : w); |
161 | 260 | } | |
162 | |||
163 | template<class ConfigIn_t, class Velocity_t, class ConfigOut_t> | ||
164 | 25806 | static void integrate_impl( | |
165 | const Eigen::MatrixBase<ConfigIn_t> & q, | ||
166 | const Eigen::MatrixBase<Velocity_t> & v, | ||
167 | const Eigen::MatrixBase<ConfigOut_t> & qout) | ||
168 | { | ||
169 | 25806 | ConfigOut_t & out = PINOCCHIO_EIGEN_CONST_CAST(ConfigOut_t, qout); | |
170 | |||
171 |
1/2✓ Branch 1 taken 12908 times.
✗ Branch 2 not taken.
|
25806 | const Scalar ca = q(0); |
172 |
1/2✓ Branch 1 taken 12908 times.
✗ Branch 2 not taken.
|
25806 | const Scalar sa = q(1); |
173 |
1/2✓ Branch 1 taken 12908 times.
✗ Branch 2 not taken.
|
25806 | const Scalar & omega = v(0); |
174 | |||
175 |
2/4✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
|
2 | Scalar cosOmega, sinOmega; |
176 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
25806 | SINCOS(omega, &sinOmega, &cosOmega); |
177 | // TODO check the cost of atan2 vs SINCOS | ||
178 | |||
179 |
8/16✓ Branch 1 taken 12908 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12908 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 2 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 2 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 2 times.
✗ Branch 23 not taken.
|
25806 | out << cosOmega * ca - sinOmega * sa, sinOmega * ca + cosOmega * sa; |
180 | // First order approximation of the normalization of the unit complex | ||
181 | // See quaternion::firstOrderNormalize for equations. | ||
182 |
1/2✓ Branch 1 taken 12908 times.
✗ Branch 2 not taken.
|
25806 | const Scalar norm2 = out.squaredNorm(); |
183 |
5/10✓ Branch 1 taken 12908 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2 times.
✗ Branch 14 not taken.
|
25806 | out *= (3 - norm2) / 2; |
184 |
5/7✓ Branch 1 taken 2 times.
✓ Branch 2 taken 12906 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 12906 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
|
25806 | assert(pinocchio::isNormalized(out)); |
185 | 25806 | } | |
186 | |||
187 | template<class Config_t, class Jacobian_t> | ||
188 | 80 | static void integrateCoeffWiseJacobian_impl( | |
189 | const Eigen::MatrixBase<Config_t> & q, const Eigen::MatrixBase<Jacobian_t> & J) | ||
190 | { | ||
191 |
2/4✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 40 times.
✗ Branch 7 not taken.
|
80 | assert(J.rows() == nq() && J.cols() == nv() && "J is not of the right dimension"); |
192 | 80 | Jacobian_t & Jout = PINOCCHIO_EIGEN_CONST_CAST(Jacobian_t, J); | |
193 |
3/6✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 40 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 40 times.
✗ Branch 9 not taken.
|
80 | Jout << -q[1], q[0]; |
194 | 80 | } | |
195 | |||
196 | template<class Config_t, class Tangent_t, class JacobianOut_t> | ||
197 | 96 | static void dIntegrate_dq_impl( | |
198 | const Eigen::MatrixBase<Config_t> & /*q*/, | ||
199 | const Eigen::MatrixBase<Tangent_t> & /*v*/, | ||
200 | const Eigen::MatrixBase<JacobianOut_t> & J, | ||
201 | const AssignmentOperatorType op = SETTO) | ||
202 | { | ||
203 | 96 | JacobianOut_t & Jout = PINOCCHIO_EIGEN_CONST_CAST(JacobianOut_t, J); | |
204 |
1/4✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
96 | switch (op) |
205 | { | ||
206 | 96 | case SETTO: | |
207 |
0/4✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
96 | Jout(0, 0) = Scalar(1); |
208 | 96 | break; | |
209 | ✗ | case ADDTO: | |
210 | ✗ | Jout(0, 0) += Scalar(1); | |
211 | ✗ | break; | |
212 | ✗ | case RMTO: | |
213 | ✗ | Jout(0, 0) -= Scalar(1); | |
214 | ✗ | break; | |
215 | ✗ | default: | |
216 | ✗ | assert(false && "Wrong Op requesed value"); | |
217 | break; | ||
218 | } | ||
219 | 96 | } | |
220 | |||
221 | template<class Config_t, class Tangent_t, class JacobianOut_t> | ||
222 | 176 | static void dIntegrate_dv_impl( | |
223 | const Eigen::MatrixBase<Config_t> & /*q*/, | ||
224 | const Eigen::MatrixBase<Tangent_t> & /*v*/, | ||
225 | const Eigen::MatrixBase<JacobianOut_t> & J, | ||
226 | const AssignmentOperatorType op = SETTO) | ||
227 | { | ||
228 | 176 | JacobianOut_t & Jout = PINOCCHIO_EIGEN_CONST_CAST(JacobianOut_t, J); | |
229 |
1/4✓ Branch 0 taken 88 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
176 | switch (op) |
230 | { | ||
231 | 176 | case SETTO: | |
232 |
0/4✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
176 | Jout(0, 0) = Scalar(1); |
233 | 176 | break; | |
234 | ✗ | case ADDTO: | |
235 | ✗ | Jout(0, 0) += Scalar(1); | |
236 | ✗ | break; | |
237 | ✗ | case RMTO: | |
238 | ✗ | Jout(0, 0) -= Scalar(1); | |
239 | ✗ | break; | |
240 | ✗ | default: | |
241 | ✗ | assert(false && "Wrong Op requesed value"); | |
242 | break; | ||
243 | } | ||
244 | 176 | } | |
245 | |||
246 | template<class Config_t, class Tangent_t, class JacobianIn_t, class JacobianOut_t> | ||
247 | 325 | static void dIntegrateTransport_dq_impl( | |
248 | const Eigen::MatrixBase<Config_t> & /*q*/, | ||
249 | const Eigen::MatrixBase<Tangent_t> & /*v*/, | ||
250 | const Eigen::MatrixBase<JacobianIn_t> & Jin, | ||
251 | const Eigen::MatrixBase<JacobianOut_t> & Jout) | ||
252 | { | ||
253 | 325 | PINOCCHIO_EIGEN_CONST_CAST(JacobianOut_t, Jout) = Jin; | |
254 | 325 | } | |
255 | |||
256 | template<class Config_t, class Tangent_t, class JacobianIn_t, class JacobianOut_t> | ||
257 | 1 | static void dIntegrateTransport_dv_impl( | |
258 | const Eigen::MatrixBase<Config_t> & /*q*/, | ||
259 | const Eigen::MatrixBase<Tangent_t> & /*v*/, | ||
260 | const Eigen::MatrixBase<JacobianIn_t> & Jin, | ||
261 | const Eigen::MatrixBase<JacobianOut_t> & Jout) | ||
262 | { | ||
263 | 1 | PINOCCHIO_EIGEN_CONST_CAST(JacobianOut_t, Jout) = Jin; | |
264 | 1 | } | |
265 | |||
266 | template<class Config_t, class Tangent_t, class Jacobian_t> | ||
267 | ✗ | static void dIntegrateTransport_dq_impl( | |
268 | const Eigen::MatrixBase<Config_t> & /*q*/, | ||
269 | const Eigen::MatrixBase<Tangent_t> & /*v*/, | ||
270 | const Eigen::MatrixBase<Jacobian_t> & /*J*/) | ||
271 | { | ||
272 | } | ||
273 | |||
274 | template<class Config_t, class Tangent_t, class Jacobian_t> | ||
275 | ✗ | static void dIntegrateTransport_dv_impl( | |
276 | const Eigen::MatrixBase<Config_t> & /*q*/, | ||
277 | const Eigen::MatrixBase<Tangent_t> & /*v*/, | ||
278 | const Eigen::MatrixBase<Jacobian_t> & /*J*/) | ||
279 | { | ||
280 | } | ||
281 | |||
282 | template<class ConfigL_t, class ConfigR_t, class ConfigOut_t> | ||
283 | 9180 | static void interpolate_impl( | |
284 | const Eigen::MatrixBase<ConfigL_t> & q0, | ||
285 | const Eigen::MatrixBase<ConfigR_t> & q1, | ||
286 | const Scalar & u, | ||
287 | const Eigen::MatrixBase<ConfigOut_t> & qout) | ||
288 | { | ||
289 | 9180 | ConfigOut_t & out = PINOCCHIO_EIGEN_CONST_CAST(ConfigOut_t, qout); | |
290 | |||
291 |
3/53✓ Branch 1 taken 9180 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 9180 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 9180 times.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 54 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✗ Branch 57 not taken.
✗ Branch 58 not taken.
|
9180 | assert( |
292 | check_expression_if_real<Scalar>(abs(q0.norm() - 1) < 1e-8) | ||
293 | && "initial configuration not normalized"); | ||
294 |
3/53✓ Branch 1 taken 9180 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 9180 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 9180 times.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 54 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✗ Branch 57 not taken.
✗ Branch 58 not taken.
|
9180 | assert( |
295 | check_expression_if_real<Scalar>(abs(q1.norm() - 1) < 1e-8) | ||
296 | && "final configuration not normalized"); | ||
297 |
1/2✓ Branch 1 taken 9180 times.
✗ Branch 2 not taken.
|
9180 | const Scalar cosTheta = q0.dot(q1); |
298 |
4/14✓ Branch 1 taken 9180 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9180 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 9180 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 9180 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
|
9180 | const Scalar sinTheta = q0(0) * q1(1) - q0(1) * q1(0); |
299 |
0/2✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
9180 | const Scalar theta = atan2(sinTheta, cosTheta); |
300 |
2/15✓ Branch 1 taken 9180 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 9180 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
|
9180 | assert(check_expression_if_real<Scalar>(fabs(sin(theta) - sinTheta) < 1e-8)); |
301 | |||
302 |
3/8✓ Branch 0 taken 1 times.
✓ Branch 1 taken 9179 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
9180 | static const Scalar PI_value = PI<Scalar>(); |
303 |
3/10✓ Branch 0 taken 1 times.
✓ Branch 1 taken 9179 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
|
9180 | static const Scalar PI_value_lower = PI_value - static_cast<Scalar>(1e-6); |
304 | using namespace internal; | ||
305 | |||
306 | // const Scalar theta0 = atan2(q0(1), q0(0)); | ||
307 |
0/2✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
9180 | const Scalar abs_theta = fabs(theta); |
308 |
1/10✓ Branch 1 taken 9180 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
|
9180 | out[0] = if_then_else( |
309 | ✗ | LT, abs_theta, static_cast<Scalar>(1e-6), | |
310 |
2/14✓ Branch 1 taken 9180 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9180 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
|
9180 | static_cast<Scalar>((Scalar(1) - u) * q0[0] + u * q1[0]), // then |
311 |
1/2✓ Branch 1 taken 9180 times.
✗ Branch 2 not taken.
|
9180 | if_then_else( |
312 | LT, abs_theta, PI_value_lower, // else | ||
313 | ✗ | static_cast<Scalar>( | |
314 |
0/2✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
18360 | (sin((Scalar(1) - u) * theta) / sinTheta) * q0[0] |
315 |
2/4✓ Branch 1 taken 9180 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9180 times.
✗ Branch 5 not taken.
|
9180 | + (sin(u * theta) / sinTheta) * q1[0]), // then |
316 |
2/4✓ Branch 1 taken 9180 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9180 times.
✗ Branch 5 not taken.
|
9180 | q0(0) // cos(theta0) // else |
317 | )); | ||
318 | |||
319 |
1/10✓ Branch 1 taken 9180 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
|
9180 | out[1] = if_then_else( |
320 | ✗ | LT, abs_theta, static_cast<Scalar>(1e-6), | |
321 |
2/14✓ Branch 1 taken 9180 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9180 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
|
9180 | static_cast<Scalar>((Scalar(1) - u) * q0[1] + u * q1[1]), // then |
322 |
1/2✓ Branch 1 taken 9180 times.
✗ Branch 2 not taken.
|
9180 | if_then_else( |
323 | LT, abs_theta, PI_value_lower, // else | ||
324 | ✗ | static_cast<Scalar>( | |
325 |
0/2✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
18360 | (sin((Scalar(1) - u) * theta) / sinTheta) * q0[1] |
326 |
2/4✓ Branch 1 taken 9180 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9180 times.
✗ Branch 5 not taken.
|
9180 | + (sin(u * theta) / sinTheta) * q1[1]), // then |
327 |
2/4✓ Branch 1 taken 9180 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9180 times.
✗ Branch 5 not taken.
|
9180 | q0(1) // sin(theta0) // else |
328 | )); | ||
329 | 9180 | } | |
330 | |||
331 | template<class Config_t> | ||
332 | 6127 | static void normalize_impl(const Eigen::MatrixBase<Config_t> & qout) | |
333 | { | ||
334 | 6127 | pinocchio::normalize(qout.const_cast_derived()); | |
335 | 6127 | } | |
336 | |||
337 | template<class Config_t> | ||
338 | 30602 | static bool isNormalized_impl(const Eigen::MatrixBase<Config_t> & qin, const Scalar & prec) | |
339 | { | ||
340 | 30602 | const Scalar norm = qin.norm(); | |
341 | using std::abs; | ||
342 | 30602 | return abs(norm - Scalar(1.0)) < prec; | |
343 | } | ||
344 | |||
345 | template<class Config_t> | ||
346 | 25390 | static void random_impl(const Eigen::MatrixBase<Config_t> & qout) | |
347 | { | ||
348 | 25390 | Config_t & out = PINOCCHIO_EIGEN_CONST_CAST(Config_t, qout); | |
349 | |||
350 |
3/8✓ Branch 0 taken 29 times.
✓ Branch 1 taken 12669 times.
✓ Branch 3 taken 29 times.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
25390 | static const Scalar PI_value = PI<Scalar>(); |
351 |
0/16✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
|
25390 | const Scalar angle = -PI_value + Scalar(2) * PI_value * ((Scalar)rand()) / RAND_MAX; |
352 |
2/6✓ Branch 1 taken 12698 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12698 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
|
25390 | SINCOS(angle, &out(1), &out(0)); |
353 | 25390 | } | |
354 | |||
355 | template<class ConfigL_t, class ConfigR_t, class ConfigOut_t> | ||
356 | 24590 | static void randomConfiguration_impl( | |
357 | const Eigen::MatrixBase<ConfigL_t> &, | ||
358 | const Eigen::MatrixBase<ConfigR_t> &, | ||
359 | const Eigen::MatrixBase<ConfigOut_t> & qout) | ||
360 | { | ||
361 | 24590 | random_impl(qout); | |
362 | 24590 | } | |
363 | }; // struct SpecialOrthogonalOperationTpl<2,_Scalar,_Options> | ||
364 | |||
365 | template<typename _Scalar, int _Options> | ||
366 | struct SpecialOrthogonalOperationTpl<3, _Scalar, _Options> | ||
367 | : public LieGroupBase<SpecialOrthogonalOperationTpl<3, _Scalar, _Options>> | ||
368 | { | ||
369 | PINOCCHIO_LIE_GROUP_TPL_PUBLIC_INTERFACE(SpecialOrthogonalOperationTpl); | ||
370 | |||
371 | typedef Eigen::Quaternion<Scalar> Quaternion_t; | ||
372 | typedef Eigen::Map<Quaternion_t> QuaternionMap_t; | ||
373 | typedef Eigen::Map<const Quaternion_t> ConstQuaternionMap_t; | ||
374 | typedef SE3Tpl<Scalar, Options> SE3; | ||
375 | typedef typename Eigen::NumTraits<Scalar>::Real RealScalar; | ||
376 | |||
377 | /// Get dimension of Lie Group vector representation | ||
378 | /// | ||
379 | /// For instance, for SO(3), the dimension of the vector representation is | ||
380 | /// 4 (quaternion) while the dimension of the tangent space is 3. | ||
381 | 30589 | static Index nq() | |
382 | { | ||
383 | 30589 | return NQ; | |
384 | } | ||
385 | |||
386 | /// Get dimension of Lie Group tangent space | ||
387 | 6613 | static Index nv() | |
388 | { | ||
389 | 6613 | return NV; | |
390 | } | ||
391 | |||
392 | 26 | static ConfigVector_t neutral() | |
393 | { | ||
394 | 26 | ConfigVector_t n; | |
395 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
26 | n.setZero(); |
396 |
3/6✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
|
26 | n[3] = Scalar(1); |
397 | 26 | return n; | |
398 | } | ||
399 | |||
400 | 175 | static std::string name() | |
401 | { | ||
402 |
1/2✓ Branch 2 taken 175 times.
✗ Branch 3 not taken.
|
175 | return std::string("SO(3)"); |
403 | } | ||
404 | |||
405 | template<class ConfigL_t, class ConfigR_t, class Tangent_t> | ||
406 | 16130 | static void difference_impl( | |
407 | const Eigen::MatrixBase<ConfigL_t> & q0, | ||
408 | const Eigen::MatrixBase<ConfigR_t> & q1, | ||
409 | const Eigen::MatrixBase<Tangent_t> & d) | ||
410 | { | ||
411 |
3/5✓ Branch 2 taken 7413 times.
✓ Branch 3 taken 652 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 7413 times.
✗ Branch 6 not taken.
|
16130 | ConstQuaternionMap_t quat0(q0.derived().data()); |
412 |
3/7✓ Branch 1 taken 8065 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 8065 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 3 times.
|
16130 | assert(quaternion::isNormalized( |
413 | quat0, RealScalar(PINOCCHIO_DEFAULT_QUATERNION_NORM_TOLERANCE_VALUE))); | ||
414 |
3/5✓ Branch 2 taken 7413 times.
✓ Branch 3 taken 652 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 7413 times.
✗ Branch 6 not taken.
|
16130 | ConstQuaternionMap_t quat1(q1.derived().data()); |
415 |
3/7✓ Branch 1 taken 8065 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 8065 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 3 times.
|
16130 | assert(quaternion::isNormalized( |
416 | quat1, RealScalar(PINOCCHIO_DEFAULT_QUATERNION_NORM_TOLERANCE_VALUE))); | ||
417 | |||
418 |
2/4✓ Branch 1 taken 8065 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 645 times.
✗ Branch 6 not taken.
|
16130 | PINOCCHIO_EIGEN_CONST_CAST(Tangent_t, d) = |
419 |
2/4✓ Branch 1 taken 8065 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8065 times.
✗ Branch 5 not taken.
|
16136 | quaternion::log3(Quaternion_t(quat0.conjugate() * quat1)); |
420 | 16130 | } | |
421 | |||
422 | template<ArgumentPosition arg, class ConfigL_t, class ConfigR_t, class JacobianOut_t> | ||
423 | 364 | static void dDifference_impl( | |
424 | const Eigen::MatrixBase<ConfigL_t> & q0, | ||
425 | const Eigen::MatrixBase<ConfigR_t> & q1, | ||
426 | const Eigen::MatrixBase<JacobianOut_t> & J) | ||
427 | { | ||
428 | typedef typename SE3::Matrix3 Matrix3; | ||
429 | |||
430 |
3/5✓ Branch 2 taken 62 times.
✓ Branch 3 taken 120 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 62 times.
✗ Branch 6 not taken.
|
364 | ConstQuaternionMap_t quat0(q0.derived().data()); |
431 |
2/7✓ Branch 1 taken 182 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 182 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
364 | assert(quaternion::isNormalized( |
432 | quat0, RealScalar(PINOCCHIO_DEFAULT_QUATERNION_NORM_TOLERANCE_VALUE))); | ||
433 |
3/5✓ Branch 2 taken 62 times.
✓ Branch 3 taken 120 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 62 times.
✗ Branch 6 not taken.
|
364 | ConstQuaternionMap_t quat1(q1.derived().data()); |
434 |
2/7✓ Branch 1 taken 182 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 182 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
364 | assert(quaternion::isNormalized( |
435 | quat1, RealScalar(PINOCCHIO_DEFAULT_QUATERNION_NORM_TOLERANCE_VALUE))); | ||
436 | |||
437 | // TODO: check whether the merge with 2.6.9 is correct | ||
438 |
2/4✓ Branch 1 taken 182 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 182 times.
✗ Branch 5 not taken.
|
364 | const Quaternion_t q = quat0.conjugate() * quat1; |
439 |
1/2✓ Branch 1 taken 182 times.
✗ Branch 2 not taken.
|
364 | const Matrix3 R = q.matrix(); |
440 | |||
441 | if (arg == ARG0) | ||
442 | { | ||
443 |
1/2✓ Branch 1 taken 71 times.
✗ Branch 2 not taken.
|
142 | JacobianMatrix_t J1; |
444 |
1/2✓ Branch 1 taken 71 times.
✗ Branch 2 not taken.
|
142 | Jlog3(R, J1); |
445 | |||
446 |
5/10✓ Branch 1 taken 71 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 71 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 71 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 71 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 71 times.
✗ Branch 15 not taken.
|
142 | PINOCCHIO_EIGEN_CONST_CAST(JacobianOut_t, J).noalias() = -J1 * R.transpose(); |
447 | } | ||
448 | else if (arg == ARG1) | ||
449 | { | ||
450 |
1/2✓ Branch 1 taken 111 times.
✗ Branch 2 not taken.
|
222 | Jlog3(R, J); |
451 | } | ||
452 | /* | ||
453 | const Quaternion_t quat_diff = quat0.conjugate() * quat1; | ||
454 | |||
455 | if (arg == ARG0) { | ||
456 | PINOCCHIO_COMPILER_DIAGNOSTIC_PUSH | ||
457 | PINOCCHIO_COMPILER_DIAGNOSTIC_IGNORED_MAYBE_UNINITIALIZED | ||
458 | JacobianMatrix_t J1; | ||
459 | quaternion::Jlog3(quat_diff, J1); | ||
460 | PINOCCHIO_COMPILER_DIAGNOSTIC_POP | ||
461 | const Matrix3 R = (quat_diff).matrix(); | ||
462 | |||
463 | PINOCCHIO_EIGEN_CONST_CAST(JacobianOut_t,J).noalias() = - J1 * R.transpose(); | ||
464 | } else if (arg == ARG1) { | ||
465 | quaternion::Jlog3(quat_diff, J); | ||
466 | } | ||
467 | */ | ||
468 | 364 | } | |
469 | |||
470 | template<class ConfigIn_t, class Velocity_t, class ConfigOut_t> | ||
471 | 17390 | static void integrate_impl( | |
472 | const Eigen::MatrixBase<ConfigIn_t> & q, | ||
473 | const Eigen::MatrixBase<Velocity_t> & v, | ||
474 | const Eigen::MatrixBase<ConfigOut_t> & qout) | ||
475 | { | ||
476 |
3/5✓ Branch 2 taken 7593 times.
✓ Branch 3 taken 1110 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 7593 times.
✗ Branch 6 not taken.
|
17390 | ConstQuaternionMap_t quat(q.derived().data()); |
477 |
3/7✓ Branch 1 taken 8703 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 8703 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 5 times.
|
17390 | assert(quaternion::isNormalized( |
478 | quat, RealScalar(PINOCCHIO_DEFAULT_QUATERNION_NORM_TOLERANCE_VALUE))); | ||
479 |
3/5✓ Branch 2 taken 1 times.
✓ Branch 3 taken 8702 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
|
17390 | QuaternionMap_t quat_map(PINOCCHIO_EIGEN_CONST_CAST(ConfigOut_t, qout).data()); |
480 | |||
481 |
1/2✓ Branch 1 taken 8703 times.
✗ Branch 2 not taken.
|
17390 | Quaternion_t pOmega; |
482 |
1/2✓ Branch 1 taken 8703 times.
✗ Branch 2 not taken.
|
17390 | quaternion::exp3(v, pOmega); |
483 |
2/4✓ Branch 1 taken 8703 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8703 times.
✗ Branch 5 not taken.
|
17390 | quat_map = quat * pOmega; |
484 |
1/2✓ Branch 1 taken 8703 times.
✗ Branch 2 not taken.
|
17390 | quaternion::firstOrderNormalize(quat_map); |
485 |
3/7✓ Branch 1 taken 8703 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 8703 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 5 times.
|
17390 | assert(quaternion::isNormalized( |
486 | quat_map, RealScalar(PINOCCHIO_DEFAULT_QUATERNION_NORM_TOLERANCE_VALUE))); | ||
487 | 17390 | } | |
488 | |||
489 | template<class Config_t, class Jacobian_t> | ||
490 | 80 | static void integrateCoeffWiseJacobian_impl( | |
491 | const Eigen::MatrixBase<Config_t> & q, const Eigen::MatrixBase<Jacobian_t> & J) | ||
492 | { | ||
493 |
2/4✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 40 times.
✗ Branch 7 not taken.
|
80 | assert(J.rows() == nq() && J.cols() == nv() && "J is not of the right dimension"); |
494 | |||
495 | typedef typename PINOCCHIO_EIGEN_PLAIN_TYPE(Jacobian_t) JacobianPlainType; | ||
496 | typedef typename SE3::Vector3 Vector3; | ||
497 | typedef typename SE3::Matrix3 Matrix3; | ||
498 | |||
499 |
3/5✓ Branch 2 taken 20 times.
✓ Branch 3 taken 20 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 20 times.
✗ Branch 6 not taken.
|
80 | ConstQuaternionMap_t quat_map(q.derived().data()); |
500 |
2/4✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 40 times.
|
80 | assert(quaternion::isNormalized( |
501 | quat_map, RealScalar(PINOCCHIO_DEFAULT_QUATERNION_NORM_TOLERANCE_VALUE))); | ||
502 | |||
503 | PINOCCHIO_COMPILER_DIAGNOSTIC_PUSH | ||
504 | PINOCCHIO_COMPILER_DIAGNOSTIC_IGNORED_MAYBE_UNINITIALIZED | ||
505 | Eigen::Matrix<Scalar, NQ, NV, JacobianPlainType::Options | Eigen::RowMajor> | ||
506 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
80 | Jexp3QuatCoeffWise; |
507 | |||
508 | Scalar theta; | ||
509 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
80 | const Vector3 v = quaternion::log3(quat_map, theta); |
510 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
80 | quaternion::Jexp3CoeffWise(v, Jexp3QuatCoeffWise); |
511 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
80 | Matrix3 Jlog; |
512 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
80 | Jlog3(theta, v, Jlog); |
513 | PINOCCHIO_COMPILER_DIAGNOSTIC_POP | ||
514 | |||
515 | // if(quat_map.w() >= 0.) // comes from the log3 for quaternions which may change the | ||
516 | // sign. | ||
517 |
3/4✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 23 times.
✓ Branch 5 taken 17 times.
|
80 | if (quat_map.coeffs()[3] >= 0.) // comes from the log3 for quaternions which may change the |
518 | // sign. | ||
519 |
3/6✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 23 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 23 times.
✗ Branch 9 not taken.
|
46 | PINOCCHIO_EIGEN_CONST_CAST(Jacobian_t, J).noalias() = Jexp3QuatCoeffWise * Jlog; |
520 | else | ||
521 |
4/8✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 17 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 17 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 17 times.
✗ Branch 12 not taken.
|
34 | PINOCCHIO_EIGEN_CONST_CAST(Jacobian_t, J).noalias() = -Jexp3QuatCoeffWise * Jlog; |
522 | |||
523 | // Jexp3(quat_map,PINOCCHIO_EIGEN_CONST_CAST(Jacobian_t,J).template | ||
524 | // topLeftCorner<NQ,NV>()); | ||
525 | 80 | } | |
526 | |||
527 | template<class Config_t, class Tangent_t, class JacobianOut_t> | ||
528 | 115 | static void dIntegrate_dq_impl( | |
529 | const Eigen::MatrixBase<Config_t> & /*q*/, | ||
530 | const Eigen::MatrixBase<Tangent_t> & v, | ||
531 | const Eigen::MatrixBase<JacobianOut_t> & J, | ||
532 | const AssignmentOperatorType op = SETTO) | ||
533 | { | ||
534 | 115 | JacobianOut_t & Jout = PINOCCHIO_EIGEN_CONST_CAST(JacobianOut_t, J); | |
535 |
3/4✓ Branch 0 taken 61 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
115 | switch (op) |
536 | { | ||
537 | 113 | case SETTO: | |
538 |
2/4✓ Branch 2 taken 61 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 35 times.
✗ Branch 6 not taken.
|
113 | Jout = exp3(-v); |
539 | 113 | break; | |
540 | 1 | case ADDTO: | |
541 |
2/4✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
|
1 | Jout += exp3(-v); |
542 | 1 | break; | |
543 | 1 | case RMTO: | |
544 |
2/4✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
|
1 | Jout -= exp3(-v); |
545 | 1 | break; | |
546 | ✗ | default: | |
547 | ✗ | assert(false && "Wrong Op requesed value"); | |
548 | break; | ||
549 | } | ||
550 | 115 | } | |
551 | |||
552 | template<class Config_t, class Tangent_t, class JacobianOut_t> | ||
553 | 195 | static void dIntegrate_dv_impl( | |
554 | const Eigen::MatrixBase<Config_t> & /*q*/, | ||
555 | const Eigen::MatrixBase<Tangent_t> & v, | ||
556 | const Eigen::MatrixBase<JacobianOut_t> & J, | ||
557 | const AssignmentOperatorType op = SETTO) | ||
558 | { | ||
559 |
3/4✓ Branch 0 taken 101 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
195 | switch (op) |
560 | { | ||
561 | 193 | case SETTO: | |
562 | 193 | Jexp3<SETTO>(v, J.derived()); | |
563 | 193 | break; | |
564 | 1 | case ADDTO: | |
565 | 1 | Jexp3<ADDTO>(v, J.derived()); | |
566 | 1 | break; | |
567 | 1 | case RMTO: | |
568 | 1 | Jexp3<RMTO>(v, J.derived()); | |
569 | 1 | break; | |
570 | ✗ | default: | |
571 | ✗ | assert(false && "Wrong Op requesed value"); | |
572 | break; | ||
573 | } | ||
574 | 195 | } | |
575 | |||
576 | template<class Config_t, class Tangent_t, class JacobianIn_t, class JacobianOut_t> | ||
577 | 331 | static void dIntegrateTransport_dq_impl( | |
578 | const Eigen::MatrixBase<Config_t> & /*q*/, | ||
579 | const Eigen::MatrixBase<Tangent_t> & v, | ||
580 | const Eigen::MatrixBase<JacobianIn_t> & Jin, | ||
581 | const Eigen::MatrixBase<JacobianOut_t> & J_out) | ||
582 | { | ||
583 | typedef typename SE3::Matrix3 Matrix3; | ||
584 | 331 | JacobianOut_t & Jout = PINOCCHIO_EIGEN_CONST_CAST(JacobianOut_t, J_out); | |
585 |
2/4✓ Branch 1 taken 171 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 171 times.
✗ Branch 5 not taken.
|
331 | const Matrix3 Jtmp3 = exp3(-v); |
586 |
3/6✓ Branch 1 taken 171 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 171 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 171 times.
✗ Branch 8 not taken.
|
331 | Jout.noalias() = Jtmp3 * Jin; |
587 | 331 | } | |
588 | |||
589 | template<class Config_t, class Tangent_t, class JacobianIn_t, class JacobianOut_t> | ||
590 | 3 | static void dIntegrateTransport_dv_impl( | |
591 | const Eigen::MatrixBase<Config_t> & /*q*/, | ||
592 | const Eigen::MatrixBase<Tangent_t> & v, | ||
593 | const Eigen::MatrixBase<JacobianIn_t> & Jin, | ||
594 | const Eigen::MatrixBase<JacobianOut_t> & J_out) | ||
595 | { | ||
596 | typedef typename SE3::Matrix3 Matrix3; | ||
597 | 3 | JacobianOut_t & Jout = PINOCCHIO_EIGEN_CONST_CAST(JacobianOut_t, J_out); | |
598 | PINOCCHIO_COMPILER_DIAGNOSTIC_PUSH | ||
599 | PINOCCHIO_COMPILER_DIAGNOSTIC_IGNORED_MAYBE_UNINITIALIZED | ||
600 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | Matrix3 Jtmp3; |
601 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | Jexp3<SETTO>(v, Jtmp3); |
602 | PINOCCHIO_COMPILER_DIAGNOSTIC_POP | ||
603 |
3/6✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
|
3 | Jout.noalias() = Jtmp3 * Jin; |
604 | 3 | } | |
605 | |||
606 | template<class Config_t, class Tangent_t, class Jacobian_t> | ||
607 | 1 | static void dIntegrateTransport_dq_impl( | |
608 | const Eigen::MatrixBase<Config_t> & /*q*/, | ||
609 | const Eigen::MatrixBase<Tangent_t> & v, | ||
610 | const Eigen::MatrixBase<Jacobian_t> & J_out) | ||
611 | { | ||
612 | typedef typename SE3::Matrix3 Matrix3; | ||
613 | 1 | Jacobian_t & Jout = PINOCCHIO_EIGEN_CONST_CAST(Jacobian_t, J_out); | |
614 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | const Matrix3 Jtmp3 = exp3(-v); |
615 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | Jout = Jtmp3 * Jout; |
616 | 1 | } | |
617 | |||
618 | template<class Config_t, class Tangent_t, class Jacobian_t> | ||
619 | 1 | static void dIntegrateTransport_dv_impl( | |
620 | const Eigen::MatrixBase<Config_t> & /*q*/, | ||
621 | const Eigen::MatrixBase<Tangent_t> & v, | ||
622 | const Eigen::MatrixBase<Jacobian_t> & J_out) | ||
623 | { | ||
624 | typedef typename SE3::Matrix3 Matrix3; | ||
625 | 1 | Jacobian_t & Jout = PINOCCHIO_EIGEN_CONST_CAST(Jacobian_t, J_out); | |
626 | PINOCCHIO_COMPILER_DIAGNOSTIC_PUSH | ||
627 | PINOCCHIO_COMPILER_DIAGNOSTIC_IGNORED_MAYBE_UNINITIALIZED | ||
628 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | Matrix3 Jtmp3; |
629 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | Jexp3<SETTO>(v, Jtmp3); |
630 | PINOCCHIO_COMPILER_DIAGNOSTIC_POP | ||
631 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | Jout = Jtmp3 * Jout; |
632 | 1 | } | |
633 | |||
634 | template<class ConfigL_t, class ConfigR_t, class ConfigOut_t> | ||
635 | 3063 | static void interpolate_impl( | |
636 | const Eigen::MatrixBase<ConfigL_t> & q0, | ||
637 | const Eigen::MatrixBase<ConfigR_t> & q1, | ||
638 | const Scalar & u, | ||
639 | const Eigen::MatrixBase<ConfigOut_t> & qout) | ||
640 | { | ||
641 |
3/5✓ Branch 2 taken 3060 times.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3060 times.
✗ Branch 6 not taken.
|
3063 | ConstQuaternionMap_t quat0(q0.derived().data()); |
642 |
3/7✓ Branch 1 taken 3063 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 3063 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
|
3063 | assert(quaternion::isNormalized( |
643 | quat0, RealScalar(PINOCCHIO_DEFAULT_QUATERNION_NORM_TOLERANCE_VALUE))); | ||
644 |
3/5✓ Branch 2 taken 3060 times.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3060 times.
✗ Branch 6 not taken.
|
3063 | ConstQuaternionMap_t quat1(q1.derived().data()); |
645 |
3/7✓ Branch 1 taken 3063 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 3063 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
|
3063 | assert(quaternion::isNormalized( |
646 | quat1, RealScalar(PINOCCHIO_DEFAULT_QUATERNION_NORM_TOLERANCE_VALUE))); | ||
647 | |||
648 |
1/2✓ Branch 3 taken 3063 times.
✗ Branch 4 not taken.
|
3063 | QuaternionMap_t quat_res(PINOCCHIO_EIGEN_CONST_CAST(ConfigOut_t, qout).data()); |
649 | |||
650 |
1/2✓ Branch 1 taken 3063 times.
✗ Branch 2 not taken.
|
3063 | TangentVector_t w; |
651 |
1/2✓ Branch 1 taken 3063 times.
✗ Branch 2 not taken.
|
3063 | difference_impl(q0, q1, w); |
652 |
2/4✓ Branch 1 taken 3063 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3063 times.
✗ Branch 5 not taken.
|
3063 | integrate_impl(q0, u * w, qout); |
653 |
3/7✓ Branch 1 taken 3063 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 3063 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
|
3063 | assert(quaternion::isNormalized( |
654 | quat_res, RealScalar(PINOCCHIO_DEFAULT_QUATERNION_NORM_TOLERANCE_VALUE))); | ||
655 | 3063 | } | |
656 | |||
657 | template<class ConfigL_t, class ConfigR_t> | ||
658 | 2057 | static Scalar squaredDistance_impl( | |
659 | const Eigen::MatrixBase<ConfigL_t> & q0, const Eigen::MatrixBase<ConfigR_t> & q1) | ||
660 | { | ||
661 | PINOCCHIO_COMPILER_DIAGNOSTIC_PUSH | ||
662 | PINOCCHIO_COMPILER_DIAGNOSTIC_IGNORED_MAYBE_UNINITIALIZED | ||
663 |
1/2✓ Branch 1 taken 1030 times.
✗ Branch 2 not taken.
|
2057 | TangentVector_t t; |
664 |
1/2✓ Branch 1 taken 1030 times.
✗ Branch 2 not taken.
|
2057 | difference_impl(q0, q1, t); |
665 | PINOCCHIO_COMPILER_DIAGNOSTIC_POP | ||
666 |
1/2✓ Branch 1 taken 1030 times.
✗ Branch 2 not taken.
|
4114 | return t.squaredNorm(); |
667 | } | ||
668 | |||
669 | template<class Config_t> | ||
670 | 2054 | static void normalize_impl(const Eigen::MatrixBase<Config_t> & qout) | |
671 | { | ||
672 | 2054 | pinocchio::normalize(qout.const_cast_derived()); | |
673 | 2054 | } | |
674 | |||
675 | template<class Config_t> | ||
676 | 10209 | static bool isNormalized_impl(const Eigen::MatrixBase<Config_t> & qin, const Scalar & prec) | |
677 | { | ||
678 | 10209 | const Scalar norm = qin.norm(); | |
679 | using std::abs; | ||
680 | 10209 | return abs(norm - Scalar(1.0)) < prec; | |
681 | } | ||
682 | |||
683 | template<class Config_t> | ||
684 | 18130 | static void random_impl(const Eigen::MatrixBase<Config_t> & qout) | |
685 | { | ||
686 |
3/5✓ Branch 2 taken 2 times.
✓ Branch 3 taken 9063 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
|
18130 | QuaternionMap_t quat_map(PINOCCHIO_EIGEN_CONST_CAST(Config_t, qout).data()); |
687 |
1/2✓ Branch 1 taken 9065 times.
✗ Branch 2 not taken.
|
18130 | quaternion::uniformRandom(quat_map); |
688 | |||
689 |
2/7✓ Branch 1 taken 9065 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 9065 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
18130 | assert(quaternion::isNormalized( |
690 | quat_map, RealScalar(PINOCCHIO_DEFAULT_QUATERNION_NORM_TOLERANCE_VALUE))); | ||
691 | 18130 | } | |
692 | |||
693 | template<class ConfigL_t, class ConfigR_t, class ConfigOut_t> | ||
694 | 17170 | static void randomConfiguration_impl( | |
695 | const Eigen::MatrixBase<ConfigL_t> &, | ||
696 | const Eigen::MatrixBase<ConfigR_t> &, | ||
697 | const Eigen::MatrixBase<ConfigOut_t> & qout) | ||
698 | { | ||
699 | 17170 | random_impl(qout); | |
700 | 17170 | } | |
701 | |||
702 | template<class ConfigL_t, class ConfigR_t> | ||
703 | 11 | static bool isSameConfiguration_impl( | |
704 | const Eigen::MatrixBase<ConfigL_t> & q0, | ||
705 | const Eigen::MatrixBase<ConfigR_t> & q1, | ||
706 | const Scalar & prec) | ||
707 | { | ||
708 | 11 | ConstQuaternionMap_t quat1(q0.derived().data()); | |
709 | 11 | assert(quaternion::isNormalized( | |
710 | quat1, RealScalar(PINOCCHIO_DEFAULT_QUATERNION_NORM_TOLERANCE_VALUE))); | ||
711 | 11 | ConstQuaternionMap_t quat2(q1.derived().data()); | |
712 | 11 | assert(quaternion::isNormalized( | |
713 | quat1, RealScalar(PINOCCHIO_DEFAULT_QUATERNION_NORM_TOLERANCE_VALUE))); | ||
714 | |||
715 | 22 | return quaternion::defineSameRotation(quat1, quat2, prec); | |
716 | } | ||
717 | }; // struct SpecialOrthogonalOperationTpl<3,_Scalar,_Options> | ||
718 | |||
719 | } // namespace pinocchio | ||
720 | |||
721 | #endif // ifndef __pinocchio_multibody_liegroup_special_orthogonal_operation_hpp__ | ||
722 |