// // Copyright (c) 2015-2020 CNRS INRIA // Copyright (c) 2015-2016 Wandercraft, 86 rue de Paris 91400 Orsay, France. // #pragma once // IWYU pragma: private, include "pinocchio/multibody/joint.hpp" #ifdef PINOCCHIO_LSP #undef PINOCCHIO_LSP #include "pinocchio/multibody/joint.hpp" #endif // PINOCCHIO_LSP namespace pinocchio { template struct JointMotionSubspaceIdentityTpl; template struct traits> { typedef _Scalar Scalar; static constexpr int Options = _Options; typedef Eigen::Matrix Matrix6; static constexpr int LINEAR = 0; static constexpr int ANGULAR = 3; typedef MotionTpl JointMotion; typedef Eigen::Matrix JointForce; typedef Eigen::Matrix DenseBase; typedef Eigen::Matrix ReducedSquaredMatrix; typedef typename Matrix6::IdentityReturnType ConstMatrixReturnType; typedef typename Matrix6::IdentityReturnType MatrixReturnType; typedef typename Matrix6::IdentityReturnType StDiagonalMatrixSOperationReturnType; }; // traits ConstraintRevolute template struct JointMotionSubspaceIdentityTpl : JointMotionSubspaceBase> { PINOCCHIO_CONSTRAINT_TYPEDEF_TPL(JointMotionSubspaceIdentityTpl) static constexpr int NV = 6; template JointMotion __mult__(const Eigen::MatrixBase & vj) const { PINOCCHIO_EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE_OR_DYNAMIC(Vector6Like, 6); return JointMotion(vj); } template typename SE3Tpl::ActionMatrixType se3Action(const SE3Tpl & m) const { return m.toActionMatrix(); } template typename SE3Tpl::ActionMatrixType se3ActionInverse(const SE3Tpl & m) const { return m.toActionMatrixInverse(); } int nv_impl() const { return NV; } struct TransposeConst : JointMotionSubspaceTransposeBase { template typename ForceDense::ToVectorConstReturnType operator*(const ForceDense & phi) { return phi.toVector(); } /* [CRBA] MatrixBase operator* (Constraint::Transpose S, ForceSet::Block) */ template typename PINOCCHIO_EIGEN_REF_CONST_TYPE(MatrixDerived) operator*(const Eigen::MatrixBase & F) { return F.derived(); } }; TransposeConst transpose() const { return TransposeConst(); } MatrixReturnType matrix_impl() const { return DenseBase::Identity(); } template typename MotionDerived::ActionMatrixType motionAction(const MotionBase & v) const { return v.toActionMatrix(); } bool isEqual(const JointMotionSubspaceIdentityTpl &) const { return true; } }; // struct JointMotionSubspaceIdentityTpl template MotionRef operator*( const JointMotionSubspaceIdentityTpl &, const Eigen::MatrixBase & v) { PINOCCHIO_EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE_OR_DYNAMIC(Vector6Like, 6); // typedef typename JointMotionSubspaceIdentityTpl::Motion Motion; typedef MotionRef Motion; return Motion(v.derived()); } /* [CRBA] ForceSet operator* (Inertia Y,Constraint S) */ template inline typename InertiaTpl::Matrix6 operator*(const InertiaTpl & Y, const JointMotionSubspaceIdentityTpl &) { return Y.matrix(); } /* [ABA] Y*S operator*/ template inline typename PINOCCHIO_EIGEN_REF_CONST_TYPE(Matrix6Like) operator*( const Eigen::MatrixBase & Y, const JointMotionSubspaceIdentityTpl &) { return Y.derived(); } template struct SE3GroupAction> { typedef typename SE3Tpl::ActionMatrixType ReturnType; }; template struct MotionAlgebraAction, MotionDerived> { typedef typename SE3Tpl::ActionMatrixType ReturnType; }; template struct JointFreeFlyerTpl; template struct traits> { static constexpr int NQ = 7; static constexpr int NV = 6; static constexpr int NVExtended = 6; typedef _Scalar Scalar; static constexpr int Options = _Options; typedef JointDataFreeFlyerTpl JointDataDerived; typedef JointModelFreeFlyerTpl JointModelDerived; typedef JointMotionSubspaceIdentityTpl Constraint_t; typedef SE3Tpl Transformation_t; typedef MotionTpl Motion_t; typedef MotionZeroTpl Bias_t; // [ABA] typedef Eigen::Matrix U_t; typedef Eigen::Matrix D_t; typedef Eigen::Matrix UD_t; typedef Eigen::Matrix ConfigVector_t; typedef Eigen::Matrix TangentVector_t; typedef std::false_type is_mimicable_t; PINOCCHIO_JOINT_DATA_BASE_ACCESSOR_DEFAULT_RETURN_TYPE }; template struct traits> { typedef JointFreeFlyerTpl<_Scalar, _Options> JointDerived; typedef _Scalar Scalar; }; template struct traits> { typedef JointFreeFlyerTpl<_Scalar, _Options> JointDerived; typedef _Scalar Scalar; }; template struct JointDataFreeFlyerTpl : public JointDataBase> { typedef JointFreeFlyerTpl<_Scalar, _Options> JointDerived; PINOCCHIO_JOINT_DATA_TYPEDEF_TEMPLATE(JointDerived); PINOCCHIO_JOINT_DATA_BASE_DEFAULT_ACCESSOR ConfigVector_t joint_q; TangentVector_t joint_v; Constraint_t S; Transformation_t M; Motion_t v; Bias_t c; // [ABA] specific data U_t U; D_t Dinv; UD_t UDinv; D_t StU; JointDataFreeFlyerTpl() : joint_q(ConfigVector_t::Zero()) , joint_v(TangentVector_t::Zero()) , M(Transformation_t::Identity()) , v(Motion_t::Zero()) , U(U_t::Zero()) , Dinv(D_t::Zero()) , UDinv(UD_t::Identity()) , StU(D_t::Zero()) { joint_q[6] = Scalar(1); } static std::string classname() { return std::string("JointDataFreeFlyer"); } std::string shortname() const { return classname(); } }; // struct JointDataFreeFlyerTpl PINOCCHIO_JOINT_CAST_TYPE_SPECIALIZATION(JointModelFreeFlyerTpl); /// @brief Free-flyer joint in \f$SE(3)\f$. /// /// A free-flyer joint adds seven coordinates to the configuration space. /// Given a configuration vector `q`: /// /// - `q[idx_q:idx_q + 3]` are the translation coordinates, in meters, /// representing the position of the child frame in the parent frame. /// - `q[idx_q + 3:idx_q + 7]` is a unit quaternion representing the rotation /// from the child frame to the parent frame, with quaternion coordinates /// ordered as (x, y, z, w). /// /// Likewise, a free-flyer joint adds six coordinates to the tangent space. /// Let's consider a tangent vector `v`, say, a velocity vector. Following /// Featherstone's convention, all our tangent vectors are body rather than /// spatial vectors: /// /// - `v[idx_v:idx_v + 3]` is the linear velocity, in meters / second, /// corresponding to the linear velocity of the child frame with respect /// to the parent frame, expressed in the child frame (body linear velocity /// of the child frame). /// - `v[idx_v + 3:idx_v + 6]` is the angular velocity, in radians / second, /// corresponding to the angular velocity from the child frame to the /// parent frame, expressed in the child frame (body angular velocity of the /// child frame). template struct JointModelFreeFlyerTpl : public JointModelBase> { typedef JointFreeFlyerTpl<_Scalar, _Options> JointDerived; PINOCCHIO_JOINT_TYPEDEF_TEMPLATE(JointDerived); typedef JointModelBase Base; using Base::id; using Base::idx_q; using Base::idx_v; using Base::idx_vExtended; using Base::setIndexes; JointDataDerived createData() const { return JointDataDerived(); } const std::vector hasConfigurationLimit() const { return {true, true, true, false, false, false, false}; } const std::vector hasConfigurationLimitInTangent() const { return {true, true, true, false, false, false}; } template inline void forwardKinematics( Transformation_t & M, const Eigen::MatrixBase & q_joint) const { EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(ConfigVector_t, ConfigVectorLike); typedef typename Eigen::Quaternion< typename ConfigVectorLike::Scalar, PINOCCHIO_EIGEN_PLAIN_TYPE(ConfigVectorLike)::Options> Quaternion; typedef Eigen::Map ConstQuaternionMap; ConstQuaternionMap quat(q_joint.template tail<4>().data()); // assert(math::fabs(quat.coeffs().squaredNorm()-1.) <= sqrt(Eigen::NumTraits::epsilon())); TODO: check validity of the rhs precision assert(math::fabs(static_cast(quat.coeffs().squaredNorm() - 1)) <= 1e-4); M.rotation(quat.matrix()); M.translation(q_joint.template head<3>()); } template PINOCCHIO_DONT_INLINE void calc( JointDataDerived & data, const typename Eigen::MatrixBase & trans, const typename Eigen::QuaternionBase & quat) const { data.M.translation(trans); data.M.rotation(quat.matrix()); } template PINOCCHIO_DONT_INLINE void calc(JointDataDerived & data, const typename Eigen::MatrixBase & qs) const { typedef typename Eigen::Quaternion Quaternion; typedef Eigen::Map ConstQuaternionMap; data.joint_q = qs.template segment(idx_q()); ConstQuaternionMap quat(data.joint_q.template tail<4>().data()); calc(data, data.joint_q.template head<3>(), quat); } template PINOCCHIO_DONT_INLINE void calc(JointDataDerived & data, const Blank, const typename Eigen::MatrixBase & vs) const { data.joint_v = vs.template segment(idx_v()); data.v = data.joint_v; } template PINOCCHIO_DONT_INLINE void calc( JointDataDerived & data, const typename Eigen::MatrixBase & qs, const typename Eigen::MatrixBase & vs) const { calc(data, qs.derived()); data.joint_v = vs.template segment(idx_v()); data.v = data.joint_v; } template void calc_aba( JointDataDerived & data, const Eigen::MatrixBase & armature, const Eigen::MatrixBase & I, const bool update_I) const { data.U = I; data.StU = I; data.StU.diagonal() += armature; internal::matrix_inversion(data.StU, data.Dinv); data.UDinv.noalias() = I * data.Dinv; if (update_I) I.const_cast_derived().noalias() -= data.UDinv * data.U.transpose(); } static std::string classname() { return std::string("JointModelFreeFlyer"); } std::string shortname() const { return classname(); } /// \returns An expression of *this with the Scalar type casted to NewScalar. template JointModelFreeFlyerTpl cast() const { typedef JointModelFreeFlyerTpl ReturnType; ReturnType res; res.setIndexes(id(), idx_q(), idx_v(), idx_vExtended()); return res; } }; // struct JointModelFreeFlyerTpl } // namespace pinocchio namespace boost { template struct has_nothrow_constructor<::pinocchio::JointModelFreeFlyerTpl> : public integral_constant { }; template struct has_nothrow_copy<::pinocchio::JointModelFreeFlyerTpl> : public integral_constant { }; template struct has_nothrow_constructor<::pinocchio::JointDataFreeFlyerTpl> : public integral_constant { }; template struct has_nothrow_copy<::pinocchio::JointDataFreeFlyerTpl> : public integral_constant { }; } // namespace boost