5 #ifndef __pinocchio_multibody_liegroup_special_orthogonal_operation_hpp__
6 #define __pinocchio_multibody_liegroup_special_orthogonal_operation_hpp__
17 template<
int Dim,
typename Scalar,
int Options = 0>
22 template<
int Dim,
typename Scalar,
int Options>
27 template<
typename _Scalar,
int _Options>
39 template<
typename _Scalar,
int _Options>
51 template<
typename _Scalar,
int _Options>
53 :
public LieGroupBase<SpecialOrthogonalOperationTpl<2, _Scalar, _Options>>
56 typedef Eigen::Matrix<Scalar, 2, 2>
Matrix2;
57 typedef typename Eigen::NumTraits<Scalar>::Real
RealScalar;
59 template<
typename Matrix2Like>
63 EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Matrix2Like, 2, 2);
67 static const Scalar PI_value = PI<Scalar>();
77 static_cast<Scalar>(-PI_value)),
94 assert(check_expression_if_real<Scalar>(theta == theta) &&
"theta is NaN");
100 template<
typename Matrix2Like>
104 EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Matrix2Like, 2, 2);
132 return std::string(
"SO(2)");
135 template<
class ConfigL_t,
class ConfigR_t,
class Tangent_t>
137 const Eigen::MatrixBase<ConfigL_t> &
q0,
138 const Eigen::MatrixBase<ConfigR_t> &
q1,
139 const Eigen::MatrixBase<Tangent_t> &
d)
142 R(0, 0) =
R(1, 1) =
q0.dot(
q1);
148 template<ArgumentPosition arg,
class ConfigL_t,
class ConfigR_t,
class JacobianOut_t>
150 const Eigen::MatrixBase<ConfigL_t> &
q0,
151 const Eigen::MatrixBase<ConfigR_t> &
q1,
152 const Eigen::MatrixBase<JacobianOut_t> &
J)
155 R(0, 0) =
R(1, 1) =
q0.dot(
q1);
163 template<
class ConfigIn_t,
class Velocity_t,
class ConfigOut_t>
165 const Eigen::MatrixBase<ConfigIn_t> &
q,
166 const Eigen::MatrixBase<Velocity_t> &
v,
167 const Eigen::MatrixBase<ConfigOut_t> &
qout)
175 Scalar cosOmega, sinOmega;
176 SINCOS(omega, &sinOmega, &cosOmega);
179 out << cosOmega * ca - sinOmega * sa, sinOmega * ca + cosOmega * sa;
182 const Scalar norm2 = out.squaredNorm();
183 out *= (3 - norm2) / 2;
187 template<
class Config_t,
class Jacobian_t>
189 const Eigen::MatrixBase<Config_t> &
q,
const Eigen::MatrixBase<Jacobian_t> &
J)
191 assert(
J.rows() ==
nq() &&
J.cols() ==
nv() &&
"J is not of the right dimension");
196 template<
class Config_t,
class Tangent_t,
class JacobianOut_t>
198 const Eigen::MatrixBase<Config_t> & ,
199 const Eigen::MatrixBase<Tangent_t> & ,
200 const Eigen::MatrixBase<JacobianOut_t> &
J,
216 assert(
false &&
"Wrong Op requesed value");
221 template<
class Config_t,
class Tangent_t,
class JacobianOut_t>
223 const Eigen::MatrixBase<Config_t> & ,
224 const Eigen::MatrixBase<Tangent_t> & ,
225 const Eigen::MatrixBase<JacobianOut_t> &
J,
241 assert(
false &&
"Wrong Op requesed value");
246 template<
class Config_t,
class Tangent_t,
class JacobianIn_t,
class JacobianOut_t>
248 const Eigen::MatrixBase<Config_t> & ,
249 const Eigen::MatrixBase<Tangent_t> & ,
250 const Eigen::MatrixBase<JacobianIn_t> & Jin,
251 const Eigen::MatrixBase<JacobianOut_t> & Jout)
256 template<
class Config_t,
class Tangent_t,
class JacobianIn_t,
class JacobianOut_t>
258 const Eigen::MatrixBase<Config_t> & ,
259 const Eigen::MatrixBase<Tangent_t> & ,
260 const Eigen::MatrixBase<JacobianIn_t> & Jin,
261 const Eigen::MatrixBase<JacobianOut_t> & Jout)
266 template<
class Config_t,
class Tangent_t,
class Jacobian_t>
268 const Eigen::MatrixBase<Config_t> & ,
269 const Eigen::MatrixBase<Tangent_t> & ,
270 const Eigen::MatrixBase<Jacobian_t> & )
274 template<
class Config_t,
class Tangent_t,
class Jacobian_t>
276 const Eigen::MatrixBase<Config_t> & ,
277 const Eigen::MatrixBase<Tangent_t> & ,
278 const Eigen::MatrixBase<Jacobian_t> & )
282 template<
class ConfigL_t,
class ConfigR_t,
class ConfigOut_t>
284 const Eigen::MatrixBase<ConfigL_t> &
q0,
285 const Eigen::MatrixBase<ConfigR_t> &
q1,
287 const Eigen::MatrixBase<ConfigOut_t> &
qout)
292 check_expression_if_real<Scalar>(abs(
q0.norm() - 1) < 1e-8)
293 &&
"initial configuration not normalized");
295 check_expression_if_real<Scalar>(abs(
q1.norm() - 1) < 1e-8)
296 &&
"final configuration not normalized");
299 const Scalar theta = atan2(sinTheta, cosTheta);
300 assert(check_expression_if_real<Scalar>(fabs(sin(theta) - sinTheta) < 1e-8));
302 static const Scalar PI_value = PI<Scalar>();
303 static const Scalar PI_value_lower = PI_value -
static_cast<Scalar>(1e-6);
304 using namespace internal;
307 const Scalar abs_theta = fabs(theta);
309 LT, abs_theta,
static_cast<Scalar>(1e-6),
312 LT, abs_theta, PI_value_lower,
314 (sin((
Scalar(1) -
u) * theta) / sinTheta) *
q0[0]
315 + (sin(
u * theta) / sinTheta) *
q1[0]),
320 LT, abs_theta,
static_cast<Scalar>(1e-6),
323 LT, abs_theta, PI_value_lower,
325 (sin((
Scalar(1) -
u) * theta) / sinTheta) *
q0[1]
326 + (sin(
u * theta) / sinTheta) *
q1[1]),
331 template<
class Config_t>
337 template<
class Config_t>
342 return abs(norm -
Scalar(1.0)) < prec;
345 template<
class Config_t>
350 static const Scalar PI_value = PI<Scalar>();
352 SINCOS(angle, &out(1), &out(0));
355 template<
class ConfigL_t,
class ConfigR_t,
class ConfigOut_t>
357 const Eigen::MatrixBase<ConfigL_t> &,
358 const Eigen::MatrixBase<ConfigR_t> &,
359 const Eigen::MatrixBase<ConfigOut_t> &
qout)
365 template<
typename _Scalar,
int _Options>
367 :
public LieGroupBase<SpecialOrthogonalOperationTpl<3, _Scalar, _Options>>
402 return std::string(
"SO(3)");
405 template<
class ConfigL_t,
class ConfigR_t,
class Tangent_t>
407 const Eigen::MatrixBase<ConfigL_t> &
q0,
408 const Eigen::MatrixBase<ConfigR_t> &
q1,
409 const Eigen::MatrixBase<Tangent_t> &
d)
420 template<ArgumentPosition arg,
class ConfigL_t,
class ConfigR_t,
class JacobianOut_t>
422 const Eigen::MatrixBase<ConfigL_t> &
q0,
423 const Eigen::MatrixBase<ConfigR_t> &
q1,
424 const Eigen::MatrixBase<JacobianOut_t> &
J)
435 const Matrix3
R =
q.matrix();
444 else if (arg ==
ARG1)
466 template<
class ConfigIn_t,
class Velocity_t,
class ConfigOut_t>
468 const Eigen::MatrixBase<ConfigIn_t> &
q,
469 const Eigen::MatrixBase<Velocity_t> &
v,
470 const Eigen::MatrixBase<ConfigOut_t> &
qout)
478 quat_map =
quat * pOmega;
483 template<
class Config_t,
class Jacobian_t>
485 const Eigen::MatrixBase<Config_t> &
q,
const Eigen::MatrixBase<Jacobian_t> &
J)
487 assert(
J.rows() ==
nq() &&
J.cols() ==
nv() &&
"J is not of the right dimension");
498 Eigen::Matrix<Scalar, NQ, NV, JacobianPlainType::Options | Eigen::RowMajor>
510 if (quat_map.coeffs()[3] >= 0.)
520 template<
class Config_t,
class Tangent_t,
class JacobianOut_t>
522 const Eigen::MatrixBase<Config_t> & ,
523 const Eigen::MatrixBase<Tangent_t> &
v,
524 const Eigen::MatrixBase<JacobianOut_t> &
J,
540 assert(
false &&
"Wrong Op requesed value");
545 template<
class Config_t,
class Tangent_t,
class JacobianOut_t>
547 const Eigen::MatrixBase<Config_t> & ,
548 const Eigen::MatrixBase<Tangent_t> &
v,
549 const Eigen::MatrixBase<JacobianOut_t> &
J,
555 Jexp3<SETTO>(
v,
J.derived());
558 Jexp3<ADDTO>(
v,
J.derived());
561 Jexp3<RMTO>(
v,
J.derived());
564 assert(
false &&
"Wrong Op requesed value");
569 template<
class Config_t,
class Tangent_t,
class JacobianIn_t,
class JacobianOut_t>
571 const Eigen::MatrixBase<Config_t> & ,
572 const Eigen::MatrixBase<Tangent_t> &
v,
573 const Eigen::MatrixBase<JacobianIn_t> & Jin,
574 const Eigen::MatrixBase<JacobianOut_t> & J_out)
578 const Matrix3 Jtmp3 =
exp3(-
v);
579 Jout.noalias() = Jtmp3 * Jin;
582 template<
class Config_t,
class Tangent_t,
class JacobianIn_t,
class JacobianOut_t>
584 const Eigen::MatrixBase<Config_t> & ,
585 const Eigen::MatrixBase<Tangent_t> &
v,
586 const Eigen::MatrixBase<JacobianIn_t> & Jin,
587 const Eigen::MatrixBase<JacobianOut_t> & J_out)
594 Jexp3<SETTO>(
v, Jtmp3);
596 Jout.noalias() = Jtmp3 * Jin;
599 template<
class Config_t,
class Tangent_t,
class Jacobian_t>
601 const Eigen::MatrixBase<Config_t> & ,
602 const Eigen::MatrixBase<Tangent_t> &
v,
603 const Eigen::MatrixBase<Jacobian_t> & J_out)
607 const Matrix3 Jtmp3 =
exp3(-
v);
611 template<
class Config_t,
class Tangent_t,
class Jacobian_t>
613 const Eigen::MatrixBase<Config_t> & ,
614 const Eigen::MatrixBase<Tangent_t> &
v,
615 const Eigen::MatrixBase<Jacobian_t> & J_out)
622 Jexp3<SETTO>(
v, Jtmp3);
627 template<
class ConfigL_t,
class ConfigR_t,
class ConfigOut_t>
629 const Eigen::MatrixBase<ConfigL_t> &
q0,
630 const Eigen::MatrixBase<ConfigR_t> &
q1,
632 const Eigen::MatrixBase<ConfigOut_t> &
qout)
642 difference_impl(
q0,
q1,
w);
647 template<
class ConfigL_t,
class ConfigR_t>
649 const Eigen::MatrixBase<ConfigL_t> &
q0,
const Eigen::MatrixBase<ConfigR_t> &
q1)
654 difference_impl(
q0,
q1,
t);
656 return t.squaredNorm();
659 template<
class Config_t>
665 template<
class Config_t>
670 return abs(norm -
Scalar(1.0)) < prec;
673 template<
class Config_t>
682 template<
class ConfigL_t,
class ConfigR_t,
class ConfigOut_t>
684 const Eigen::MatrixBase<ConfigL_t> &,
685 const Eigen::MatrixBase<ConfigR_t> &,
686 const Eigen::MatrixBase<ConfigOut_t> &
qout)
691 template<
class ConfigL_t,
class ConfigR_t>
693 const Eigen::MatrixBase<ConfigL_t> &
q0,
694 const Eigen::MatrixBase<ConfigR_t> &
q1,
708 #endif // ifndef __pinocchio_multibody_liegroup_special_orthogonal_operation_hpp__