@@ -215,6 +215,159 @@ namespace pinocchio
215215 return data.tau ;
216216 }
217217
218+ template <
219+ typename Scalar,
220+ int Options,
221+ template <typename , int >
222+ class JointCollectionTpl ,
223+ typename ConfigVectorType,
224+ typename TangentVectorType1,
225+ typename TangentVectorType2,
226+ typename TangentVectorType3>
227+ struct PassivityRneaForwardStep
228+ : public fusion::JointUnaryVisitorBase<PassivityRneaForwardStep<
229+ Scalar,
230+ Options,
231+ JointCollectionTpl,
232+ ConfigVectorType,
233+ TangentVectorType1,
234+ TangentVectorType2,
235+ TangentVectorType3>>
236+ {
237+ typedef ModelTpl<Scalar, Options, JointCollectionTpl> Model;
238+ typedef DataTpl<Scalar, Options, JointCollectionTpl> Data;
239+ typedef ForceTpl<Scalar, Options> Force;
240+
241+ typedef boost::fusion::vector<
242+ const Model &,
243+ Data &,
244+ const ConfigVectorType &,
245+ const TangentVectorType1 &,
246+ const TangentVectorType2 &,
247+ const TangentVectorType3 &>
248+ ArgsType;
249+
250+ template <typename JointModel>
251+ static void algo (
252+ const JointModelBase<JointModel> & jmodel,
253+ JointDataBase<typename JointModel::JointDataDerived> & jdata,
254+ const Model & model,
255+ Data & data,
256+ const Eigen::MatrixBase<ConfigVectorType> & q,
257+ const Eigen::MatrixBase<TangentVectorType1> & v,
258+ const Eigen::MatrixBase<TangentVectorType2> & v_r,
259+ const Eigen::MatrixBase<TangentVectorType3> & a_r)
260+ {
261+ typedef typename Model::JointIndex JointIndex;
262+
263+ const JointIndex i = jmodel.id ();
264+ const JointIndex parent = model.parents [i];
265+
266+ jmodel.calc (jdata.derived (), q.derived (), v.derived ());
267+ data.v [i] = jdata.v ();
268+
269+ jmodel.calc (jdata.derived (), q.derived (), v_r.derived ());
270+ data.v_r [i] = jdata.v ();
271+
272+ data.liMi [i] = model.jointPlacements [i] * jdata.M ();
273+
274+ if (parent > 0 ) {
275+ data.v [i] += data.liMi [i].actInv (data.v [parent]);
276+ data.v_r [i] += data.liMi [i].actInv (data.v_r [parent]);
277+ }
278+
279+ data.a_gf [i] = jdata.c () + (data.v [i] ^ jdata.v ());
280+ data.a_gf [i] += jdata.S () * jmodel.jointVelocitySelector (a_r);
281+ data.a_gf [i] += data.liMi [i].actInv (data.a_gf [parent]);
282+ //
283+ // data.f[i] = model.inertias[i]*data.a_gf[i];// + model.inertias[i].vxiv(data.v[i]);
284+ // // -f_ext data.h[i] = model.inertias[i]*data.v[i];
285+
286+ // model.inertias[i].__mult__(data.v_r[i], data.h[i]); // option 1
287+ data.B [i] = model.inertias [i].variation (Scalar (0.5 ) * data.v [i]);
288+ model.inertias [i].__mult__ (data.v [i], data.h [i]);
289+ addForceCrossMatrix (Scalar (0.5 ) * data.h [i], data.B [i]); // option 3 (Christoffel-consistent factorization)
290+
291+ model.inertias [i].__mult__ (data.a_gf [i], data.f [i]);
292+ // data.f[i] += data.v[i].cross(data.h[i]); // option 1
293+ data.f [i] += Force (data.B [i] * data.v_r [i].toVector ()); // option 3 (Christoffel-consistent factorization)
294+
295+ // data.h[i].motionAction(data.v[i],data.f[i]);
296+ // data.f[i] = model.inertias[i].vxiv(data.v[i]);
297+ // data.f[i].setZero();
298+ }
299+
300+ template <typename ForceDerived, typename M6>
301+ static void
302+ addForceCrossMatrix (const ForceDense<ForceDerived> & f, const Eigen::MatrixBase<M6> & mout)
303+ {
304+ M6 & mout_ = PINOCCHIO_EIGEN_CONST_CAST (M6, mout);
305+ addSkew (
306+ -f.linear (), mout_.template block <3 , 3 >(ForceDerived::LINEAR, ForceDerived::ANGULAR));
307+ addSkew (
308+ -f.linear (), mout_.template block <3 , 3 >(ForceDerived::ANGULAR, ForceDerived::LINEAR));
309+ addSkew (
310+ -f.angular (), mout_.template block <3 , 3 >(ForceDerived::ANGULAR, ForceDerived::ANGULAR));
311+ }
312+ };
313+
314+ template <
315+ typename Scalar,
316+ int Options,
317+ template <typename , int >
318+ class JointCollectionTpl ,
319+ typename ConfigVectorType,
320+ typename TangentVectorType1,
321+ typename TangentVectorType2,
322+ typename TangentVectorType3>
323+ const typename DataTpl<Scalar, Options, JointCollectionTpl>::TangentVectorType & passivityRNEA (
324+ const ModelTpl<Scalar, Options, JointCollectionTpl> & model,
325+ DataTpl<Scalar, Options, JointCollectionTpl> & data,
326+ const Eigen::MatrixBase<ConfigVectorType> & q,
327+ const Eigen::MatrixBase<TangentVectorType1> & v,
328+ const Eigen::MatrixBase<TangentVectorType2> & v_r,
329+ const Eigen::MatrixBase<TangentVectorType3> & a_r)
330+ {
331+ assert (model.check (data) && " data is not consistent with model." );
332+ PINOCCHIO_CHECK_ARGUMENT_SIZE (
333+ q.size (), model.nq , " The configuration vector is not of right size" );
334+ PINOCCHIO_CHECK_ARGUMENT_SIZE (
335+ v.size (), model.nv , " The velocity vector is not of right size" );
336+ PINOCCHIO_CHECK_ARGUMENT_SIZE (
337+ v_r.size (), model.nv , " The auxiliary velocity vector is not of right size" );
338+ PINOCCHIO_CHECK_ARGUMENT_SIZE (
339+ a_r.size (), model.nv , " The auxiliary acceleration vector is not of right size" );
340+
341+ typedef ModelTpl<Scalar, Options, JointCollectionTpl> Model;
342+ typedef typename Model::JointIndex JointIndex;
343+
344+ data.v [0 ].setZero ();
345+ data.v_r [0 ].setZero ();
346+ data.a_gf [0 ] = -model.gravity ;
347+
348+ typedef PassivityRneaForwardStep<
349+ Scalar, Options, JointCollectionTpl, ConfigVectorType, TangentVectorType1,
350+ TangentVectorType2, TangentVectorType3>
351+ Pass1;
352+ typename Pass1::ArgsType arg1 (model, data, q.derived (), v.derived (), v_r.derived (), a_r.derived ());
353+ for (JointIndex i = 1 ; i < (JointIndex)model.njoints ; ++i)
354+ {
355+ Pass1::run (model.joints [i], data.joints [i], arg1);
356+ }
357+
358+ typedef RneaBackwardStep<Scalar, Options, JointCollectionTpl> Pass2;
359+ typename Pass2::ArgsType arg2 (model, data);
360+ for (JointIndex i = (JointIndex)model.njoints - 1 ; i > 0 ; --i)
361+ {
362+ Pass2::run (model.joints [i], data.joints [i], arg2);
363+ }
364+
365+ // Add rotorinertia contribution
366+ data.tau .array () += model.armature .array () * a_r.array (); // Check if there is memory allocation
367+
368+ return data.tau ;
369+ }
370+
218371 template <
219372 typename Scalar,
220373 int Options,
@@ -786,6 +939,26 @@ namespace pinocchio
786939 return impl::rnea (model, data, make_const_ref (q), make_const_ref (v), make_const_ref (a), fext);
787940 }
788941
942+ template <
943+ typename Scalar,
944+ int Options,
945+ template <typename , int >
946+ class JointCollectionTpl ,
947+ typename ConfigVectorType,
948+ typename TangentVectorType1,
949+ typename TangentVectorType2,
950+ typename TangentVectorType3>
951+ const typename DataTpl<Scalar, Options, JointCollectionTpl>::TangentVectorType & passivityRNEA (
952+ const ModelTpl<Scalar, Options, JointCollectionTpl> & model,
953+ DataTpl<Scalar, Options, JointCollectionTpl> & data,
954+ const Eigen::MatrixBase<ConfigVectorType> & q,
955+ const Eigen::MatrixBase<TangentVectorType1> & v,
956+ const Eigen::MatrixBase<TangentVectorType2> & v_r,
957+ const Eigen::MatrixBase<TangentVectorType3> & a_r)
958+ {
959+ return impl::passivityRNEA (model, data, make_const_ref (q), make_const_ref (v), make_const_ref (v_r), make_const_ref (a_r));
960+ }
961+
789962 template <
790963 typename Scalar,
791964 int Options,
0 commit comments