GCC Code Coverage Report


Directory: ./
File: include/pinocchio/algorithm/crba.hxx
Date: 2025-02-12 21:03:38
Exec Total Coverage
Lines: 82 83 98.8%
Branches: 123 255 48.2%

Line Branch Exec Source
1 //
2 // Copyright (c) 2015-2021 CNRS INRIA
3 //
4
5 #ifndef __pinocchio_crba_hxx__
6 #define __pinocchio_crba_hxx__
7
8 #include "pinocchio/multibody/visitor.hpp"
9 #include "pinocchio/spatial/act-on-set.hpp"
10 #include "pinocchio/algorithm/kinematics.hpp"
11 #include "pinocchio/algorithm/check.hpp"
12
13 /// @cond DEV
14
15 namespace pinocchio
16 {
17 namespace impl
18 {
19 template<
20 typename Scalar,
21 int Options,
22 template<typename, int> class JointCollectionTpl,
23 typename ConfigVectorType>
24 struct CrbaWorldConventionForwardStep
25 : public fusion::JointUnaryVisitorBase<
26 CrbaWorldConventionForwardStep<Scalar, Options, JointCollectionTpl, ConfigVectorType>>
27 {
28 typedef ModelTpl<Scalar, Options, JointCollectionTpl> Model;
29 typedef DataTpl<Scalar, Options, JointCollectionTpl> Data;
30
31 typedef boost::fusion::vector<const Model &, Data &, const ConfigVectorType &> ArgsType;
32
33 template<typename JointModel>
34 3800 static void algo(
35 const JointModelBase<JointModel> & jmodel,
36 JointDataBase<typename JointModel::JointDataDerived> & jdata,
37 const Model & model,
38 Data & data,
39 const Eigen::MatrixBase<ConfigVectorType> & q)
40 {
41 typedef typename Model::JointIndex JointIndex;
42
43
1/2
✓ Branch 1 taken 1900 times.
✗ Branch 2 not taken.
3800 const JointIndex & i = jmodel.id();
44
1/2
✓ Branch 3 taken 1900 times.
✗ Branch 4 not taken.
3800 jmodel.calc(jdata.derived(), q.derived());
45
46
6/10
✓ Branch 1 taken 1900 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1816 times.
✓ Branch 5 taken 84 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1816 times.
✓ Branch 9 taken 84 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 1816 times.
✗ Branch 13 not taken.
3800 data.liMi[i] = model.jointPlacements[i] * jdata.M();
47
48 3800 const JointIndex & parent = model.parents[i];
49
2/2
✓ Branch 0 taken 1802 times.
✓ Branch 1 taken 98 times.
3800 if (parent > 0)
50
2/4
✓ Branch 3 taken 1802 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1802 times.
✗ Branch 8 not taken.
3604 data.oMi[i] = data.oMi[parent] * data.liMi[i];
51 else
52
1/2
✓ Branch 3 taken 98 times.
✗ Branch 4 not taken.
196 data.oMi[i] = data.liMi[i];
53
54
4/8
✓ Branch 2 taken 1900 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1900 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1900 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1900 times.
✗ Branch 12 not taken.
3800 jmodel.jointCols(data.J) = data.oMi[i].act(jdata.S());
55
56
2/4
✓ Branch 3 taken 1900 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1900 times.
✗ Branch 8 not taken.
3800 data.oYcrb[i] = data.oMi[i].act(model.inertias[i]);
57 }
58 };
59
60 template<typename Scalar, int Options, template<typename, int> class JointCollectionTpl>
61 struct CrbaWorldConventionBackwardStep
62 : public fusion::JointUnaryVisitorBase<
63 CrbaWorldConventionBackwardStep<Scalar, Options, JointCollectionTpl>>
64 {
65 typedef ModelTpl<Scalar, Options, JointCollectionTpl> Model;
66 typedef DataTpl<Scalar, Options, JointCollectionTpl> Data;
67
68 typedef boost::fusion::vector<const Model &, Data &> ArgsType;
69
70 template<typename JointModel>
71 3800 static void algo(const JointModelBase<JointModel> & jmodel, const Model & model, Data & data)
72 {
73 typedef typename Model::JointIndex JointIndex;
74 typedef
75 typename SizeDepType<JointModel::NV>::template ColsReturn<typename Data::Matrix6x>::Type
76 ColsBlock;
77
1/2
✓ Branch 1 taken 1900 times.
✗ Branch 2 not taken.
3800 const JointIndex & i = jmodel.id();
78
79 // Centroidal momentum map
80
1/2
✓ Branch 1 taken 1900 times.
✗ Branch 2 not taken.
3800 ColsBlock Ag_cols = jmodel.jointCols(data.Ag);
81
1/2
✓ Branch 1 taken 1900 times.
✗ Branch 2 not taken.
3800 ColsBlock J_cols = jmodel.jointCols(data.J);
82
1/2
✓ Branch 2 taken 1900 times.
✗ Branch 3 not taken.
3800 motionSet::inertiaAction(data.oYcrb[i], J_cols, Ag_cols);
83
84 // Joint Space Inertia Matrix
85
6/12
✓ Branch 2 taken 1900 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1900 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1900 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1900 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1900 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 1900 times.
✗ Branch 18 not taken.
3800 data.M.block(jmodel.idx_v(), jmodel.idx_v(), jmodel.nv(), data.nvSubtree[i]).noalias() =
86
4/8
✓ Branch 2 taken 1900 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1900 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1900 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1900 times.
✗ Branch 12 not taken.
3800 J_cols.transpose() * data.Ag.middleCols(jmodel.idx_v(), data.nvSubtree[i]);
87
88 3800 const JointIndex & parent = model.parents[i];
89
1/2
✓ Branch 3 taken 1900 times.
✗ Branch 4 not taken.
3800 data.oYcrb[parent] += data.oYcrb[i];
90 }
91 };
92
93 template<
94 typename Scalar,
95 int Options,
96 template<typename, int> class JointCollectionTpl,
97 typename ConfigVectorType>
98 struct CrbaLocalConventionForwardStep
99 : public fusion::JointUnaryVisitorBase<
100 CrbaLocalConventionForwardStep<Scalar, Options, JointCollectionTpl, ConfigVectorType>>
101 {
102 typedef ModelTpl<Scalar, Options, JointCollectionTpl> Model;
103 typedef DataTpl<Scalar, Options, JointCollectionTpl> Data;
104
105 typedef boost::fusion::vector<const Model &, Data &, const ConfigVectorType &> ArgsType;
106
107 template<typename JointModel>
108 1206 static void algo(
109 const JointModelBase<JointModel> & jmodel,
110 JointDataBase<typename JointModel::JointDataDerived> & jdata,
111 const Model & model,
112 Data & data,
113 const Eigen::MatrixBase<ConfigVectorType> & q)
114 {
115 typedef typename Model::JointIndex JointIndex;
116
117
1/2
✓ Branch 1 taken 603 times.
✗ Branch 2 not taken.
1206 const JointIndex & i = jmodel.id();
118
1/2
✓ Branch 3 taken 603 times.
✗ Branch 4 not taken.
1206 jmodel.calc(jdata.derived(), q.derived());
119
120
6/10
✓ Branch 1 taken 603 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 575 times.
✓ Branch 5 taken 28 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 575 times.
✓ Branch 9 taken 28 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 575 times.
✗ Branch 13 not taken.
1206 data.liMi[i] = model.jointPlacements[i] * jdata.M();
121
1/2
✓ Branch 3 taken 603 times.
✗ Branch 4 not taken.
1206 data.Ycrb[i] = model.inertias[i];
122 }
123 };
124
125 template<typename Scalar, int Options, template<typename, int> class JointCollectionTpl>
126 struct CrbaLocalConventionBackwardStep
127 : public fusion::JointUnaryVisitorBase<
128 CrbaLocalConventionBackwardStep<Scalar, Options, JointCollectionTpl>>
129 {
130 typedef ModelTpl<Scalar, Options, JointCollectionTpl> Model;
131 typedef DataTpl<Scalar, Options, JointCollectionTpl> Data;
132
133 typedef boost::fusion::vector<const Model &, Data &> ArgsType;
134
135 template<typename JointModel>
136 1206 static void algo(
137 const JointModelBase<JointModel> & jmodel,
138 JointDataBase<typename JointModel::JointDataDerived> & jdata,
139 const Model & model,
140 Data & data)
141 {
142 /*
143 * F[1:6,i] = Y*S
144 * M[i,SUBTREE] = S'*F[1:6,SUBTREE]
145 * if li>0
146 * Yli += liXi Yi
147 * F[1:6,SUBTREE] = liXi F[1:6,SUBTREE]
148 */
149
150 typedef typename Model::JointIndex JointIndex;
151 typedef typename Data::Matrix6x::ColsBlockXpr Block;
152
1/2
✓ Branch 1 taken 603 times.
✗ Branch 2 not taken.
1206 const JointIndex & i = jmodel.id();
153
154 /* F[1:6,i] = Y*S */
155 // data.Fcrb[i].block<6,JointModel::NV>(0,jmodel.idx_v()) = data.Ycrb[i] * jdata.S();
156
4/8
✓ Branch 1 taken 603 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 603 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 603 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 603 times.
✗ Branch 13 not taken.
1206 jmodel.jointCols(data.Fcrb[i]) = data.Ycrb[i] * jdata.S();
157
158 /* M[i,SUBTREE] = S'*F[1:6,SUBTREE] */
159
8/15
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 602 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 603 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 603 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 603 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 603 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 603 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
1206 data.M.block(jmodel.idx_v(), jmodel.idx_v(), jmodel.nv(), data.nvSubtree[i]).noalias() =
160
6/11
✓ Branch 3 taken 603 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 603 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 603 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 576 times.
✓ Branch 13 taken 27 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 575 times.
✗ Branch 16 not taken.
1206 jdata.S().transpose() * data.Fcrb[i].middleCols(jmodel.idx_v(), data.nvSubtree[i]);
161
162 1206 const JointIndex & parent = model.parents[i];
163
2/2
✓ Branch 0 taken 579 times.
✓ Branch 1 taken 24 times.
1206 if (parent > 0)
164 {
165 /* Yli += liXi Yi */
166
2/4
✓ Branch 3 taken 579 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 579 times.
✗ Branch 8 not taken.
1158 data.Ycrb[parent] += data.liMi[i].act(data.Ycrb[i]);
167
168 /* F[1:6,SUBTREE] = liXi F[1:6,SUBTREE] */
169
2/4
✓ Branch 3 taken 579 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 579 times.
✗ Branch 7 not taken.
1158 Block jF = data.Fcrb[parent].middleCols(jmodel.idx_v(), data.nvSubtree[i]);
170
2/4
✓ Branch 3 taken 579 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 579 times.
✗ Branch 7 not taken.
1158 Block iF = data.Fcrb[i].middleCols(jmodel.idx_v(), data.nvSubtree[i]);
171
1/2
✓ Branch 2 taken 579 times.
✗ Branch 3 not taken.
1158 forceSet::se3Action(data.liMi[i], iF, jF);
172 }
173 }
174 };
175
176 template<
177 typename Scalar,
178 int Options,
179 template<typename, int> class JointCollectionTpl,
180 typename ConfigVectorType>
181 24 const typename DataTpl<Scalar, Options, JointCollectionTpl>::MatrixXs & crbaLocalConvention(
182 const ModelTpl<Scalar, Options, JointCollectionTpl> & model,
183 DataTpl<Scalar, Options, JointCollectionTpl> & data,
184 const Eigen::MatrixBase<ConfigVectorType> & q)
185 {
186
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 assert(model.check(data) && "data is not consistent with model.");
187
1/24
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
24 PINOCCHIO_CHECK_ARGUMENT_SIZE(
188 q.size(), model.nq, "The configuration vector is not of right size");
189
190 typedef typename ModelTpl<Scalar, Options, JointCollectionTpl>::JointIndex JointIndex;
191
192 typedef CrbaLocalConventionForwardStep<Scalar, Options, JointCollectionTpl, ConfigVectorType>
193 Pass1;
194
2/2
✓ Branch 0 taken 603 times.
✓ Branch 1 taken 24 times.
627 for (JointIndex i = 1; i < (JointIndex)(model.njoints); ++i)
195 {
196
1/2
✓ Branch 1 taken 603 times.
✗ Branch 2 not taken.
603 Pass1::run(
197 1206 model.joints[i], data.joints[i], typename Pass1::ArgsType(model, data, q.derived()));
198 }
199
200 typedef CrbaLocalConventionBackwardStep<Scalar, Options, JointCollectionTpl> Pass2;
201
2/2
✓ Branch 0 taken 603 times.
✓ Branch 1 taken 24 times.
627 for (JointIndex i = (JointIndex)(model.njoints - 1); i > 0; --i)
202 {
203
1/2
✓ Branch 4 taken 603 times.
✗ Branch 5 not taken.
603 Pass2::run(model.joints[i], data.joints[i], typename Pass2::ArgsType(model, data));
204 }
205
206 // Add the armature contribution
207
1/2
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
24 data.M.diagonal() += model.armature;
208
209 24 return data.M;
210 }
211
212 template<
213 typename Scalar,
214 int Options,
215 template<typename, int> class JointCollectionTpl,
216 typename ConfigVectorType>
217 109 const typename DataTpl<Scalar, Options, JointCollectionTpl>::MatrixXs & crbaWorldConvention(
218 const ModelTpl<Scalar, Options, JointCollectionTpl> & model,
219 DataTpl<Scalar, Options, JointCollectionTpl> & data,
220 const Eigen::MatrixBase<ConfigVectorType> & q)
221 {
222
2/4
✓ Branch 1 taken 98 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 98 times.
✗ Branch 4 not taken.
109 assert(model.check(data) && "data is not consistent with model.");
223
1/24
✗ Branch 1 not taken.
✓ Branch 2 taken 98 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
109 PINOCCHIO_CHECK_ARGUMENT_SIZE(
224 q.size(), model.nq, "The configuration vector is not of right size");
225
226 typedef typename ModelTpl<Scalar, Options, JointCollectionTpl>::JointIndex JointIndex;
227
228
1/2
✓ Branch 2 taken 98 times.
✗ Branch 3 not taken.
109 data.oYcrb[0].setZero();
229 typedef CrbaWorldConventionForwardStep<Scalar, Options, JointCollectionTpl, ConfigVectorType>
230 Pass1;
231
2/2
✓ Branch 0 taken 1900 times.
✓ Branch 1 taken 98 times.
2072 for (JointIndex i = 1; i < (JointIndex)(model.njoints); ++i)
232 {
233
1/2
✓ Branch 1 taken 1900 times.
✗ Branch 2 not taken.
1963 Pass1::run(
234
1/2
✓ Branch 2 taken 1900 times.
✗ Branch 3 not taken.
3926 model.joints[i], data.joints[i], typename Pass1::ArgsType(model, data, q.derived()));
235 }
236
237 typedef CrbaWorldConventionBackwardStep<Scalar, Options, JointCollectionTpl> Pass2;
238
2/2
✓ Branch 0 taken 1900 times.
✓ Branch 1 taken 98 times.
2072 for (JointIndex i = (JointIndex)(model.njoints - 1); i > 0; --i)
239 {
240
2/4
✓ Branch 1 taken 1900 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1900 times.
✗ Branch 6 not taken.
1963 Pass2::run(model.joints[i], typename Pass2::ArgsType(model, data));
241 }
242
243 // Add the armature contribution
244
2/4
✓ Branch 1 taken 98 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 98 times.
✗ Branch 5 not taken.
109 data.M.diagonal() += model.armature;
245
246 // Retrieve the Centroidal Momemtum map
247 typedef DataTpl<Scalar, Options, JointCollectionTpl> Data;
248 typedef typename Data::Force Force;
249 typedef Eigen::Block<typename Data::Matrix6x, 3, -1> Block3x;
250
251
1/2
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
109 data.mass[0] = data.oYcrb[0].mass();
252
1/2
✓ Branch 4 taken 98 times.
✗ Branch 5 not taken.
109 data.com[0] = data.oYcrb[0].lever();
253
254
1/2
✓ Branch 1 taken 98 times.
✗ Branch 2 not taken.
109 const Block3x Ag_lin = data.Ag.template middleRows<3>(Force::LINEAR);
255
1/2
✓ Branch 1 taken 98 times.
✗ Branch 2 not taken.
109 Block3x Ag_ang = data.Ag.template middleRows<3>(Force::ANGULAR);
256
2/2
✓ Branch 0 taken 2276 times.
✓ Branch 1 taken 98 times.
2485 for (long i = 0; i < model.nv; ++i)
257
4/8
✓ Branch 1 taken 2276 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 2276 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 2276 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 2276 times.
✗ Branch 12 not taken.
2376 Ag_ang.col(i) += Ag_lin.col(i).cross(data.com[0]);
258
259 109 return data.M;
260 }
261 } // namespace impl
262 // --- CHECKER ---------------------------------------------------------------
263 // --- CHECKER ---------------------------------------------------------------
264 // --- CHECKER ---------------------------------------------------------------
265
266 namespace internal
267 {
268 template<typename Scalar, int Options, template<typename, int> class JointCollectionTpl>
269 6495 inline bool isDescendant(
270 const ModelTpl<Scalar, Options, JointCollectionTpl> & model,
271 const typename ModelTpl<Scalar, Options, JointCollectionTpl>::JointIndex j,
272 const typename ModelTpl<Scalar, Options, JointCollectionTpl>::JointIndex root)
273 {
274 typedef ModelTpl<Scalar, Options, JointCollectionTpl> Model;
275 typedef typename Model::JointIndex JointIndex;
276
277
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 6471 times.
6495 if (j >= (JointIndex)model.njoints)
278 24 return false;
279
2/2
✓ Branch 0 taken 774 times.
✓ Branch 1 taken 5697 times.
6471 if (j == 0)
280 774 return root == 0;
281
4/4
✓ Branch 0 taken 5364 times.
✓ Branch 1 taken 333 times.
✓ Branch 4 taken 1044 times.
✓ Branch 5 taken 4320 times.
5697 return (j == root) || isDescendant(model, model.parents[j], root);
282 }
283 } // namespace internal
284
285 template<typename Scalar, int Options, template<typename, int> class JointCollectionTpl>
286 inline bool
287 3 CRBAChecker::checkModel_impl(const ModelTpl<Scalar, Options, JointCollectionTpl> & model) const
288 {
289 typedef ModelTpl<Scalar, Options, JointCollectionTpl> Model;
290 typedef typename Model::JointIndex JointIndex;
291
292 // For CRBA, the tree must be "compact", i.e. all descendants of a node i are stored
293 // immediately after i in the "parents" map, i.e. forall joint i, the interval i+1..n-1
294 // can be separated in two intervals [i+1..k] and [k+1..n-1], where any [i+1..k] is a descendant
295 // of i and none of [k+1..n-1] is a descendant of i.
296
2/2
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 3 times.
81 for (JointIndex i = 1; i < (JointIndex)(model.njoints - 1);
297 ++i) // no need to check joints 0 and N-1
298 {
299 78 JointIndex k = i + 1;
300
2/2
✓ Branch 1 taken 333 times.
✓ Branch 2 taken 78 times.
411 while (internal::isDescendant(model, k, i))
301 333 ++k;
302
2/2
✓ Branch 0 taken 720 times.
✓ Branch 1 taken 78 times.
798 for (; int(k) < model.njoints; ++k)
303
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 720 times.
720 if (internal::isDescendant(model, k, i))
304 return false;
305 }
306 3 return true;
307 }
308
309 template<
310 typename Scalar,
311 int Options,
312 template<typename, int> class JointCollectionTpl,
313 typename ConfigVectorType>
314 133 const typename DataTpl<Scalar, Options, JointCollectionTpl>::MatrixXs & crba(
315 const ModelTpl<Scalar, Options, JointCollectionTpl> & model,
316 DataTpl<Scalar, Options, JointCollectionTpl> & data,
317 const Eigen::MatrixBase<ConfigVectorType> & q,
318 const Convention convention)
319 {
320
2/3
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 98 times.
✗ Branch 2 not taken.
133 switch (convention)
321 {
322 24 case Convention::LOCAL:
323
1/2
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
24 return ::pinocchio::impl::crbaLocalConvention(model, data, make_const_ref(q));
324 109 case Convention::WORLD:
325
1/2
✓ Branch 2 taken 98 times.
✗ Branch 3 not taken.
109 return ::pinocchio::impl::crbaWorldConvention(model, data, make_const_ref(q));
326 }
327 }
328
329 } // namespace pinocchio
330
331 /// @endcond
332
333 #endif // ifndef __pinocchio_crba_hxx__
334