18 #ifndef __se3_special_orthogonal_operation_hpp__    19 #define __se3_special_orthogonal_operation_hpp__    23 #include <pinocchio/spatial/explog.hpp>    24 #include <pinocchio/math/quaternion.hpp>    25 #include <pinocchio/multibody/liegroup/operation-base.hpp>    33     typedef double Scalar;
    41     typedef double Scalar;
    52     typedef Eigen::Matrix<Scalar,2,2> Matrix2;
    54     static Scalar log(
const Matrix2 & R)
    57       const Scalar tr = R.trace();
    58       const bool pos = (R (1, 0) > Scalar(0));
    59       const Scalar PI_value = PI<Scalar>();
    60       if (tr > Scalar(2))       theta = Scalar(0); 
    61       else if (tr < Scalar(-2)) theta = (pos ? PI_value : -PI_value); 
    64       else if (tr > Scalar(2) - 1e-2) theta = asin ((R(1,0) - R(0,1)) / Scalar(2));
    65       else              theta = (pos ? acos (tr/Scalar(2)) : -acos(tr/Scalar(2)));
    66       assert (theta == theta); 
    67       assert (fabs(theta - atan2 (R(1,0), R(0,0))) < 1e-6);
    71     static Scalar Jlog (
const Matrix2&)
    92       ConfigVector_t n; n.setZero(); n[0] = Scalar(1);
    96     std::string 
name ()
 const    98       return std::string (
"SO(2)");
   101     template <
class ConfigL_t, 
class ConfigR_t, 
class Tangent_t>
   102     static void difference_impl(
const Eigen::MatrixBase<ConfigL_t> & q0,
   103                                 const Eigen::MatrixBase<ConfigR_t> & q1,
   104                                 const Eigen::MatrixBase<Tangent_t> & d)
   107         (const_cast < Tangent_t& > (d.derived())).setZero ();
   111       R(0,0) = R(1,1) = q0.dot(q1);
   112       R(1,0) = q0(0) * q1(1) - q0(1) * q1(0);
   114       const_cast < Tangent_t& > (d.derived()) [0] = log (R);
   117     template <
class ConfigL_t, 
class ConfigR_t, 
class JacobianLOut_t, 
class JacobianROut_t>
   118     static void Jdifference_impl(
const Eigen::MatrixBase<ConfigL_t> & q0,
   119                                  const Eigen::MatrixBase<ConfigR_t> & q1,
   120                                  const Eigen::MatrixBase<JacobianLOut_t>& J0,
   121                                  const Eigen::MatrixBase<JacobianROut_t>& J1)
   124       R(0,0) = R(1,1) = q0.dot(q1);
   125       R(1,0) = q0(0) * q1(1) - q0(1) * q1(0);
   129       const_cast< JacobianLOut_t& 
> (J0.derived()).coeffRef(0,0) = -w;
   130       const_cast< JacobianROut_t& 
> (J1.derived()).coeffRef(0,0) =  w;
   133     template <
class ConfigIn_t, 
class Velocity_t, 
class ConfigOut_t>
   134     static void integrate_impl(
const Eigen::MatrixBase<ConfigIn_t> & q,
   135                                const Eigen::MatrixBase<Velocity_t> & v,
   136                                const Eigen::MatrixBase<ConfigOut_t> & qout)
   138       ConfigOut_t& out = (
const_cast< Eigen::MatrixBase<ConfigOut_t>& 
>(qout)).derived();
   140       const Scalar & ca = q(0);
   141       const Scalar & sa = q(1);
   142       const Scalar & omega = v(0);
   144       Scalar cosOmega,sinOmega; SINCOS(omega, &sinOmega, &cosOmega);
   147       out << cosOmega * ca - sinOmega * sa,
   148              sinOmega * ca + cosOmega * sa;
   149       const Scalar norm2 = q.squaredNorm();
   150       out *= (3 - norm2) / 2;
   153     template <
class Config_t, 
class Tangent_t, 
class JacobianOut_t>
   154     static void dIntegrate_dq_impl(
const Eigen::MatrixBase<Config_t >  & ,
   155                                    const Eigen::MatrixBase<Tangent_t>  & ,
   156                                    const Eigen::MatrixBase<JacobianOut_t>& J)
   158       JacobianOut_t& Jout = 
const_cast< JacobianOut_t& 
>(J.derived());
   162     template <
class Config_t, 
class Tangent_t, 
class JacobianOut_t>
   163     static void dIntegrate_dv_impl(
const Eigen::MatrixBase<Config_t >  & ,
   164                                    const Eigen::MatrixBase<Tangent_t>  & ,
   165                                    const Eigen::MatrixBase<JacobianOut_t>& J)
   167       JacobianOut_t& Jout = 
const_cast< JacobianOut_t& 
>(J.derived());
   171     template <
class ConfigL_t, 
class ConfigR_t, 
class ConfigOut_t>
   172     static void interpolate_impl(
const Eigen::MatrixBase<ConfigL_t> & q0,
   173                                  const Eigen::MatrixBase<ConfigR_t> & q1,
   175                                  const Eigen::MatrixBase<ConfigOut_t>& qout)
   177       ConfigOut_t& out = (
const_cast< Eigen::MatrixBase<ConfigOut_t>& 
>(qout)).derived();
   179       assert ( (q0.norm() - 1) < 1e-8 && 
"initial configuration not normalized");
   180       assert ( (q1.norm() - 1) < 1e-8 && 
"final configuration not normalized");
   181       Scalar cosTheta = q0.dot(q1);
   182       Scalar sinTheta = q0(0)*q1(1) - q0(1)*q1(0);
   183       Scalar theta = atan2(sinTheta, cosTheta);
   184       assert (fabs (sin (theta) - sinTheta) < 1e-8);
   186       const Scalar PI_value = PI<Scalar>();
   188       if (fabs (theta) > 1e-6 && fabs (theta) < PI_value - 1e-6)
   190         out = (sin ((1-u)*theta)/sinTheta) * q0
   191             + (sin (   u *theta)/sinTheta) * q1;
   193       else if (fabs (theta) < 1e-6) 
   195         out = (1-u) * q0 + u * q1;
   199         Scalar theta0 = atan2 (q0(1), q0(0));
   200         SINCOS(theta0,&out[1],&out[0]);
   208     template <
class Config_t>
   209     static void normalize_impl (
const Eigen::MatrixBase<Config_t>& qout)
   211       Config_t& qout_ = (
const_cast< Eigen::MatrixBase<Config_t>& 
>(qout)).derived();
   215     template <
class Config_t>
   216     void random_impl (
const Eigen::MatrixBase<Config_t>& qout)
 const   218       Config_t& out = (
const_cast< Eigen::MatrixBase<Config_t>& 
>(qout)).derived();
   220       const Scalar PI_value = PI<Scalar>();
   221       const Scalar angle = -PI_value + Scalar(2)* PI_value * ((Scalar)rand())/RAND_MAX;
   222       SINCOS(angle, &out(1), &out(0));
   225     template <
class ConfigL_t, 
class ConfigR_t, 
class ConfigOut_t>
   226     void randomConfiguration_impl(
const Eigen::MatrixBase<ConfigL_t> &,
   227                                   const Eigen::MatrixBase<ConfigR_t> &,
   228                                   const Eigen::MatrixBase<ConfigOut_t> & qout)
   240     typedef Eigen::Quaternion<Scalar> Quaternion_t;
   241     typedef Eigen::Map<      Quaternion_t> QuaternionMap_t;
   242     typedef Eigen::Map<const Quaternion_t> ConstQuaternionMap_t;
   258     ConfigVector_t 
neutral ()
 const   260       ConfigVector_t n; n.setZero (); n[3] = Scalar(1);
   264     std::string 
name ()
 const   266       return std::string (
"SO(3)");
   269     template <
class ConfigL_t, 
class ConfigR_t, 
class Tangent_t>
   270     static void difference_impl(
const Eigen::MatrixBase<ConfigL_t> & q0,
   271                                 const Eigen::MatrixBase<ConfigR_t> & q1,
   272                                 const Eigen::MatrixBase<Tangent_t> & d)
   275         (const_cast < Eigen::MatrixBase<Tangent_t>& > (d)).setZero ();
   278       ConstQuaternionMap_t p0 (q0.derived().data());
   279       ConstQuaternionMap_t p1 (q1.derived().data());
   280       const_cast < Eigen::MatrixBase<Tangent_t>& > (d)
   281         = 
log3((p0.matrix().transpose() * p1.matrix()).eval());
   284     template <
class ConfigL_t, 
class ConfigR_t, 
class JacobianLOut_t, 
class JacobianROut_t>
   285     static void Jdifference_impl(
const Eigen::MatrixBase<ConfigL_t> & q0,
   286                                  const Eigen::MatrixBase<ConfigR_t> & q1,
   287                                  const Eigen::MatrixBase<JacobianLOut_t>& J0,
   288                                  const Eigen::MatrixBase<JacobianROut_t>& J1)
   290       ConstQuaternionMap_t p0 (q0.derived().data());
   291       ConstQuaternionMap_t p1 (q1.derived().data());
   292       Eigen::Matrix<Scalar, 3, 3> R = p0.matrix().transpose() * p1.matrix();
   296       JacobianLOut_t& J0v = 
const_cast< JacobianLOut_t& 
> (J0.derived());
   297       J0v.noalias() = - J1 * R.transpose();
   300     template <
class ConfigIn_t, 
class Velocity_t, 
class ConfigOut_t>
   301     static void integrate_impl(
const Eigen::MatrixBase<ConfigIn_t> & q,
   302                                const Eigen::MatrixBase<Velocity_t> & v,
   303                                const Eigen::MatrixBase<ConfigOut_t> & qout)
   305       ConstQuaternionMap_t quat(q.derived().data());
   306       QuaternionMap_t quaternion_result (
   307           (
const_cast< Eigen::MatrixBase<ConfigOut_t>& 
>(qout)).derived().data()
   310       Quaternion_t pOmega(
exp3(v));
   311       quaternion_result = quat * pOmega;
   315     template <
class Config_t, 
class Tangent_t, 
class JacobianOut_t>
   316     static void dIntegrate_dq_impl(
const Eigen::MatrixBase<Config_t >  & ,
   317                                    const Eigen::MatrixBase<Tangent_t>  & v,
   318                                    const Eigen::MatrixBase<JacobianOut_t>& J)
   320       JacobianOut_t& Jout = 
const_cast< JacobianOut_t& 
>(J.derived());
   321       Jout = 
exp3(v).transpose();
   324     template <
class Config_t, 
class Tangent_t, 
class JacobianOut_t>
   325     static void dIntegrate_dv_impl(
const Eigen::MatrixBase<Config_t >  & ,
   326                                    const Eigen::MatrixBase<Tangent_t>  & v,
   327                                    const Eigen::MatrixBase<JacobianOut_t>& J)
   329       Jexp3 (v, J.derived());
   332     template <
class ConfigL_t, 
class ConfigR_t, 
class ConfigOut_t>
   333     static void interpolate_impl(
const Eigen::MatrixBase<ConfigL_t> & q0,
   334                                  const Eigen::MatrixBase<ConfigR_t> & q1,
   336                                  const Eigen::MatrixBase<ConfigOut_t>& qout)
   338       ConstQuaternionMap_t p0 (q0.derived().data());
   339       ConstQuaternionMap_t p1 (q1.derived().data());
   340       QuaternionMap_t quaternion_result (
   341           (
const_cast< Eigen::MatrixBase<ConfigOut_t>& 
>(qout)).derived().data()
   344       quaternion_result = p0.slerp(u, p1);
   347     template <
class ConfigL_t, 
class ConfigR_t>
   348     static double squaredDistance_impl(
const Eigen::MatrixBase<ConfigL_t> & q0,
   349                                        const Eigen::MatrixBase<ConfigR_t> & q1)
   352       difference_impl(q0, q1, t);
   353       return t.squaredNorm();
   356     template <
class Config_t>
   357     static void normalize_impl (
const Eigen::MatrixBase<Config_t>& qout)
   359       Config_t& qout_ = (
const_cast< Eigen::MatrixBase<Config_t>& 
>(qout)).derived();
   363     template <
class Config_t>
   364     void random_impl (
const Eigen::MatrixBase<Config_t>& qout)
 const   366       QuaternionMap_t out (
   367           (
const_cast< Eigen::MatrixBase<Config_t>& 
>(qout)).derived().data()
   372     template <
class ConfigL_t, 
class ConfigR_t, 
class ConfigOut_t>
   373     void randomConfiguration_impl(
const Eigen::MatrixBase<ConfigL_t> &,
   374                                   const Eigen::MatrixBase<ConfigR_t> &,
   375                                   const Eigen::MatrixBase<ConfigOut_t> & qout)
   381     template <
class ConfigL_t, 
class ConfigR_t>
   382     static bool isSameConfiguration_impl(
const Eigen::MatrixBase<ConfigL_t> & q0,
   383                                          const Eigen::MatrixBase<ConfigR_t> & q1,
   386       ConstQuaternionMap_t quat1(q0.derived().data());
   387       ConstQuaternionMap_t quat2(q1.derived().data());
   394 #endif // ifndef __se3_special_orthogonal_operation_hpp__ 
void Jexp3(const Eigen::MatrixBase< Vector3Like > &r, const Eigen::MatrixBase< Matrix3Like > &Jexp)
Derivative of  . 
 
std::string name(const LieGroupVariant &lg)
Visit a LieGroupVariant to get the name of it. 
 
Eigen::Matrix< typename Matrix3Like::Scalar, 3, 1, Eigen::internal::traits< Matrix3Like >::Options > log3(const Eigen::MatrixBase< Matrix3Like > &R, S2 &theta)
Same as log3. 
 
Eigen::VectorXd neutral(const Model &model)
Return the neutral configuration element related to the model configuration space. 
 
void uniformRandom(const Eigen::QuaternionBase< D > &q)
Uniformly random quaternion sphere. 
 
Index nv() const 
Get dimension of Lie Group tangent space. 
 
Eigen::Matrix< typename Vector3Like::Scalar, 3, 3, EIGEN_PLAIN_TYPE(Vector3Like)::Options > exp3(const Eigen::MatrixBase< Vector3Like > &v)
Exp: so3 -> SO3. 
 
void firstOrderNormalize(const Eigen::QuaternionBase< D > &q)
 
Index nv() const 
Get dimension of Lie Group tangent space. 
 
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.