joint-composite.cpp
Go to the documentation of this file.
1 //
2 // Copyright (c) 2016 CNRS
3 //
4 
5 #include "pinocchio/multibody/joint/joint-composite.hpp"
6 #include "pinocchio/algorithm/joint-configuration.hpp"
7 #include "pinocchio/algorithm/kinematics.hpp"
8 
9 #include <boost/test/unit_test.hpp>
10 #include <boost/utility/binary.hpp>
11 
12 using namespace pinocchio;
13 using namespace Eigen;
14 
15 template<typename JointModel>
16 void test_joint_methods(const JointModelBase<JointModel> & jmodel, JointModelComposite & jmodel_composite);
17 
18 template<typename JointModel>
20 {
21  JointModelComposite jmodel_composite(jmodel);
22  test_joint_methods(jmodel,jmodel_composite);
23 }
24 
25 template<typename JointModel>
26 void test_joint_methods(const JointModelBase<JointModel> & jmodel, JointModelComposite & jmodel_composite)
27 {
29 
30  JointData jdata = jmodel.createData();
31  JointDataComposite jdata_composite = jmodel_composite.createData();
32 
33  jmodel_composite.setIndexes(jmodel.id(), jmodel.idx_q(), jmodel.idx_v());
34 
35  typedef typename JointModel::ConfigVector_t ConfigVector_t;
36  typedef typename JointModel::TangentVector_t TangentVector_t;
37  typedef typename LieGroup<JointModel>::type LieGroupType;
38 
39  typedef Eigen::Matrix<typename ConfigVector_t::Scalar, Eigen::Dynamic, 1, ConfigVector_t::Options> DynConfigVectorType;
40  typedef DynConfigVectorType DynTangentVectorType;
41 
42  ConfigVector_t ql(ConfigVector_t::Constant(jmodel.nq(),-M_PI));
43  ConfigVector_t qu(ConfigVector_t::Constant(jmodel.nq(),M_PI));
44  DynConfigVectorType q = LieGroupType().randomConfiguration(ql,qu);
45 
46  BOOST_CHECK(jmodel.nv() == jmodel_composite.nv());
47  BOOST_CHECK(jmodel.nq() == jmodel_composite.nq());
48 
49  jmodel.calc(jdata,q);
50  jmodel_composite.calc(jdata_composite,q);
51 
52  BOOST_CHECK(jdata_composite.M.isApprox((SE3)jdata.M));
53  BOOST_CHECK(jdata_composite.S.matrix().isApprox(jdata.S.matrix()));
54 
55  q = LieGroupType().randomConfiguration(ql,qu);
56  DynTangentVectorType v = TangentVector_t::Random(jmodel.nv());
57  jmodel.calc(jdata,q,v);
58  jmodel_composite.calc(jdata_composite,q,v);
59 
60  BOOST_CHECK(jdata_composite.M.isApprox((SE3)jdata.M));
61  BOOST_CHECK(jdata_composite.S.matrix().isApprox(jdata.S.matrix()));
62  BOOST_CHECK(jdata_composite.v.isApprox((Motion)jdata.v));
63  BOOST_CHECK(jdata_composite.c.isApprox((Motion)jdata.c));
64 
65  // TODO: Not yet checked
66 // {
67 // VectorXd q1(jmodel.random());
68 // jmodel.normalize(q1);
69 // VectorXd q2(jmodel.random());
70 // jmodel.normalize(q2);
71 // VectorXd v(VectorXd::Random(jmodel.nv()));
72 //
73 // BOOST_CHECK(jmodel_composite.integrate(q1,v).isApprox(jmodel.integrate(q1,v)));
74 //
75 // TangentVector_t v1 = jmodel_composite.difference(q1,q2);
76 // TangentVector_t v2 = jmodel.difference(q1,q2);
77 //
78 // BOOST_CHECK(v1.isApprox(v2));
79 //
80 // const double alpha = 0.2;
81 // BOOST_CHECK(jmodel_composite.interpolate(q1,q2,alpha).isApprox(jmodel.interpolate(q1,q2,alpha)));
82 // BOOST_CHECK(math::fabs(jmodel_composite.distance(q1,q2)-jmodel.distance(q1,q2))<= NumTraits<double>::dummy_precision());
83 // }
84 
85  Inertia::Matrix6 I0(Inertia::Random().matrix());
86 
87  Inertia::Matrix6 I1 = I0;
88  Inertia::Matrix6 I2 = I0;
89 
90  jmodel.calc_aba(jdata,I1,true);
91  jmodel_composite.calc_aba(jdata_composite,I2,true);
92 
93  double prec = 1e-10; // higher tolerance to errors due to possible numerical imprecisions
94 
95  BOOST_CHECK(jdata.U.isApprox(jdata_composite.U,prec));
96  BOOST_CHECK(jdata.Dinv.isApprox(jdata_composite.Dinv,prec));
97  BOOST_CHECK(jdata.UDinv.isApprox(jdata_composite.UDinv,prec));
98 
99  // Checking the inertia was correctly updated
100  // We use isApprox as usual, except for the freeflyer,
101  // where the correct result is exacly zero and isApprox would fail.
102  // Only for this single case, we use the infinity norm of the difference
103  if(jmodel.shortname() == "JointModelFreeFlyer")
104  BOOST_CHECK((I1-I2).lpNorm<Eigen::Infinity>() < prec);
105  else
106  BOOST_CHECK(I1.isApprox(I2,prec));
107 
108  // Test operator=
109  JointModelComposite jmodel_composite2 = jmodel_composite;
110  JointDataComposite jdata_composite2 = jmodel_composite2.createData();
111 
112  jmodel_composite2.calc(jdata_composite2,q,v);
113 
114  Inertia::Matrix6 I3 = I0;
115  jmodel_composite2.calc_aba(jdata_composite2,I3,true);
116 
117  if(jmodel.shortname() == "JointModelFreeFlyer")
118  BOOST_CHECK((I3-I2).lpNorm<Eigen::Infinity>() < prec);
119  else
120  BOOST_CHECK(I3.isApprox(I2,prec));
121 
122  BOOST_CHECK(jmodel_composite2 == jmodel_composite);
123 
124  BOOST_CHECK(jdata_composite2.U.isApprox(jdata_composite.U,prec));
125  BOOST_CHECK(jdata_composite2.Dinv.isApprox(jdata_composite.Dinv,prec));
126  BOOST_CHECK(jdata_composite2.UDinv.isApprox(jdata_composite.UDinv,prec));
127 
128  // Test operator <<
129  std::cout << "JointModelComposite operator<<:\n" << jmodel_composite << std::endl;
130 
131  // Test block operators
132  const int m = 100;
133  Data::Matrix6x mat(Data::Matrix6x::Ones(6,m));
134  const Data::Matrix6x mat_const(Data::Matrix6x::Ones(6,m));
135  Model::ConfigVectorType vec(Model::ConfigVectorType::Ones(m));
136  const Model::ConfigVectorType vec_const(Model::ConfigVectorType::Ones(m));
137 
138  BOOST_CHECK(jmodel.jointConfigSelector(vec) == jmodel_composite.jointConfigSelector(vec));
139  BOOST_CHECK(jmodel.jointConfigSelector(vec_const) == jmodel_composite.jointConfigSelector(vec_const));
140 
141  BOOST_CHECK(jmodel.jointVelocitySelector(vec) == jmodel_composite.jointVelocitySelector(vec));
142  BOOST_CHECK(jmodel.jointVelocitySelector(vec_const) == jmodel_composite.jointVelocitySelector(vec_const));
143 
144  BOOST_CHECK(jmodel.jointCols(mat) == jmodel_composite.jointCols(mat));
145  BOOST_CHECK(jmodel.jointCols(mat_const) == jmodel_composite.jointCols(mat_const));
146 }
147 
149 
150  template <typename JointModel>
152  {
153  JointModel jmodel;
154  jmodel.setIndexes(0,0,0);
155 
156  test_joint_methods(jmodel);
157  }
158 
159 // void operator()(const JointModelBase<JointModelComposite> &) const
160 // {
161 // JointModelComposite jmodel_composite;
162 // jmodel_composite.addJoint(pinocchio::JointModelRX());
163 // jmodel_composite.addJoint(pinocchio::JointModelRY());
164 // jmodel_composite.setIndexes(0,0,0);
165 //
166 // test_joint_methods(jmodel_composite);
167 // }
168 
170  {
171  JointModelRevoluteUnaligned jmodel(1.5, 1., 0.);
172  jmodel.setIndexes(0,0,0);
173 
174  test_joint_methods(jmodel);
175  }
176 
178  {
179  JointModelPrismaticUnaligned jmodel(1.5, 1., 0.);
180  jmodel.setIndexes(0,0,0);
181 
182  test_joint_methods(jmodel);
183  }
184 
185 };
186 
187 BOOST_AUTO_TEST_SUITE ( BOOST_TEST_MODULE )
188 
190 {
199  > Variant;
200 
201  boost::mpl::for_each<Variant::types>(TestJointComposite());
202 }
203 
205 {
206  JointModelComposite jmodel_composite;
207  jmodel_composite.addJoint(JointModelRZ()).addJoint(JointModelRY(),SE3::Random()).addJoint(JointModelRX());
208  BOOST_CHECK_MESSAGE( jmodel_composite.nq() == 3, "Chain did not work");
209  BOOST_CHECK_MESSAGE( jmodel_composite.nv() == 3, "Chain did not work");
210  BOOST_CHECK_MESSAGE( jmodel_composite.njoints == 3, "Chain did not work");
211 }
212 
214 {
215  JointModelSphericalZYX jmodel_spherical;
216  jmodel_spherical.setIndexes(0,0,0);
217 
218  JointModelComposite jmodel_composite((JointModelRZ()));
219  jmodel_composite.addJoint(JointModelRY());
220  jmodel_composite.addJoint(JointModelRX());
221 
222  test_joint_methods(jmodel_spherical, jmodel_composite);
223 }
224 
225 BOOST_AUTO_TEST_CASE(vsTranslation)
226 {
227  JointModelTranslation jmodel_translation;
228  jmodel_translation.setIndexes(0,0,0);
229 
230  JointModelComposite jmodel_composite((JointModelPX()));
231  jmodel_composite.addJoint(JointModelPY());
232  jmodel_composite.addJoint(JointModelPZ());
233 
234  test_joint_methods(jmodel_translation, jmodel_composite);
235 }
236 
237 BOOST_AUTO_TEST_CASE (test_recursive_variant)
238 {
240  JointModelComposite jmodel_composite_two_rx((JointModelRX()));
241  jmodel_composite_two_rx.addJoint(JointModelRY());
242 
244  JointModelComposite jmodel_composite_recursive((JointModelFreeFlyer()));
245  jmodel_composite_recursive.addJoint(JointModelPlanar());
246  jmodel_composite_recursive.addJoint(jmodel_composite_two_rx);
247 }
248 
249 
251 {
252  JointModelComposite jmodel_composite_planar((JointModelPX()));
253  jmodel_composite_planar.addJoint(JointModelPY());
254  jmodel_composite_planar.addJoint(JointModelRZ());
255  jmodel_composite_planar.setIndexes(0,0,0);
256 
257  JointDataComposite jdata_composite_planar = jmodel_composite_planar.createData();
258 
259  VectorXd q1(VectorXd::Random(3));
260  VectorXd q1_dot(VectorXd::Random(3));
261 
262  JointModelComposite model_copy = jmodel_composite_planar;
263  JointDataComposite data_copy = model_copy.createData();
264 
265  BOOST_CHECK_MESSAGE( model_copy.nq() == jmodel_composite_planar.nq(), "Test Copy Composite, nq are differents");
266  BOOST_CHECK_MESSAGE( model_copy.nv() == jmodel_composite_planar.nv(), "Test Copy Composite, nv are differents");
267 
268  jmodel_composite_planar.calc(jdata_composite_planar,q1, q1_dot);
269  model_copy.calc(data_copy,q1, q1_dot);
270 
271 }
272 
273 BOOST_AUTO_TEST_CASE(test_kinematics)
274 {
275  Model model;
276  JointModelComposite jmodel_composite;
277 
279  JointIndex parent=0;
280 
281  for(int i=0; i<10; i++)
282  {
283  parent = model.addJoint(parent, JointModelRX(), config, "joint");
284  jmodel_composite.addJoint(JointModelRX(),config);
285 
286  config.setRandom();
287  }
288 
289  Data data(model);
290 
291  Model model_c;
292  model_c.addJoint(0,jmodel_composite,SE3::Identity(),"joint");
293 
294  Data data_c(model_c);
295 
296  BOOST_CHECK(model.nv == model_c.nv);
297  BOOST_CHECK(model.nq == model_c.nq);
298 
299  VectorXd q(VectorXd::Random(model.nv));
300  forwardKinematics(model,data,q);
301  forwardKinematics(model_c,data_c,q);
302 
303  BOOST_CHECK(data.oMi.back().isApprox(data_c.oMi.back()));
304 
305  q.setRandom(model.nq);
306  VectorXd v(VectorXd::Random(model.nv));
307  forwardKinematics(model,data,q,v);
308  forwardKinematics(model_c,data_c,q,v);
309 
310  BOOST_CHECK(data.oMi.back().isApprox(data_c.oMi.back()));
311  BOOST_CHECK(data.v.back().isApprox(data_c.v.back()));
312 
313  q.setRandom(model.nq);
314  v.setRandom(model.nv);
315  VectorXd a(VectorXd::Random(model.nv));
316  forwardKinematics(model,data,q,v,a);
317  forwardKinematics(model_c,data_c,q,v,a);
318 
319  BOOST_CHECK(data.oMi.back().isApprox(data_c.oMi.back()));
320  BOOST_CHECK(data.v.back().isApprox(data_c.v.back()));
321  BOOST_CHECK(data.a.back().isApprox(data_c.a.back()));
322 }
323 
324 BOOST_AUTO_TEST_SUITE_END ()
325 
JointCollectionTpl const Eigen::MatrixBase< ConfigVectorType > const Eigen::MatrixBase< TangentVectorType > & v
Constraint_t S() const
JointModelPrismaticTpl< double, 0, 0 > JointModelPX
SizeDepType< NV >::template SegmentReturn< D >::ConstType jointVelocitySelector(const Eigen::MatrixBase< D > &a) const
void test_joint_methods(const JointModelBase< JointModel > &jmodel, JointModelComposite &jmodel_composite)
void calc(JointDataDerived &data, const Eigen::MatrixBase< ConfigVectorType > &qs) const
parent
Definition: lambdas.py:16
void setIndexes(JointIndex id, int q, int v)
boost::python::object matrix()
void operator()(const JointModelBase< JointModel > &) const
JointDataDerived createData() const
SizeDepType< NQ >::template SegmentReturn< D >::ConstType jointConfigSelector(const Eigen::MatrixBase< D > &a) const
JointModelDerived & addJoint(const JointModelBase< JointModel > &jmodel, const SE3 &placement=SE3::Identity())
Add a joint to the vector of joints.
void operator()(const JointModelBase< JointModelRevoluteUnaligned > &) const
static InertiaTpl Random()
mat
vec
JointModelRevoluteUnboundedTpl< double, 0, 1 > JointModelRUBY
JointModelRevoluteUnalignedTpl< double > JointModelRevoluteUnaligned
JointDataTpl< double > JointData
JointModelPrismaticTpl< double, 0, 1 > JointModelPY
data
JointCollectionTpl const Eigen::MatrixBase< ConfigVectorType > & q
void calc_aba(JointDataDerived &data, const Eigen::MatrixBase< Matrix6Like > &I, const bool update_I) const
SizeDepType< NQ >::template SegmentReturn< D >::ConstType jointConfigSelector(const Eigen::MatrixBase< D > &a) const
JointDataDerived createData() const
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.
JointModelRevoluteTpl< double, 0, 1 > JointModelRY
JointModelSphericalZYXTpl< double > JointModelSphericalZYX
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.
JointModelRevoluteTpl< double, 0, 2 > JointModelRZ
void calc(JointDataDerived &data, const Eigen::MatrixBase< ConfigVectorType > &qs) const
JointCollectionTpl const Eigen::MatrixBase< ConfigVectorIn1 > const Eigen::MatrixBase< ConfigVectorIn2 > & q1
config
BOOST_AUTO_TEST_CASE(test_basic)
JointModelTranslationTpl< double > JointModelTranslation
Transformation_t M() const
void setIndexes(JointIndex id, int nq, int nv)
int njoints
Number of joints contained in the JointModelComposite.
Main pinocchio namespace.
Definition: timings.cpp:30
JointModelSphericalTpl< double > JointModelSpherical
SizeDepType< NV >::template ColsReturn< D >::ConstType jointCols(const Eigen::MatrixBase< D > &A) const
Motion_t v() const
int nv
Dimension of the velocity vector space.
JointModelPrismaticTpl< double, 0, 2 > JointModelPZ
list a
JointModelFreeFlyerTpl< double > JointModelFreeFlyer
VectorXs ConfigVectorType
Dense vectorized version of a joint configuration vector.
SizeDepType< NV >::template ColsReturn< D >::ConstType jointCols(const Eigen::MatrixBase< D > &A) const
SizeDepType< NV >::template SegmentReturn< D >::ConstType jointVelocitySelector(const Eigen::MatrixBase< D > &a) const
JointModelRevoluteUnboundedTpl< double, 0, 0 > JointModelRUBX
JointModelPrismaticUnalignedTpl< double > JointModelPrismaticUnaligned
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
JointCollectionTpl & model
int nq
Dimension of the configuration vector representation.
void calc_aba(JointDataDerived &data, const Eigen::MatrixBase< Matrix6Type > &I, const bool update_I=false) const
JointModelPlanarTpl< double > JointModelPlanar
void operator()(const JointModelBase< JointModelPrismaticUnaligned > &) const
std::string shortname() const


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