5 #include "pinocchio/multibody/model.hpp" 6 #include "pinocchio/multibody/data.hpp" 7 #include "pinocchio/algorithm/model.hpp" 8 #include "pinocchio/algorithm/jacobian.hpp" 9 #include "pinocchio/algorithm/frames.hpp" 10 #include "pinocchio/algorithm/rnea.hpp" 11 #include "pinocchio/algorithm/crba.hpp" 12 #include "pinocchio/spatial/act-on-set.hpp" 13 #include "pinocchio/parsers/sample-models.hpp" 14 #include "pinocchio/utils/timer.hpp" 15 #include "pinocchio/algorithm/joint-configuration.hpp" 19 #include <boost/test/unit_test.hpp> 20 #include <boost/utility/binary.hpp> 22 template<
typename Derived>
23 inline bool isFinite(
const Eigen::MatrixBase<Derived> & x)
25 return ((x - x).array() == (x - x).array()).all();
38 for(Model::FrameVector::const_iterator it = model.
frames.begin();
39 it != model.
frames.end(); ++it)
41 const Frame & frame = *it;
42 BOOST_CHECK(frame == frame);
43 Frame frame_copy(frame);
44 BOOST_CHECK(frame_copy == frame);
47 std::ostringstream os;
49 BOOST_CHECK(!os.str().empty());
57 BOOST_CHECK(frame.
cast<
double>() == frame);
58 BOOST_CHECK(frame.
cast<
double>().cast<
long double>() == frame.
cast<
long double>());
63 using namespace Eigen;
69 const std::string & frame_name = std::string( model.
names[parent_idx]+
"_frame");
78 BOOST_CHECK(data.oMf[model.
getFrameId(frame_name)].isApprox(data.oMi[parent_idx]*framePlacement));
84 using namespace Eigen;
90 const std::string & frame_name = std::string( model.
names[parent_idx]+
"_frame");
104 BOOST_CHECK(data.oMf[frame_idx].isApprox(data_ref.oMf[frame_idx]));
109 using namespace Eigen;
115 const std::string & frame_name = std::string( model.
names[parent_idx]+
"_frame");
129 BOOST_CHECK(data.oMf[frame_idx].isApprox(data_ref.oMf[frame_idx]));
134 using namespace Eigen;
140 const std::string & frame_name = std::string( model.
names[parent_idx]+
"_frame");
152 BOOST_CHECK(vf.
isApprox(framePlacement.
actInv(data.v[parent_idx])));
161 BOOST_CHECK(data_ref.oMf[frame_idx].act(v_ref).isApprox(
getFrameVelocity(model,data,frame_idx,
WORLD)));
167 using namespace Eigen;
173 const std::string & frame_name = std::string( model.
names[parent_idx]+
"_frame");
186 BOOST_CHECK(af.
isApprox(framePlacement.
actInv(data.a[parent_idx])));
201 using namespace Eigen;
207 const std::string & frame_name = std::string( model.
names[parent_idx]+
"_frame");
224 acc_classical_local.
linear() = linear;
228 BOOST_CHECK(af.
isApprox(acc_classical_local));
234 SE3 T_ref = data_ref.oMf[frame_idx];
238 Motion acc_classical_local_ref = a_ref;
240 acc_classical_local_ref.
linear() = linear;
246 Motion acc_classical_world_ref = T_ref.
act(a_ref);
247 linear = acc_classical_world_ref.
linear() + vel_world_ref.angular().cross(vel_world_ref.linear());
248 acc_classical_world_ref.
linear() = linear;
254 linear = acc_classical_aligned_ref.
linear() + vel_aligned_ref.angular().cross(vel_aligned_ref.linear());
255 acc_classical_aligned_ref.
linear() = linear;
262 using namespace Eigen;
284 v_local.
linear() = Vector3d(0.0, 1.0, 0.0);
285 v_local.
angular() = Vector3d(0.0, 0.0, 1.0);
288 v_world.
linear() = Vector3d::Zero();
289 v_world.
angular() = Vector3d(0.0, 0.0, 1.0);
292 v_align.
linear() = Vector3d(-1.0, 0.0, 0.0);
293 v_align.
angular() = Vector3d(0.0, 0.0, 1.0);
297 ac_local.
linear() = Vector3d(-1.0, 0.0, 0.0);
298 ac_local.
angular() = Vector3d::Zero();
303 ac_align.
linear() = Vector3d(0.0, -1.0, 0.0);
304 ac_align.
angular() = Vector3d::Zero();
330 using namespace Eigen;
336 const std::string & frame_name = std::string( model.
names[parent_idx]+
"_frame");
368 BOOST_CHECK(Jjj_from_frame.isApprox(Jjj));
375 BOOST_CHECK(Jff.isApprox(Jjj));
379 BOOST_CHECK(Jff2.isApprox(Jjj));
384 using namespace Eigen;
390 const std::string & frame_name = std::string( model.
names[parent_idx]+
"_frame");
416 BOOST_CHECK(Jf.isApprox(Jf_ref));
420 BOOST_CHECK(Jf2.isApprox(Jf_ref));
425 using namespace Eigen;
431 const std::string & frame_name = std::string( model.
names[parent_idx]+
"_frame");
453 Jf_ref =
SE3(data.oMf[idx].rotation(), Eigen::Vector3d::Zero()).toActionMatrix() * Jf_ref;
456 BOOST_CHECK(Jf.isApprox(Jf_ref));
460 BOOST_CHECK(Jf2.isApprox(Jf_ref));
465 using namespace Eigen;
471 const std::string & frame_name = std::string( model.
names[parent_idx]+
"_frame");
502 const Motion & v_ref = data_ref.oMf[idx].act(v_ref_local);
504 const SE3 & wMf =
SE3(data_ref.oMf[idx].rotation(),SE3::Vector3::Zero());
505 const Motion & v_ref_local_world_aligned = wMf.
act(v_ref_local);
510 const Motion & a_ref = data_ref.oMf[idx].act(a_ref_local);
511 const Motion & a_ref_local_world_aligned = wMf.
act(a_ref_local);
512 BOOST_CHECK(a_idx.isApprox(a_ref));
514 J.fill(0.); dJ.fill(0.);
519 v_idx = (Motion::Vector6)(J*v);
520 BOOST_CHECK(v_idx.
isApprox(v_ref_local));
522 a_idx = (Motion::Vector6)(J*a + dJ*v);
523 BOOST_CHECK(a_idx.isApprox(a_ref_local));
529 v_idx = (Motion::Vector6)(J*v);
530 BOOST_CHECK(v_idx.
isApprox(v_ref_local_world_aligned));
532 a_idx = (Motion::Vector6)(J*a + dJ*v);
533 BOOST_CHECK(a_idx.isApprox(a_ref_local_world_aligned));
537 Data data_ref(model), data_ref_plus(model);
539 const double alpha = 1e-8;
544 Data::Matrix6x J_ref_world(6,model.
nv), J_ref_local(6,model.
nv), J_ref_local_world_aligned(6,model.
nv);
545 J_ref_world.fill(0.); J_ref_local.fill(0.); J_ref_local_world_aligned.fill(0.);
548 const SE3 & oMf_q = data_ref.oMf[idx];
554 Data::Matrix6x J_ref_plus_world(6,model.
nv), J_ref_plus_local(6,model.
nv), J_ref_plus_local_world_aligned(6,model.
nv);
555 J_ref_plus_world.fill(0.); J_ref_plus_local.fill(0.); J_ref_plus_local_world_aligned.fill(0.);
558 const SE3 & oMf_q_plus = data_ref_plus.oMf[idx];
564 J_ref_plus_local = (oMf_q.
inverse()*oMf_q_plus).toActionMatrix()*(J_ref_plus_local);
569 J_ref_plus_local_world_aligned = oMf_translation.
toActionMatrix()*(J_ref_plus_local_world_aligned);
571 Data::Matrix6x dJ_ref_world(6,model.
nv), dJ_ref_local(6,model.
nv), dJ_ref_local_world_aligned(6,model.
nv);
572 dJ_ref_world.fill(0.); dJ_ref_local.fill(0.); dJ_ref_local_world_aligned.fill(0.);
573 dJ_ref_world = (J_ref_plus_world - J_ref_world)/alpha;
574 dJ_ref_local = (J_ref_plus_local - J_ref_local)/alpha;
575 dJ_ref_local_world_aligned = (J_ref_plus_local_world_aligned - J_ref_local_world_aligned)/alpha;
582 dJ_world.fill(0.); dJ_local.fill(0.); dJ_local_world_aligned.fill(0.);
587 BOOST_CHECK(dJ_world.isApprox(dJ_ref_world,sqrt(alpha)));
588 BOOST_CHECK(dJ_local.isApprox(dJ_ref_local,sqrt(alpha)));
589 BOOST_CHECK(dJ_local_world_aligned.isApprox(dJ_ref_local_world_aligned,sqrt(alpha)));
595 using namespace Eigen;
601 Data data_free(model_free);
608 const std::string
joint_name =
"chest2_joint";
613 Data data_fix(model_fix);
617 const int joint_idx_q(model_free.
joints[joint_id].idx_q());
618 const int joint_idx_v(model_free.
joints[joint_id].idx_v());
622 VectorXd v_free(VectorXd::Random(model_free.
nv));
623 VectorXd a_free(VectorXd::Random(model_free.
nv));
626 q_free[joint_idx_q] = 0;
627 v_free[joint_idx_v] = 0;
628 a_free[joint_idx_v] = 0;
632 q_fix << q_free.head(joint_idx_q), q_free.tail(model_free.
nq - joint_idx_q - 1);
634 v_fix << v_free.head(joint_idx_v), v_free.tail(model_free.
nv - joint_idx_v - 1);
636 a_fix << a_free.head(joint_idx_v), a_free.tail(model_free.
nv - joint_idx_v - 1);
640 crba(model_free, data_free, q_free);
643 Inertia inertia_free(model_free.inertias[joint_id]);
644 BOOST_CHECK(inertia_fix.
isApprox(inertia_free));
647 inertia_free = data_free.Ycrb[
joint_id];
648 BOOST_CHECK(inertia_fix.isApprox(inertia_free));
650 rnea(model_fix, data_fix, q_fix, v_fix, a_fix);
651 rnea(model_free, data_free, q_free, v_free, a_free);
654 Force force_free(data_free.f[joint_id]);
655 BOOST_CHECK(force_fix.
isApprox(force_free));
657 BOOST_AUTO_TEST_SUITE_END ()
Matrix6x dJ
Derivative of the Jacobian with respect to the time.
JointCollectionTpl const Eigen::MatrixBase< ConfigVectorType > const Eigen::MatrixBase< TangentVectorType > & v
The WORLD frame convention corresponds to the frame concident with the Universe/Inertial frame but mo...
bool isApprox(const ForceDense< M2 > &f, const Scalar &prec=Eigen::NumTraits< Scalar >::dummy_precision()) const
JointModelVector joints
Model of joint i, encapsulated in a JointModelAccessor.
bool isApprox_impl(const SE3Tpl< Scalar, O2 > &m2, const Scalar &prec=Eigen::NumTraits< Scalar >::dummy_precision()) const
const DataTpl< Scalar, Options, JointCollectionTpl >::MatrixXs & crba(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, DataTpl< Scalar, Options, JointCollectionTpl > &data, const Eigen::MatrixBase< ConfigVectorType > &q)
Computes the upper triangular part of the joint space inertia matrix M by using the Composite Rigid B...
bool existFrame(const std::string &name, const FrameType &type=(FrameType)(JOINT|FIXED_JOINT|BODY|OP_FRAME|SENSOR)) const
Checks if a frame given by its name exists.
SE3GroupAction< D >::ReturnType actInv(const D &d) const
by = aXb.actInv(ay)
void rnea(const int num_threads, ModelPoolTpl< Scalar, Options, JointCollectionTpl > &pool, const Eigen::MatrixBase< ConfigVectorPool > &q, const Eigen::MatrixBase< TangentVectorPool1 > &v, const Eigen::MatrixBase< TangentVectorPool2 > &a, const Eigen::MatrixBase< TangentVectorPool3 > &tau)
The Recursive Newton-Euler algorithm. It computes the inverse dynamics, aka the joint torques accordi...
void computeFrameJacobian(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, DataTpl< Scalar, Options, JointCollectionTpl > &data, const Eigen::MatrixBase< ConfigVectorType > &q, const FrameIndex frameId, const ReferenceFrame reference_frame, const Eigen::MatrixBase< Matrix6xLike > &J)
Computes the Jacobian of a specific Frame expressed in the desired reference_frame given as argument...
void integrate(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, const Eigen::MatrixBase< ConfigVectorType > &q, const Eigen::MatrixBase< TangentVectorType > &v, const Eigen::MatrixBase< ReturnType > &qout)
Integrate a configuration vector for the specified model for a tangent vector during one unit time...
A Plucker coordinate frame attached to a parent joint inside a kinematic tree.
bool isZero(const Eigen::MatrixBase< MatrixLike > &m, const typename MatrixLike::RealScalar &prec=Eigen::NumTraits< typename MatrixLike::Scalar >::dummy_precision())
int njoints
Number of joints.
std::vector< std::string > names
Name of joint i
MotionTpl< Scalar, Options > getFrameVelocity(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, const DataTpl< Scalar, Options, JointCollectionTpl > &data, const FrameIndex frame_id, const ReferenceFrame rf=LOCAL)
Returns the spatial velocity of the Frame expressed in the desired reference frame. You must first call pinocchio::forwardKinematics to update placement and velocity values in data structure.
NewScalar cast(const Scalar &value)
ConfigVectorType lowerPositionLimit
Lower joint configuration limit.
InertiaTpl< Scalar, Options > computeSupportedInertiaByFrame(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, const DataTpl< Scalar, Options, JointCollectionTpl > &data, const FrameIndex frame_id, bool with_subtree)
Compute the inertia supported by a specific frame (given by frame_id) expressed in the LOCAL frame...
FrameVector frames
Vector of operational frames registered on the model.
void randomConfiguration(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, const Eigen::MatrixBase< ConfigVectorIn1 > &lowerLimits, const Eigen::MatrixBase< ConfigVectorIn2 > &upperLimits, const Eigen::MatrixBase< ReturnType > &qout)
Generate a configuration vector uniformly sampled among provided limits.
bool existJointName(const std::string &name) const
Check if a joint given by its name exists.
void getJointJacobian(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, const DataTpl< Scalar, Options, JointCollectionTpl > &data, const typename ModelTpl< Scalar, Options, JointCollectionTpl >::JointIndex jointId, const ReferenceFrame rf, const Eigen::MatrixBase< Matrix6Like > &J)
Computes the Jacobian of a specific joint frame expressed either in the world (rf = WORLD) frame or i...
ConstLinearType linear() const
JointCollectionTpl const Eigen::MatrixBase< ConfigVectorType > & q
static void act(const Eigen::MatrixBase< Mat > &iV, const ForceDense< ForceDerived > &f, Eigen::MatrixBase< MatRet > const &jF)
Action of a motion set on a force object. The input motion set is represented by a 6xN matrix whose e...
void humanoid(ModelTpl< Scalar, Options, JointCollectionTpl > &model, bool usingFF=true)
Create a 28-DOF kinematic chain of a floating humanoid robot.
ConstAngularType angular() const
operational frame: user-defined frames that are defined at runtime
ActionMatrixType toActionMatrix() const
The action matrix of .
MotionTpl< Scalar, Options > getFrameAcceleration(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, const DataTpl< Scalar, Options, JointCollectionTpl > &data, const FrameIndex frame_id, const ReferenceFrame rf=LOCAL)
Returns the spatial acceleration of the Frame expressed in the desired reference frame. You must first call pinocchio::forwardKinematics to update placement, velocity and acceleration values in data structure.
void forwardKinematics(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, DataTpl< Scalar, Options, JointCollectionTpl > &data, const Eigen::MatrixBase< ConfigVectorType > &q)
Update the joint placements according to the current joint configuration.
pinocchio::FrameIndex FrameIndex
JointIndex addJoint(const JointIndex parent, const JointModel &joint_model, const SE3 &joint_placement, const std::string &joint_name)
Add a joint to the kinematic tree with infinite bounds.
bool isFinite(const Eigen::MatrixBase< Derived > &x)
SE3Tpl inverse() const
aXb = bXa.inverse()
const DataTpl< Scalar, Options, JointCollectionTpl >::SE3 & updateFramePlacement(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, DataTpl< Scalar, Options, JointCollectionTpl > &data, const FrameIndex frame_id)
Updates the placement of the given frame.
The LOCAL frame convention corresponds to the frame directly attached to the moving part (Joint...
JointModelRevoluteTpl< double, 0, 2 > JointModelRZ
MotionTpl< double, 0 > Motion
ForceTpl< Scalar, Options > computeSupportedForceByFrame(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, const DataTpl< Scalar, Options, JointCollectionTpl > &data, const FrameIndex frame_id)
Computes the force supported by a specific frame (given by frame_id) expressed in the LOCAL frame...
FrameIndex getFrameId(const std::string &name, const FrameType &type=(FrameType)(JOINT|FIXED_JOINT|BODY|OP_FRAME|SENSOR)) const
Returns the index of a frame given by its name.
const DataTpl< Scalar, Options, JointCollectionTpl >::Matrix6x & computeJointJacobiansTimeVariation(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, DataTpl< Scalar, Options, JointCollectionTpl > &data, const Eigen::MatrixBase< ConfigVectorType > &q, const Eigen::MatrixBase< TangentVectorType > &v)
Computes the full model Jacobian variations with respect to time. It corresponds to dJ/dt which depen...
BOOST_AUTO_TEST_CASE(frame_basic)
#define BOOST_TEST_MODULE
FrameTpl< NewScalar, Options > cast() const
FrameIndex addFrame(const Frame &frame, const bool append_inertia=true)
Adds a frame to the kinematic tree. The inertia stored within the frame will be happened to the inert...
ConstAngularRef rotation() const
SE3 placement
Placement of the frame wrt the parent joint.
Main pinocchio namespace.
void neutral(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, const Eigen::MatrixBase< ReturnType > &qout)
Return the neutral configuration element related to the model configuration space.
JointIndex getJointId(const std::string &name) const
Return the index of a joint given by its name.
const DataTpl< Scalar, Options, JointCollectionTpl >::Matrix6x & computeJointJacobians(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, DataTpl< Scalar, Options, JointCollectionTpl > &data, const Eigen::MatrixBase< ConfigVectorType > &q)
Computes the full model Jacobian, i.e. the stack of all motion subspace expressed in the world frame...
The LOCAL_WORLD_ALIGNED frame convention corresponds to the frame centered on the moving part (Joint...
int nv
Dimension of the velocity vector space.
void updateFramePlacements(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, DataTpl< Scalar, Options, JointCollectionTpl > &data)
Updates the position of each frame contained in the model.
bool isApprox(const MotionDense< M2 > &m2, const Scalar &prec=Eigen::NumTraits< Scalar >::dummy_precision()) const
SE3GroupAction< D >::ReturnType act(const D &d) const
ay = aXb.act(by)
void getFrameJacobianTimeVariation(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, DataTpl< Scalar, Options, JointCollectionTpl > &data, const FrameIndex frame_id, const ReferenceFrame rf, const Eigen::MatrixBase< Matrix6xLike > &dJ)
Computes the Jacobian time variation of a specific frame (given by frame_id) expressed either in the ...
void normalize(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, const Eigen::MatrixBase< ConfigVectorType > &qout)
Normalize a configuration vector.
ConfigVectorType upperPositionLimit
Upper joint configuration limit.
bool isApprox(const Derived &other, const Scalar &prec=Eigen::NumTraits< Scalar >::dummy_precision()) const
void getFrameJacobian(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, DataTpl< Scalar, Options, JointCollectionTpl > &data, const FrameIndex frame_id, const ReferenceFrame rf, const Eigen::MatrixBase< Matrix6xLike > &J)
Returns the jacobian of the frame expressed either expressed in the LOCAL frame coordinate system or ...
void humanoidRandom(ModelTpl< Scalar, Options, JointCollectionTpl > &model, bool usingFF=true)
Create a humanoid kinematic tree with 6-DOF limbs and random joint placements.
Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > VectorXd
Eigen::Matrix< Scalar, 6, Eigen::Dynamic, Options > Matrix6x
The 6d jacobian type (temporary)
JointCollectionTpl & model
int nq
Dimension of the configuration vector representation.
void framesForwardKinematics(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, DataTpl< Scalar, Options, JointCollectionTpl > &data, const Eigen::MatrixBase< ConfigVectorType > &q)
First calls the forwardKinematics on the model, then computes the placement of each frame...
void buildReducedModel(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, std::vector< JointIndex > list_of_joints_to_lock, const Eigen::MatrixBase< ConfigVectorType > &reference_configuration, ModelTpl< Scalar, Options, JointCollectionTpl > &reduced_model)
Build a reduced model from a given input model and a list of joint to lock.
MotionTpl< Scalar, Options > getFrameClassicalAcceleration(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, const DataTpl< Scalar, Options, JointCollectionTpl > &data, const FrameIndex frame_id, const ReferenceFrame rf=LOCAL)
Returns the "classical" acceleration of the Frame expressed in the desired reference frame...
ConstLinearRef translation() const