5 #ifndef __pinocchio_multibody_liegroup_special_orthogonal_operation_hpp__
6 #define __pinocchio_multibody_liegroup_special_orthogonal_operation_hpp__
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"
17 template<
int Dim,
typename Scalar,
int Options = 0>
22 template<
int Dim,
typename Scalar,
int Options>
27 template<
typename _Scalar,
int _Options>
30 typedef _Scalar Scalar;
39 template<
typename _Scalar,
int _Options>
42 typedef _Scalar Scalar;
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>
60 static typename Matrix2Like::Scalar log(
const Eigen::MatrixBase<Matrix2Like> & R)
62 typedef typename Matrix2Like::Scalar Scalar;
63 EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Matrix2Like, 2, 2);
65 const Scalar tr = R.trace();
67 static const Scalar PI_value = PI<Scalar>();
69 using internal::if_then_else;
70 Scalar theta = if_then_else(
71 internal::GT, tr, Scalar(2),
74 internal::LT, tr, Scalar(-2),
76 internal::GE, R(1, 0), Scalar(0), PI_value,
77 static_cast<Scalar
>(-PI_value)),
80 static_cast<Scalar
>(Scalar(2) - Scalar(1e-2)),
81 static_cast<Scalar
>(asin((R(1, 0) - R(0, 1)) / Scalar(2))),
83 internal::GE, R(1, 0), Scalar(0),
84 static_cast<Scalar
>(acos(tr / Scalar(2))),
85 static_cast<Scalar
>(-acos(tr / Scalar(2)))))));
94 assert(check_expression_if_real<Scalar>(theta == theta) &&
"theta is NaN");
100 template<
typename Matrix2Like>
101 static typename Matrix2Like::Scalar Jlog(
const Eigen::MatrixBase<Matrix2Like> &)
103 typedef typename Matrix2Like::Scalar Scalar;
104 EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Matrix2Like, 2, 2);
123 static ConfigVector_t
neutral()
126 n << Scalar(1), Scalar(0);
130 static std::string
name()
132 return std::string(
"SO(2)");
135 template<
class ConfigL_t,
class ConfigR_t,
class Tangent_t>
136 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)
142 R(0, 0) = R(1, 1) = q0.dot(q1);
143 R(1, 0) = q0(0) * q1(1) - q0(1) * q1(0);
145 PINOCCHIO_EIGEN_CONST_CAST(Tangent_t, d)[0] = log(R);
148 template<ArgumentPosition arg,
class ConfigL_t,
class ConfigR_t,
class JacobianOut_t>
149 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)
155 R(0, 0) = R(1, 1) = q0.dot(q1);
156 R(1, 0) = q0(0) * q1(1) - q0(1) * q1(0);
160 PINOCCHIO_EIGEN_CONST_CAST(JacobianOut_t, J).coeffRef(0, 0) = ((arg == ARG0) ? -w : w);
163 template<
class ConfigIn_t,
class Velocity_t,
class ConfigOut_t>
164 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)
169 ConfigOut_t & out = PINOCCHIO_EIGEN_CONST_CAST(ConfigOut_t, qout);
171 const Scalar ca = q(0);
172 const Scalar sa = q(1);
173 const Scalar & omega = v(0);
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>
188 static void integrateCoeffWiseJacobian_impl(
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");
192 Jacobian_t & Jout = PINOCCHIO_EIGEN_CONST_CAST(Jacobian_t, J);
196 template<
class Config_t,
class Tangent_t,
class JacobianOut_t>
197 static void dIntegrate_dq_impl(
198 const Eigen::MatrixBase<Config_t> & ,
199 const Eigen::MatrixBase<Tangent_t> & ,
200 const Eigen::MatrixBase<JacobianOut_t> & J,
201 const AssignmentOperatorType op = SETTO)
203 JacobianOut_t & Jout = PINOCCHIO_EIGEN_CONST_CAST(JacobianOut_t, J);
207 Jout(0, 0) = Scalar(1);
210 Jout(0, 0) += Scalar(1);
213 Jout(0, 0) -= Scalar(1);
216 assert(
false &&
"Wrong Op requesed value");
221 template<
class Config_t,
class Tangent_t,
class JacobianOut_t>
222 static void dIntegrate_dv_impl(
223 const Eigen::MatrixBase<Config_t> & ,
224 const Eigen::MatrixBase<Tangent_t> & ,
225 const Eigen::MatrixBase<JacobianOut_t> & J,
226 const AssignmentOperatorType op = SETTO)
228 JacobianOut_t & Jout = PINOCCHIO_EIGEN_CONST_CAST(JacobianOut_t, J);
232 Jout(0, 0) = Scalar(1);
235 Jout(0, 0) += Scalar(1);
238 Jout(0, 0) -= Scalar(1);
241 assert(
false &&
"Wrong Op requesed value");
246 template<
class Config_t,
class Tangent_t,
class JacobianIn_t,
class JacobianOut_t>
247 static void dIntegrateTransport_dq_impl(
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)
253 PINOCCHIO_EIGEN_CONST_CAST(JacobianOut_t, Jout) = Jin;
256 template<
class Config_t,
class Tangent_t,
class JacobianIn_t,
class JacobianOut_t>
257 static void dIntegrateTransport_dv_impl(
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)
263 PINOCCHIO_EIGEN_CONST_CAST(JacobianOut_t, Jout) = Jin;
266 template<
class Config_t,
class Tangent_t,
class Jacobian_t>
267 static void dIntegrateTransport_dq_impl(
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>
275 static void dIntegrateTransport_dv_impl(
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>
283 static void interpolate_impl(
284 const Eigen::MatrixBase<ConfigL_t> & q0,
285 const Eigen::MatrixBase<ConfigR_t> & q1,
287 const Eigen::MatrixBase<ConfigOut_t> & qout)
289 ConfigOut_t & out = PINOCCHIO_EIGEN_CONST_CAST(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");
297 const Scalar cosTheta = q0.dot(q1);
298 const Scalar sinTheta = q0(0) * q1(1) - q0(1) * q1(0);
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);
308 out[0] = if_then_else(
309 LT, abs_theta,
static_cast<Scalar
>(1e-6),
310 static_cast<Scalar
>((Scalar(1) - u) * q0[0] + u * q1[0]),
312 LT, abs_theta, PI_value_lower,
314 (sin((Scalar(1) - u) * theta) / sinTheta) * q0[0]
315 + (sin(u * theta) / sinTheta) * q1[0]),
319 out[1] = if_then_else(
320 LT, abs_theta,
static_cast<Scalar
>(1e-6),
321 static_cast<Scalar
>((Scalar(1) - u) * q0[1] + u * q1[1]),
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>
332 static void normalize_impl(
const Eigen::MatrixBase<Config_t> & qout)
337 template<
class Config_t>
338 static bool isNormalized_impl(
const Eigen::MatrixBase<Config_t> & qin,
const Scalar & prec)
340 const Scalar norm = qin.norm();
342 return abs(norm - Scalar(1.0)) < prec;
345 template<
class Config_t>
346 static void random_impl(
const Eigen::MatrixBase<Config_t> & qout)
348 Config_t & out = PINOCCHIO_EIGEN_CONST_CAST(Config_t, qout);
350 static const Scalar PI_value = PI<Scalar>();
351 const Scalar angle = -PI_value + Scalar(2) * PI_value * ((Scalar)rand()) / RAND_MAX;
352 SINCOS(angle, &out(1), &out(0));
355 template<
class ConfigL_t,
class ConfigR_t,
class ConfigOut_t>
356 static void randomConfiguration_impl(
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>>
371 typedef Eigen::Quaternion<Scalar> Quaternion_t;
372 typedef Eigen::Map<Quaternion_t> QuaternionMap_t;
373 typedef Eigen::Map<const Quaternion_t> ConstQuaternionMap_t;
375 typedef typename Eigen::NumTraits<Scalar>::Real RealScalar;
392 static ConfigVector_t
neutral()
400 static std::string
name()
402 return std::string(
"SO(3)");
405 template<
class ConfigL_t,
class ConfigR_t,
class Tangent_t>
406 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)
411 ConstQuaternionMap_t quat0(q0.derived().data());
413 quat0, RealScalar(PINOCCHIO_DEFAULT_QUATERNION_NORM_TOLERANCE_VALUE)));
414 ConstQuaternionMap_t quat1(q1.derived().data());
416 quat1, RealScalar(PINOCCHIO_DEFAULT_QUATERNION_NORM_TOLERANCE_VALUE)));
418 PINOCCHIO_EIGEN_CONST_CAST(Tangent_t, d) =
422 template<ArgumentPosition arg,
class ConfigL_t,
class ConfigR_t,
class JacobianOut_t>
423 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)
428 typedef typename SE3::Matrix3 Matrix3;
430 ConstQuaternionMap_t quat0(q0.derived().data());
432 quat0, RealScalar(PINOCCHIO_DEFAULT_QUATERNION_NORM_TOLERANCE_VALUE)));
433 ConstQuaternionMap_t quat1(q1.derived().data());
435 quat1, RealScalar(PINOCCHIO_DEFAULT_QUATERNION_NORM_TOLERANCE_VALUE)));
438 const Quaternion_t q = quat0.conjugate() * quat1;
439 const Matrix3 R = q.matrix();
446 PINOCCHIO_EIGEN_CONST_CAST(JacobianOut_t, J).noalias() = -J1 * R.transpose();
448 else if (arg == ARG1)
470 template<
class ConfigIn_t,
class Velocity_t,
class ConfigOut_t>
471 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)
476 ConstQuaternionMap_t quat(q.derived().data());
478 quat, RealScalar(PINOCCHIO_DEFAULT_QUATERNION_NORM_TOLERANCE_VALUE)));
479 QuaternionMap_t quat_map(PINOCCHIO_EIGEN_CONST_CAST(ConfigOut_t, qout).data());
483 quat_map = quat * pOmega;
486 quat_map, RealScalar(PINOCCHIO_DEFAULT_QUATERNION_NORM_TOLERANCE_VALUE)));
489 template<
class Config_t,
class Jacobian_t>
490 static void integrateCoeffWiseJacobian_impl(
491 const Eigen::MatrixBase<Config_t> & q,
const Eigen::MatrixBase<Jacobian_t> & J)
493 assert(J.rows() ==
nq() && J.cols() ==
nv() &&
"J is not of the right dimension");
495 typedef typename PINOCCHIO_EIGEN_PLAIN_TYPE(Jacobian_t) JacobianPlainType;
496 typedef typename SE3::Vector3 Vector3;
497 typedef typename SE3::Matrix3 Matrix3;
499 ConstQuaternionMap_t quat_map(q.derived().data());
501 quat_map, RealScalar(PINOCCHIO_DEFAULT_QUATERNION_NORM_TOLERANCE_VALUE)));
503 PINOCCHIO_COMPILER_DIAGNOSTIC_PUSH
504 PINOCCHIO_COMPILER_DIAGNOSTIC_IGNORED_MAYBE_UNINITIALIZED
505 Eigen::Matrix<Scalar, NQ, NV, JacobianPlainType::Options | Eigen::RowMajor>
512 Jlog3(theta, v, Jlog);
513 PINOCCHIO_COMPILER_DIAGNOSTIC_POP
517 if (quat_map.coeffs()[3] >= 0.)
519 PINOCCHIO_EIGEN_CONST_CAST(Jacobian_t, J).noalias() = Jexp3QuatCoeffWise * Jlog;
521 PINOCCHIO_EIGEN_CONST_CAST(Jacobian_t, J).noalias() = -Jexp3QuatCoeffWise * Jlog;
527 template<
class Config_t,
class Tangent_t,
class JacobianOut_t>
528 static void dIntegrate_dq_impl(
529 const Eigen::MatrixBase<Config_t> & ,
530 const Eigen::MatrixBase<Tangent_t> & v,
531 const Eigen::MatrixBase<JacobianOut_t> & J,
532 const AssignmentOperatorType op = SETTO)
534 JacobianOut_t & Jout = PINOCCHIO_EIGEN_CONST_CAST(JacobianOut_t, J);
547 assert(
false &&
"Wrong Op requesed value");
552 template<
class Config_t,
class Tangent_t,
class JacobianOut_t>
553 static void dIntegrate_dv_impl(
554 const Eigen::MatrixBase<Config_t> & ,
555 const Eigen::MatrixBase<Tangent_t> & v,
556 const Eigen::MatrixBase<JacobianOut_t> & J,
557 const AssignmentOperatorType op = SETTO)
562 Jexp3<SETTO>(v, J.derived());
565 Jexp3<ADDTO>(v, J.derived());
568 Jexp3<RMTO>(v, J.derived());
571 assert(
false &&
"Wrong Op requesed value");
576 template<
class Config_t,
class Tangent_t,
class JacobianIn_t,
class JacobianOut_t>
577 static void dIntegrateTransport_dq_impl(
578 const Eigen::MatrixBase<Config_t> & ,
579 const Eigen::MatrixBase<Tangent_t> & v,
580 const Eigen::MatrixBase<JacobianIn_t> & Jin,
581 const Eigen::MatrixBase<JacobianOut_t> & J_out)
583 typedef typename SE3::Matrix3 Matrix3;
584 JacobianOut_t & Jout = PINOCCHIO_EIGEN_CONST_CAST(JacobianOut_t, J_out);
585 const Matrix3 Jtmp3 =
exp3(-v);
586 Jout.noalias() = Jtmp3 * Jin;
589 template<
class Config_t,
class Tangent_t,
class JacobianIn_t,
class JacobianOut_t>
590 static void dIntegrateTransport_dv_impl(
591 const Eigen::MatrixBase<Config_t> & ,
592 const Eigen::MatrixBase<Tangent_t> & v,
593 const Eigen::MatrixBase<JacobianIn_t> & Jin,
594 const Eigen::MatrixBase<JacobianOut_t> & J_out)
596 typedef typename SE3::Matrix3 Matrix3;
597 JacobianOut_t & Jout = PINOCCHIO_EIGEN_CONST_CAST(JacobianOut_t, J_out);
598 PINOCCHIO_COMPILER_DIAGNOSTIC_PUSH
599 PINOCCHIO_COMPILER_DIAGNOSTIC_IGNORED_MAYBE_UNINITIALIZED
601 Jexp3<SETTO>(v, Jtmp3);
602 PINOCCHIO_COMPILER_DIAGNOSTIC_POP
603 Jout.noalias() = Jtmp3 * Jin;
606 template<
class Config_t,
class Tangent_t,
class Jacobian_t>
607 static void dIntegrateTransport_dq_impl(
608 const Eigen::MatrixBase<Config_t> & ,
609 const Eigen::MatrixBase<Tangent_t> & v,
610 const Eigen::MatrixBase<Jacobian_t> & J_out)
612 typedef typename SE3::Matrix3 Matrix3;
613 Jacobian_t & Jout = PINOCCHIO_EIGEN_CONST_CAST(Jacobian_t, J_out);
614 const Matrix3 Jtmp3 =
exp3(-v);
618 template<
class Config_t,
class Tangent_t,
class Jacobian_t>
619 static void dIntegrateTransport_dv_impl(
620 const Eigen::MatrixBase<Config_t> & ,
621 const Eigen::MatrixBase<Tangent_t> & v,
622 const Eigen::MatrixBase<Jacobian_t> & J_out)
624 typedef typename SE3::Matrix3 Matrix3;
625 Jacobian_t & Jout = PINOCCHIO_EIGEN_CONST_CAST(Jacobian_t, J_out);
626 PINOCCHIO_COMPILER_DIAGNOSTIC_PUSH
627 PINOCCHIO_COMPILER_DIAGNOSTIC_IGNORED_MAYBE_UNINITIALIZED
629 Jexp3<SETTO>(v, Jtmp3);
630 PINOCCHIO_COMPILER_DIAGNOSTIC_POP
634 template<
class ConfigL_t,
class ConfigR_t,
class ConfigOut_t>
635 static void interpolate_impl(
636 const Eigen::MatrixBase<ConfigL_t> & q0,
637 const Eigen::MatrixBase<ConfigR_t> & q1,
639 const Eigen::MatrixBase<ConfigOut_t> & qout)
641 ConstQuaternionMap_t quat0(q0.derived().data());
643 quat0, RealScalar(PINOCCHIO_DEFAULT_QUATERNION_NORM_TOLERANCE_VALUE)));
644 ConstQuaternionMap_t quat1(q1.derived().data());
646 quat1, RealScalar(PINOCCHIO_DEFAULT_QUATERNION_NORM_TOLERANCE_VALUE)));
648 QuaternionMap_t quat_res(PINOCCHIO_EIGEN_CONST_CAST(ConfigOut_t, qout).data());
651 difference_impl(q0, q1, w);
652 integrate_impl(q0, u * w, qout);
654 quat_res, RealScalar(PINOCCHIO_DEFAULT_QUATERNION_NORM_TOLERANCE_VALUE)));
657 template<
class ConfigL_t,
class ConfigR_t>
658 static Scalar squaredDistance_impl(
659 const Eigen::MatrixBase<ConfigL_t> & q0,
const Eigen::MatrixBase<ConfigR_t> & q1)
661 PINOCCHIO_COMPILER_DIAGNOSTIC_PUSH
662 PINOCCHIO_COMPILER_DIAGNOSTIC_IGNORED_MAYBE_UNINITIALIZED
664 difference_impl(q0, q1, t);
665 PINOCCHIO_COMPILER_DIAGNOSTIC_POP
666 return t.squaredNorm();
669 template<
class Config_t>
670 static void normalize_impl(
const Eigen::MatrixBase<Config_t> & qout)
675 template<
class Config_t>
676 static bool isNormalized_impl(
const Eigen::MatrixBase<Config_t> & qin,
const Scalar & prec)
678 const Scalar norm = qin.norm();
680 return abs(norm - Scalar(1.0)) < prec;
683 template<
class Config_t>
684 static void random_impl(
const Eigen::MatrixBase<Config_t> & qout)
686 QuaternionMap_t quat_map(PINOCCHIO_EIGEN_CONST_CAST(Config_t, qout).data());
690 quat_map, RealScalar(PINOCCHIO_DEFAULT_QUATERNION_NORM_TOLERANCE_VALUE)));
693 template<
class ConfigL_t,
class ConfigR_t,
class ConfigOut_t>
694 static void randomConfiguration_impl(
695 const Eigen::MatrixBase<ConfigL_t> &,
696 const Eigen::MatrixBase<ConfigR_t> &,
697 const Eigen::MatrixBase<ConfigOut_t> & qout)
702 template<
class ConfigL_t,
class ConfigR_t>
703 static bool isSameConfiguration_impl(
704 const Eigen::MatrixBase<ConfigL_t> & q0,
705 const Eigen::MatrixBase<ConfigR_t> & q1,
708 ConstQuaternionMap_t quat1(q0.derived().data());
710 quat1, RealScalar(PINOCCHIO_DEFAULT_QUATERNION_NORM_TOLERANCE_VALUE)));
711 ConstQuaternionMap_t quat2(q1.derived().data());
713 quat1, RealScalar(PINOCCHIO_DEFAULT_QUATERNION_NORM_TOLERANCE_VALUE)));
void exp3(const Eigen::MatrixBase< Vector3Like > &v, Eigen::QuaternionBase< QuaternionLike > &quat_out)
Exp: so3 -> SO3 (quaternion)
void firstOrderNormalize(const Eigen::QuaternionBase< D > &q)
bool defineSameRotation(const Eigen::QuaternionBase< D1 > &q1, const Eigen::QuaternionBase< D2 > &q2, const typename D1::RealScalar &prec=Eigen::NumTraits< typename D1::Scalar >::dummy_precision())
Check if two quaternions define the same rotations.
bool isNormalized(const Eigen::QuaternionBase< Quaternion > &quat, const typename Quaternion::Coefficients::RealScalar &prec=Eigen::NumTraits< typename Quaternion::Coefficients::RealScalar >::dummy_precision())
Check whether the input quaternion is Normalized within the given precision.
Eigen::Matrix< typename QuaternionLike::Scalar, 3, 1, typename QuaternionLike::Vector3 ::Options > log3(const Eigen::QuaternionBase< QuaternionLike > &quat, typename QuaternionLike::Scalar &theta)
Same as log3 but with a unit quaternion as input.
void Jexp3CoeffWise(const Eigen::MatrixBase< Vector3Like > &v, const Eigen::MatrixBase< Matrix43Like > &Jexp)
Derivative of where is a small perturbation of at identity.
void uniformRandom(Eigen::QuaternionBase< Derived > &q)
Uniformly random quaternion sphere.
Main pinocchio namespace.
Eigen::Matrix< typename Vector3Like::Scalar, 3, 3, Vector3Like ::Options > exp3(const Eigen::MatrixBase< Vector3Like > &v)
Exp: so3 -> SO3.
void Jlog3(const Scalar &theta, const Eigen::MatrixBase< Vector3Like > &log, const Eigen::MatrixBase< Matrix3Like > &Jlog)
Derivative of log3.
bool isNormalized(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, const Eigen::MatrixBase< ConfigVectorType > &q, const Scalar &prec=Eigen::NumTraits< Scalar >::dummy_precision())
Check whether a configuration vector is normalized within the given precision provided by prec.
int nv(const JointModelTpl< Scalar, Options, JointCollectionTpl > &jmodel)
Visit a JointModelTpl through JointNvVisitor to get the dimension of the joint tangent space.
int nq(const JointModelTpl< Scalar, Options, JointCollectionTpl > &jmodel)
Visit a JointModelTpl through JointNqVisitor to get the dimension of the joint configuration space.
std::string name(const LieGroupGenericTpl< LieGroupCollection > &lg)
Visit a LieGroupVariant to get the name of it.
void normalize(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, const Eigen::MatrixBase< ConfigVectorType > &qout)
Normalize a configuration vector.
void neutral(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, const Eigen::MatrixBase< ReturnType > &qout)
Return the neutral configuration element related to the model configuration space.
void SINCOS(const S1 &a, S2 *sa, S3 *ca)
Computes sin/cos values of a given input scalar.
static Index nv()
Get dimension of Lie Group tangent space.
static Index nv()
Get dimension of Lie Group tangent space.
Common traits structure to fully define base classes for CRTP.