From a7763faf7594f96654e57a35c892e93d25917a7e Mon Sep 17 00:00:00 2001 From: jcarpent <jcarpent@laas.fr> Date: Mon, 14 Dec 2015 19:15:56 +0100 Subject: [PATCH] [C++] Add unaligned prismatic joint --- CMakeLists.txt | 1 + src/multibody/joint.hpp | 1 + .../joint/joint-prismatic-unaligned.hpp | 360 ++++++++++++++++++ src/multibody/joint/joint-variant.hpp | 4 +- 4 files changed, 364 insertions(+), 2 deletions(-) create mode 100644 src/multibody/joint/joint-prismatic-unaligned.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 6421351d8..2b5bcd4ca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -102,6 +102,7 @@ SET(${PROJECT_NAME}_MULTIBODY_JOINT_HEADERS multibody/joint/joint-spherical.hpp multibody/joint/joint-spherical-ZYX.hpp multibody/joint/joint-prismatic.hpp + multibody/joint/joint-prismatic-unaligned.hpp multibody/joint/joint-planar.hpp multibody/joint/joint-translation.hpp multibody/joint/joint-free-flyer.hpp diff --git a/src/multibody/joint.hpp b/src/multibody/joint.hpp index 30cb0018b..cf8303790 100644 --- a/src/multibody/joint.hpp +++ b/src/multibody/joint.hpp @@ -23,6 +23,7 @@ #include "pinocchio/multibody/joint/joint-free-flyer.hpp" #include "pinocchio/multibody/joint/joint-planar.hpp" #include "pinocchio/multibody/joint/joint-prismatic.hpp" +#include "pinocchio/multibody/joint/joint-prismatic-unaligned.hpp" #include "pinocchio/multibody/joint/joint-revolute-unaligned.hpp" #include "pinocchio/multibody/joint/joint-revolute.hpp" #include "pinocchio/multibody/joint/joint-spherical-ZYX.hpp" diff --git a/src/multibody/joint/joint-prismatic-unaligned.hpp b/src/multibody/joint/joint-prismatic-unaligned.hpp new file mode 100644 index 000000000..edb20fc61 --- /dev/null +++ b/src/multibody/joint/joint-prismatic-unaligned.hpp @@ -0,0 +1,360 @@ +// +// Copyright (c) 2015 CNRS +// +// This file is part of Pinocchio +// Pinocchio is free software: you can redistribute it +// and/or modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation, either version +// 3 of the License, or (at your option) any later version. +// +// Pinocchio is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied warranty +// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Lesser Public License for more details. You should have +// received a copy of the GNU Lesser General Public License along with +// Pinocchio If not, see +// <http://www.gnu.org/licenses/>. + +#ifndef __se3_joint_prismatic_unaligned_hpp__ +#define __se3_joint_prismatic_unaligned_hpp__ + +#include "pinocchio/multibody/joint/joint-base.hpp" +#include "pinocchio/multibody/joint/joint-dense.hpp" +#include "pinocchio/multibody/constraint.hpp" +#include "pinocchio/spatial/inertia.hpp" + +namespace se3 +{ + + struct JointDataPrismaticUnaligned; + struct JointModelPrismaticUnaligned; + + struct MotionPrismaticUnaligned; + + template <> + struct traits <MotionPrismaticUnaligned> + { + typedef double Scalar_t; + typedef Eigen::Matrix<Scalar_t,3,1,0> Vector3; + typedef Eigen::Matrix<Scalar_t,4,1,0> Vector4; + typedef Eigen::Matrix<Scalar_t,6,1,0> Vector6; + typedef Eigen::Matrix<Scalar_t,3,3,0> Matrix3; + typedef Eigen::Matrix<Scalar_t,4,4,0> Matrix4; + typedef Eigen::Matrix<Scalar_t,6,6,0> Matrix6; + typedef Vector3 Angular_t; + typedef Vector3 Linear_t; + typedef Matrix6 ActionMatrix_t; + typedef Eigen::Quaternion<Scalar_t,0> Quaternion_t; + typedef SE3Tpl<Scalar_t,0> SE3; + typedef ForceTpl<Scalar_t,0> Force; + typedef MotionTpl<Scalar_t,0> Motion; + typedef Symmetric3Tpl<Scalar_t,0> Symmetric3; + enum { + LINEAR = 0, + ANGULAR = 3 + }; + }; // traits MotionPrismaticUnaligned + + struct MotionPrismaticUnaligned : MotionBase <MotionPrismaticUnaligned> + { + SPATIAL_TYPEDEF_NO_TEMPLATE(MotionPrismaticUnaligned); + + MotionPrismaticUnaligned () : axis(Vector3::Constant(NAN)), v(NAN) {} + MotionPrismaticUnaligned (const Vector3 & axis, const Scalar_t v) : axis(axis), v(v) {} + + Vector3 axis; + Scalar_t v; + + operator Motion() const { return Motion(axis*v, Vector3::Zero());} + }; // struct MotionPrismaticUnaligned + + inline const MotionPrismaticUnaligned & operator+ (const MotionPrismaticUnaligned & m, const BiasZero &) + { return m; } + + inline Motion operator+ (const MotionPrismaticUnaligned & m1, const Motion & m2) + { + return Motion(m1.v*m1.axis + m2.linear(), m2.angular()); + } + + struct ConstraintPrismaticUnaligned; + template <> + struct traits <ConstraintPrismaticUnaligned> + { + typedef double Scalar_t; + typedef Eigen::Matrix<Scalar_t,3,1,0> Vector3; + typedef Eigen::Matrix<Scalar_t,4,1,0> Vector4; + typedef Eigen::Matrix<Scalar_t,6,1,0> Vector6; + typedef Eigen::Matrix<Scalar_t,3,3,0> Matrix3; + typedef Eigen::Matrix<Scalar_t,4,4,0> Matrix4; + typedef Eigen::Matrix<Scalar_t,6,6,0> Matrix6; + typedef Matrix3 Angular_t; + typedef Vector3 Linear_t; + typedef Matrix6 ActionMatrix_t; + typedef Eigen::Quaternion<Scalar_t,0> Quaternion_t; + typedef SE3Tpl<Scalar_t,0> SE3; + typedef ForceTpl<Scalar_t,0> Force; + typedef MotionTpl<Scalar_t,0> Motion; + typedef Symmetric3Tpl<Scalar_t,0> Symmetric3; + enum { + LINEAR = 0, + ANGULAR = 3 + }; + typedef Eigen::Matrix<Scalar_t,1,1,0> JointMotion; + typedef Eigen::Matrix<Scalar_t,1,1,0> JointForce; + typedef Eigen::Matrix<Scalar_t,6,1> DenseBase; + }; // traits ConstraintPrismaticUnaligned + + struct ConstraintPrismaticUnaligned : ConstraintBase <ConstraintPrismaticUnaligned> + { + SPATIAL_TYPEDEF_NO_TEMPLATE(ConstraintPrismaticUnaligned); + enum { NV = 1, Options = 0 }; + typedef traits<ConstraintPrismaticUnaligned>::JointMotion JointMotion; + typedef traits<ConstraintPrismaticUnaligned>::JointForce JointForce; + typedef traits<ConstraintPrismaticUnaligned>::DenseBase DenseBase; + + ConstraintPrismaticUnaligned () : axis (Vector3::Constant(NAN)) {} + ConstraintPrismaticUnaligned (const Vector3 & axis) : axis(axis) {} + + Vector3 axis; + + template<typename D> + MotionPrismaticUnaligned operator* (const Eigen::MatrixBase<D> & v) const + { + EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(D,1); + return MotionPrismaticUnaligned(axis,v[0]); + } + + Vector6 se3Action (const SE3 & m) const + { + Vector6 res; + res.head<3> () = m.rotation()*axis; + res.tail<3>().setZero(); + return res; + } + + int nv_impl() const { return NV; } + + struct TransposeConst + { + typedef traits<ConstraintPrismaticUnaligned>::Scalar_t Scalar_t; + typedef traits<ConstraintPrismaticUnaligned>::Force Force; + typedef traits<ConstraintPrismaticUnaligned>::Vector6 Vector6; + + const ConstraintPrismaticUnaligned & ref; + TransposeConst(const ConstraintPrismaticUnaligned & ref) : ref(ref) {} + + const Eigen::Matrix<Scalar_t, 1, 1> + operator* (const Force & f) const + { + return ref.axis.transpose()*f.linear(); + } + + /* [CRBA] MatrixBase operator* (Constraint::Transpose S, ForceSet::Block) */ + template<typename D> + friend + typename Eigen::ProductReturnType< + Eigen::Transpose<const Eigen::Matrix<typename Eigen::MatrixBase<D>::Scalar, 3, 1> >, + Eigen::Block<const Eigen::Block<Eigen::Matrix<typename Eigen::MatrixBase<D>::Scalar,6,-1>,-1,-1>, 3, -1> + >::Type + operator* (const TransposeConst & tc, const Eigen::MatrixBase<D> & F) + { + /* Return ax.T * F[1:3,:] */ + assert(F.rows()==6); + return tc.ref.axis.transpose () * F.template topRows<3> (); + } + + }; + TransposeConst transpose() const { return TransposeConst(*this); } + + + /* CRBA joint operators + * - ForceSet::Block = ForceSet + * - ForceSet operator* (Inertia Y,Constraint S) + * - MatrixBase operator* (Constraint::Transpose S, ForceSet::Block) + * - SE3::act(ForceSet::Block) + */ + operator ConstraintXd () const + { + Vector6 S; + S << axis, Vector3::Zero(); + return ConstraintXd(S); + } + + }; // struct ConstraintPrismaticUnaligned + + + inline Motion operator^ (const Motion & m1, const MotionPrismaticUnaligned & m2) + { + /* m1xm2 = [ v1xw2 + w1xv2; w1xw2 ] = [ v1xw2; w1xw2 ] */ + const Motion::Vector3 & w1 = m1.angular(); + const Motion::Vector3 & v2 = m2.axis * m2.v; + return Motion (w1.cross(v2), Motion::Vector3::Zero()); + } + + /* [CRBA] ForceSet operator* (Inertia Y,Constraint S) */ + inline Eigen::Matrix<double,6,1> + operator* (const Inertia & Y, const ConstraintPrismaticUnaligned & cpu) + { + /* YS = [ m -mcx ; mcx I-mcxcx ] [ v ; 0 ] = [ mv ; mcxv ] */ + const double & m = Y.mass(); + const Inertia::Vector3 & c = Y.lever(); + + Eigen::Matrix<double,6,1> res; + res.head<3>() = m*cpu.axis; + res.tail<3>() = c.cross(res.head<3>()); + return res; + } + + namespace internal + { + template<> + struct ActionReturn<ConstraintPrismaticUnaligned > + { typedef Eigen::Matrix<double,6,1> Type; }; + } + + struct JointPrismaticUnaligned; + template<> + struct traits<JointPrismaticUnaligned> + { + typedef JointDataPrismaticUnaligned JointData; + typedef JointModelPrismaticUnaligned JointModel; + typedef ConstraintPrismaticUnaligned Constraint_t; + typedef SE3 Transformation_t; + typedef MotionPrismaticUnaligned Motion_t; + typedef BiasZero Bias_t; + typedef Eigen::Matrix<double,6,1> F_t; + enum { + NQ = 1, + NV = 1 + }; + }; + + template<> struct traits<JointDataPrismaticUnaligned> { typedef JointPrismaticUnaligned Joint; }; + template<> struct traits<JointModelPrismaticUnaligned> { typedef JointPrismaticUnaligned Joint; }; + + struct JointDataPrismaticUnaligned : public JointDataBase <JointDataPrismaticUnaligned> + { + typedef JointPrismaticUnaligned Joint; + SE3_JOINT_TYPEDEF; + + Transformation_t M; + Constraint_t S; + Motion_t v; + Bias_t c; + + F_t F; + + JointDataPrismaticUnaligned() : + M(1), + S(Eigen::Vector3d::Constant(NAN)), + v(Eigen::Vector3d::Constant(NAN),NAN) + {} + + JointDataPrismaticUnaligned(const Motion_t::Vector3 & axis) : + M(1), + S(axis), + v(axis,NAN) + {} + + JointDataDense<NQ, NV> toDense_impl() const + { + return JointDataDense<NQ, NV>(S, M, v, c, F); + } + }; // struct JointDataPrismaticUnaligned + + struct JointModelPrismaticUnaligned : public JointModelBase <JointModelPrismaticUnaligned> + { + typedef JointPrismaticUnaligned Joint; + SE3_JOINT_TYPEDEF; + + using JointModelBase<JointModelPrismaticUnaligned>::id; + using JointModelBase<JointModelPrismaticUnaligned>::idx_q; + using JointModelBase<JointModelPrismaticUnaligned>::idx_v; + using JointModelBase<JointModelPrismaticUnaligned>::lowerPosLimit; + using JointModelBase<JointModelPrismaticUnaligned>::upperPosLimit; + using JointModelBase<JointModelPrismaticUnaligned>::maxEffortLimit; + using JointModelBase<JointModelPrismaticUnaligned>::maxVelocityLimit; + using JointModelBase<JointModelPrismaticUnaligned>::setIndexes; + typedef Motion::Vector3 Vector3; + typedef double Scalar_t; + + JointModelPrismaticUnaligned() : axis(Vector3::Constant(NAN)) {} + JointModelPrismaticUnaligned(Scalar_t x, Scalar_t y, Scalar_t z) + { + axis << x, y, z ; + axis.normalize(); + assert(axis.isUnitary() && "Translation axis is not unitary"); + } + + JointModelPrismaticUnaligned(const Vector3 & axis) : axis(axis) + { + assert(axis.isUnitary() && "Translation axis is not unitary"); + } + + JointData createData() const { return JointData(axis); } + + void calc(JointData & data, const Eigen::VectorXd & qs) const + { + const double & q = qs[idx_q()]; + + /* It should not be necessary to copy axis in jdata, however a current bug + * in the fusion visitor prevents a proper access to jmodel::axis. A + * by-pass is to access to a copy of it in jdata. */ + data.M.translation() = axis * q; + } + + void calc(JointData & data, + const Eigen::VectorXd & qs, + const Eigen::VectorXd & vs) const + { + const Scalar_t & q = qs[idx_q()]; + const Scalar_t & v = vs[idx_v()]; + + /* It should not be necessary to copy axis in jdata, however a current bug + * in the fusion visitor prevents a proper access to jmodel::axis. A + * by-pass is to access to a copy of it in jdata. */ + data.M.translation() = axis * q; + data.v.v = v; + } + + Vector3 axis; + + JointModelDense<NQ, NV> toDense_impl() const + { + return JointModelDense<NQ, NV>( id(), + idx_q(), + idx_v(), + lowerPosLimit(), + upperPosLimit(), + maxEffortLimit(), + maxVelocityLimit() + ); + } + + static const std::string shortname() + { + return std::string("JointModelPrismaticUnaligned"); + } + + template <class D> + bool operator== (const JointModelBase<D> &) const + { + return false; + } + + bool operator== (const JointModelBase<JointModelPrismaticUnaligned> & jmodel) const + { + return jmodel.id() == id() + && jmodel.idx_q() == idx_q() + && jmodel.idx_v() == idx_v() + && jmodel.lowerPosLimit() == lowerPosLimit() + && jmodel.upperPosLimit() == upperPosLimit() + && jmodel.maxEffortLimit() == maxEffortLimit() + && jmodel.maxVelocityLimit() == maxVelocityLimit(); + } + }; // struct JointModelPrismaticUnaligned + +} //namespace se3 + + +#endif // ifndef __se3_joint_prismatic_unaligned_hpp__ diff --git a/src/multibody/joint/joint-variant.hpp b/src/multibody/joint/joint-variant.hpp index d72f71b2c..86b977ceb 100644 --- a/src/multibody/joint/joint-variant.hpp +++ b/src/multibody/joint/joint-variant.hpp @@ -22,8 +22,8 @@ namespace se3 { - typedef boost::variant< JointModelRX, JointModelRY, JointModelRZ, JointModelRevoluteUnaligned, JointModelSpherical, JointModelSphericalZYX, JointModelPX, JointModelPY, JointModelPZ, JointModelFreeFlyer, JointModelPlanar, JointModelTranslation,JointModelDense<-1,-1> > JointModelVariant; - typedef boost::variant< JointDataRX, JointDataRY, JointDataRZ, JointDataRevoluteUnaligned, JointDataSpherical, JointDataSphericalZYX, JointDataPX, JointDataPY, JointDataPZ, JointDataFreeFlyer, JointDataPlanar, JointDataTranslation,JointDataDense<-1,-1> > JointDataVariant; + typedef boost::variant< JointModelRX, JointModelRY, JointModelRZ, JointModelRevoluteUnaligned, JointModelSpherical, JointModelSphericalZYX, JointModelPX, JointModelPY, JointModelPZ, JointModelPrismaticUnaligned, JointModelFreeFlyer, JointModelPlanar, JointModelTranslation, JointModelDense<-1,-1> > JointModelVariant; + typedef boost::variant< JointDataRX, JointDataRY, JointDataRZ, JointDataRevoluteUnaligned, JointDataSpherical, JointDataSphericalZYX, JointDataPX, JointDataPY, JointDataPZ, JointDataPrismaticUnaligned, JointDataFreeFlyer, JointDataPlanar, JointDataTranslation, JointDataDense<-1,-1> > JointDataVariant; typedef std::vector<JointModelVariant> JointModelVector; typedef std::vector<JointDataVariant> JointDataVector; -- GitLab