unittest/aba.cpp
Go to the documentation of this file.
1 //
2 // Copyright (c) 2016-2020 CNRS INRIA
3 //
4 
5 #include "pinocchio/spatial/fwd.hpp"
6 #include "pinocchio/spatial/se3.hpp"
7 #include "pinocchio/multibody/visitor.hpp"
8 #include "pinocchio/multibody/model.hpp"
9 #include "pinocchio/multibody/data.hpp"
10 #include "pinocchio/algorithm/aba.hpp"
11 #include "pinocchio/algorithm/rnea.hpp"
12 #include "pinocchio/algorithm/jacobian.hpp"
13 #include "pinocchio/algorithm/joint-configuration.hpp"
14 #include "pinocchio/algorithm/crba.hpp"
15 #include "pinocchio/parsers/sample-models.hpp"
16 
17 #include "pinocchio/algorithm/compute-all-terms.hpp"
18 #include "pinocchio/utils/timer.hpp"
19 
20 #include <iostream>
21 
22 #include <boost/test/unit_test.hpp>
23 #include <boost/utility/binary.hpp>
24 
25 BOOST_AUTO_TEST_SUITE ( BOOST_TEST_MODULE )
26 
27 template<typename JointModel>
28 void test_joint_methods(const pinocchio::JointModelBase<JointModel> & jmodel)
29 {
31  typedef typename JointModel::ConfigVector_t ConfigVector_t;
32  typedef typename pinocchio::LieGroup<JointModel>::type LieGroupType;
33 
34  JointData jdata = jmodel.createData();
35 
36  ConfigVector_t ql(ConfigVector_t::Constant(jmodel.nq(),-M_PI));
37  ConfigVector_t qu(ConfigVector_t::Constant(jmodel.nq(),M_PI));
38 
39  ConfigVector_t q = LieGroupType().randomConfiguration(ql,qu);
40  pinocchio::Inertia::Matrix6 I(pinocchio::Inertia::Random().matrix());
41  pinocchio::Inertia::Matrix6 I_check = I;
42 
43  jmodel.calc(jdata,q);
44  jmodel.calc_aba(jdata,I,true);
45 
46  Eigen::MatrixXd S = jdata.S.matrix();
47  Eigen::MatrixXd U_check = I_check*S;
48  Eigen::MatrixXd D_check = S.transpose()*U_check;
49  Eigen::MatrixXd Dinv_check = D_check.inverse();
50  Eigen::MatrixXd UDinv_check = U_check*Dinv_check;
51  Eigen::MatrixXd update_check = U_check*Dinv_check*U_check.transpose();
52  I_check -= update_check;
53 
54  BOOST_CHECK(jdata.U.isApprox(U_check));
55  BOOST_CHECK(jdata.Dinv.isApprox(Dinv_check));
56  BOOST_CHECK(jdata.UDinv.isApprox(UDinv_check));
57 
58  // Checking the inertia was correctly updated
59  // We use isApprox as usual, except for the freeflyer,
60  // where the correct result is exacly zero and isApprox would fail.
61  // Only for this single case, we use the infinity norm of the difference
62  if(jmodel.shortname() == "JointModelFreeFlyer")
63  BOOST_CHECK((I-I_check).lpNorm<Eigen::Infinity>() < Eigen::NumTraits<double>::dummy_precision());
64  else
65  BOOST_CHECK(I.isApprox(I_check));
66 }
67 
69 
70  template <typename JointModel>
72  {
73  JointModel jmodel;
74  jmodel.setIndexes(0,0,0);
75 
76  test_joint_methods(jmodel);
77  }
78 
80  {
81  pinocchio::JointModelComposite jmodel_composite;
82  jmodel_composite.addJoint(pinocchio::JointModelRX());
83  jmodel_composite.addJoint(pinocchio::JointModelRY());
84  jmodel_composite.setIndexes(0,0,0);
85 
86  //TODO: correct LieGroup
87  //test_joint_methods(jmodel_composite);
88 
89  }
90 
92  {
93  pinocchio::JointModelRevoluteUnaligned jmodel(1.5, 1., 0.);
94  jmodel.setIndexes(0,0,0);
95 
96  test_joint_methods(jmodel);
97  }
98 
100  {
101  pinocchio::JointModelPrismaticUnaligned jmodel(1.5, 1., 0.);
102  jmodel.setIndexes(0,0,0);
103 
104  test_joint_methods(jmodel);
105  }
106 
107 };
108 
109 BOOST_AUTO_TEST_CASE( test_joint_basic )
110 {
111  using namespace pinocchio;
112 
121  > Variant;
122 
123  boost::mpl::for_each<Variant::types>(TestJointMethods());
124 }
125 
126 BOOST_AUTO_TEST_CASE ( test_aba_simple )
127 {
128  using namespace Eigen;
129  using namespace pinocchio;
130 
132 
133  pinocchio::Data data(model);
134  pinocchio::Data data_ref(model);
135 
136  VectorXd q = VectorXd::Ones(model.nq);
137  q.segment<4>(3).normalize();
138  VectorXd v = VectorXd::Ones(model.nv);
139  VectorXd tau = VectorXd::Zero(model.nv);
140  VectorXd a = VectorXd::Ones(model.nv);
141 
142  tau = rnea(model, data_ref, q, v, a);
143  aba(model, data, q, v, tau);
144 
145  for(size_t k = 1; k < (size_t)model.njoints; ++k)
146  {
147  BOOST_CHECK(data_ref.liMi[k].isApprox(data.liMi[k]));
148  BOOST_CHECK(data_ref.v[k].isApprox(data.v[k]));
149  }
150 
151  BOOST_CHECK(data.ddq.isApprox(a, 1e-12));
152 
153 }
154 
155 BOOST_AUTO_TEST_CASE ( test_aba_with_fext )
156 {
157  using namespace Eigen;
158  using namespace pinocchio;
159 
161 
162  pinocchio::Data data(model);
163 
164  VectorXd q = VectorXd::Random(model.nq);
165  q.segment<4>(3).normalize();
166  VectorXd v = VectorXd::Random(model.nv);
167  VectorXd a = VectorXd::Random(model.nv);
168 
169  PINOCCHIO_ALIGNED_STD_VECTOR(Force) fext(model.joints.size(), Force::Random());
170 
171  crba(model, data, q);
172  computeJointJacobians(model, data, q);
173  nonLinearEffects(model, data, q, v);
174  data.M.triangularView<Eigen::StrictlyLower>()
175  = data.M.transpose().triangularView<Eigen::StrictlyLower>();
176 
177 
178  VectorXd tau = data.M * a + data.nle;
179  Data::Matrix6x J = Data::Matrix6x::Zero(6, model.nv);
180  for(Model::Index i=1;i<(Model::Index)model.njoints;++i) {
181  getJointJacobian(model, data, i, LOCAL, J);
182  tau -= J.transpose()*fext[i].toVector();
183  J.setZero();
184  }
185  aba(model, data, q, v, tau, fext);
186 
187  BOOST_CHECK(data.ddq.isApprox(a, 1e-12));
188 }
189 
190 BOOST_AUTO_TEST_CASE ( test_aba_vs_rnea )
191 {
192  using namespace Eigen;
193  using namespace pinocchio;
194 
196 
197  pinocchio::Data data(model);
198  pinocchio::Data data_ref(model);
199 
200  VectorXd q = VectorXd::Ones(model.nq);
201  VectorXd v = VectorXd::Ones(model.nv);
202  VectorXd tau = VectorXd::Zero(model.nv);
203  VectorXd a = VectorXd::Ones(model.nv);
204 
205  crba(model, data_ref, q);
206  nonLinearEffects(model, data_ref, q, v);
207  data_ref.M.triangularView<Eigen::StrictlyLower>()
208  = data_ref.M.transpose().triangularView<Eigen::StrictlyLower>();
209 
210  tau = data_ref.M * a + data_ref.nle;
211  aba(model, data, q, v, tau);
212 
213  VectorXd tau_ref = rnea(model, data_ref, q, v, a);
214  BOOST_CHECK(tau_ref.isApprox(tau, 1e-12));
215 
216 
217  BOOST_CHECK(data.ddq.isApprox(a, 1e-12));
218 
219 }
220 
221 BOOST_AUTO_TEST_CASE ( test_computeMinverse )
222 {
223  using namespace Eigen;
224  using namespace pinocchio;
225 
228  model.gravity.setZero();
229 
230  pinocchio::Data data(model);
231  pinocchio::Data data_ref(model);
232 
233  model.lowerPositionLimit.head<3>().fill(-1.);
234  model.upperPositionLimit.head<3>().fill(1.);
235  VectorXd q = randomConfiguration(model);
236  VectorXd v = VectorXd::Random(model.nv);
237 
238  crba(model, data_ref, q);
239  data_ref.M.triangularView<Eigen::StrictlyLower>()
240  = data_ref.M.transpose().triangularView<Eigen::StrictlyLower>();
241  MatrixXd Minv_ref(data_ref.M.inverse());
242 
243  computeMinverse(model, data, q);
244 
245 
246  BOOST_CHECK(data.Minv.topRows<6>().isApprox(Minv_ref.topRows<6>()));
247 
248  data.Minv.triangularView<Eigen::StrictlyLower>()
249  = data.Minv.transpose().triangularView<Eigen::StrictlyLower>();
250 
251  BOOST_CHECK(data.Minv.isApprox(Minv_ref));
252 
253 // std::cout << "Minv:\n" << data.Minv.block<10,10>(0,0) << std::endl;
254 // std::cout << "Minv_ref:\n" << Minv_ref.block<10,10>(0,0) << std::endl;
255 //
256 // std::cout << "Minv:\n" << data.Minv.bottomRows<10>() << std::endl;
257 // std::cout << "Minv_ref:\n" << Minv_ref.bottomRows<10>() << std::endl;
258 
259 }
260 
261 BOOST_AUTO_TEST_CASE(test_multiple_calls)
262 {
263  using namespace Eigen;
264  using namespace pinocchio;
265 
266  Model model;
268 
269  Data data1(model), data2(model);
270 
271  model.lowerPositionLimit.head<3>().fill(-1.);
272  model.upperPositionLimit.head<3>().fill(1.);
273  VectorXd q = randomConfiguration(model);
274 
275  computeMinverse(model,data1,q);
276  data2 = data1;
277 
278  for(int k = 0; k < 20; ++k)
279  {
280  computeMinverse(model,data1,q);
281  }
282 
283  BOOST_CHECK(data1.Minv.isApprox(data2.Minv));
284 }
285 
286 BOOST_AUTO_TEST_SUITE_END ()
const DataTpl< Scalar, Options, JointCollectionTpl >::TangentVectorType & aba(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, DataTpl< Scalar, Options, JointCollectionTpl > &data, const Eigen::MatrixBase< ConfigVectorType > &q, const Eigen::MatrixBase< TangentVectorType1 > &v, const Eigen::MatrixBase< TangentVectorType2 > &tau)
The Articulated-Body algorithm. It computes the forward dynamics, aka the joint accelerations given t...
JointModelPrismaticTpl< double, 0, 0 > JointModelPX
JointModelVector joints
Model of joint i, encapsulated in a JointModelAccessor.
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...
q
void setIndexes(JointIndex id, int q, int v)
const DataTpl< Scalar, Options, JointCollectionTpl >::RowMatrixXs & computeMinverse(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, DataTpl< Scalar, Options, JointCollectionTpl > &data, const Eigen::MatrixBase< ConfigVectorType > &q)
Computes the inverse of the joint space inertia matrix using Articulated Body formulation.
boost::python::object matrix()
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...
JointModelDerived & addJoint(const JointModelBase< JointModel > &jmodel, const SE3 &placement=SE3::Identity())
Add a joint to the vector of joints.
void test_joint_methods(const pinocchio::JointModelBase< JointModel > &jmodel)
static InertiaTpl Random()
int njoints
Number of joints.
JointModelRevoluteUnboundedTpl< double, 0, 1 > JointModelRUBY
JointModelRevoluteUnalignedTpl< double > JointModelRevoluteUnaligned
JointDataTpl< double > JointData
JointModelPrismaticTpl< double, 0, 1 > JointModelPY
ConfigVectorType lowerPositionLimit
Lower joint configuration limit.
v
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.
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...
data
RowMatrixXs Minv
The inverse of the joint space inertia matrix (a square matrix of dim model.nv).
VectorXs nle
Vector of Non Linear Effects (dim model.nv). It corresponds to concatenation of the Coriolis...
JointModelRevoluteTpl< double, 0, 1 > JointModelRY
JointModelSphericalZYXTpl< double > JointModelSphericalZYX
The LOCAL frame convention corresponds to the frame directly attached to the moving part (Joint...
JointModelRevoluteTpl< double, 0, 2 > JointModelRZ
void operator()(const pinocchio::JointModelBase< pinocchio::JointModelRevoluteUnaligned > &) const
MatrixXs M
The joint space inertia matrix (a square matrix of dim model.nv).
void operator()(const pinocchio::JointModelBase< pinocchio::JointModelPrismaticUnaligned > &) const
#define PINOCCHIO_ALIGNED_STD_VECTOR(Type)
Motion gravity
Spatial gravity of the model.
TangentVectorType ddq
The joint accelerations computed from ABA.
JointModelTranslationTpl< double > JointModelTranslation
void setIndexes(JointIndex id, int nq, int nv)
Main pinocchio namespace.
Definition: timings.cpp:30
JointModelSphericalTpl< double > JointModelSpherical
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...
int nv
Dimension of the velocity vector space.
JointModelPrismaticTpl< double, 0, 2 > JointModelPZ
JointModelTpl< double > JointModel
void operator()(const pinocchio::JointModelBase< pinocchio::JointModelComposite > &) const
std::size_t Index
BOOST_AUTO_TEST_CASE(test_joint_basic)
list a
JointModelFreeFlyerTpl< double > JointModelFreeFlyer
void normalize(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, const Eigen::MatrixBase< ConfigVectorType > &qout)
Normalize a configuration vector.
ConfigVectorType upperPositionLimit
Upper joint configuration limit.
const DataTpl< Scalar, Options, JointCollectionTpl >::TangentVectorType & nonLinearEffects(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, DataTpl< Scalar, Options, JointCollectionTpl > &data, const Eigen::MatrixBase< ConfigVectorType > &q, const Eigen::MatrixBase< TangentVectorType > &v)
Computes the non-linear effects (Corriolis, centrifual and gravitationnal effects), also called the bias terms of the Lagrangian dynamics:
JointModelRevoluteUnboundedTpl< double, 0, 0 > JointModelRUBX
JointModelPrismaticUnalignedTpl< double > JointModelPrismaticUnaligned
void operator()(const pinocchio::JointModelBase< JointModel > &) const
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
Definition: conversions.cpp:14
Eigen::Matrix< Scalar, 6, Eigen::Dynamic, Options > Matrix6x
The 6d jacobian type (temporary)
JointModelRevoluteTpl< double, 0, 0 > JointModelRX
int nq
Dimension of the configuration vector representation.
JointModelPlanarTpl< double > JointModelPlanar
void fill(Eigen::Ref< MatType > mat, const typename MatType::Scalar &value)


pinocchio
Author(s):
autogenerated on Tue Jun 1 2021 02:45:02