GCC Code Coverage Report


Directory: ./
File: include/pinocchio/spatial/explog-quaternion.hpp
Date: 2025-02-12 21:03:38
Exec Total Coverage
Lines: 99 103 96.1%
Branches: 214 425 50.4%

Line Branch Exec Source
1 //
2 // Copyright (c) 2018-2021 CNRS INRIA
3 //
4
5 #ifndef __pinocchio_spatial_explog_quaternion_hpp__
6 #define __pinocchio_spatial_explog_quaternion_hpp__
7
8 #include "pinocchio/math/quaternion.hpp"
9 #include "pinocchio/spatial/explog.hpp"
10 #include "pinocchio/utils/static-if.hpp"
11
12 namespace pinocchio
13 {
14 namespace quaternion
15 {
16
17 ///
18 /// \brief Exp: so3 -> SO3 (quaternion)
19 ///
20 /// \returns the integral of the velocity vector as a quaternion.
21 ///
22 /// \param[in] v The angular velocity vector.
23 /// \param[out] qout The quaternion where the result is stored.
24 ///
25 template<typename Vector3Like, typename QuaternionLike>
26 void
27 42720 exp3(const Eigen::MatrixBase<Vector3Like> & v, Eigen::QuaternionBase<QuaternionLike> & quat_out)
28 {
29 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Vector3Like);
30
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 21361 times.
42720 assert(v.size() == 3);
31
32 typedef typename Vector3Like::Scalar Scalar;
33 enum
34 {
35 Options = PINOCCHIO_EIGEN_PLAIN_TYPE(typename QuaternionLike::Coefficients)::Options
36 };
37 typedef Eigen::Quaternion<typename QuaternionLike::Scalar, Options> QuaternionPlain;
38
1/2
✓ Branch 1 taken 334 times.
✗ Branch 2 not taken.
42720 const Scalar eps = Eigen::NumTraits<Scalar>::epsilon();
39
40
1/2
✓ Branch 1 taken 21361 times.
✗ Branch 2 not taken.
42720 const Scalar t2 = v.squaredNorm();
41
3/6
✓ Branch 1 taken 334 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 334 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 334 times.
✗ Branch 8 not taken.
43388 const Scalar t = math::sqrt(t2 + eps * eps);
42
43
4/9
✓ Branch 0 taken 76 times.
✓ Branch 1 taken 21285 times.
✓ Branch 3 taken 76 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 8 times.
✗ Branch 7 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
42720 static const Scalar ts_prec =
44
1/2
✓ Branch 1 taken 68 times.
✗ Branch 2 not taken.
134 TaylorSeriesExpansion<Scalar>::template precision<3>(); // Precision for the Taylor series
45 // expansion.
46
47
2/4
✓ Branch 1 taken 21361 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 21361 times.
✗ Branch 5 not taken.
42720 Eigen::AngleAxis<Scalar> aa(t, v / t);
48
1/2
✓ Branch 1 taken 21361 times.
✗ Branch 2 not taken.
42720 QuaternionPlain quat_then(aa);
49
50 // order 4 Taylor expansion in theta / (order 2 in t2)
51
1/2
✓ Branch 1 taken 21361 times.
✗ Branch 2 not taken.
42720 QuaternionPlain quat_else;
52
2/4
✓ Branch 1 taken 334 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 334 times.
✗ Branch 5 not taken.
42720 const Scalar t2_2 = t2 / 4; // theta/2 squared
53
9/18
✓ Branch 1 taken 21361 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 21361 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 334 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 334 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 334 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 334 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 334 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 334 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 334 times.
✗ Branch 26 not taken.
46060 quat_else.vec() =
54
4/8
✓ Branch 1 taken 21361 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 334 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 334 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 334 times.
✗ Branch 11 not taken.
46728 Scalar(0.5) * (Scalar(1) - t2_2 / Scalar(6) + t2_2 * t2_2 / Scalar(120)) * v;
55
10/20
✓ Branch 1 taken 21361 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 334 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 334 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 334 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 334 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 334 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 334 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 334 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 334 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 334 times.
✗ Branch 29 not taken.
42720 quat_else.w() = Scalar(1) - t2_2 / 2 + t2_2 * t2_2 / 24;
56
57 using ::pinocchio::internal::if_then_else;
58
2/2
✓ Branch 0 taken 85444 times.
✓ Branch 1 taken 21361 times.
213600 for (Eigen::DenseIndex k = 0; k < 4; ++k)
59 {
60
4/8
✓ Branch 1 taken 85444 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7848 times.
✓ Branch 5 taken 1296 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 40 times.
✗ Branch 9 not taken.
170880 quat_out.coeffs().coeffRef(k) = if_then_else(
61
2/4
✓ Branch 1 taken 17136 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 17136 times.
✗ Branch 5 not taken.
170880 ::pinocchio::internal::GT, t2, ts_prec, quat_then.coeffs().coeffRef(k),
62
1/2
✓ Branch 2 taken 17136 times.
✗ Branch 3 not taken.
170880 quat_else.coeffs().coeffRef(k));
63 }
64 42720 }
65
66 /// \brief Exp: so3 -> SO3 (quaternion)
67 ///
68 /// \returns the integral of the velocity vector as a quaternion.
69 ///
70 /// \param[in] v The angular velocity vector.
71 ///
72 template<typename Vector3Like>
73 Eigen::
74 Quaternion<typename Vector3Like::Scalar, PINOCCHIO_EIGEN_PLAIN_TYPE(Vector3Like)::Options>
75 exp3(const Eigen::MatrixBase<Vector3Like> & v)
76 {
77 typedef Eigen::Quaternion<
78 typename Vector3Like::Scalar, PINOCCHIO_EIGEN_PLAIN_TYPE(Vector3Like)::Options>
79 ReturnType;
80 ReturnType res;
81 exp3(v, res);
82 return res;
83 }
84
85 /// \brief The se3 -> SE3 exponential map, using quaternions to represent the output rotation.
86 ///
87 /// \returns the integral of the twist motion over unit time.
88 ///
89 /// \param[in] motion the spatial motion.
90 /// \param[out] q the output transform in \f$\mathbb{R}^3 x S^3\f$.
91 template<typename MotionDerived, typename Config_t>
92 22854 void exp6(const MotionDense<MotionDerived> & motion, Eigen::MatrixBase<Config_t> & qout)
93 {
94 enum
95 {
96 Options = PINOCCHIO_EIGEN_PLAIN_TYPE(Config_t)::Options
97 };
98 typedef typename Config_t::Scalar Scalar;
99 typedef typename MotionDerived::Vector3 Vector3;
100 typedef Eigen::Quaternion<Scalar, Options> Quaternion_t;
101
1/2
✓ Branch 1 taken 329 times.
✗ Branch 2 not taken.
22854 const Scalar eps = Eigen::NumTraits<Scalar>::epsilon();
102
103
1/2
✓ Branch 1 taken 11642 times.
✗ Branch 2 not taken.
22854 const typename MotionDerived::ConstAngularType & w = motion.angular();
104
1/2
✓ Branch 1 taken 11642 times.
✗ Branch 2 not taken.
22854 const typename MotionDerived::ConstLinearType & v = motion.linear();
105
106
3/6
✓ Branch 1 taken 11642 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 329 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 329 times.
✗ Branch 8 not taken.
23509 const Scalar t2 = w.squaredNorm() + eps * eps;
107
1/2
✓ Branch 1 taken 329 times.
✗ Branch 2 not taken.
22854 const Scalar t = math::sqrt(t2);
108
109
2/4
✓ Branch 1 taken 329 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 329 times.
✗ Branch 5 not taken.
655 Scalar ct, st;
110
1/2
✓ Branch 1 taken 329 times.
✗ Branch 2 not taken.
22854 SINCOS(t, &st, &ct);
111
112
2/4
✓ Branch 1 taken 329 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 329 times.
✗ Branch 5 not taken.
22854 const Scalar inv_t2 = Scalar(1) / t2;
113
1/2
✓ Branch 1 taken 329 times.
✗ Branch 2 not taken.
22854 const Scalar ts_prec =
114
1/2
✓ Branch 1 taken 11313 times.
✗ Branch 2 not taken.
22199 TaylorSeriesExpansion<Scalar>::template precision<3>(); // Taylor expansion precision
115
116 using ::pinocchio::internal::if_then_else;
117 using ::pinocchio::internal::LT;
118
119
5/10
✓ Branch 1 taken 329 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 329 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 329 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 329 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 329 times.
✗ Branch 14 not taken.
48328 const Scalar alpha_wxv = if_then_else(
120 LT, t, ts_prec,
121
2/4
✓ Branch 1 taken 329 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 329 times.
✗ Branch 5 not taken.
2620 Scalar(0.5) - t2 / Scalar(24), // then: use Taylor expansion
122
1/2
✓ Branch 1 taken 11642 times.
✗ Branch 2 not taken.
22854 (Scalar(1) - ct) * inv_t2 // else
123 );
124
125
7/14
✓ Branch 1 taken 329 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 329 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 329 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 329 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 329 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 329 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 329 times.
✗ Branch 20 not taken.
48328 const Scalar alpha_w2 = if_then_else(
126
3/6
✓ Branch 1 taken 11642 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 329 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 329 times.
✗ Branch 8 not taken.
24819 LT, t, ts_prec, Scalar(1) / Scalar(6) - t2 / Scalar(120), (t - st) * inv_t2 / t);
127
128 // linear part
129
5/10
✓ Branch 1 taken 10982 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 660 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 10982 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 660 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 10982 times.
✗ Branch 10 not taken.
22854 Eigen::Map<Vector3> trans_(qout.derived().template head<3>().data());
130
9/18
✓ Branch 1 taken 11642 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 11642 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 11642 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 11642 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 11642 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 11642 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 11642 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 11642 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 11642 times.
✗ Branch 26 not taken.
22854 trans_.noalias() = v + alpha_wxv * w.cross(v) + alpha_w2 * w.cross(w.cross(v));
131
132 // quaternion part
133 typedef Eigen::Map<Quaternion_t> QuaternionMap_t;
134
2/4
✓ Branch 2 taken 11642 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 11642 times.
✗ Branch 7 not taken.
22854 QuaternionMap_t quat_(qout.derived().template tail<4>().data());
135
1/2
✓ Branch 1 taken 11642 times.
✗ Branch 2 not taken.
22854 exp3(w, quat_);
136 22854 }
137
138 /// \brief The se3 -> SE3 exponential map, using quaternions to represent the output rotation.
139 ///
140 /// \returns the integral of the twist motion over unit time.
141 ///
142 /// \param[in] motion the spatial motion.
143 template<typename MotionDerived>
144 Eigen::Matrix<
145 typename MotionDerived::Scalar,
146 7,
147 1,
148 PINOCCHIO_EIGEN_PLAIN_TYPE(typename MotionDerived::Vector3)::Options>
149 1 exp6(const MotionDense<MotionDerived> & motion)
150 {
151 typedef typename MotionDerived::Scalar Scalar;
152 enum
153 {
154 Options = PINOCCHIO_EIGEN_PLAIN_TYPE(typename MotionDerived::Vector3)::Options
155 };
156 typedef Eigen::Matrix<Scalar, 7, 1, Options> ReturnType;
157
158 1 ReturnType qout;
159 1 exp6(motion, qout);
160 1 return qout;
161 }
162
163 /// \brief The se3 -> SE3 exponential map, using quaternions to represent the output rotation.
164 ///
165 /// \returns the integral of the spatial velocity over unit time.
166 ///
167 /// \param[in] vec6 the vector representing the spatial velocity.
168 /// \param[out] qout the output transform in R^3 x S^3.
169 template<typename Vector6Like, typename Config_t>
170 22853 void exp6(const Eigen::MatrixBase<Vector6Like> & vec6, Eigen::MatrixBase<Config_t> & qout)
171 {
172
3/5
✓ Branch 2 taken 10620 times.
✓ Branch 3 taken 1021 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 647 times.
✗ Branch 6 not taken.
22853 MotionRef<const Vector6Like> nu(vec6.derived());
173
1/2
✓ Branch 1 taken 11641 times.
✗ Branch 2 not taken.
22853 ::pinocchio::quaternion::exp6(nu, qout);
174 22853 }
175
176 /// \brief The se3 -> SE3 exponential map, using quaternions to represent the output rotation.
177 ///
178 /// \returns the integral of the spatial velocity over unit time.
179 ///
180 /// \param[in] vec6 the vector representing the spatial velocity.
181 template<typename Vector6Like>
182 Eigen::
183 Matrix<typename Vector6Like::Scalar, 7, 1, PINOCCHIO_EIGEN_PLAIN_TYPE(Vector6Like)::Options>
184 exp6(const Eigen::MatrixBase<Vector6Like> & vec6)
185 {
186 typedef typename Vector6Like::Scalar Scalar;
187 enum
188 {
189 Options = PINOCCHIO_EIGEN_PLAIN_TYPE(Vector6Like)::Options
190 };
191 typedef Eigen::Matrix<Scalar, 7, 1, Options> ReturnType;
192
193 ReturnType qout;
194 ::pinocchio::quaternion::exp6(vec6, qout);
195 return qout;
196 }
197
198 /// \brief Same as \ref log3 but with a unit quaternion as input.
199 ///
200 /// \param[in] quat the unit quaternion.
201 /// \param[out] theta the angle value (resuling from compurations).
202 ///
203 /// \return The angular velocity vector associated to the rotation matrix.
204 ///
205 template<typename QuaternionLike>
206 Eigen::Matrix<
207 typename QuaternionLike::Scalar,
208 3,
209 1,
210 PINOCCHIO_EIGEN_PLAIN_TYPE(typename QuaternionLike::Vector3)::Options>
211 34394 log3(
212 const Eigen::QuaternionBase<QuaternionLike> & quat, typename QuaternionLike::Scalar & theta)
213 {
214 typedef typename QuaternionLike::Scalar Scalar;
215 enum
216 {
217 Options = PINOCCHIO_EIGEN_PLAIN_TYPE(typename QuaternionLike::Vector3)::Options
218 };
219 typedef Eigen::Matrix<Scalar, 3, 1, Options> Vector3;
220
221
1/2
✓ Branch 1 taken 17210 times.
✗ Branch 2 not taken.
34394 Vector3 res;
222
2/4
✓ Branch 1 taken 17210 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 17210 times.
✗ Branch 5 not taken.
34394 const Scalar norm_squared = quat.vec().squaredNorm();
223
224
4/8
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 165 times.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
330 static const Scalar eps = Eigen::NumTraits<Scalar>::epsilon();
225
4/9
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 17192 times.
✓ Branch 3 taken 18 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 18 times.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
34394 static const Scalar ts_prec = TaylorSeriesExpansion<Scalar>::template precision<2>();
226
3/6
✓ Branch 1 taken 168 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 168 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 168 times.
✗ Branch 8 not taken.
34724 const Scalar norm = math::sqrt(norm_squared + eps * eps);
227
228 using ::pinocchio::internal::GE;
229 using ::pinocchio::internal::if_then_else;
230 using ::pinocchio::internal::LT;
231
232
5/10
✓ Branch 1 taken 17210 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 17210 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 168 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 168 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 168 times.
✗ Branch 14 not taken.
34724 const Scalar pos_neg = if_then_else(GE, quat.w(), Scalar(0), Scalar(+1), Scalar(-1));
233
234
1/2
✓ Branch 1 taken 17210 times.
✗ Branch 2 not taken.
34394 Eigen::Quaternion<Scalar, Options> quat_pos;
235
4/8
✓ Branch 1 taken 17210 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 17210 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 168 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 168 times.
✗ Branch 11 not taken.
34394 quat_pos.w() = pos_neg * quat.w();
236
4/8
✓ Branch 1 taken 17210 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 17210 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 17210 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 17210 times.
✗ Branch 11 not taken.
34394 quat_pos.vec() = pos_neg * quat.vec();
237
238
2/4
✓ Branch 1 taken 17210 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 17210 times.
✗ Branch 5 not taken.
34394 const Scalar theta_2 = math::atan2(norm, quat_pos.w()); // in [0,pi]
239
2/4
✓ Branch 1 taken 17210 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 168 times.
✗ Branch 5 not taken.
34394 const Scalar y_x = norm / quat_pos.w(); // nonnegative
240
4/8
✓ Branch 1 taken 17210 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 17210 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 168 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 168 times.
✗ Branch 11 not taken.
34394 const Scalar y_x_sq = norm_squared / (quat_pos.w() * quat_pos.w());
241
242
7/14
✓ Branch 1 taken 168 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 168 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 168 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 168 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 168 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 168 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 168 times.
✗ Branch 20 not taken.
69448 theta = if_then_else(
243
3/6
✓ Branch 1 taken 168 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 168 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 168 times.
✗ Branch 8 not taken.
1320 LT, norm_squared, ts_prec, Scalar(2.) * (Scalar(1) - y_x_sq / Scalar(3)) * y_x,
244
1/2
✓ Branch 1 taken 17210 times.
✗ Branch 2 not taken.
34724 Scalar(2.) * theta_2);
245
246
3/6
✓ Branch 1 taken 168 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 168 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 168 times.
✗ Branch 8 not taken.
34724 const Scalar th2_2 = theta * theta / Scalar(4);
247
10/20
✓ Branch 1 taken 168 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 168 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 168 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 168 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 168 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 168 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 168 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 168 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 168 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 168 times.
✗ Branch 29 not taken.
71428 const Scalar inv_sinc = if_then_else(
248 LT, norm_squared, ts_prec,
249
5/10
✓ Branch 1 taken 168 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 168 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 168 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 168 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 168 times.
✗ Branch 14 not taken.
2640 Scalar(2) * (Scalar(1) + th2_2 / Scalar(6) + Scalar(7) / Scalar(360) * th2_2 * th2_2),
250
1/2
✓ Branch 2 taken 17042 times.
✗ Branch 3 not taken.
34064 theta / math::sin(theta_2));
251
252
2/2
✓ Branch 0 taken 51630 times.
✓ Branch 1 taken 17210 times.
137576 for (Eigen::DenseIndex k = 0; k < 3; ++k)
253 {
254 // res[k] = if_then_else(LT, norm_squared, ts_prec,
255 // Scalar(2) * (Scalar(1) + y_x_sq / Scalar(6) - y_x_sq*y_x_sq /
256 // Scalar(9)) * pos_neg * quat.vec()[k], inv_sinc * pos_neg *
257 // quat.vec()[k]);
258
5/10
✓ Branch 1 taken 51630 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 51630 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 51630 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 504 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 504 times.
✗ Branch 14 not taken.
103182 res[k] = inv_sinc * quat_pos.vec()[k];
259 }
260 68788 return res;
261 330 }
262
263 ///
264 /// \brief Log: SO3 -> so3.
265 ///
266 /// Pseudo-inverse of log from \f$ SO3 -> { v \in so3, ||v|| \le pi } \f$.
267 ///
268 /// \param[in] quat The unit quaternion representing a certain rotation.
269 ///
270 /// \return The angular velocity vector associated to the quaternion.
271 ///
272 template<typename QuaternionLike>
273 Eigen::Matrix<
274 typename QuaternionLike::Scalar,
275 3,
276 1,
277 PINOCCHIO_EIGEN_PLAIN_TYPE(typename QuaternionLike::Vector3)::Options>
278 8077 log3(const Eigen::QuaternionBase<QuaternionLike> & quat)
279 {
280
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 typename QuaternionLike::Scalar theta;
281
1/2
✓ Branch 2 taken 8066 times.
✗ Branch 3 not taken.
16154 return log3(quat.derived(), theta);
282 3 }
283
284 ///
285 /// \brief Derivative of \f$ q = \exp{\mathbf{v} + \delta\mathbf{v}} \f$ where \f$
286 /// \delta\mathbf{v} \f$
287 /// is a small perturbation of \f$ \mathbf{v} \f$ at identity.
288 ///
289 /// \returns The Jacobian of the quaternion components variation.
290 ///
291 template<typename Vector3Like, typename Matrix43Like>
292 64 void Jexp3CoeffWise(
293 const Eigen::MatrixBase<Vector3Like> & v, const Eigen::MatrixBase<Matrix43Like> & Jexp)
294 {
295 // EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Matrix43Like,4,3);
296
2/4
✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 64 times.
✗ Branch 5 not taken.
64 assert(Jexp.rows() == 4 && Jexp.cols() == 3 && "Jexp does have the right size.");
297 64 Matrix43Like & Jout = PINOCCHIO_EIGEN_CONST_CAST(Matrix43Like, Jexp);
298
299 typedef typename Vector3Like::Scalar Scalar;
300
301
1/2
✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
64 const Scalar n2 = v.squaredNorm();
302 64 const Scalar n = math::sqrt(n2);
303 64 const Scalar theta = Scalar(0.5) * n;
304 64 const Scalar theta2 = Scalar(0.25) * n2;
305
306
2/2
✓ Branch 2 taken 63 times.
✓ Branch 3 taken 1 times.
64 if (n2 > math::sqrt(Eigen::NumTraits<Scalar>::epsilon()))
307 {
308 Scalar c, s;
309 63 SINCOS(theta, &s, &c);
310
4/8
✓ Branch 1 taken 63 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 63 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 63 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 63 times.
✗ Branch 11 not taken.
63 Jout.template topRows<3>().noalias() =
311
2/4
✓ Branch 1 taken 63 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 63 times.
✗ Branch 5 not taken.
63 ((Scalar(0.5) / n2) * (c - 2 * s / n)) * v * v.transpose();
312
4/8
✓ Branch 1 taken 63 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 63 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 63 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 63 times.
✗ Branch 11 not taken.
63 Jout.template topRows<3>().diagonal().array() += s / n;
313
5/10
✓ Branch 1 taken 63 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 63 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 63 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 63 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 63 times.
✗ Branch 14 not taken.
63 Jout.template bottomRows<1>().noalias() = -s / (2 * n) * v.transpose();
314 }
315 else
316 {
317
4/8
✓ 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.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
1 Jout.template topRows<3>().noalias() =
318
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 (-Scalar(1) / Scalar(12) + n2 / Scalar(480)) * v * v.transpose();
319
4/8
✓ 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.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
1 Jout.template topRows<3>().diagonal().array() += Scalar(0.5) * (1 - theta2 / 6);
320
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.
1 Jout.template bottomRows<1>().noalias() =
321
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 (Scalar(-0.25) * (Scalar(1) - theta2 / 6)) * v.transpose();
322 }
323 64 }
324
325 ///
326 ///  \brief Computes the Jacobian of log3 operator for a unit quaternion.
327 ///
328 /// \param[in] quat A unit quaternion representing the input rotation.
329 /// \param[out] Jlog The resulting Jacobian of the log operator.
330 ///
331 template<typename QuaternionLike, typename Matrix3Like>
332 1 void Jlog3(
333 const Eigen::QuaternionBase<QuaternionLike> & quat,
334 const Eigen::MatrixBase<Matrix3Like> & Jlog)
335 {
336 typedef typename QuaternionLike::Scalar Scalar;
337 typedef Eigen::Matrix<
338 Scalar, 3, 1, PINOCCHIO_EIGEN_PLAIN_TYPE(typename QuaternionLike::Coefficients)::Options>
339 Vector3;
340
341 Scalar t;
342
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 Vector3 w(log3(quat, t));
343
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 pinocchio::Jlog3(t, w, PINOCCHIO_EIGEN_CONST_CAST(Matrix3Like, Jlog));
344 1 }
345 } // namespace quaternion
346 } // namespace pinocchio
347
348 #endif // ifndef __pinocchio_spatial_explog_quaternion_hpp__
349