6 #ifndef __pinocchio_multibody_joint_planar_hpp__
7 #define __pinocchio_multibody_joint_planar_hpp__
9 #include "pinocchio/macros.hpp"
10 #include "pinocchio/multibody/joint/joint-base.hpp"
11 #include "pinocchio/spatial/cartesian-axis.hpp"
12 #include "pinocchio/multibody/joint-motion-subspace.hpp"
13 #include "pinocchio/spatial/motion.hpp"
14 #include "pinocchio/spatial/inertia.hpp"
19 template<
typename Scalar,
int Options = context::Options>
20 struct MotionPlanarTpl;
21 typedef MotionPlanarTpl<context::Scalar> MotionPlanar;
23 template<
typename Scalar,
int Options>
29 template<
typename Scalar,
int Options,
typename MotionDerived>
35 template<
typename _Scalar,
int _Options>
38 typedef _Scalar Scalar;
43 typedef Eigen::Matrix<Scalar, 3, 1, Options> Vector3;
44 typedef Eigen::Matrix<Scalar, 6, 1, Options> Vector6;
45 typedef Eigen::Matrix<Scalar, 4, 4, Options> Matrix4;
46 typedef Eigen::Matrix<Scalar, 6, 6, Options> Matrix6;
47 typedef typename PINOCCHIO_EIGEN_REF_CONST_TYPE(Vector6) ToVectorConstReturnType;
48 typedef typename PINOCCHIO_EIGEN_REF_TYPE(Vector6) ToVectorReturnType;
49 typedef Vector3 AngularType;
50 typedef Vector3 LinearType;
51 typedef const Vector3 ConstAngularType;
52 typedef const Vector3 ConstLinearType;
53 typedef Matrix6 ActionMatrixType;
54 typedef Matrix4 HomogeneousMatrixType;
64 template<
typename _Scalar,
int _Options>
67 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
76 MotionPlanarTpl(
const Scalar & x_dot,
const Scalar & y_dot,
const Scalar & theta_dot)
78 m_data << x_dot, y_dot, theta_dot;
81 template<
typename Vector3Like>
85 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Vector3Like, 3);
88 inline PlainReturnType plain()
const
90 return PlainReturnType(
91 typename PlainReturnType::Vector3(vx(), vy(), Scalar(0)),
92 typename PlainReturnType::Vector3(Scalar(0), Scalar(0), wz()));
95 template<
typename Derived>
98 other.linear()[0] += vx();
99 other.linear()[1] += vy();
100 other.angular()[2] += wz();
103 template<
typename MotionDerived>
106 other.linear() << vx(), vy(), (Scalar)0;
107 other.angular() << (Scalar)0, (Scalar)0, wz();
110 template<
typename S2,
int O2,
typename D2>
113 v.angular().noalias() = m.rotation().col(2) * wz();
114 v.linear().noalias() = m.rotation().template leftCols<2>() * m_data.template head<2>();
115 v.linear() += m.translation().cross(v.angular());
118 template<
typename S2,
int O2>
122 se3Action_impl(m, res);
126 template<
typename S2,
int O2,
typename D2>
132 ZAxis::alphaCross(wz(), m.translation(), v3_tmp);
135 v.linear().noalias() = m.rotation().transpose() * v3_tmp;
138 v.angular().noalias() = m.rotation().transpose().col(2) * wz();
141 template<
typename S2,
int O2>
145 se3ActionInverse_impl(m, res);
149 template<
typename M1,
typename M2>
153 ZAxis::alphaCross(-wz(), v.linear(), mout.linear());
155 typename M1::ConstAngularType w_in = v.angular();
156 typename M2::LinearType v_out = mout.linear();
158 v_out[0] -= w_in[2] * vy();
159 v_out[1] += w_in[2] * vx();
160 v_out[2] += -w_in[1] * vx() + w_in[0] * vy();
163 ZAxis::alphaCross(-wz(), v.angular(), mout.angular());
166 template<
typename M1>
170 motionAction(v, res);
174 const Scalar & vx()
const
183 const Scalar & vy()
const
192 const Scalar & wz()
const
201 const Vector3 & data()
const
212 return internal::comparison_eq(m_data, other.m_data);
220 template<
typename Scalar,
int Options,
typename MotionDerived>
221 inline typename MotionDerived::MotionPlain
224 typename MotionDerived::MotionPlain result(m2);
225 result.linear()[0] += m1.vx();
226 result.linear()[1] += m1.vy();
228 result.angular()[2] += m1.wz();
233 template<
typename Scalar,
int Options>
234 struct JointMotionSubspacePlanarTpl;
236 template<
typename _Scalar,
int _Options>
239 typedef _Scalar Scalar;
250 typedef Eigen::Matrix<Scalar, 3, 1, Options> JointForce;
251 typedef Eigen::Matrix<Scalar, 6, 3, Options> DenseBase;
252 typedef Eigen::Matrix<Scalar, 3, 3, Options> ReducedSquaredMatrix;
254 typedef DenseBase MatrixReturnType;
255 typedef const DenseBase ConstMatrixReturnType;
257 typedef typename ReducedSquaredMatrix::IdentityReturnType StDiagonalMatrixSOperationReturnType;
260 template<
typename _Scalar,
int _Options>
264 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
274 template<
typename Vector3Like>
275 JointMotion __mult__(
const Eigen::MatrixBase<Vector3Like> & vj)
const
277 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Vector3Like, 3);
278 return JointMotion(vj);
294 template<
typename Derived>
302 template<
typename Derived>
303 friend typename Eigen::
304 Matrix<typename Eigen::MatrixBase<Derived>::Scalar, 3, Derived::ColsAtCompileTime>
307 typedef typename Eigen::MatrixBase<Derived>::Scalar Scalar;
308 typedef Eigen::Matrix<Scalar, 3, Derived::ColsAtCompileTime> MatrixReturnType;
309 assert(F.rows() == 6);
311 MatrixReturnType result(3, F.cols());
312 result.template topRows<2>() = F.template topRows<2>();
313 result.template bottomRows<1>() = F.template bottomRows<1>();
324 DenseBase matrix_impl()
const
327 S.template block<3, 3>(Inertia::LINEAR, 0).setZero();
328 S.template block<3, 3>(Inertia::ANGULAR, 0).setZero();
329 S(Inertia::LINEAR + 0, 0) = Scalar(1);
330 S(Inertia::LINEAR + 1, 1) = Scalar(1);
331 S(Inertia::ANGULAR + 2, 2) = Scalar(1);
335 template<
typename S1,
int O1>
336 DenseBase se3Action(
const SE3Tpl<S1, O1> & m)
const
338 DenseBase X_subspace;
341 X_subspace.template block<3, 2>(Motion::LINEAR, 0) = m.rotation().template leftCols<2>();
342 X_subspace.template block<3, 1>(Motion::LINEAR, 2).noalias() =
343 m.translation().cross(m.rotation().template rightCols<1>());
346 X_subspace.template block<3, 2>(Motion::ANGULAR, 0).setZero();
347 X_subspace.template block<3, 1>(Motion::ANGULAR, 2) = m.rotation().template rightCols<1>();
352 template<
typename S1,
int O1>
353 DenseBase se3ActionInverse(
const SE3Tpl<S1, O1> & m)
const
355 DenseBase X_subspace;
358 X_subspace.template block<3, 2>(Motion::LINEAR, 0) =
359 m.rotation().transpose().template leftCols<2>();
360 X_subspace.template block<3, 1>(Motion::ANGULAR, 2).noalias() =
361 m.rotation().transpose() * m.translation();
362 X_subspace.template block<3, 1>(Motion::LINEAR, 2).noalias() =
363 -X_subspace.template block<3, 1>(Motion::ANGULAR, 2)
364 .cross(m.rotation().transpose().template rightCols<1>());
367 X_subspace.template block<3, 2>(Motion::ANGULAR, 0).setZero();
368 X_subspace.template block<3, 1>(Motion::ANGULAR, 2) =
369 m.rotation().transpose().template rightCols<1>();
374 template<
typename MotionDerived>
375 DenseBase motionAction(
const MotionDense<MotionDerived> & m)
const
377 const typename MotionDerived::ConstLinearType v = m.linear();
378 const typename MotionDerived::ConstAngularType w = m.angular();
379 DenseBase res(DenseBase::Zero());
393 bool isEqual(
const JointMotionSubspacePlanarTpl &)
const
400 template<
typename MotionDerived,
typename S2,
int O2>
401 inline typename MotionDerived::MotionPlain
402 operator^(
const MotionDense<MotionDerived> & m1,
const MotionPlanarTpl<S2, O2> & m2)
404 return m2.motionAction(m1);
408 template<
typename S1,
int O1,
typename S2,
int O2>
409 inline typename Eigen::Matrix<S1, 6, 3, O1>
410 operator*(
const InertiaTpl<S1, O1> & Y,
const JointMotionSubspacePlanarTpl<S2, O2> &)
412 typedef InertiaTpl<S1, O1> Inertia;
413 typedef typename Inertia::Scalar Scalar;
414 typedef Eigen::Matrix<S1, 6, 3, O1> ReturnType;
417 const Scalar mass = Y.mass();
418 const typename Inertia::Vector3 & com = Y.lever();
419 const typename Inertia::Symmetric3 & inertia = Y.inertia();
421 M.template topLeftCorner<3, 3>().setZero();
422 M.template topLeftCorner<2, 2>().diagonal().fill(mass);
424 const typename Inertia::Vector3 mc(mass * com);
425 M.template rightCols<1>().template head<2>() << -mc(1), mc(0);
427 M.template bottomLeftCorner<3, 2>() << (Scalar)0, -mc(2), mc(2), (Scalar)0, -mc(1), mc(0);
428 M.template rightCols<1>().template tail<3>() = inertia.data().template tail<3>();
429 M.template rightCols<1>()[3] -= mc(0) * com(2);
430 M.template rightCols<1>()[4] -= mc(1) * com(2);
431 M.template rightCols<1>()[5] += mass * (com(0) * com(0) + com(1) * com(1));
439 template<
typename M6Like,
typename S2,
int O2>
440 inline Eigen::Matrix<S2, 6, 3, O2>
441 operator*(
const Eigen::MatrixBase<M6Like> & Y,
const JointMotionSubspacePlanarTpl<S2, O2> &)
443 EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(M6Like, 6, 6);
444 typedef Eigen::Matrix<S2, 6, 3, O2> Matrix63;
447 IS.template leftCols<2>() = Y.template leftCols<2>();
448 IS.template rightCols<1>() = Y.template rightCols<1>();
453 template<
typename S1,
int O1>
456 typedef Eigen::Matrix<S1, 6, 3, O1> ReturnType;
459 template<
typename S1,
int O1,
typename MotionDerived>
462 typedef Eigen::Matrix<S1, 6, 3, O1> ReturnType;
465 template<
typename Scalar,
int Options>
468 template<
typename _Scalar,
int _Options>
480 typedef _Scalar Scalar;
489 typedef Eigen::Matrix<Scalar, 6, NV, Options> U_t;
490 typedef Eigen::Matrix<Scalar, NV, NV, Options> D_t;
491 typedef Eigen::Matrix<Scalar, 6, NV, Options> UD_t;
493 typedef Eigen::Matrix<Scalar, NQ, 1, Options> ConfigVector_t;
494 typedef Eigen::Matrix<Scalar, NV, 1, Options> TangentVector_t;
496 PINOCCHIO_JOINT_DATA_BASE_ACCESSOR_DEFAULT_RETURN_TYPE
499 template<
typename _Scalar,
int _Options>
503 typedef _Scalar Scalar;
505 template<
typename _Scalar,
int _Options>
509 typedef _Scalar Scalar;
512 template<
typename _Scalar,
int _Options>
515 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
518 PINOCCHIO_JOINT_DATA_BASE_DEFAULT_ACCESSOR
520 ConfigVector_t joint_q;
521 TangentVector_t joint_v;
535 :
joint_q(Scalar(0), Scalar(0), Scalar(1), Scalar(0))
536 ,
joint_v(TangentVector_t::Zero())
537 , M(Transformation_t::Identity())
538 , v(Motion_t::Vector3::Zero())
541 , UDinv(UD_t::Zero())
546 static std::string classname()
548 return std::string(
"JointDataPlanar");
550 std::string shortname()
const
558 template<
typename _Scalar,
int _Options>
561 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
569 using Base::setIndexes;
571 JointDataDerived createData()
const
573 return JointDataDerived();
576 const std::vector<bool> hasConfigurationLimit()
const
578 return {
true,
true,
false,
false};
581 const std::vector<bool> hasConfigurationLimitInTangent()
const
583 return {
true,
true,
false};
586 template<
typename ConfigVector>
588 forwardKinematics(Transformation_t & M,
const Eigen::MatrixBase<ConfigVector> & q_joint)
const
590 const Scalar &c_theta = q_joint(2), &s_theta = q_joint(3);
592 M.rotation().template topLeftCorner<2, 2>() << c_theta, -s_theta, s_theta, c_theta;
593 M.translation().template head<2>() = q_joint.template head<2>();
596 template<
typename ConfigVector>
597 void calc(JointDataDerived & data,
const typename Eigen::MatrixBase<ConfigVector> & qs)
const
599 data.joint_q = qs.template segment<NQ>(idx_q());
601 const Scalar &c_theta = data.joint_q(2), &s_theta = data.joint_q(3);
603 data.M.rotation().template topLeftCorner<2, 2>() << c_theta, -s_theta, s_theta, c_theta;
604 data.M.translation().template head<2>() = data.joint_q.template head<2>();
607 template<
typename TangentVector>
609 calc(JointDataDerived & data,
const Blank,
const typename Eigen::MatrixBase<TangentVector> & vs)
612 data.joint_v = vs.template segment<NV>(idx_v());
614 #define q_dot data.joint_v
615 data.v.vx() = q_dot(0);
616 data.v.vy() = q_dot(1);
617 data.v.wz() = q_dot(2);
621 template<
typename ConfigVector,
typename TangentVector>
623 JointDataDerived & data,
624 const typename Eigen::MatrixBase<ConfigVector> & qs,
625 const typename Eigen::MatrixBase<TangentVector> & vs)
const
627 calc(data, qs.derived());
629 data.joint_v = vs.template segment<NV>(idx_v());
631 #define q_dot data.joint_v
632 data.v.vx() = q_dot(0);
633 data.v.vy() = q_dot(1);
634 data.v.wz() = q_dot(2);
638 template<
typename VectorLike,
typename Matrix6Like>
640 JointDataDerived & data,
641 const Eigen::MatrixBase<VectorLike> & armature,
642 const Eigen::MatrixBase<Matrix6Like> & I,
643 const bool update_I)
const
645 data.U.template leftCols<2>() = I.template leftCols<2>();
646 data.U.template rightCols<1>() = I.template rightCols<1>();
648 data.StU.template leftCols<2>() = data.U.template topRows<2>().transpose();
649 data.StU.template rightCols<1>() = data.U.template bottomRows<1>();
651 data.StU.diagonal() += armature;
652 internal::PerformStYSInversion<Scalar>::run(data.StU, data.Dinv);
654 data.UDinv.noalias() = data.U * data.Dinv;
657 PINOCCHIO_EIGEN_CONST_CAST(Matrix6Like, I).noalias() -= data.UDinv * data.U.transpose();
660 static std::string classname()
662 return std::string(
"JointModelPlanar");
664 std::string shortname()
const
670 template<
typename NewScalar>
675 res.setIndexes(
id(), idx_q(), idx_v());
683 #include <boost/type_traits.hpp>
687 template<
typename Scalar,
int Options>
689 :
public integral_constant<bool, true>
693 template<
typename Scalar,
int Options>
695 :
public integral_constant<bool, true>
699 template<
typename Scalar,
int Options>
701 :
public integral_constant<bool, true>
705 template<
typename Scalar,
int Options>
707 :
public integral_constant<bool, true>
ConstAngularType angular() const
Return the angular part of the force vector.
ConstLinearType linear() const
Return the linear part of the force vector.
Main pinocchio namespace.
JointDataTpl< Scalar, Options, JointCollectionTpl >::TangentVector_t joint_v(const JointDataTpl< Scalar, Options, JointCollectionTpl > &jdata)
Visit a JointDataVariant through JointConfigVisitor to get the joint velocity vector.
JointDataTpl< Scalar, Options, JointCollectionTpl >::ConfigVector_t joint_q(const JointDataTpl< Scalar, Options, JointCollectionTpl > &jdata)
Visit a JointDataVariant through JointConfigVisitor to get the joint configuration vector.
JointModelPlanarTpl< NewScalar, Options > cast() const
Return type of the ation of a Motion onto an object of type D.
Common traits structure to fully define base classes for CRTP.