5#ifndef __pinocchio_spatial_explog_quaternion_hpp__ 6#define __pinocchio_spatial_explog_quaternion_hpp__ 8#include "pinocchio/math/quaternion.hpp" 9#include "pinocchio/spatial/explog.hpp" 10#include "pinocchio/utils/static-if.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);
32 typedef typename Vector3Like::Scalar
Scalar;
35 Options = PINOCCHIO_EIGEN_PLAIN_TYPE(
typename QuaternionLike::Coefficients)::Options
37 typedef Eigen::Quaternion<typename QuaternionLike::Scalar, Options> QuaternionPlain;
38 const Scalar eps = Eigen::NumTraits<Scalar>::epsilon();
40 const Scalar t2 = v.squaredNorm();
41 const Scalar t = math::sqrt(t2 + eps * eps);
43 static const Scalar ts_prec =
47 Eigen::AngleAxis<Scalar> aa(t, v / t);
48 QuaternionPlain quat_then(aa);
51 QuaternionPlain quat_else;
52 const Scalar t2_2 = t2 / 4;
55 quat_else.w() =
Scalar(1) - t2_2 / 2 + t2_2 * t2_2 / 24;
57 using ::pinocchio::internal::if_then_else;
58 for (Eigen::DenseIndex k = 0; k < 4; ++k)
60 quat_out.coeffs().coeffRef(k) = if_then_else(
61 ::pinocchio::internal::GT, t2, ts_prec, quat_then.coeffs().coeffRef(k),
62 quat_else.coeffs().coeffRef(k));
72 template<
typename Vector3Like>
74 Quaternion<
typename Vector3Like::Scalar, PINOCCHIO_EIGEN_PLAIN_TYPE(Vector3Like)::Options>
75 exp3(const Eigen::MatrixBase<Vector3Like> & v)
77 typedef Eigen::Quaternion<
78 typename Vector3Like::Scalar, PINOCCHIO_EIGEN_PLAIN_TYPE(Vector3Like)::Options>
91 template<
typename MotionDerived,
typename Config_t>
96 Options = PINOCCHIO_EIGEN_PLAIN_TYPE(Config_t)::Options
98 typedef typename Config_t::Scalar
Scalar;
99 typedef typename MotionDerived::Vector3
Vector3;
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();
106 const Scalar t2 = w.squaredNorm() + eps * eps;
107 const Scalar t = math::sqrt(t2);
116 using ::pinocchio::internal::if_then_else;
117 using ::pinocchio::internal::LT;
119 const Scalar alpha_wxv = if_then_else(
125 const Scalar alpha_w2 = if_then_else(
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>
145 typename MotionDerived::Scalar,
148 PINOCCHIO_EIGEN_PLAIN_TYPE(
typename MotionDerived::Vector3)::Options>
151 typedef typename MotionDerived::Scalar
Scalar;
154 Options = PINOCCHIO_EIGEN_PLAIN_TYPE(
typename MotionDerived::Vector3)::Options
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>
183 Matrix<
typename Vector6Like::Scalar, 7, 1, PINOCCHIO_EIGEN_PLAIN_TYPE(Vector6Like)::Options>
184 exp6(const Eigen::MatrixBase<Vector6Like> & vec6)
186 typedef typename Vector6Like::Scalar
Scalar;
189 Options = PINOCCHIO_EIGEN_PLAIN_TYPE(Vector6Like)::Options
191 typedef Eigen::Matrix<Scalar, 7, 1, Options>
ReturnType;
205 template<
typename QuaternionLike>
207 typename QuaternionLike::Scalar,
210 PINOCCHIO_EIGEN_PLAIN_TYPE(
typename QuaternionLike::Vector3)::Options>
212 const Eigen::QuaternionBase<QuaternionLike> & quat, typename QuaternionLike::
Scalar & theta)
214 typedef typename QuaternionLike::Scalar
Scalar;
217 Options = PINOCCHIO_EIGEN_PLAIN_TYPE(
typename QuaternionLike::Vector3)::Options
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);
228 using ::pinocchio::internal::GE;
229 using ::pinocchio::internal::if_then_else;
230 using ::pinocchio::internal::LT;
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());
242 theta = if_then_else(
247 const Scalar inv_sinc = if_then_else(
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>
274 typename QuaternionLike::Scalar,
277 PINOCCHIO_EIGEN_PLAIN_TYPE(
typename QuaternionLike::Vector3)::Options>
278 log3(const Eigen::QuaternionBase<QuaternionLike> & quat)
280 typename QuaternionLike::Scalar theta;
281 return log3(quat.derived(), theta);
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.");
297 Matrix43Like & Jout = PINOCCHIO_EIGEN_CONST_CAST(Matrix43Like, Jexp);
299 typedef typename Vector3Like::Scalar
Scalar;
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() =
321 (
Scalar(-0.25) * (
Scalar(1) - theta2 / 6)) * v.transpose();
331 template<
typename QuaternionLike,
typename Matrix3Like>
333 const Eigen::QuaternionBase<QuaternionLike> & quat,
334 const Eigen::MatrixBase<Matrix3Like> & Jlog)
336 typedef typename QuaternionLike::Scalar
Scalar;
337 typedef Eigen::Matrix<
338 Scalar, 3, 1, PINOCCHIO_EIGEN_PLAIN_TYPE(
typename QuaternionLike::Coefficients)::Options>
void Jexp3CoeffWise(const Eigen::MatrixBase< Vector3Like > &v, const Eigen::MatrixBase< Matrix43Like > &Jexp)
Derivative of where is a small perturbation of at identity.
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 exp6(const MotionDense< MotionDerived > &motion, Eigen::MatrixBase< Config_t > &qout)
The se3 -> SE3 exponential map, using quaternions to represent the output rotation.
void exp3(const Eigen::MatrixBase< Vector3Like > &v, Eigen::QuaternionBase< QuaternionLike > &quat_out)
Exp: so3 -> SO3 (quaternion)
void Jlog3(const Eigen::QuaternionBase< QuaternionLike > &quat, const Eigen::MatrixBase< Matrix3Like > &Jlog)
Computes the Jacobian of log3 operator for a unit quaternion.
Main pinocchio namespace.
void Jlog3(const Scalar &theta, const Eigen::MatrixBase< Vector3Like > &log, const Eigen::MatrixBase< Matrix3Like > &Jlog)
Derivative of log3.
void SINCOS(const S1 &a, S2 *sa, S3 *ca)
Computes sin/cos values of a given input scalar.
MotionTpl< Scalar, Options > motion(const JointDataTpl< Scalar, Options, JointCollectionTpl > &jdata)
Visit a JointDataTpl through JointMotionVisitor to get the joint internal motion as a dense motion.