5 #ifndef __pinocchio_math_quaternion_hpp__
6 #define __pinocchio_math_quaternion_hpp__
8 #ifndef PINOCCHIO_DEFAULT_QUATERNION_NORM_TOLERANCE_VALUE
9 #define PINOCCHIO_DEFAULT_QUATERNION_NORM_TOLERANCE_VALUE 1e-8
18 #include <boost/type_traits.hpp>
19 #include <Eigen/Geometry>
34 template<
typename D1,
typename D2>
36 const Eigen::QuaternionBase<D1> &
q1,
const Eigen::QuaternionBase<D2> & q2)
40 Scalar theta = math::acos(innerprod);
41 static const Scalar PI_value = PI<Scalar>();
57 template<
typename D1,
typename D2>
59 const Eigen::QuaternionBase<D1> &
q1,
60 const Eigen::QuaternionBase<D2> & q2,
61 const typename D1::RealScalar & prec =
62 Eigen::NumTraits<typename D1::Scalar>::dummy_precision())
64 return (
q1.coeffs().isApprox(
q2.coeffs(), prec) ||
q1.coeffs().isApprox(-
q2.coeffs(), prec));
93 const Scalar N2 =
q.squaredNorm();
95 const Scalar epsilon = sqrt(sqrt(Eigen::NumTraits<Scalar>::epsilon()));
98 assert(static_leq::op(math::fabs(
static_cast<Scalar>(N2 -
Scalar(1))), epsilon));
105 assert(static_leq::op(
109 Eigen::NumTraits<Scalar>::dummy_precision())));
114 template<
typename Derived>
125 const Scalar mult2 = sqrt(u1);
127 static const Scalar PI_value = PI<Scalar>();
142 template<typename Scalar, bool value = is_floating_point<Scalar>::value>
145 template<Eigen::DenseIndex i>
148 template<
typename Scalar,
typename Matrix3,
typename QuaternionDerived>
150 run(
Scalar t, Eigen::QuaternionBase<QuaternionDerived> &
q,
const Matrix3 & mat)
152 using pinocchio::math::sqrt;
154 Eigen::DenseIndex j = (
i + 1) % 3;
155 Eigen::DenseIndex k = (j + 1) % 3;
158 q.coeffs().coeffRef(
i) =
Scalar(0.5) *
t;
160 q.w() = (
mat.coeff(k, j) -
mat.coeff(j, k)) *
t;
161 q.coeffs().coeffRef(j) = (
mat.coeff(j,
i) +
mat.coeff(
i, j)) *
t;
162 q.coeffs().coeffRef(k) = (
mat.coeff(k,
i) +
mat.coeff(
i, k)) *
t;
168 template<
typename Scalar,
typename Matrix3,
typename QuaternionDerived>
170 run(
Scalar t, Eigen::QuaternionBase<QuaternionDerived> &
q,
const Matrix3 & mat)
172 using pinocchio::math::sqrt;
177 q.x() = (
mat.coeff(2, 1) -
mat.coeff(1, 2)) *
t;
178 q.y() = (
mat.coeff(0, 2) -
mat.coeff(2, 0)) *
t;
179 q.z() = (
mat.coeff(1, 0) -
mat.coeff(0, 1)) *
t;
183 template<
typename Scalar>
186 template<
typename Matrix3,
typename QuaternionDerived>
187 static inline void run(Eigen::QuaternionBase<QuaternionDerived> &
q,
const Matrix3 & mat)
189 using pinocchio::math::sqrt;
196 Eigen::DenseIndex
i = 0;
197 if (
mat.coeff(1, 1) >
mat.coeff(0, 0))
199 if (
mat.coeff(2, 2) >
mat.coeff(
i,
i))
214 template<
typename D,
typename Matrix3>
215 void assignQuaternion(Eigen::QuaternionBase<D> & quat,
const Eigen::MatrixBase<Matrix3> & R)
218 quat.derived(),
R.derived());
229 template<
typename Quaternion>
231 const Eigen::QuaternionBase<Quaternion> & quat,
232 const typename Quaternion::Coefficients::RealScalar & prec)
244 template<
typename Quaternion>
245 inline bool isNormalized(
const Eigen::QuaternionBase<Quaternion> & quat)
247 typedef typename Quaternion::Coefficients::RealScalar RealScalar;
248 const RealScalar prec = math::sqrt(Eigen::NumTraits<RealScalar>::epsilon());
257 template<
typename Quaternion>
258 inline void normalize(
const Eigen::QuaternionBase<Quaternion> & quat)
271 typename QuaternionIn1,
272 typename QuaternionIn2,
273 typename QuaternionOut>
276 const Eigen::QuaternionBase<QuaternionIn1> & quat0,
277 const Eigen::QuaternionBase<QuaternionIn2> & quat1,
278 const Eigen::QuaternionBase<QuaternionOut> &
res)
280 const Scalar one =
Scalar(1) - Eigen::NumTraits<Scalar>::epsilon();
281 const Scalar d = quat0.dot(quat1);
284 const Scalar theta = acos(absD);
285 const Scalar sinTheta = sin(theta);
295 const Scalar scale1_factor =
300 static_cast<Scalar>(sin((
u * theta)) / sinTheta)
305 scale0 * quat0.coeffs() + scale1 * quat1.coeffs();
311 #endif // #ifndef __pinocchio_math_quaternion_hpp__