unittest/crba.cpp
Go to the documentation of this file.
1 //
2 // Copyright (c) 2015-2023 CNRS INRIA
3 //
4 
5 /*
6  * Test the CRBA algorithm. The code validates both the computation times and
7  * the value by comparing the results of the CRBA with the reconstruction of
8  * the mass matrix using the RNEA.
9  * For a strong timing benchmark, see benchmark/timings.
10  *
11  */
12 
13 #ifndef EIGEN_RUNTIME_NO_MALLOC
14  #define EIGEN_RUNTIME_NO_MALLOC
15 #endif
16 
28 
29 #include <iostream>
30 
31 #include <boost/test/unit_test.hpp>
32 #include <boost/utility/binary.hpp>
33 
35 
36 template<typename JointModel>
37 static void addJointAndBody(
40  const std::string & parent_name,
41  const std::string & name,
42  const pinocchio::SE3 placement = pinocchio::SE3::Random(),
43  bool setRandomLimits = true)
44 {
45  using namespace pinocchio;
46  typedef typename JointModel::ConfigVector_t CV;
47  typedef typename JointModel::TangentVector_t TV;
48 
50 
51  if (setRandomLimits)
52  idx = model.addJoint(
53  model.getJointId(parent_name), joint, SE3::Random(), name + "_joint",
54  TV::Random() + TV::Constant(1), TV::Random() + TV::Constant(1),
55  CV::Random() - CV::Constant(1), CV::Random() + CV::Constant(1));
56  else
57  idx = model.addJoint(model.getJointId(parent_name), joint, placement, name + "_joint");
58 
59  model.addJointFrame(idx);
60 
61  model.appendBodyToJoint(idx, Inertia::Random(), SE3::Identity());
62  model.addBodyFrame(name + "_body", idx);
63 }
64 
65 BOOST_AUTO_TEST_SUITE(BOOST_TEST_MODULE)
66 
68 {
72 
73 #ifdef NDEBUG
74  #ifdef _INTENSE_TESTING_
75  const size_t NBT = 1000 * 1000;
76  #else
77  const size_t NBT = 10;
78  #endif
79 
80  Eigen::VectorXd q = pinocchio::neutral(model);
81 
83  timer.tic();
84  SMOOTH(NBT)
85  {
87  }
88  timer.toc(std::cout, NBT);
89 
90 #else
91  const size_t NBT = 1;
92  using namespace Eigen;
93  using namespace pinocchio;
94 
95  Eigen::MatrixXd M(model.nv, model.nv);
96  Eigen::VectorXd q = Eigen::VectorXd::Ones(model.nq);
97  q.segment<4>(3).normalize();
98  Eigen::VectorXd v = Eigen::VectorXd::Zero(model.nv);
99  Eigen::VectorXd a = Eigen::VectorXd::Zero(model.nv);
100  data.M.fill(0);
102  data.M.triangularView<Eigen::StrictlyLower>() =
103  data.M.transpose().triangularView<Eigen::StrictlyLower>();
104 
105  /* Joint inertia from iterative crba. */
106  const Eigen::VectorXd bias = rnea(model, data, q, v, a);
107  for (int i = 0; i < model.nv; ++i)
108  {
109  M.col(i) = rnea(model, data, q, v, Eigen::VectorXd::Unit(model.nv, i)) - bias;
110  }
111 
112  // std::cout << "Mcrb = [ " << data.M << " ];" << std::endl;
113  // std::cout << "Mrne = [ " << M << " ]; " << std::endl;
114  BOOST_CHECK(M.isApprox(data.M, 1e-12));
115 
116  std::cout << "(the time score in debug mode is not relevant) ";
117 
119 
121  timer.tic();
122  SMOOTH(NBT)
123  {
125  }
126  timer.toc(std::cout, NBT);
127 
128 #endif // ifndef NDEBUG
129 }
130 
131 BOOST_AUTO_TEST_CASE(test_crba_mimic)
132 {
133  for (int i = 0; i < pinocchio::MimicTestCases::N_CASES; i++)
134  {
135  const pinocchio::MimicTestCases mimic_test_case(i);
136  const pinocchio::Model & model_mimic = mimic_test_case.model_mimic;
137  const pinocchio::Model & model_full = mimic_test_case.model_full;
138  const Eigen::MatrixXd & G = mimic_test_case.G;
139 
141  Eigen::VectorXd v_mimic = Eigen::VectorXd::Random(model_mimic.nv);
142  Eigen::VectorXd as_mimic = Eigen::VectorXd::Random(model_mimic.nv);
143 
144  Eigen::VectorXd q_full(model_full.nq);
145  Eigen::VectorXd v_full = G * v_mimic;
146  Eigen::VectorXd a_full = G * as_mimic;
147 
148  mimic_test_case.toFull(q_mimic, q_full);
149 
152  pinocchio::Data data_ref_mimic(model_mimic);
153 
155  // World vs local
158 
159  BOOST_CHECK(data_ref_mimic.M.isApprox(data_mimic.M));
160 
161  // Compute other half of matrix
162  data_mimic.M.triangularView<Eigen::StrictlyLower>() =
163  data_mimic.M.transpose().triangularView<Eigen::StrictlyLower>();
164  data_full.M.triangularView<Eigen::StrictlyLower>() =
165  data_full.M.transpose().triangularView<Eigen::StrictlyLower>();
166 
167  // Check full model against reduced
168  BOOST_CHECK(data_mimic.M.isApprox(G.transpose() * data_full.M * G, 1e-12));
169  }
170 }
171 
172 BOOST_AUTO_TEST_CASE(test_minimal_crba)
173 {
176  pinocchio::Data data(model), data_ref(model);
177 
178  model.lowerPositionLimit.head<7>().fill(-1.);
179  model.upperPositionLimit.head<7>().fill(1.);
180 
181  Eigen::VectorXd q =
182  randomConfiguration(model, model.lowerPositionLimit, model.upperPositionLimit);
183  Eigen::VectorXd v(Eigen::VectorXd::Random(model.nv));
184 
186  data_ref.M.triangularView<Eigen::StrictlyLower>() =
187  data_ref.M.transpose().triangularView<Eigen::StrictlyLower>();
188 
190  data.M.triangularView<Eigen::StrictlyLower>() =
191  data.M.transpose().triangularView<Eigen::StrictlyLower>();
192 
193  BOOST_CHECK(data.M.isApprox(data_ref.M));
194 
195  ccrba(model, data_ref, q, v);
196  computeJointJacobians(model, data_ref, q);
197  BOOST_CHECK(data.Ag.isApprox(data_ref.Ag));
198  BOOST_CHECK(data.J.isApprox(data_ref.J));
199 
200  // Check double call
201  {
202  pinocchio::Data data2(model);
205 
206  BOOST_CHECK(data2.Ycrb[0] == data.Ycrb[0]);
207  }
208 }
209 
210 BOOST_AUTO_TEST_CASE(test_roto_inertia_effects)
211 {
212  pinocchio::Model model, model_ref;
214  model_ref = model;
215 
216  BOOST_CHECK(model == model_ref);
217 
218  pinocchio::Data data(model), data_ref(model_ref);
219 
220  model.armature = Eigen::VectorXd::Random(model.nv) + Eigen::VectorXd::Constant(model.nv, 1.);
221 
222  Eigen::VectorXd q = randomConfiguration(model);
223  pinocchio::crba(model_ref, data_ref, q, pinocchio::Convention::WORLD);
224  data_ref.M.triangularView<Eigen::StrictlyLower>() =
225  data_ref.M.transpose().triangularView<Eigen::StrictlyLower>();
226  data_ref.M.diagonal() += model.armature;
227 
229  data.M.triangularView<Eigen::StrictlyLower>() =
230  data.M.transpose().triangularView<Eigen::StrictlyLower>();
231 
232  BOOST_CHECK(data.M.isApprox(data_ref.M));
233 }
234 
235 #ifndef NDEBUG
236 
237 BOOST_AUTO_TEST_CASE(test_crba_malloc)
238 {
239  using namespace pinocchio;
242 
243  model.addJoint(
244  size_t(model.njoints - 1), pinocchio::JointModelRevoluteUnaligned(SE3::Vector3::UnitX()),
245  SE3::Random(), "revolute_unaligned");
247 
248  const Eigen::VectorXd q = pinocchio::neutral(model);
249  Eigen::internal::set_is_malloc_allowed(false);
252  Eigen::internal::set_is_malloc_allowed(true);
253 }
254 
255 #endif
256 
257 BOOST_AUTO_TEST_SUITE_END()
pinocchio::DataTpl::M
MatrixXs M
The joint space inertia matrix (a square matrix of dim model.nv).
Definition: multibody/data.hpp:199
pinocchio::WORLD
@ WORLD
Definition: multibody/fwd.hpp:48
display-shapes-meshcat.placement
placement
Definition: display-shapes-meshcat.py:24
PinocchioTicToc::toc
double toc()
Definition: timer.hpp:88
Eigen
pinocchio::DataTpl
Definition: context/generic.hpp:25
pinocchio::MimicTestCases::toFull
void toFull(const Eigen::VectorXd &q, Eigen::VectorXd &q_full) const
Definition: model-generator.hpp:241
model.hpp
pinocchio::JointModelBase
Definition: joint-model-base.hpp:78
pinocchio::SE3
context::SE3 SE3
Definition: spatial/fwd.hpp:59
pinocchio::Convention::WORLD
@ WORLD
inverse-kinematics.i
int i
Definition: inverse-kinematics.py:17
pinocchio::name
std::string name(const LieGroupGenericTpl< LieGroupCollection > &lg)
Visit a LieGroupVariant to get the name of it.
model.hpp
setup.data
data
Definition: cmake/cython/setup.in.py:48
mimic_dynamics.a_full
a_full
Definition: mimic_dynamics.py:49
mimic_dynamics.q_mimic
q_mimic
Definition: mimic_dynamics.py:39
pinocchio::crba
const DataTpl< Scalar, Options, JointCollectionTpl >::MatrixXs & crba(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, DataTpl< Scalar, Options, JointCollectionTpl > &data, const Eigen::MatrixBase< ConfigVectorType > &q, const Convention convention=Convention::LOCAL)
Computes the upper triangular part of the joint space inertia matrix M by using the Composite Rigid B...
pinocchio::MimicTestCases::G
Eigen::MatrixXd G
Definition: model-generator.hpp:134
pinocchio::computeJointJacobians
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....
pinocchio::MimicTestCases::N_CASES
static const int N_CASES
Definition: model-generator.hpp:128
pinocchio::buildModels::humanoidRandom
void humanoidRandom(ModelTpl< Scalar, Options, JointCollectionTpl > &model, bool usingFF=true, bool mimic=false)
Create a humanoid kinematic tree with 6-DOF limbs and random joint placements.
pinocchio::randomConfiguration
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.
Definition: joint-configuration.hpp:315
model-generator.hpp
rnea.hpp
timer.hpp
mimic_dynamics.model_full
model_full
Definition: mimic_dynamics.py:9
anymal-simulation.model
model
Definition: anymal-simulation.py:8
pinocchio::ModelTpl< Scalar >::JointIndex
pinocchio::JointIndex JointIndex
Definition: multibody/model.hpp:67
center-of-mass.hpp
SMOOTH
#define SMOOTH(s)
Definition: timer.hpp:38
joint-configuration.hpp
pinocchio::placement
const MotionDense< Motion2 > const SE3Tpl< SE3Scalar, SE3Options > & placement
Definition: spatial/classic-acceleration.hpp:122
mimic_dynamics.v_full
v_full
Definition: mimic_dynamics.py:48
BOOST_AUTO_TEST_CASE
BOOST_AUTO_TEST_CASE(test_crba)
Definition: unittest/crba.cpp:67
cartpole.v
v
Definition: cartpole.py:153
data.hpp
pinocchio::ccrba
const DataTpl< Scalar, Options, JointCollectionTpl >::Matrix6x & ccrba(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, DataTpl< Scalar, Options, JointCollectionTpl > &data, const Eigen::MatrixBase< ConfigVectorType > &q, const Eigen::MatrixBase< TangentVectorType > &v)
Computes the Centroidal Momentum Matrix, the Composite Ridig Body Inertia as well as the centroidal m...
pinocchio::MimicTestCases::model_mimic
pinocchio::Model model_mimic
Definition: model-generator.hpp:130
mimic_dynamics.model_mimic
model_mimic
Definition: mimic_dynamics.py:19
M
M
pinocchio::DataTpl::Ag
Matrix6x Ag
Centroidal Momentum Matrix.
Definition: multibody/data.hpp:284
setup.name
name
Definition: cmake/cython/setup.in.py:179
q
q
a
Vec3f a
addJointAndBody
static void addJointAndBody(pinocchio::Model &model, const pinocchio::JointModelBase< JointModel > &joint, const std::string &parent_name, const std::string &name, const pinocchio::SE3 placement=pinocchio::SE3::Random(), bool setRandomLimits=true)
Definition: unittest/crba.cpp:37
PinocchioTicToc::US
@ US
Definition: timer.hpp:53
pinocchio::bias
MotionTpl< Scalar, Options > bias(const JointDataTpl< Scalar, Options, JointCollectionTpl > &jdata)
Visit a JointDataTpl through JointBiasVisitor to get the joint bias as a dense motion.
mimic_dynamics.q_full
q_full
Definition: mimic_dynamics.py:46
pinocchio::DataTpl::J
Matrix6x J
Jacobian of joint placements.
Definition: multibody/data.hpp:374
pinocchio::JointModelRevoluteUnalignedTpl
Definition: multibody/joint/fwd.hpp:38
fill
fill
centroidal.hpp
pinocchio::rnea
const DataTpl< Scalar, Options, JointCollectionTpl >::TangentVectorType & rnea(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 > &a)
The Recursive Newton-Euler algorithm. It computes the inverse dynamics, aka the joint torques accordi...
mimic_dynamics.G
G
Definition: mimic_dynamics.py:27
pinocchio::MimicTestCases
Definition: model-generator.hpp:125
pinocchio::Convention::LOCAL
@ LOCAL
mimic_dynamics.v_mimic
v_mimic
Definition: mimic_dynamics.py:40
mimic_dynamics.data_full
data_full
Definition: mimic_dynamics.py:53
pinocchio::neutral
void neutral(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, const Eigen::MatrixBase< ReturnType > &qout)
Return the neutral configuration element related to the model configuration space.
Definition: joint-configuration.hpp:363
sample-models.hpp
jacobian.hpp
pinocchio::ModelTpl< context::Scalar, context::Options >
pinocchio::MimicTestCases::model_full
pinocchio::Model model_full
Definition: model-generator.hpp:131
crba.hpp
PinocchioTicToc
Definition: timer.hpp:47
mimic_dynamics.data_mimic
data_mimic
Definition: mimic_dynamics.py:52
pinocchio::normalize
void normalize(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, const Eigen::MatrixBase< ConfigVectorType > &qout)
Normalize a configuration vector.
Definition: joint-configuration.hpp:887
pinocchio::model
JointCollectionTpl & model
Definition: joint-configuration.hpp:1082
pinocchio
Main pinocchio namespace.
Definition: timings.cpp:33
PinocchioTicToc::tic
void tic()
Definition: timer.hpp:82


pinocchio
Author(s):
autogenerated on Wed Apr 16 2025 02:41:46