5 #ifndef __pinocchio_spatial_explog_quaternion_hpp__
6 #define __pinocchio_spatial_explog_quaternion_hpp__
25 template<
typename Vector3Like,
typename QuaternionLike>
27 exp3(
const Eigen::MatrixBase<Vector3Like> &
v, Eigen::QuaternionBase<QuaternionLike> & quat_out)
29 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Vector3Like);
30 assert(
v.size() == 3);
37 typedef Eigen::Quaternion<typename QuaternionLike::Scalar, Options> QuaternionPlain;
38 const Scalar eps = Eigen::NumTraits<Scalar>::epsilon();
43 static const Scalar ts_prec =
47 Eigen::AngleAxis<Scalar> aa(
t,
v /
t);
48 QuaternionPlain quat_then(aa);
51 QuaternionPlain quat_else;
55 quat_else.w() =
Scalar(1) - t2_2 / 2 + t2_2 * t2_2 / 24;
58 for (Eigen::DenseIndex k = 0; k < 4; ++k)
62 quat_else.coeffs().coeffRef(k));
72 template<
typename Vector3Like>
91 template<
typename MotionDerived,
typename Config_t>
100 typedef Eigen::Quaternion<Scalar, Options> Quaternion_t;
101 const Scalar eps = Eigen::NumTraits<Scalar>::epsilon();
103 const typename MotionDerived::ConstAngularType &
w =
motion.angular();
104 const typename MotionDerived::ConstLinearType &
v =
motion.linear();
129 Eigen::Map<Vector3> trans_(
qout.derived().template head<3>().data());
130 trans_.noalias() =
v + alpha_wxv *
w.cross(
v) + alpha_w2 *
w.cross(
w.cross(
v));
133 typedef Eigen::Map<Quaternion_t> QuaternionMap_t;
134 QuaternionMap_t quat_(
qout.derived().template tail<4>().data());
143 template<
typename MotionDerived>
156 typedef Eigen::Matrix<Scalar, 7, 1, Options> ReturnType;
169 template<
typename Vector6Like,
typename Config_t>
170 void exp6(
const Eigen::MatrixBase<Vector6Like> & vec6, Eigen::MatrixBase<Config_t> &
qout)
181 template<
typename Vector6Like>
191 typedef Eigen::Matrix<Scalar, 7, 1, Options> ReturnType;
205 template<
typename QuaternionLike>
212 const
Eigen::QuaternionBase<QuaternionLike> &
quat, typename QuaternionLike::
Scalar & theta)
219 typedef Eigen::Matrix<Scalar, 3, 1, Options>
Vector3;
222 const Scalar norm_squared =
quat.vec().squaredNorm();
224 static const Scalar eps = Eigen::NumTraits<Scalar>::epsilon();
226 const Scalar norm = math::sqrt(norm_squared +
eps *
eps);
234 Eigen::Quaternion<Scalar, Options> quat_pos;
235 quat_pos.w() = pos_neg *
quat.w();
236 quat_pos.vec() = pos_neg *
quat.vec();
238 const Scalar theta_2 = math::atan2(norm, quat_pos.w());
239 const Scalar y_x = norm / quat_pos.w();
240 const Scalar y_x_sq = norm_squared / (quat_pos.w() * quat_pos.w());
248 LT, norm_squared, ts_prec,
250 theta / math::sin(theta_2));
252 for (Eigen::DenseIndex k = 0; k < 3; ++k)
258 res[k] = inv_sinc * quat_pos.vec()[k];
272 template<
typename QuaternionLike>
291 template<
typename Vector3Like,
typename Matrix43Like>
293 const Eigen::MatrixBase<Vector3Like> &
v,
const Eigen::MatrixBase<Matrix43Like> & Jexp)
296 assert(Jexp.rows() == 4 && Jexp.cols() == 3 &&
"Jexp does have the right size.");
301 const Scalar n2 =
v.squaredNorm();
302 const Scalar n = math::sqrt(n2);
306 if (n2 > math::sqrt(Eigen::NumTraits<Scalar>::epsilon()))
310 Jout.template topRows<3>().noalias() =
311 ((
Scalar(0.5) / n2) * (
c - 2 * s /
n)) *
v *
v.transpose();
312 Jout.template topRows<3>().diagonal().array() += s /
n;
313 Jout.template bottomRows<1>().noalias() = -s / (2 *
n) *
v.transpose();
317 Jout.template topRows<3>().noalias() =
319 Jout.template topRows<3>().diagonal().array() +=
Scalar(0.5) * (1 - theta2 / 6);
320 Jout.template bottomRows<1>().noalias() =
331 template<
typename QuaternionLike,
typename Matrix3Like>
333 const Eigen::QuaternionBase<QuaternionLike> & quat,
334 const Eigen::MatrixBase<Matrix3Like> & Jlog)
337 typedef Eigen::Matrix<
348 #endif // ifndef __pinocchio_spatial_explog_quaternion_hpp__