GCC Code Coverage Report


Directory: ./
File: include/pinocchio/algorithm/impulse-dynamics-derivatives.hxx
Date: 2025-02-12 21:03:38
Exec Total Coverage
Lines: 153 163 93.9%
Branches: 198 472 41.9%

Line Branch Exec Source
1 //
2 // Copyright (c) 2020 CNRS INRIA
3 //
4
5 #ifndef __pinocchio_algorithm_impulse_dynamics_derivatives_hxx__
6 #define __pinocchio_algorithm_impulse_dynamics_derivatives_hxx__
7
8 #include "pinocchio/algorithm/check.hpp"
9 #include "pinocchio/algorithm/rnea-derivatives.hpp"
10 #include "pinocchio/algorithm/kinematics-derivatives.hpp"
11 #include "pinocchio/algorithm/contact-cholesky.hpp"
12 #include "pinocchio/algorithm/constrained-dynamics-derivatives.hxx"
13
14 namespace pinocchio
15 {
16
17 template<
18 typename Scalar,
19 int Options,
20 template<typename, int> class JointCollectionTpl,
21 typename Matrix3xOut1,
22 typename Matrix3xOut2>
23 struct JointImpulseVelocityDerivativesBackwardStep3D
24 : public fusion::JointUnaryVisitorBase<JointImpulseVelocityDerivativesBackwardStep3D<
25 Scalar,
26 Options,
27 JointCollectionTpl,
28 Matrix3xOut1,
29 Matrix3xOut2>>
30 {
31 typedef ModelTpl<Scalar, Options, JointCollectionTpl> Model;
32 typedef DataTpl<Scalar, Options, JointCollectionTpl> Data;
33
34 typedef boost::fusion::vector<
35 const Model &,
36 Data &,
37 const typename Model::JointIndex &,
38 const SE3Tpl<Scalar> &,
39 const ReferenceFrame &,
40 const Scalar &,
41 Matrix3xOut1 &,
42 Matrix3xOut2 &>
43 ArgsType;
44
45 template<typename JointModel>
46 42 static void algo(
47 const JointModelBase<JointModel> & jmodel,
48 const Model & model,
49 Data & data,
50 const typename Model::JointIndex & joint_id,
51 const SE3Tpl<Scalar> & placement,
52 const ReferenceFrame & rf,
53 const Scalar & r_coeff,
54 const Eigen::MatrixBase<Matrix3xOut1> & v_partial_dq,
55 const Eigen::MatrixBase<Matrix3xOut2> & v_partial_dv)
56 {
57 typedef typename Model::JointIndex JointIndex;
58 typedef typename Data::SE3 SE3;
59 typedef typename Data::Motion Motion;
60
61
1/2
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
42 const JointIndex i = jmodel.id();
62 42 const JointIndex parent = model.parents[i];
63
64
1/2
✓ Branch 2 taken 21 times.
✗ Branch 3 not taken.
42 const SE3 oMlast = data.oMi[joint_id] * placement;
65
66 typedef
67 typename SizeDepType<JointModel::NV>::template ColsReturn<typename Data::Matrix6x>::Type
68 ColsBlock;
69
1/2
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
42 ColsBlock Jcols = jmodel.jointCols(data.J);
70
71 typedef
72 typename SizeDepType<JointModel::NV>::template ColsReturn<Matrix3xOut1>::Type ColsBlockOut1;
73 42 Matrix3xOut1 & v_partial_dq_ = PINOCCHIO_EIGEN_CONST_CAST(Matrix3xOut1, v_partial_dq);
74 typedef
75 typename SizeDepType<JointModel::NV>::template ColsReturn<Matrix3xOut2>::Type ColsBlockOut2;
76 42 Matrix3xOut2 & v_partial_dv_ = PINOCCHIO_EIGEN_CONST_CAST(Matrix3xOut2, v_partial_dv);
77
78 // dvec/dv
79
1/2
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
42 const int nv = jmodel.nv();
80
1/2
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
42 Eigen::Matrix<Scalar, 6, JointModel::NV, Options> v_spatial_partial_dv_cols(6, nv);
81
1/2
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
42 ColsBlockOut2 v_partial_dv_cols = jmodel.jointCols(v_partial_dv_);
82
83
1/2
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
42 motionSet::se3ActionInverse(oMlast, Jcols, v_spatial_partial_dv_cols);
84
2/4
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 21 times.
✗ Branch 5 not taken.
42 v_partial_dv_cols = v_spatial_partial_dv_cols.template middleRows<3>(Motion::LINEAR);
85
86 // dvec/dq
87
1/2
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
42 ColsBlockOut1 v_partial_dq_cols = jmodel.jointCols(v_partial_dq_);
88
89 #define FOR_NV() for (Eigen::DenseIndex j = 0; j < nv; ++j)
90 #define GET_LINEAR(vec6) vec6.template segment<3>(Motion::LINEAR)
91 #define GET_ANGULAR(vec6) vec6.template segment<3>(Motion::ANGULAR)
92
93
0/4
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
42 const Scalar factor = Scalar(1) + r_coeff;
94
95
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 3 times.
42 if (parent > 0)
96 {
97
3/8
✓ Branch 3 taken 18 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 18 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 18 times.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
36 const Motion vtmp = oMlast.actInv(factor * data.ov[parent] + data.oa[parent]);
98
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 18 times.
72 FOR_NV()
99
6/12
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 18 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 18 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 18 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 18 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 18 times.
✗ Branch 17 not taken.
72 v_partial_dq_cols.col(j).noalias() =
100
3/6
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 18 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 18 times.
✗ Branch 8 not taken.
36 vtmp.angular().cross(GET_LINEAR(v_spatial_partial_dv_cols.col(j)))
101
3/6
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 18 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 18 times.
✗ Branch 8 not taken.
72 + vtmp.linear().cross(GET_ANGULAR(v_spatial_partial_dv_cols.col(j)));
102 }
103 else
104
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
6 v_partial_dq_cols.setZero();
105
106
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 14 times.
42 if (rf == LOCAL_WORLD_ALIGNED)
107 {
108
3/8
✓ Branch 3 taken 7 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 7 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 7 times.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
14 const Motion vtmp = oMlast.actInv(factor * data.ov[joint_id] + data.oa[joint_id]);
109
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 7 times.
38 FOR_NV()
110
4/8
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 12 times.
✗ Branch 11 not taken.
72 v_partial_dq_cols.col(j) =
111
2/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
24 oMlast.rotation()
112
4/8
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 12 times.
✗ Branch 11 not taken.
72 * (v_partial_dq_cols.col(j) + GET_ANGULAR(v_spatial_partial_dv_cols.col(j)).cross(vtmp.linear()));
113
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 7 times.
38 FOR_NV()
114
5/10
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 12 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 12 times.
✗ Branch 14 not taken.
24 v_partial_dv_cols.col(j) = oMlast.rotation() * v_partial_dv_cols.col(j);
115 }
116
117 #undef FOR_NV
118 #undef GET_LINEAR
119 #undef GET_ANGULAR
120 }
121 };
122
123 template<
124 typename Scalar,
125 int Options,
126 template<typename, int> class JointCollectionTpl,
127 typename Matrix6xOut1,
128 typename Matrix6xOut2>
129 struct JointImpulseVelocityDerivativesBackwardStep6D
130 : public fusion::JointUnaryVisitorBase<JointImpulseVelocityDerivativesBackwardStep6D<
131 Scalar,
132 Options,
133 JointCollectionTpl,
134 Matrix6xOut1,
135 Matrix6xOut2>>
136 {
137 typedef ModelTpl<Scalar, Options, JointCollectionTpl> Model;
138 typedef DataTpl<Scalar, Options, JointCollectionTpl> Data;
139
140 typedef boost::fusion::vector<
141 const Model &,
142 Data &,
143 const typename Model::JointIndex &,
144 const SE3Tpl<Scalar> &,
145 const ReferenceFrame &,
146 const Scalar &,
147 Matrix6xOut1 &,
148 Matrix6xOut2 &>
149 ArgsType;
150
151 template<typename JointModel>
152 42 static void algo(
153 const JointModelBase<JointModel> & jmodel,
154 const Model & model,
155 Data & data,
156 const typename Model::JointIndex & joint_id,
157 const SE3Tpl<Scalar> & placement,
158 const ReferenceFrame & rf,
159 const Scalar & r_coeff,
160 const Eigen::MatrixBase<Matrix6xOut1> & v_partial_dq,
161 const Eigen::MatrixBase<Matrix6xOut2> & v_partial_dv)
162 {
163 typedef typename Model::JointIndex JointIndex;
164 typedef typename Data::SE3 SE3;
165 typedef typename Data::Motion Motion;
166
167
1/2
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
42 const JointIndex i = jmodel.id();
168 42 const JointIndex parent = model.parents[i];
169
1/2
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
42 Motion vtmp; // Temporary variables
170
171
1/2
✓ Branch 2 taken 21 times.
✗ Branch 3 not taken.
42 const SE3 oMlast = data.oMi[joint_id] * placement;
172 42 const Motion & v_last = data.ov[joint_id];
173 42 const Motion & dv_last = data.oa[joint_id];
174
175 typedef
176 typename SizeDepType<JointModel::NV>::template ColsReturn<typename Data::Matrix6x>::Type
177 ColsBlock;
178
1/2
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
42 ColsBlock Jcols = jmodel.jointCols(data.J);
179
180 typedef
181 typename SizeDepType<JointModel::NV>::template ColsReturn<Matrix6xOut1>::Type ColsBlockOut1;
182 42 Matrix6xOut1 & v_partial_dq_ = PINOCCHIO_EIGEN_CONST_CAST(Matrix6xOut1, v_partial_dq);
183 typedef
184 typename SizeDepType<JointModel::NV>::template ColsReturn<Matrix6xOut2>::Type ColsBlockOut2;
185 42 Matrix6xOut2 & v_partial_dv_ = PINOCCHIO_EIGEN_CONST_CAST(Matrix6xOut2, v_partial_dv);
186
187 // dvec/dv
188
1/2
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
42 ColsBlockOut2 v_partial_dv_cols = jmodel.jointCols(v_partial_dv_);
189
190
2/3
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
42 switch (rf)
191 {
192 14 case LOCAL_WORLD_ALIGNED:
193
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
14 details::translateJointJacobian(oMlast, Jcols, v_partial_dv_cols);
194 14 break;
195 28 case LOCAL:
196
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
28 motionSet::se3ActionInverse(oMlast, Jcols, v_partial_dv_cols);
197 28 break;
198 default:
199 assert(false && "This must never happened");
200 }
201
202 // dvec/dq
203
1/2
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
42 ColsBlockOut1 v_partial_dq_cols = jmodel.jointCols(v_partial_dq_);
204
0/4
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
42 const Scalar factor = Scalar(1) + r_coeff;
205
2/3
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
42 switch (rf)
206 {
207 14 case LOCAL_WORLD_ALIGNED:
208
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 1 times.
14 if (parent > 0)
209 {
210
3/8
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 6 times.
✗ Branch 9 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
12 vtmp = factor * (data.ov[parent] - v_last);
211
2/4
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
12 vtmp += data.oa[parent] - dv_last;
212 }
213 else
214 {
215
4/10
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
2 vtmp = -(factor * v_last + dv_last);
216 }
217
5/10
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 7 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 7 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 7 times.
✗ Branch 14 not taken.
14 vtmp.linear() += vtmp.angular().cross(oMlast.translation());
218
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
14 motionSet::motionAction(vtmp, v_partial_dv_cols, v_partial_dq_cols);
219 14 break;
220 28 case LOCAL:
221
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 2 times.
28 if (parent > 0)
222 {
223
4/10
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 12 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 12 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 12 times.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
24 vtmp = oMlast.actInv(factor * data.ov[parent] + data.oa[parent]);
224
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
24 motionSet::motionAction(vtmp, v_partial_dv_cols, v_partial_dq_cols);
225 }
226 28 break;
227 default:
228 assert(false && "This must never happened");
229 }
230 }
231 };
232
233 template<
234 typename Scalar,
235 int Options,
236 template<typename, int> class JointCollectionTpl,
237 class ConstraintModelAllocator,
238 class ConstraintDataAllocator,
239 typename MatrixType1,
240 typename MatrixType2,
241 typename MatrixType3,
242 typename MatrixType4>
243 4 inline void computeImpulseDynamicsDerivatives(
244 const ModelTpl<Scalar, Options, JointCollectionTpl> & model,
245 DataTpl<Scalar, Options, JointCollectionTpl> & data,
246 const std::vector<RigidConstraintModelTpl<Scalar, Options>, ConstraintModelAllocator> &
247 contact_models,
248 std::vector<RigidConstraintDataTpl<Scalar, Options>, ConstraintDataAllocator> & contact_data,
249 const Scalar r_coeff,
250 const ProximalSettingsTpl<Scalar> & settings,
251 const Eigen::MatrixBase<MatrixType1> & dvimpulse_partial_dq,
252 const Eigen::MatrixBase<MatrixType2> & dvimpulse_partial_dv,
253 const Eigen::MatrixBase<MatrixType3> & impulse_partial_dq,
254 const Eigen::MatrixBase<MatrixType4> & impulse_partial_dv)
255 {
256 4 const Eigen::DenseIndex nc = data.contact_chol.constraintDim();
257
258
1/4
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
4 PINOCCHIO_CHECK_INPUT_ARGUMENT(
259 contact_data.size() == contact_models.size(),
260 "contact_data and contact_models do not have the same size");
261
262
1/4
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
4 PINOCCHIO_CHECK_INPUT_ARGUMENT(dvimpulse_partial_dq.cols() == model.nv);
263
1/4
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
4 PINOCCHIO_CHECK_INPUT_ARGUMENT(dvimpulse_partial_dq.rows() == model.nv);
264
265
1/4
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
4 PINOCCHIO_CHECK_INPUT_ARGUMENT(dvimpulse_partial_dv.cols() == model.nv);
266
1/4
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
4 PINOCCHIO_CHECK_INPUT_ARGUMENT(dvimpulse_partial_dv.rows() == model.nv);
267
268
1/4
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
4 PINOCCHIO_CHECK_INPUT_ARGUMENT(impulse_partial_dq.cols() == model.nv);
269
1/4
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
4 PINOCCHIO_CHECK_INPUT_ARGUMENT(impulse_partial_dq.rows() == nc);
270
271
1/4
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
4 PINOCCHIO_CHECK_INPUT_ARGUMENT(impulse_partial_dv.cols() == model.nv);
272
1/4
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
4 PINOCCHIO_CHECK_INPUT_ARGUMENT(impulse_partial_dv.rows() == nc);
273
274
11/41
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 4 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 4 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 4 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 4 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 4 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 4 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✓ Branch 25 taken 4 times.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✓ Branch 28 taken 4 times.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 54 not taken.
✗ Branch 55 not taken.
✗ Branch 58 not taken.
✗ Branch 59 not taken.
4 PINOCCHIO_CHECK_INPUT_ARGUMENT(
275 check_expression_if_real<Scalar>(
276 model.gravity.angular()[0] == Scalar(0) && model.gravity.angular()[1] == Scalar(0)
277 && model.gravity.angular()[2] == Scalar(0)),
278 "The gravity must be a pure force vector, no angular part");
279
280
5/42
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 4 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 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 32 not taken.
✗ Branch 33 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
✗ Branch 54 not taken.
✗ Branch 55 not taken.
4 PINOCCHIO_CHECK_INPUT_ARGUMENT(
281 check_expression_if_real<Scalar>((r_coeff >= Scalar(0)) && (r_coeff <= Scalar(1)))
282 && "coeff of restitution lies between 0 and 1.");
283
3/22
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
4 PINOCCHIO_CHECK_INPUT_ARGUMENT(
284 check_expression_if_real<Scalar>(settings.mu >= (Scalar(0))) && "mu must be positive.");
285
286
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 assert(model.check(data) && "data is not consistent with model.");
287
288 // TODO: User should make sure the internal quantities are reset.
289 4 data.dtau_dq.setZero();
290
291 typedef ModelTpl<Scalar, Options, JointCollectionTpl> Model;
292 typedef DataTpl<Scalar, Options, JointCollectionTpl> Data;
293 typedef typename Data::Force Force;
294
295 typedef RigidConstraintModelTpl<Scalar, Options> RigidConstraintModel;
296 typedef RigidConstraintDataTpl<Scalar, Options> RigidConstraintData;
297
298 typedef typename ModelTpl<Scalar, Options, JointCollectionTpl>::JointIndex JointIndex;
299
300 typedef ComputeConstraintDynamicsDerivativesForwardStep<
301 Scalar, Options, JointCollectionTpl, false>
302 Pass1;
303
2/2
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 4 times.
112 for (JointIndex i = 1; i < (JointIndex)model.njoints; ++i)
304 {
305
1/2
✓ Branch 4 taken 108 times.
✗ Branch 5 not taken.
108 Pass1::run(model.joints[i], data.joints[i], typename Pass1::ArgsType(model, data));
306 }
307
308 4 internal::ContactForceContribution<Scalar>::run(contact_models, data, contact_data);
309
310 typedef ComputeContactDynamicDerivativesBackwardStep<Scalar, Options, JointCollectionTpl, false>
311 Pass2;
312
2/2
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 4 times.
112 for (JointIndex i = (JointIndex)(model.njoints - 1); i > 0; --i)
313 {
314
1/2
✓ Branch 3 taken 108 times.
✗ Branch 4 not taken.
108 Pass2::run(model.joints[i], typename Pass2::ArgsType(model, data));
315 }
316
317 4 Eigen::DenseIndex current_row_sol_id = 0;
318 typedef typename SizeDepType<3>::template RowsReturn<typename Data::MatrixXs>::Type Rows3Block;
319 typedef typename SizeDepType<6>::template RowsReturn<typename Data::MatrixXs>::Type Rows6Block;
320
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 4 times.
10 for (size_t k = 0; k < contact_models.size(); ++k)
321 {
322 6 const RigidConstraintModel & cmodel = contact_models[k];
323
324 6 const typename Model::JointIndex joint1_id = cmodel.joint1_id;
325
326
2/3
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
6 switch (cmodel.type)
327 {
328 3 case CONTACT_6D: {
329 typedef JointImpulseVelocityDerivativesBackwardStep6D<
330 Scalar, Options, JointCollectionTpl, Rows6Block, Rows6Block>
331 Pass3;
332
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 Rows6Block contact_dvc_dq = SizeDepType<6>::middleRows(data.dvc_dq, current_row_sol_id);
333
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 Rows6Block contact_dvc_dv = SizeDepType<6>::middleRows(data.dac_da, current_row_sol_id);
334
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 3 times.
24 for (JointIndex i = joint1_id; i > 0; i = model.parents[i])
335 {
336
1/2
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
21 Pass3::run(
337 21 model.joints[i],
338 42 typename Pass3::ArgsType(
339
1/2
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
21 model, data, joint1_id, cmodel.joint1_placement, cmodel.reference_frame, r_coeff,
340 PINOCCHIO_EIGEN_CONST_CAST(Rows6Block, contact_dvc_dq),
341 PINOCCHIO_EIGEN_CONST_CAST(Rows6Block, contact_dvc_dv)));
342 }
343
344 3 break;
345 }
346 3 case CONTACT_3D: {
347 typedef JointImpulseVelocityDerivativesBackwardStep3D<
348 Scalar, Options, JointCollectionTpl, Rows3Block, Rows3Block>
349 Pass3;
350
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 Rows3Block contact_dvc_dq = SizeDepType<3>::middleRows(data.dvc_dq, current_row_sol_id);
351
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 Rows3Block contact_dvc_dv = SizeDepType<3>::middleRows(data.dac_da, current_row_sol_id);
352
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 3 times.
24 for (JointIndex i = joint1_id; i > 0; i = model.parents[i])
353 {
354
1/2
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
21 Pass3::run(
355 42 model.joints[i], typename Pass3::ArgsType(
356 21 model, data, joint1_id, cmodel.joint1_placement,
357
1/2
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
21 cmodel.reference_frame, r_coeff, contact_dvc_dq, contact_dvc_dv));
358 }
359 3 break;
360 }
361 default:
362 assert(false && "must never happen");
363 break;
364 }
365 6 current_row_sol_id += cmodel.size();
366 }
367
368 4 data.contact_chol.getOperationalSpaceInertiaMatrix(data.osim);
369 4 data.contact_chol.getInverseMassMatrix(data.Minv);
370 // Temporary: dlambda_dtau stores J*Minv
371 4 typename Data::MatrixXs & JMinv = data.dlambda_dtau;
372 4 typename Data::MatrixXs & Jc = data.dac_da;
373
374
2/4
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
4 JMinv.noalias() = Jc * data.Minv;
375
2/4
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
4 data.dvc_dq.noalias() -= JMinv * data.dtau_dq;
376
377 4 MatrixType3 & dic_dq = PINOCCHIO_EIGEN_CONST_CAST(MatrixType3, impulse_partial_dq);
378
3/6
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
4 dic_dq.noalias() = -data.osim * data.dvc_dq; // OUTPUT
379
380 // TODO: Implem sparse.
381
3/6
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
4 data.dtau_dq.noalias() -= Jc.transpose() * impulse_partial_dq;
382
383
3/14
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
4 PINOCCHIO_EIGEN_CONST_CAST(MatrixType4, impulse_partial_dv).noalias() =
384
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 -(Scalar(1) + r_coeff) * data.osim * Jc;
385 ; // OUTPUT
386
387
3/6
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
4 PINOCCHIO_EIGEN_CONST_CAST(MatrixType1, dvimpulse_partial_dq).noalias() =
388 4 -data.Minv * data.dtau_dq; // OUTPUT
389
2/4
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
4 PINOCCHIO_EIGEN_CONST_CAST(MatrixType2, dvimpulse_partial_dv).noalias() =
390
1/2
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 JMinv.transpose() * impulse_partial_dv; // OUTPUT
391
392 // update in world frame a(df/dt) = d(af)/dt + av X af
393
394 4 current_row_sol_id = 0;
395
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 4 times.
10 for (size_t k = 0; k < contact_models.size(); ++k)
396 {
397 6 const RigidConstraintModel & cmodel = contact_models[k];
398 6 const RigidConstraintData & cdata = contact_data[k];
399 6 const typename Model::JointIndex joint1_id = cmodel.joint1_id;
400 6 const int colRef = nv(model.joints[joint1_id]) + idx_v(model.joints[joint1_id]) - 1;
401
2/3
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
6 switch (cmodel.reference_frame)
402 {
403 4 case LOCAL:
404 4 break;
405 2 case LOCAL_WORLD_ALIGNED: {
406 2 const Force & of = cdata.contact_force;
407
2/3
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 switch (cmodel.type)
408 {
409 1 case CONTACT_6D: {
410
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 Rows6Block contact_dvc_dv = SizeDepType<6>::middleRows(data.dac_da, current_row_sol_id);
411
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 Rows6Block contact_dic_dq = SizeDepType<6>::middleRows(dic_dq, current_row_sol_id);
412
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 1 times.
13 for (Eigen::DenseIndex j = colRef; j >= 0; j = data.parents_fromRow[(size_t)j])
413 {
414 typedef typename Rows6Block::ColXpr ColType;
415 typedef typename Rows6Block::ColXpr ColTypeOut;
416
2/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
12 MotionRef<ColType> min(contact_dvc_dv.col(j));
417
2/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
12 ForceRef<ColTypeOut> fout(contact_dic_dq.col(j));
418
6/12
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 12 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 12 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 12 times.
✗ Branch 17 not taken.
12 fout.linear().noalias() += min.angular().cross(of.linear());
419
6/12
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 12 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 12 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 12 times.
✗ Branch 17 not taken.
12 fout.angular().noalias() += min.angular().cross(of.angular());
420 }
421 1 break;
422 }
423 1 case CONTACT_3D: {
424
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 Rows3Block contact_dic_dq = SizeDepType<3>::middleRows(dic_dq, current_row_sol_id);
425
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 1 times.
13 for (Eigen::DenseIndex j = colRef; j >= 0; j = data.parents_fromRow[(size_t)j])
426 {
427 typedef typename Data::Matrix6x::ColXpr ColType;
428
2/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
12 MotionRef<ColType> min(data.J.col(j));
429
6/12
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 12 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 12 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 12 times.
✗ Branch 17 not taken.
12 contact_dic_dq.col(j).noalias() += min.angular().cross(of.linear());
430 }
431 1 break;
432 }
433 default:
434 assert(false && "must never happen");
435 break;
436 }
437 2 break;
438 }
439 default:
440 assert(false && "must never happen");
441 break;
442 }
443 6 current_row_sol_id += cmodel.size();
444 }
445 4 }
446 } // namespace pinocchio
447
448 #endif // ifndef __pinocchio_algorithm_impulse_dynamics_derivatives_hxx__
449