joint-jacobian.cpp
Go to the documentation of this file.
1 //
2 // Copyright (c) 2015-2020 CNRS INRIA
3 //
4 
14 
15 #include <iostream>
16 
17 #include <boost/test/unit_test.hpp>
18 #include <boost/utility/binary.hpp>
19 
20 template<typename Derived>
21 inline bool isFinite(const Eigen::MatrixBase<Derived> & x)
22 {
23  return ((x - x).array() == (x - x).array()).all();
24 }
25 
26 BOOST_AUTO_TEST_SUITE(BOOST_TEST_MODULE)
27 
28 BOOST_AUTO_TEST_CASE(test_jacobian)
29 {
30  using namespace Eigen;
31  using namespace pinocchio;
32 
36 
37  VectorXd q = VectorXd::Zero(model.nq);
39 
40  Model::Index idx =
41  model.existJointName("rarm2") ? model.getJointId("rarm2") : (Model::Index)(model.njoints - 1);
42  Data::Matrix6x Jrh(6, model.nv);
43  Jrh.fill(0);
44  getJointJacobian(model, data, idx, WORLD, Jrh);
45 
46  /* Test J*q == v */
47  VectorXd qdot = VectorXd::Random(model.nv);
48  VectorXd qddot = VectorXd::Zero(model.nv);
49  rnea(model, data, q, qdot, qddot);
50  Motion v = data.oMi[idx].act(data.v[idx]);
51  BOOST_CHECK(v.toVector().isApprox(Jrh * qdot, 1e-12));
52 
53  /* Test local jacobian: rhJrh == rhXo oJrh */
54  Data::Matrix6x rhJrh(6, model.nv);
55  rhJrh.fill(0);
56  getJointJacobian(model, data, idx, LOCAL, rhJrh);
57  Data::Matrix6x XJrh(6, model.nv);
58  motionSet::se3Action(data.oMi[idx].inverse(), Jrh, XJrh);
59  BOOST_CHECK(XJrh.isApprox(rhJrh, 1e-12));
60 
61  XJrh.setZero();
62  Data data_jointJacobian(model);
63  computeJointJacobian(model, data_jointJacobian, q, idx, XJrh);
64  BOOST_CHECK(XJrh.isApprox(rhJrh, 1e-12));
65 
66  /* Test computeJointJacobians with pre-computation of the forward kinematics */
67  Data data_fk(model);
68  forwardKinematics(model, data_fk, q);
69  computeJointJacobians(model, data_fk);
70 
71  BOOST_CHECK(data_fk.J.isApprox(data.J));
72 }
73 
74 BOOST_AUTO_TEST_CASE(test_jacobian_time_variation)
75 {
76  using namespace Eigen;
77  using namespace pinocchio;
78 
82  pinocchio::Data data_ref(model);
83 
84  VectorXd q = randomConfiguration(
85  model, -1 * Eigen::VectorXd::Ones(model.nq), Eigen::VectorXd::Ones(model.nq));
86  VectorXd v = VectorXd::Random(model.nv);
87  VectorXd a = VectorXd::Random(model.nv);
88 
90 
92 
93  forwardKinematics(model, data_ref, q, v, a);
94  Model::Index idx =
95  model.existJointName("rarm2") ? model.getJointId("rarm2") : (Model::Index)(model.njoints - 1);
96 
97  Data::Matrix6x J(6, model.nv);
98  J.fill(0.);
99  Data::Matrix6x dJ(6, model.nv);
100  dJ.fill(0.);
101 
102  // Regarding to the WORLD origin
103  getJointJacobian(model, data, idx, WORLD, J);
104  BOOST_CHECK(J.isApprox(getJointJacobian(model, data, idx, WORLD)));
106 
107  Motion v_idx(J * v);
108  BOOST_CHECK(v_idx.isApprox(data_ref.oMi[idx].act(data_ref.v[idx])));
109 
110  Motion a_idx(J * a + dJ * v);
111  const Motion & a_ref = data_ref.oMi[idx].act(data_ref.a[idx]);
112  BOOST_CHECK(a_idx.isApprox(a_ref));
113 
114  // Regarding to the LOCAL frame
115  getJointJacobian(model, data, idx, LOCAL, J);
116  BOOST_CHECK(J.isApprox(getJointJacobian(model, data, idx, LOCAL)));
118 
119  v_idx = (Motion::Vector6)(J * v);
120  BOOST_CHECK(v_idx.isApprox(data_ref.v[idx]));
121 
122  a_idx = (Motion::Vector6)(J * a + dJ * v);
123  BOOST_CHECK(a_idx.isApprox(data_ref.a[idx]));
124 
125  // Regarding to the LOCAL_WORLD_ALIGNED frame
129 
130  Data::SE3 worldMlocal = data.oMi[idx];
131  worldMlocal.translation().setZero();
132 
133  v_idx = (Motion::Vector6)(J * v);
134  BOOST_CHECK(v_idx.isApprox(worldMlocal.act(data_ref.v[idx])));
135 
136  a_idx = (Motion::Vector6)(J * a + dJ * v);
137  BOOST_CHECK(a_idx.isApprox(worldMlocal.act(data_ref.a[idx])));
138 
139  // compare to finite differencies : WORLD
140  {
141  Data data_ref(model), data_ref_plus(model);
142 
143  const double alpha = 1e-8;
144  Eigen::VectorXd q_plus(model.nq);
145  q_plus = integrate(model, q, alpha * v);
146 
147  Data::Matrix6x J_ref(6, model.nv);
148  J_ref.fill(0.);
149  computeJointJacobians(model, data_ref, q);
150  getJointJacobian(model, data_ref, idx, WORLD, J_ref);
151 
152  Data::Matrix6x J_ref_plus(6, model.nv);
153  J_ref_plus.fill(0.);
154  computeJointJacobians(model, data_ref_plus, q_plus);
155  getJointJacobian(model, data_ref_plus, idx, WORLD, J_ref_plus);
156 
157  Data::Matrix6x dJ_ref(6, model.nv);
158  dJ_ref.fill(0.);
159  dJ_ref = (J_ref_plus - J_ref) / alpha;
160 
162  Data::Matrix6x dJ(6, model.nv);
163  dJ.fill(0.);
165 
166  BOOST_CHECK(dJ.isApprox(dJ_ref, sqrt(alpha)));
167  }
168 
169  // compare to finite differencies : LOCAL
170  {
171  Data data_ref(model), data_ref_plus(model);
172 
173  const double alpha = 1e-8;
174  Eigen::VectorXd q_plus(model.nq);
175  q_plus = integrate(model, q, alpha * v);
176 
177  Data::Matrix6x J_ref(6, model.nv);
178  J_ref.fill(0.);
179  computeJointJacobians(model, data_ref, q);
180  getJointJacobian(model, data_ref, idx, LOCAL, J_ref);
181 
182  Data::Matrix6x J_ref_plus(6, model.nv);
183  J_ref_plus.fill(0.);
184  computeJointJacobians(model, data_ref_plus, q_plus);
185  getJointJacobian(model, data_ref_plus, idx, LOCAL, J_ref_plus);
186 
187  const Data::SE3 M_plus = data_ref.oMi[idx].inverse() * data_ref_plus.oMi[idx];
188 
189  Data::Matrix6x dJ_ref(6, model.nv);
190  dJ_ref.fill(0.);
191  dJ_ref = (M_plus.toActionMatrix() * J_ref_plus - J_ref) / alpha;
192 
194  Data::Matrix6x dJ(6, model.nv);
195  dJ.fill(0.);
197 
198  BOOST_CHECK(dJ.isApprox(dJ_ref, sqrt(alpha)));
199  }
200 }
201 
202 BOOST_AUTO_TEST_CASE(test_timings)
203 {
204  using namespace Eigen;
205  using namespace pinocchio;
206 
210 
211  long flag = BOOST_BINARY(1111);
213 #ifdef NDEBUG
214  #ifdef _INTENSE_TESTING_
215  const size_t NBT = 1000 * 1000;
216  #else
217  const size_t NBT = 10;
218  #endif
219 #else
220  const size_t NBT = 1;
221  std::cout << "(the time score in debug mode is not relevant) ";
222 #endif
223 
224  bool verbose = flag & (flag - 1); // True is two or more binaries of the flag are 1.
225  if (verbose)
226  std::cout << "--" << std::endl;
227  Eigen::VectorXd q = Eigen::VectorXd::Zero(model.nq);
228 
229  if (flag >> 0 & 1)
230  {
231  timer.tic();
232  SMOOTH(NBT)
233  {
235  }
236  if (verbose)
237  std::cout << "Compute =\t";
238  timer.toc(std::cout, NBT);
239  }
240 
241  if (flag >> 1 & 1)
242  {
244  Model::Index idx =
245  model.existJointName("rarm6") ? model.getJointId("rarm6") : (Model::Index)(model.njoints - 1);
246  Data::Matrix6x Jrh(6, model.nv);
247  Jrh.fill(0);
248 
249  timer.tic();
250  SMOOTH(NBT)
251  {
252  getJointJacobian(model, data, idx, WORLD, Jrh);
253  }
254  if (verbose)
255  std::cout << "Copy =\t";
256  timer.toc(std::cout, NBT);
257  }
258 
259  if (flag >> 2 & 1)
260  {
262  Model::Index idx =
263  model.existJointName("rarm6") ? model.getJointId("rarm6") : (Model::Index)(model.njoints - 1);
264  Data::Matrix6x Jrh(6, model.nv);
265  Jrh.fill(0);
266 
267  timer.tic();
268  SMOOTH(NBT)
269  {
270  getJointJacobian(model, data, idx, LOCAL, Jrh);
271  }
272  if (verbose)
273  std::cout << "Change frame =\t";
274  timer.toc(std::cout, NBT);
275  }
276 
277  if (flag >> 3 & 1)
278  {
280  Model::Index idx =
281  model.existJointName("rarm6") ? model.getJointId("rarm6") : (Model::Index)(model.njoints - 1);
282  Data::Matrix6x Jrh(6, model.nv);
283  Jrh.fill(0);
284 
285  timer.tic();
286  SMOOTH(NBT)
287  {
288  computeJointJacobian(model, data, q, idx, Jrh);
289  }
290  if (verbose)
291  std::cout << "Single jacobian =\t";
292  timer.toc(std::cout, NBT);
293  }
294 }
295 
296 BOOST_AUTO_TEST_SUITE_END()
pinocchio::WORLD
@ WORLD
Definition: multibody/fwd.hpp:48
act-on-set.hpp
PinocchioTicToc::toc
double toc()
Definition: timer.hpp:88
Eigen
pinocchio::getJointJacobianTimeVariation
void getJointJacobianTimeVariation(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, const DataTpl< Scalar, Options, JointCollectionTpl > &data, const JointIndex joint_id, const ReferenceFrame reference_frame, const Eigen::MatrixBase< Matrix6Like > &dJ)
Computes the Jacobian time variation of a specific joint frame expressed either in the world frame (r...
pinocchio::DataTpl
Definition: context/generic.hpp:25
pinocchio::forwardKinematics
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::SE3Tpl< Scalar, Options >
inverse-kinematics.J
J
Definition: inverse-kinematics.py:31
kinematics.hpp
model.hpp
setup.data
data
Definition: cmake/cython/setup.in.py:48
pinocchio::buildModels::humanoidRandom
void humanoidRandom(ModelTpl< Scalar, Options, JointCollectionTpl > &model, bool usingFF=true)
Create a humanoid kinematic tree with 6-DOF limbs and random joint placements.
pinocchio::computeJointJacobiansTimeVariation
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...
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::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:325
rnea.hpp
timer.hpp
pinocchio::Index
PINOCCHIO_COMPILER_DIAGNOSTIC_POP typedef std::size_t Index
Definition: multibody/fwd.hpp:22
anymal-simulation.model
model
Definition: anymal-simulation.py:12
pinocchio::SE3Tpl::translation
ConstLinearRef translation() const
Definition: se3-base.hpp:52
pinocchio::LOCAL_WORLD_ALIGNED
@ LOCAL_WORLD_ALIGNED
Definition: multibody/fwd.hpp:52
SMOOTH
#define SMOOTH(s)
Definition: timer.hpp:38
joint-configuration.hpp
reachable-workspace-with-collisions.alpha
float alpha
Definition: reachable-workspace-with-collisions.py:159
pinocchio::integrate
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.
Definition: joint-configuration.hpp:72
autodiff-rnea.v
v
Definition: autodiff-rnea.py:15
isFinite
bool isFinite(const Eigen::MatrixBase< Derived > &x)
Definition: joint-jacobian.cpp:21
pinocchio::getJointJacobian
void getJointJacobian(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, const DataTpl< Scalar, Options, JointCollectionTpl > &data, const JointIndex joint_id, const ReferenceFrame reference_frame, const Eigen::MatrixBase< Matrix6Like > &J)
Computes the Jacobian of a specific joint frame expressed in one of the pinocchio::ReferenceFrame opt...
data.hpp
x
x
pinocchio::forceSet::se3Action
static void se3Action(const SE3Tpl< Scalar, Options > &m, const Eigen::MatrixBase< Mat > &iF, Eigen::MatrixBase< MatRet > const &jF)
SE3 action on a set of forces, represented by a 6xN matrix whose each column represent a spatial forc...
q
q
BOOST_AUTO_TEST_CASE
BOOST_AUTO_TEST_CASE(test_jacobian)
Definition: joint-jacobian.cpp:28
a
Vec3f a
PinocchioTicToc::US
@ US
Definition: timer.hpp:53
pinocchio::DataTpl::J
Matrix6x J
Jacobian of joint placements.
Definition: multibody/data.hpp:360
pinocchio::ModelTpl::Index
pinocchio::Index Index
Definition: multibody/model.hpp:67
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...
pinocchio::computeJointJacobian
void computeJointJacobian(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, DataTpl< Scalar, Options, JointCollectionTpl > &data, const Eigen::MatrixBase< ConfigVectorType > &q, const JointIndex joint_id, const Eigen::MatrixBase< Matrix6Like > &J)
Computes the Jacobian of a specific joint frame expressed in the local frame of the joint and store t...
pinocchio::DataTpl::Matrix6x
Eigen::Matrix< Scalar, 6, Eigen::Dynamic, Options > Matrix6x
The 6d jacobian type (temporary)
Definition: multibody/data.hpp:92
sample-models.hpp
pinocchio::MotionTpl
Definition: context/casadi.hpp:27
jacobian.hpp
pinocchio::ModelTpl
Definition: context/generic.hpp:20
verbose
bool verbose
PinocchioTicToc
Definition: timer.hpp:47
pinocchio
Main pinocchio namespace.
Definition: timings.cpp:27
BOOST_CHECK
#define BOOST_CHECK(check)
Definition: overview-urdf.cpp:34
PinocchioTicToc::tic
void tic()
Definition: timer.hpp:82
pinocchio::LOCAL
@ LOCAL
Definition: multibody/fwd.hpp:50


pinocchio
Author(s):
autogenerated on Sat Jun 22 2024 02:41:47