pinocchio  2.1.3
quaternion.hpp
1 //
2 // Copyright (c) 2016,2018 CNRS, INRIA
3 //
4 
5 #ifndef __math_quaternion_hpp__
6 #define __math_quaternion_hpp__
7 
8 #include "pinocchio/math/fwd.hpp"
9 
10 namespace pinocchio
11 {
12  namespace quaternion
13  {
22  template<typename D1, typename D2>
23  typename D1::Scalar
24  angleBetweenQuaternions(const Eigen::QuaternionBase<D1> & q1,
25  const Eigen::QuaternionBase<D2> & q2)
26  {
27  typedef typename D1::Scalar Scalar;
28  const Scalar innerprod = q1.dot(q2);
29  Scalar theta = acos(innerprod);
30  static const Scalar PI_value = PI<Scalar>();
31 
32  if(innerprod < 0)
33  return PI_value - theta;
34 
35  return theta;
36  }
37 
47  template<typename D1, typename D2>
48  bool defineSameRotation(const Eigen::QuaternionBase<D1> & q1,
49  const Eigen::QuaternionBase<D2> & q2,
50  const typename D1::RealScalar & prec = Eigen::NumTraits<typename D1::Scalar>::dummy_precision())
51  {
52  return (q1.coeffs().isApprox(q2.coeffs(), prec) || q1.coeffs().isApprox(-q2.coeffs(), prec) );
53  }
54 
76  template<typename D>
77  void firstOrderNormalize(const Eigen::QuaternionBase<D> & q)
78  {
79  typedef typename D::Scalar Scalar;
80  const Scalar N2 = q.squaredNorm();
81 #ifndef NDEBUG
82  const Scalar epsilon = sqrt(sqrt(Eigen::NumTraits<Scalar>::epsilon()));
83  assert(math::fabs(N2-1.) <= epsilon);
84 #endif
85  const Scalar alpha = ((Scalar)3 - N2) / Scalar(2);
86  const_cast <Eigen::QuaternionBase<D> &> (q).coeffs() *= alpha;
87 #ifndef NDEBUG
88  const Scalar M = Scalar(3) * math::pow(Scalar(1)-epsilon, ((Scalar)-Scalar(5))/Scalar(2)) / Scalar(4);
89  assert(math::fabs(q.norm() - Scalar(1)) <=
90  std::max(M * sqrt(N2) * (N2 - Scalar(1))*(N2 - Scalar(1)) / Scalar(2), Eigen::NumTraits<Scalar>::dummy_precision()));
91 #endif
92  }
93 
95  template<typename Derived>
96  void uniformRandom(const Eigen::QuaternionBase<Derived> & q)
97  {
98  typedef typename Derived::Scalar Scalar;
99 
100  // Rotational part
101  const Scalar u1 = (Scalar)rand() / RAND_MAX;
102  const Scalar u2 = (Scalar)rand() / RAND_MAX;
103  const Scalar u3 = (Scalar)rand() / RAND_MAX;
104 
105  const Scalar mult1 = sqrt(Scalar(1)-u1);
106  const Scalar mult2 = sqrt(u1);
107 
108  const Scalar PI_value = PI<Scalar>();
109  Scalar s2,c2; SINCOS(Scalar(2)*PI_value*u2,&s2,&c2);
110  Scalar s3,c3; SINCOS(Scalar(2)*PI_value*u3,&s3,&c3);
111 
112  PINOCCHIO_EIGEN_CONST_CAST(Derived,q).w() = mult1 * s2;
113  PINOCCHIO_EIGEN_CONST_CAST(Derived,q).x() = mult1 * c2;
114  PINOCCHIO_EIGEN_CONST_CAST(Derived,q).y() = mult2 * s3;
115  PINOCCHIO_EIGEN_CONST_CAST(Derived,q).z() = mult2 * c3;
116  }
117 
118  } // namespace quaternion
119 
120  // Deprecated functions. They are now in the pinocchio::quaternion namespace
121 
123  template<typename D1, typename D2>
124  typename D1::Scalar PINOCCHIO_DEPRECATED
125  angleBetweenQuaternions(const Eigen::QuaternionBase<D1> & q1,
126  const Eigen::QuaternionBase<D2> & q2)
127  {
129  }
130 
132  template<typename D1, typename D2>
133  bool PINOCCHIO_DEPRECATED
134  defineSameRotation(const Eigen::QuaternionBase<D1> & q1,
135  const Eigen::QuaternionBase<D2> & q2,
136  const typename D1::RealScalar & prec
137  = Eigen::NumTraits<typename D1::Scalar>::dummy_precision())
138  {
139  return quaternion::defineSameRotation(q1,q2,prec);
140  }
141 
143  template<typename D>
144  void PINOCCHIO_DEPRECATED
145  firstOrderNormalize(const Eigen::QuaternionBase<D> & q)
146  {
148  }
149 
151  template<typename D>
152  void PINOCCHIO_DEPRECATED
153  uniformRandom(const Eigen::QuaternionBase<D> & q)
154  {
156  }
157 }
158 #endif //#ifndef __math_quaternion_hpp__
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.
Definition: quaternion.hpp:48
D1::Scalar angleBetweenQuaternions(const Eigen::QuaternionBase< D1 > &q1, const Eigen::QuaternionBase< D2 > &q2)
Compute the minimal angle between q1 and q2.
Definition: quaternion.hpp:24
void firstOrderNormalize(const Eigen::QuaternionBase< D > &q)
Definition: quaternion.hpp:77
void SINCOS(const Scalar &a, Scalar *sa, Scalar *ca)
Computes sin/cos values of a given input scalar.
Definition: sincos.hpp:28
void uniformRandom(const Eigen::QuaternionBase< Derived > &q)
Uniformly random quaternion sphere.
Definition: quaternion.hpp:96
Main pinocchio namespace.
Definition: treeview.dox:24