Skip to content

Commit d78d951

Browse files
authored
Merge pull request #1311 from jcarpent/topic/coriolis
Add getCoriolisMatrix
2 parents 1b10650 + 0ca05e2 commit d78d951

File tree

12 files changed

+223
-99
lines changed

12 files changed

+223
-99
lines changed

bindings/python/algorithm/expose-rnea.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,15 @@ namespace pinocchio
8282
"\tq: the joint configuration vector (size model.nq)\n"
8383
"\tv: the joint velocity vector (size model.nv)\n",
8484
bp::return_value_policy<bp::return_by_value>());
85+
86+
bp::def("getCoriolisMatrix",
87+
&getCoriolisMatrix<double,0,JointCollectionDefaultTpl>,
88+
bp::args("model","Data"),
89+
"Retrives the Coriolis Matrix C(q,v) of the Lagrangian dynamics after calling one of the derivative algorithms, store the result in data.C and return it.\n\n"
90+
"Parameters:\n"
91+
"\tmodel: model of the kinematic tree\n"
92+
"\tdata: data related to the model\n",
93+
bp::return_value_policy<bp::return_by_value>());
8594

8695
}
8796

cmake

src/algorithm/aba-derivatives.hxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ namespace pinocchio
5555
ov = data.oMi[i].act(data.v[i]);
5656
data.a_gf[i] = jdata.c() + (data.v[i] ^ jdata.v());
5757
data.Yaba[i] = model.inertias[i].matrix();
58-
data.oYcrb[i] = data.oMi[i].act(model.inertias[i]);
58+
data.oYcrb[i] = data.oinertias[i] = data.oMi[i].act(model.inertias[i]);
5959

6060
data.oh[i] = data.oYcrb[i] * ov;
6161
data.of[i] = ov.cross(data.oh[i]);

src/algorithm/rnea-derivatives.hxx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Copyright (c) 2017-2019 CNRS INRIA
2+
// Copyright (c) 2017-2020 CNRS INRIA
33
//
44

55
#ifndef __pinocchio_rnea_derivatives_hxx__
@@ -46,7 +46,7 @@ namespace pinocchio
4646
else
4747
data.oMi[i] = data.liMi[i];
4848

49-
data.oYcrb[i] = data.oMi[i].act(model.inertias[i]);
49+
data.oYcrb[i] = data.oinertias[i] = data.oMi[i].act(model.inertias[i]);
5050
data.of[i] = data.oYcrb[i] * minus_gravity;
5151

5252
typedef typename SizeDepType<JointModel::NV>::template ColsReturn<typename Data::Matrix6x>::Type ColsBlock;
@@ -242,7 +242,7 @@ namespace pinocchio
242242
data.a[i] += data.liMi[i].actInv(data.a[parent]);
243243
}
244244

245-
data.oYcrb[i] = data.oMi[i].act(model.inertias[i]);
245+
data.oYcrb[i] = data.oinertias[i] = data.oMi[i].act(model.inertias[i]);
246246
ov = data.oMi[i].act(data.v[i]);
247247
oa = data.oMi[i].act(data.a[i]);
248248
oa_gf = oa - model.gravity; // add gravity contribution

src/algorithm/rnea.hpp

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
//
2-
// Copyright (c) 2015-2019 CNRS INRIA
2+
// Copyright (c) 2015-2020 CNRS INRIA
33
//
44

5-
#ifndef __pinocchio_rnea_hpp__
6-
#define __pinocchio_rnea_hpp__
5+
#ifndef __pinocchio_algorithm_rnea_hpp__
6+
#define __pinocchio_algorithm_rnea_hpp__
77

88
#include "pinocchio/multibody/model.hpp"
99
#include "pinocchio/multibody/data.hpp"
@@ -154,9 +154,28 @@ namespace pinocchio
154154
const Eigen::MatrixBase<ConfigVectorType> & q,
155155
const Eigen::MatrixBase<TangentVectorType> & v);
156156

157+
///
158+
/// \brief Retrives the Coriolis Matrix \f$ C(q,\dot{q}) \f$ of the Lagrangian dynamics:
159+
/// <CENTER> \f$ \begin{eqnarray} M \ddot{q} + C(q, \dot{q})\dot{q} + g(q) = \tau \end{eqnarray} \f$ </CENTER> <BR>
160+
/// after a call to the dynamics derivatives.
161+
///
162+
/// \note In the previous equation, \f$ c(q, \dot{q}) = C(q, \dot{q})\dot{q} \f$.
163+
///
164+
/// \tparam JointCollection Collection of Joint types.
165+
///
166+
/// \param[in] model The model structure of the rigid body system.
167+
/// \param[in] data The data structure of the rigid body system.
168+
///
169+
/// \return The Coriolis matrix stored in data.C.
170+
///
171+
template<typename Scalar, int Options, template<typename,int> class JointCollectionTpl>
172+
inline const typename DataTpl<Scalar,Options,JointCollectionTpl>::MatrixXs &
173+
getCoriolisMatrix(const ModelTpl<Scalar,Options,JointCollectionTpl> & model,
174+
DataTpl<Scalar,Options,JointCollectionTpl> & data);
175+
157176
} // namespace pinocchio
158177

159178
/* --- Details -------------------------------------------------------------------- */
160179
#include "pinocchio/algorithm/rnea.hxx"
161180

162-
#endif // ifndef __pinocchio_rnea_hpp__
181+
#endif // ifndef __pinocchio_algorithm_rnea_hpp__

src/algorithm/rnea.hxx

Lines changed: 81 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
//
2-
// Copyright (c) 2015-2019 CNRS INRIA
2+
// Copyright (c) 2015-2020 CNRS INRIA
33
//
44

5-
#ifndef __pinocchio_rnea_hxx__
6-
#define __pinocchio_rnea_hxx__
5+
#ifndef __pinocchio_algorithm_rnea_hxx__
6+
#define __pinocchio_algorithm_rnea_hxx__
77

88
/// @cond DEV
99

@@ -473,8 +473,8 @@ namespace pinocchio
473473
{
474474
typedef typename Model::JointIndex JointIndex;
475475

476-
const JointIndex & i = jmodel.id();
477-
const JointIndex & parent = model.parents[i];
476+
const JointIndex i = jmodel.id();
477+
const JointIndex parent = model.parents[i];
478478
typename Data::RowMatrix6 & M6tmpR = data.M6tmpR;
479479

480480
typedef typename SizeDepType<JointModel::NV>::template ColsReturn<typename Data::Matrix6x>::Type ColsBlock;
@@ -543,9 +543,84 @@ namespace pinocchio
543543

544544
return data.C;
545545
}
546+
547+
template<typename Scalar, int Options, template<typename,int> class JointCollectionTpl>
548+
struct GetCoriolisMatrixBackwardStep
549+
: public fusion::JointUnaryVisitorBase< GetCoriolisMatrixBackwardStep<Scalar,Options,JointCollectionTpl> >
550+
{
551+
typedef ModelTpl<Scalar,Options,JointCollectionTpl> Model;
552+
typedef DataTpl<Scalar,Options,JointCollectionTpl> Data;
553+
554+
typedef boost::fusion::vector<const Model &,
555+
Data &
556+
> ArgsType;
557+
558+
template<typename JointModel>
559+
static void algo(const JointModelBase<JointModel> & jmodel,
560+
const Model & model,
561+
Data & data)
562+
{
563+
typedef typename Model::JointIndex JointIndex;
564+
typedef CoriolisMatrixBackwardStep<Scalar,Options,JointCollectionTpl> EquivalentPass;
565+
566+
const JointIndex i = jmodel.id();
567+
const JointIndex parent = model.parents[i];
568+
typename Data::RowMatrix6 & M6tmpR = data.M6tmpR;
569+
570+
typedef typename SizeDepType<JointModel::NV>::template ColsReturn<typename Data::Matrix6x>::Type ColsBlock;
571+
ColsBlock dJ_cols = jmodel.jointCols(data.dJ);
572+
ColsBlock J_cols = jmodel.jointCols(data.J);
573+
typename Data::Matrix6x & dFdv = data.Fcrb[0];
574+
ColsBlock dFdv_cols = jmodel.jointCols(dFdv);
575+
576+
motionSet::inertiaAction(data.oYcrb[i],dJ_cols,dFdv_cols);
577+
dFdv_cols.noalias() += data.vxI[i] * J_cols;
578+
579+
data.C.block(jmodel.idx_v(),jmodel.idx_v(),jmodel.nv(),data.nvSubtree[i]).noalias()
580+
= J_cols.transpose() * dFdv.middleCols(jmodel.idx_v(),data.nvSubtree[i]);
581+
582+
EquivalentPass::lhsInertiaMult(data.oYcrb[i],J_cols.transpose(),M6tmpR.topRows(jmodel.nv()));
583+
for(int j = data.parents_fromRow[(JointIndex)jmodel.idx_v()];j >= 0; j = data.parents_fromRow[(JointIndex)j])
584+
data.C.middleRows(jmodel.idx_v(),jmodel.nv()).col(j).noalias() = M6tmpR.topRows(jmodel.nv()) * data.dJ.col(j);
585+
586+
M6tmpR.topRows(jmodel.nv()).noalias() = J_cols.transpose() * data.vxI[i];
587+
for(int j = data.parents_fromRow[(JointIndex)jmodel.idx_v()];j >= 0; j = data.parents_fromRow[(JointIndex)j])
588+
data.C.middleRows(jmodel.idx_v(),jmodel.nv()).col(j).noalias() += M6tmpR.topRows(jmodel.nv()) * data.J.col(j);
589+
590+
if(parent>0)
591+
{
592+
data.vxI[parent] += data.vxI[i];
593+
}
594+
595+
}
596+
};
597+
598+
template<typename Scalar, int Options, template<typename,int> class JointCollectionTpl>
599+
inline const typename DataTpl<Scalar,Options,JointCollectionTpl>::MatrixXs &
600+
getCoriolisMatrix(const ModelTpl<Scalar,Options,JointCollectionTpl> & model,
601+
DataTpl<Scalar,Options,JointCollectionTpl> & data)
602+
{
603+
assert(model.check(data) && "data is not consistent with model.");
604+
605+
typedef ModelTpl<Scalar,Options,JointCollectionTpl> Model;
606+
typedef typename Model::JointIndex JointIndex;
607+
608+
for(JointIndex i=1; i<(JointIndex)model.njoints; ++i)
609+
{
610+
Inertia::vxi(data.ov[i],data.oinertias[i],data.vxI[i]);
611+
}
612+
613+
typedef GetCoriolisMatrixBackwardStep<Scalar,Options,JointCollectionTpl> Pass2;
614+
for(JointIndex i=(JointIndex)(model.njoints-1); i>0; --i)
615+
{
616+
Pass2::run(model.joints[i],typename Pass2::ArgsType(model,data));
617+
}
618+
619+
return data.C;
620+
}
546621

547622
} // namespace pinocchio
548623

549624
/// @endcond
550625

551-
#endif // ifndef __pinocchio_rnea_hxx__
626+
#endif // ifndef __pinocchio_algorithm_rnea_hxx__

src/multibody/data.hpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,10 +183,13 @@ namespace pinocchio
183183
/// \brief Left variation of the inertia matrix
184184
PINOCCHIO_ALIGNED_STD_VECTOR(Matrix6) Ivx;
185185

186-
/// \brief Inertia quantities expressed in the world frame
186+
/// \brief Rigid Body Inertia supported by the joint expressed in the world frame
187+
PINOCCHIO_ALIGNED_STD_VECTOR(Inertia) oinertias;
188+
189+
/// \brief Composite Rigid Body Inertia expressed in the world frame
187190
PINOCCHIO_ALIGNED_STD_VECTOR(Inertia) oYcrb;
188191

189-
/// \brief Time variation of the inertia quantities expressed in the world frame
192+
/// \brief Time variation of Composite Rigid Body Inertia expressed in the world frame
190193
PINOCCHIO_ALIGNED_STD_VECTOR(Matrix6) doYcrb;
191194

192195
/// \brief Temporary for derivative algorithms

src/multibody/data.hxx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ namespace pinocchio
5353
, IS(MatrixXs::Zero(6,model.nv))
5454
, vxI((std::size_t)model.njoints,Inertia::Matrix6::Zero())
5555
, Ivx((std::size_t)model.njoints,Inertia::Matrix6::Zero())
56+
, oinertias((std::size_t)model.njoints,Inertia::Zero())
5657
, oYcrb((std::size_t)model.njoints,Inertia::Zero())
5758
, doYcrb((std::size_t)model.njoints,Inertia::Matrix6::Zero())
5859
, ddq(VectorXs::Zero(model.nv))
@@ -248,6 +249,7 @@ namespace pinocchio
248249
&& data1.IS == data2.IS
249250
&& data1.vxI == data2.vxI
250251
&& data1.Ivx == data2.Ivx
252+
&& data1.oinertias == data2.oinertias
251253
&& data1.oYcrb == data2.oYcrb
252254
&& data1.doYcrb == data2.doYcrb
253255
&& data1.ddq == data2.ddq

src/multibody/joint/joint-spherical.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,7 @@ namespace pinocchio
419419
{
420420
typedef typename ConfigVectorLike::Scalar Scalar;
421421
EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(ConfigVector_t,ConfigVectorLike);
422-
typedef typename Eigen::Quaternion<typename ConfigVectorLike::Scalar,PINOCCHIO_EIGEN_PLAIN_TYPE(ConfigVectorLike)::Options> Quaternion;
422+
typedef typename Eigen::Quaternion<Scalar,PINOCCHIO_EIGEN_PLAIN_TYPE(ConfigVectorLike)::Options> Quaternion;
423423
typedef Eigen::Map<const Quaternion> ConstQuaternionMap;
424424

425425
ConstQuaternionMap quat(q_joint.derived().data());

src/serialization/data.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ namespace boost
5757
PINOCCHIO_MAKE_DATA_NVP(ar,data,IS);
5858
PINOCCHIO_MAKE_DATA_NVP(ar,data,vxI);
5959
PINOCCHIO_MAKE_DATA_NVP(ar,data,Ivx);
60+
PINOCCHIO_MAKE_DATA_NVP(ar,data,oinertias);
6061
PINOCCHIO_MAKE_DATA_NVP(ar,data,oYcrb);
6162
PINOCCHIO_MAKE_DATA_NVP(ar,data,doYcrb);
6263
PINOCCHIO_MAKE_DATA_NVP(ar,data,ddq);

0 commit comments

Comments
 (0)