com.cpp
Go to the documentation of this file.
1 //
2 // Copyright (c) 2015-2019 CNRS INRIA
3 //
4 
5 #include "pinocchio/multibody/model.hpp"
6 #include "pinocchio/multibody/data.hpp"
7 #include "pinocchio/algorithm/jacobian.hpp"
8 #include "pinocchio/algorithm/joint-configuration.hpp"
9 #include "pinocchio/algorithm/crba.hpp"
10 #include "pinocchio/algorithm/compute-all-terms.hpp"
11 #include "pinocchio/algorithm/rnea.hpp"
12 #include "pinocchio/algorithm/center-of-mass.hpp"
13 #include "pinocchio/utils/timer.hpp"
14 #include "pinocchio/parsers/sample-models.hpp"
15 
16 #include <iostream>
17 
18 #include <boost/test/unit_test.hpp>
19 #include <boost/utility/binary.hpp>
20 
21 BOOST_AUTO_TEST_SUITE ( BOOST_TEST_MODULE )
22 
24 {
25  using namespace Eigen;
26  using namespace pinocchio;
27 
30  pinocchio::Data data(model);
31 
32  VectorXd q = VectorXd::Ones(model.nq);
33  q.middleRows<4> (3).normalize();
34  VectorXd v = VectorXd::Ones(model.nv);
35  VectorXd a = VectorXd::Ones(model.nv);
36 
37  crba(model,data,q);
38 
39 
40  /* Test COM against CRBA*/
41  Vector3d com = centerOfMass(model,data,q);
42  BOOST_CHECK(data.com[0].isApprox(getComFromCrba(model,data), 1e-12));
43 
44  /* Test COM against Jcom (both use different way to compute the COM). */
45  com = centerOfMass(model,data,q);
46  jacobianCenterOfMass(model,data,q);
47  BOOST_CHECK(com.isApprox(data.com[0], 1e-12));
48 
49  /* Test COM against Jcom (both use different way to compute the COM). */
50  centerOfMass(model,data,q,v,a);
51  BOOST_CHECK(com.isApprox(data.com[0], 1e-12));
52 
53  /* Test vCoM against nle algorithm without gravity field */
54  a.setZero();
55  model.gravity.setZero();
56  centerOfMass(model,data,q,v,a);
57  nonLinearEffects(model, data, q, v);
58 
59  pinocchio::SE3::Vector3 acom_from_nle (data.nle.head <3> ()/data.mass[0]);
60  BOOST_CHECK((data.liMi[1].rotation() * acom_from_nle).isApprox(data.acom[0], 1e-12));
61 
62  /* Test Jcom against CRBA */
63  Eigen::MatrixXd Jcom = jacobianCenterOfMass(model,data,q);
64  BOOST_CHECK(data.Jcom.isApprox(getJacobianComFromCrba(model,data), 1e-12));
65 
66  /* Test CoM velocity againt jacobianCenterOfMass */
67  BOOST_CHECK((Jcom * v).isApprox(data.vcom[0], 1e-12));
68 
69 
70  centerOfMass(model,data,q,v);
71  /* Test CoM velocity againt jacobianCenterOfMass */
72  BOOST_CHECK((Jcom * v).isApprox(data.vcom[0], 1e-12));
73 
74 
75 // std::cout << "com = [ " << data.com[0].transpose() << " ];" << std::endl;
76 // std::cout << "mass = [ " << data.mass[0] << " ];" << std::endl;
77 // std::cout << "Jcom = [ " << data.Jcom << " ];" << std::endl;
78 // std::cout << "M3 = [ " << data.M.topRows<3>() << " ];" << std::endl;
79 }
80 
81 BOOST_AUTO_TEST_CASE ( test_mass )
82 {
83  using namespace Eigen;
84  using namespace pinocchio;
85 
88 
89  double mass = computeTotalMass(model);
90 
91  BOOST_CHECK(mass == mass); // checking it is not NaN
92 
93  double mass_check = 0.0;
94  for(size_t i=1; i<(size_t)(model.njoints);++i)
95  mass_check += model.inertias[i].mass();
96 
97  BOOST_CHECK_CLOSE(mass, mass_check, 1e-12);
98 
99  pinocchio::Data data1(model);
100 
101  double mass_data = computeTotalMass(model,data1);
102 
103  BOOST_CHECK(mass_data == mass_data); // checking it is not NaN
104  BOOST_CHECK_CLOSE(mass, mass_data, 1e-12);
105  BOOST_CHECK_CLOSE(data1.mass[0], mass_data, 1e-12);
106 
107  pinocchio::Data data2(model);
108  VectorXd q = VectorXd::Ones(model.nq);
109  q.middleRows<4> (3).normalize();
110  centerOfMass(model,data2,q);
111 
112  BOOST_CHECK_CLOSE(data2.mass[0], mass, 1e-12);
113 }
114 
115 BOOST_AUTO_TEST_CASE ( test_subtree_masses )
116 {
117  using namespace Eigen;
118  using namespace pinocchio;
119 
122 
123  pinocchio::Data data1(model);
124 
125  computeSubtreeMasses(model,data1);
126 
127  pinocchio::Data data2(model);
128  VectorXd q = VectorXd::Ones(model.nq);
129  q.middleRows<4> (3).normalize();
130  centerOfMass(model,data2,q);
131 
132  for(size_t i=0; i<(size_t)(model.njoints);++i)
133  {
134  BOOST_CHECK_CLOSE(data1.mass[i], data2.mass[i], 1e-12);
135  }
136 }
137 
138 //BOOST_AUTO_TEST_CASE ( test_timings )
139 //{
140 // using namespace Eigen;
141 // using namespace pinocchio;
142 //
143 // pinocchio::Model model;
144 // pinocchio::buildModels::humanoidRandom(model);
145 // pinocchio::Data data(model);
146 //
147 // long flag = BOOST_BINARY(1111);
148 // PinocchioTicToc timer(PinocchioTicToc::US);
149 // #ifdef NDEBUG
150 // #ifdef _INTENSE_TESTING_
151 // const size_t NBT = 1000*1000;
152 // #else
153 // const size_t NBT = 10;
154 // #endif
155 // #else
156 // const size_t NBT = 1;
157 // std::cout << "(the time score in debug mode is not relevant) " ;
158 // #endif
159 //
160 // bool verbose = flag & (flag-1) ; // True is two or more binaries of the flag are 1.
161 // if(verbose) std::cout <<"--" << std::endl;
162 // Eigen::VectorXd q = Eigen::VectorXd::Zero(model.nq);
163 //
164 // if( flag >> 0 & 1 )
165 // {
166 // timer.tic();
167 // SMOOTH(NBT)
168 // {
169 // centerOfMass(model,data,q);
170 // }
171 // if(verbose) std::cout << "COM =\t";
172 // timer.toc(std::cout,NBT);
173 // }
174 //
175 // if( flag >> 1 & 1 )
176 // {
177 // timer.tic();
178 // SMOOTH(NBT)
179 // {
180 // centerOfMass(model,data,q,false);
181 // }
182 // if(verbose) std::cout << "Without sub-tree =\t";
183 // timer.toc(std::cout,NBT);
184 // }
185 //
186 // if( flag >> 2 & 1 )
187 // {
188 // timer.tic();
189 // SMOOTH(NBT)
190 // {
191 // jacobianCenterOfMass(model,data,q);
192 // }
193 // if(verbose) std::cout << "Jcom =\t";
194 // timer.toc(std::cout,NBT);
195 // }
196 //}
197 
198 BOOST_AUTO_TEST_CASE(test_subtree_com_jacobian)
199 {
200  using namespace Eigen;
201  using namespace pinocchio;
202 
203  Model model;
205  Data data(model);
206 
207  model.upperPositionLimit.head<3>().fill(1000);
208  model.lowerPositionLimit.head<3>() = -model.upperPositionLimit.head<3>();
210  VectorXd v = VectorXd::Random(model.nv);
211 
212  Data data_ref(model);
213  jacobianCenterOfMass(model,data_ref,q,true);
214 
215  centerOfMass(model, data, q, v);
216  Data::Matrix3x Jcom(3,model.nv); Jcom.setZero();
217  jacobianSubtreeCenterOfMass(model, data, 0, Jcom);
218 
219  BOOST_CHECK(Jcom.isApprox(data_ref.Jcom));
220 
221  centerOfMass(model, data_ref, q, v, true);
222  computeJointJacobians(model, data_ref, q);
223  Data::Matrix3x Jcom_extracted(3,model.nv), Jcom_fd(3,model.nv);
224  Data data_extracted(model), data_fd(model);
225  const double eps = 1e-8;
226  jacobianCenterOfMass(model,data_extracted,q);
227 
228  // Get subtree jacobian and check that it is consistent with the com velocity
229  for(JointIndex joint_id = 1; joint_id < (JointIndex)model.njoints; joint_id++)
230  {
231  SE3::Vector3 subtreeComVelocityInWorld_ref = data_ref.oMi[joint_id].rotation() * data_ref.vcom[joint_id];
232  Jcom.setZero();
233  data.J.setZero();
234  jacobianSubtreeCenterOfMass(model, data, joint_id, Jcom);
235 
236  BOOST_CHECK(data.J.middleCols(model.joints[joint_id].idx_v(),data.nvSubtree[joint_id]).isApprox(data_ref.J.middleCols(model.joints[joint_id].idx_v(),data.nvSubtree[joint_id])));
237  SE3::Vector3 subtreeComVelocityInWorld = Jcom * v;
238 
239  Jcom_extracted.setZero();
240  getJacobianSubtreeCenterOfMass(model,data_extracted,joint_id,Jcom_extracted);
241 
242  // Check with finite differences
243  Eigen::VectorXd v_plus(model.nv); v_plus.setZero();
244  centerOfMass(model,data_fd,q);
245  const SE3::Vector3 com = data_fd.oMi[joint_id].act(data_fd.com[joint_id]);
246  Jcom_fd.setZero();
247  for(Eigen::DenseIndex k = 0; k < model.nv; ++k)
248  {
249  v_plus[k] = eps;
250  Eigen::VectorXd q_plus = integrate(model,q,v_plus);
251  centerOfMass(model,data_fd,q_plus);
252  const SE3::Vector3 com_plus = data_fd.oMi[joint_id].act(data_fd.com[joint_id]);
253  Jcom_fd.col(k) = (com_plus - com)/eps;
254  v_plus[k] = 0.;
255  }
256 
257 // Eigen::VectorXd q_plus = integrate(model,q,v*eps);
258 // centerOfMass(model,data_fd,q_plus);
259 // const SE3::Vector3 com_plus = data_fd.oMi[joint_id].act(data_fd.com[joint_id]);
260 //
261 // const SE3::Vector3 vcom_subtree_fd = (com_plus - com)/eps;
262 
263  BOOST_CHECK(Jcom.isApprox(Jcom_fd,sqrt(eps)));
264  BOOST_CHECK(Jcom_extracted.isApprox(Jcom_fd,sqrt(eps)));
265  BOOST_CHECK(Jcom_extracted.isApprox(Jcom));
266 
267  BOOST_CHECK(std::fabs(data.mass[joint_id] - data_ref.mass[joint_id]) <= 1e-12);
268  BOOST_CHECK(data.com[joint_id].isApprox(data_ref.oMi[joint_id].act(data_ref.com[joint_id])));
269  BOOST_CHECK(subtreeComVelocityInWorld.isApprox(subtreeComVelocityInWorld_ref));
270  }
271 }
272 
273 BOOST_AUTO_TEST_SUITE_END ()
const DataTpl< Scalar, Options, JointCollectionTpl >::Matrix3x & getJacobianComFromCrba(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, DataTpl< Scalar, Options, JointCollectionTpl > &data)
Extracts both the jacobian of the center of mass (CoM), the total mass of the system and the CoM posi...
const DataTpl< Scalar, Options, JointCollectionTpl >::Matrix3x & jacobianCenterOfMass(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, DataTpl< Scalar, Options, JointCollectionTpl > &data, const Eigen::MatrixBase< ConfigVectorType > &q, const bool computeSubtreeComs=true)
Computes both the jacobian and the the center of mass position of a given model according to a partic...
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
Matrix6x J
Jacobian of joint placements.
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...
int eps
Definition: dcrba.py:384
int njoints
Number of joints.
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.
Scalar computeTotalMass(const ModelTpl< Scalar, Options, JointCollectionTpl > &model)
Compute the total mass of the model and return it.
const DataTpl< Scalar, Options, JointCollectionTpl >::Vector3 & getComFromCrba(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, DataTpl< Scalar, Options, JointCollectionTpl > &data)
Extracts the center of mass position from the joint space inertia matrix (also called the mass matrix...
data
BOOST_AUTO_TEST_CASE(test_com)
Definition: com.cpp:23
VectorXs nle
Vector of Non Linear Effects (dim model.nv). It corresponds to concatenation of the Coriolis...
void computeSubtreeMasses(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, DataTpl< Scalar, Options, JointCollectionTpl > &data)
Compute the mass of each kinematic subtree and store it in data.mass. The element mass[0] corresponds...
Matrix3x Jcom
Jacobian of center of mass.
Motion gravity
Spatial gravity of the model.
traits< SE3Tpl >::Vector3 Vector3
void getJacobianSubtreeCenterOfMass(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, const DataTpl< Scalar, Options, JointCollectionTpl > &data, const JointIndex &rootSubtreeId, const Eigen::MatrixBase< Matrix3xLike > &res)
Retrieves the Jacobian of the center of mass of the given subtree according to the current value stor...
Main pinocchio namespace.
Definition: timings.cpp:30
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.
Eigen::Matrix< Scalar, 3, Eigen::Dynamic, Options > Matrix3x
The 3d jacobian type (temporary)
const DataTpl< Scalar, Options, JointCollectionTpl >::Vector3 & centerOfMass(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, DataTpl< Scalar, Options, JointCollectionTpl > &data, const Eigen::MatrixBase< ConfigVectorType > &q, const bool computeSubtreeComs=true)
Computes the center of mass position of a given model according to a particular joint configuration...
list a
void normalize(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, const Eigen::MatrixBase< ConfigVectorType > &qout)
Normalize a configuration vector.
ConfigVectorType upperPositionLimit
Upper joint configuration limit.
std::vector< int > nvSubtree
Dimension of the subtree motion space (for CRBA)
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:
void jacobianSubtreeCenterOfMass(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, DataTpl< Scalar, Options, JointCollectionTpl > &data, const Eigen::MatrixBase< ConfigVectorType > &q, const JointIndex &rootSubtreeId, const Eigen::MatrixBase< Matrix3xLike > &res)
Computes the Jacobian of the center of mass of the given subtree according to a particular joint conf...
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
int nq
Dimension of the configuration vector representation.
std::vector< Scalar > mass
Vector of subtree mass. In other words, mass[j] is the mass of the subtree supported by joint ...
void fill(Eigen::Ref< MatType > mat, const typename MatType::Scalar &value)


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