5 #ifndef __pinocchio_algorithm_contact_cholesky_hpp__
6 #define __pinocchio_algorithm_contact_cholesky_hpp__
8 #include "pinocchio/multibody/model.hpp"
9 #include "pinocchio/math/matrix-block.hpp"
10 #include "pinocchio/math/triangular-matrix.hpp"
12 #include "pinocchio/algorithm/contact-info.hpp"
13 #include "pinocchio/algorithm/delassus-operator-base.hpp"
21 template<
typename MatrixLike,
int ColsAtCompileTime = MatrixLike::ColsAtCompileTime>
24 template<
typename MatrixLike,
int ColsAtCompileTime = MatrixLike::ColsAtCompileTime>
27 template<
typename MatrixLike,
int ColsAtCompileTime = MatrixLike::ColsAtCompileTime>
30 template<
typename MatrixLike,
int ColsAtCompileTime = MatrixLike::ColsAtCompileTime>
33 template<
typename Scalar,
int Options,
typename VectorLike>
34 VectorLike & inverseAlgo(
36 const Eigen::DenseIndex col,
37 const Eigen::MatrixBase<VectorLike> & vec);
40 template<
typename _ContactCholeskyDecomposition>
54 template<
typename _Scalar,
int _Options>
58 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
60 typedef pinocchio::Index Index;
61 typedef _Scalar Scalar;
69 typedef Eigen::Matrix<Scalar, Eigen::Dynamic, 1, Options> Vector;
70 typedef Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, Options> Matrix;
71 typedef typename PINOCCHIO_EIGEN_PLAIN_ROW_MAJOR_TYPE(Matrix) RowMatrix;
73 PINOCCHIO_COMPILER_DIAGNOSTIC_PUSH
74 PINOCCHIO_COMPILER_DIAGNOSTIC_IGNORED_DEPRECECATED_DECLARATIONS
77 PINOCCHIO_COMPILER_DIAGNOSTIC_POP
78 typedef Eigen::Matrix<Eigen::DenseIndex, Eigen::Dynamic, 1, Options> IndexVector;
79 typedef typename PINOCCHIO_STD_VECTOR_WITH_EIGEN_ALLOCATOR(IndexVector) VectorOfIndexVector;
80 typedef Eigen::Matrix<bool, Eigen::Dynamic, 1, Options> BooleanVector;
86 Slice(
const Eigen::DenseIndex & first_index,
const Eigen::DenseIndex & size)
87 : first_index(first_index)
92 Eigen::DenseIndex first_index;
93 Eigen::DenseIndex size;
96 typedef DelassusCholeskyExpressionTpl<ContactCholeskyDecompositionTpl>
97 DelassusCholeskyExpression;
98 friend struct DelassusCholeskyExpressionTpl<ContactCholeskyDecompositionTpl>;
100 typedef std::vector<Slice> SliceVector;
101 typedef std::vector<SliceVector> VectorOfSliceVector;
107 ContactCholeskyDecompositionTpl() =
default;
114 template<
typename S1,
int O1,
template<
typename,
int>
class JointCollectionTpl>
115 explicit ContactCholeskyDecompositionTpl(
const ModelTpl<S1, O1, JointCollectionTpl> & model)
118 PINOCCHIO_COMPILER_DIAGNOSTIC_PUSH
119 PINOCCHIO_COMPILER_DIAGNOSTIC_IGNORED_DEPRECECATED_DECLARATIONS
120 PINOCCHIO_STD_VECTOR_WITH_EIGEN_ALLOCATOR(RigidConstraintModel) empty_contact_models;
121 PINOCCHIO_COMPILER_DIAGNOSTIC_POP
122 allocate(model, empty_contact_models);
133 PINOCCHIO_COMPILER_DIAGNOSTIC_PUSH
134 PINOCCHIO_COMPILER_DIAGNOSTIC_IGNORED_DEPRECECATED_DECLARATIONS
135 template<
typename S1,
int O1,
template<
typename,
int>
class JointCollectionTpl,
class Allocator>
136 ContactCholeskyDecompositionTpl(
137 const ModelTpl<S1, O1, JointCollectionTpl> & model,
138 const std::vector<RigidConstraintModelTpl<S1, O1>, Allocator> & contact_models)
140 allocate(model, contact_models);
142 PINOCCHIO_COMPILER_DIAGNOSTIC_POP
146 ContactCholeskyDecompositionTpl(
const ContactCholeskyDecompositionTpl &
copy) =
default;
156 PINOCCHIO_COMPILER_DIAGNOSTIC_PUSH
157 PINOCCHIO_COMPILER_DIAGNOSTIC_IGNORED_DEPRECECATED_DECLARATIONS
158 template<
typename S1,
int O1,
template<
typename,
int>
class JointCollectionTpl,
class Allocator>
160 const ModelTpl<S1, O1, JointCollectionTpl> & model,
161 const std::vector<RigidConstraintModelTpl<S1, O1>, Allocator> & contact_models);
162 PINOCCHIO_COMPILER_DIAGNOSTIC_POP
168 Matrix getInverseOperationalSpaceInertiaMatrix()
const
170 Matrix res(constraintDim(), constraintDim());
171 getInverseOperationalSpaceInertiaMatrix(res);
175 template<
typename MatrixType>
176 void getInverseOperationalSpaceInertiaMatrix(
const Eigen::MatrixBase<MatrixType> & res)
const
178 typedef typename SizeDepType<Eigen::Dynamic>::template BlockReturn<RowMatrix>::ConstType
181 const ConstBlockXpr U1 = U.topLeftCorner(constraintDim(), constraintDim());
183 PINOCCHIO_EIGEN_MALLOC_NOT_ALLOWED();
184 MatrixType & res_ = PINOCCHIO_EIGEN_CONST_CAST(MatrixType, res);
185 OSIMinv_tmp.noalias() = D.head(constraintDim()).asDiagonal() * U1.adjoint();
186 res_.noalias() = -U1 * OSIMinv_tmp;
187 PINOCCHIO_EIGEN_MALLOC_ALLOWED();
192 DelassusCholeskyExpression getDelassusCholeskyExpression()
const
194 return DelassusCholeskyExpression(*
this);
200 Matrix getOperationalSpaceInertiaMatrix()
const
202 Matrix res(constraintDim(), constraintDim());
203 getOperationalSpaceInertiaMatrix(res);
207 template<
typename MatrixType>
208 void getOperationalSpaceInertiaMatrix(
const Eigen::MatrixBase<MatrixType> & res_)
const
210 MatrixType & res = PINOCCHIO_EIGEN_CONST_CAST(MatrixType, res_);
211 typedef typename SizeDepType<Eigen::Dynamic>::template BlockReturn<RowMatrix>::ConstType
214 const Eigen::TriangularView<ConstBlockXpr, Eigen::UnitUpper> U1 =
215 U.topLeftCorner(constraintDim(), constraintDim())
216 .template triangularView<Eigen::UnitUpper>();
218 PINOCCHIO_EIGEN_MALLOC_NOT_ALLOWED();
220 U1.solveInPlace(U1inv);
221 OSIMinv_tmp.noalias() = -U1inv.adjoint() * Dinv.head(constraintDim()).asDiagonal();
222 res.noalias() = OSIMinv_tmp * U1inv;
223 PINOCCHIO_EIGEN_MALLOC_ALLOWED();
226 Matrix getInverseMassMatrix()
const
229 getInverseMassMatrix(res);
233 template<
typename MatrixType>
234 void getInverseMassMatrix(
const Eigen::MatrixBase<MatrixType> & res_)
const
236 MatrixType & res = PINOCCHIO_EIGEN_CONST_CAST(MatrixType, res_);
237 typedef typename SizeDepType<Eigen::Dynamic>::template BlockReturn<RowMatrix>::ConstType
240 const Eigen::TriangularView<ConstBlockXpr, Eigen::UnitUpper> U4 =
241 U.bottomRightCorner(
nv,
nv).template triangularView<Eigen::UnitUpper>();
243 PINOCCHIO_EIGEN_MALLOC_NOT_ALLOWED();
245 U4.solveInPlace(U4inv);
246 Minv_tmp.noalias() = U4inv.adjoint() * Dinv.tail(
nv).asDiagonal();
247 res.noalias() = Minv_tmp * U4inv;
248 PINOCCHIO_EIGEN_MALLOC_ALLOWED();
251 template<
typename MatrixType>
252 void getJMinv(
const Eigen::MatrixBase<MatrixType> & res_)
const
254 MatrixType & res = PINOCCHIO_EIGEN_CONST_CAST(MatrixType, res_);
255 typedef typename SizeDepType<Eigen::Dynamic>::template BlockReturn<RowMatrix>::ConstType
257 const Eigen::TriangularView<ConstBlockXpr, Eigen::UnitUpper> U4 =
258 U.bottomRightCorner(
nv,
nv).template triangularView<Eigen::UnitUpper>();
259 ConstBlockXpr U2 = U.topRightCorner(constraintDim(),
nv);
260 PINOCCHIO_EIGEN_MALLOC_NOT_ALLOWED();
262 U4.solveInPlace(U4inv);
263 res.noalias() = U2 * U4inv;
264 PINOCCHIO_EIGEN_MALLOC_ALLOWED();
284 PINOCCHIO_COMPILER_DIAGNOSTIC_PUSH
285 PINOCCHIO_COMPILER_DIAGNOSTIC_IGNORED_DEPRECECATED_DECLARATIONS
289 template<
typename,
int>
class JointCollectionTpl,
290 class ConstraintModelAllocator,
291 class ConstraintDataAllocator>
293 const ModelTpl<S1, O1, JointCollectionTpl> & model,
294 DataTpl<S1, O1, JointCollectionTpl> & data,
295 const std::vector<RigidConstraintModelTpl<S1, O1>, ConstraintModelAllocator> & contact_models,
296 std::vector<RigidConstraintDataTpl<S1, O1>, ConstraintDataAllocator> & contact_datas,
297 const S1 mu = S1(0.))
299 compute(model, data, contact_models, contact_datas, Vector::Constant(U1inv.rows(), mu));
321 template<
typename,
int>
class JointCollectionTpl,
322 class ConstraintModelAllocator,
323 class ConstraintDataAllocator,
326 const ModelTpl<S1, O1, JointCollectionTpl> & model,
327 DataTpl<S1, O1, JointCollectionTpl> & data,
328 const std::vector<RigidConstraintModelTpl<S1, O1>, ConstraintModelAllocator> & contact_models,
329 std::vector<RigidConstraintDataTpl<S1, O1>, ConstraintDataAllocator> & contact_datas,
330 const Eigen::MatrixBase<VectorLike> & mus);
331 PINOCCHIO_COMPILER_DIAGNOSTIC_POP
340 template<
typename VectorLike>
341 void updateDamping(
const Eigen::MatrixBase<VectorLike> & mus);
350 void updateDamping(
const Scalar & mu);
353 Eigen::DenseIndex size()
const
360 Eigen::DenseIndex constraintDim()
const
366 Eigen::DenseIndex numContacts()
const
382 template<
typename MatrixLike>
383 void solveInPlace(
const Eigen::MatrixBase<MatrixLike> & mat)
const;
394 template<
typename MatrixLike>
395 Matrix
solve(
const Eigen::MatrixBase<MatrixLike> & mat)
const;
402 template<
typename S1,
int O1,
template<
typename,
int>
class JointCollectionTpl>
403 ContactCholeskyDecompositionTpl
404 getMassMatrixChoeslkyDecomposition(
const ModelTpl<S1, O1, JointCollectionTpl> & model)
const;
408 template<
typename MatrixLike>
409 void Uv(
const Eigen::MatrixBase<MatrixLike> & mat)
const;
411 template<
typename MatrixLike>
412 void Utv(
const Eigen::MatrixBase<MatrixLike> & mat)
const;
414 template<
typename MatrixLike>
415 void Uiv(
const Eigen::MatrixBase<MatrixLike> & mat)
const;
417 template<
typename MatrixLike>
418 void Utiv(
const Eigen::MatrixBase<MatrixLike> & mat)
const;
422 Matrix matrix()
const;
425 template<
typename MatrixType>
426 void matrix(
const Eigen::MatrixBase<MatrixType> & res)
const;
429 Matrix inverse()
const;
432 template<
typename MatrixType>
433 void inverse(
const Eigen::MatrixBase<MatrixType> & res)
const;
441 template<
typename MatrixLike,
int ColsAtCompileTime>
442 friend struct details::UvAlgo;
444 template<
typename MatrixLike,
int ColsAtCompileTime>
445 friend struct details::UtvAlgo;
447 template<
typename MatrixLike,
int ColsAtCompileTime>
448 friend struct details::UivAlgo;
450 template<
typename MatrixLike,
int ColsAtCompileTime>
451 friend struct details::UtivAlgo;
454 PINOCCHIO_COMPILER_DIAGNOSTIC_PUSH
455 PINOCCHIO_COMPILER_DIAGNOSTIC_IGNORED_DEPRECECATED_DECLARATIONS
456 template<
typename Scalar,
int Options,
typename VectorLike>
457 friend VectorLike & details::inverseAlgo(
458 const ContactCholeskyDecompositionTpl<Scalar, Options> & chol,
459 const Eigen::DenseIndex col,
460 const Eigen::MatrixBase<VectorLike> & vec);
463 template<
typename S1,
int O1>
464 bool operator==(
const ContactCholeskyDecompositionTpl<S1, O1> & other)
const;
466 template<
typename S1,
int O1>
467 bool operator!=(
const ContactCholeskyDecompositionTpl<S1, O1> & other)
const;
468 PINOCCHIO_COMPILER_DIAGNOSTIC_POP
471 IndexVector parents_fromRow;
472 IndexVector nv_subtree_fromRow;
475 IndexVector last_child;
480 Eigen::DenseIndex
nv;
483 Eigen::DenseIndex num_contacts;
485 VectorOfSliceVector rowise_sparsity_pattern;
488 mutable Matrix U1inv;
490 mutable Matrix U4inv;
492 mutable RowMatrix OSIMinv_tmp, Minv_tmp;
495 template<
typename ContactCholeskyDecomposition>
500 RowsAtCompileTime = Eigen::Dynamic
502 typedef typename ContactCholeskyDecomposition::Scalar Scalar;
503 typedef typename ContactCholeskyDecomposition::Matrix Matrix;
504 typedef typename ContactCholeskyDecomposition::Vector Vector;
507 template<
typename _ContactCholeskyDecomposition>
511 typedef _ContactCholeskyDecomposition ContactCholeskyDecomposition;
512 typedef typename ContactCholeskyDecomposition::Scalar Scalar;
513 typedef typename ContactCholeskyDecomposition::Vector Vector;
514 typedef typename ContactCholeskyDecomposition::Matrix Matrix;
515 typedef typename ContactCholeskyDecomposition::RowMatrix RowMatrix;
522 RowMatrixConstBlockXpr;
530 :
Base(
self.constraintDim())
535 template<
typename MatrixIn,
typename MatrixOut>
536 void applyOnTheRight(
537 const Eigen::MatrixBase<MatrixIn> & x,
const Eigen::MatrixBase<MatrixOut> & res)
const
539 PINOCCHIO_CHECK_ARGUMENT_SIZE(x.rows(),
self.constraintDim());
540 PINOCCHIO_CHECK_ARGUMENT_SIZE(res.rows(),
self.constraintDim());
541 PINOCCHIO_CHECK_ARGUMENT_SIZE(res.cols(), x.cols());
543 PINOCCHIO_EIGEN_MALLOC_NOT_ALLOWED();
545 const RowMatrixConstBlockXpr U1 =
546 self.U.topLeftCorner(
self.constraintDim(),
self.constraintDim());
548 if (x.cols() <=
self.constraintDim())
550 RowMatrixBlockXpr tmp_mat =
551 const_cast<ContactCholeskyDecomposition &
>(
self).OSIMinv_tmp.topLeftCorner(
552 self.constraintDim(), x.cols());
554 triangularMatrixMatrixProduct<Eigen::UnitLower>(U1.adjoint(), x.derived(), tmp_mat);
555 tmp_mat.array().colwise() *= -
self.D.head(
self.constraintDim()).array();
557 triangularMatrixMatrixProduct<Eigen::UnitUpper>(U1, tmp_mat, res.const_cast_derived());
561 RowMatrix tmp_mat(x.rows(), x.cols());
563 triangularMatrixMatrixProduct<Eigen::UnitLower>(U1.adjoint(), x.derived(), tmp_mat);
564 tmp_mat.array().colwise() *= -
self.D.head(
self.constraintDim()).array();
566 triangularMatrixMatrixProduct<Eigen::UnitUpper>(U1, tmp_mat, res.const_cast_derived());
569 PINOCCHIO_EIGEN_MALLOC_ALLOWED();
572 template<
typename MatrixDerived>
573 typename PINOCCHIO_EIGEN_PLAIN_TYPE(MatrixDerived)
574 operator*(
const Eigen::MatrixBase<MatrixDerived> & x)
const
576 typedef typename PINOCCHIO_EIGEN_PLAIN_TYPE(MatrixDerived) ReturnType;
577 ReturnType res(
self.constraintDim(), x.cols());
578 applyOnTheRight(x.derived(), res);
582 template<
typename MatrixDerived>
583 void solveInPlace(
const Eigen::MatrixBase<MatrixDerived> & x)
const
585 PINOCCHIO_CHECK_ARGUMENT_SIZE(x.rows(),
self.constraintDim());
587 const Eigen::TriangularView<RowMatrixConstBlockXpr, Eigen::UnitUpper> U1 =
588 self.U.topLeftCorner(
self.constraintDim(),
self.constraintDim())
589 .template triangularView<Eigen::UnitUpper>();
591 PINOCCHIO_EIGEN_MALLOC_NOT_ALLOWED();
592 U1.solveInPlace(x.const_cast_derived());
593 x.const_cast_derived().array().colwise() *= -
self.Dinv.head(
self.constraintDim()).array();
594 U1.adjoint().solveInPlace(x);
595 PINOCCHIO_EIGEN_MALLOC_ALLOWED();
598 template<
typename MatrixDerivedIn,
typename MatrixDerivedOut>
600 const Eigen::MatrixBase<MatrixDerivedIn> & x,
601 const Eigen::MatrixBase<MatrixDerivedOut> & res)
const
603 res.const_cast_derived() = x;
604 solveInPlace(res.const_cast_derived());
607 template<
typename MatrixDerived>
608 typename PINOCCHIO_EIGEN_PLAIN_TYPE(MatrixDerived)
609 solve(
const Eigen::MatrixBase<MatrixDerived> & x)
const
611 typedef typename PINOCCHIO_EIGEN_PLAIN_TYPE(MatrixDerived) ReturnType;
612 ReturnType res(
self.constraintDim(), x.cols());
613 solve(x.derived(), res);
619 const ContactCholeskyDecomposition &
cholesky()
const
624 Matrix matrix()
const
626 return self.getInverseOperationalSpaceInertiaMatrix();
629 Matrix inverse()
const
631 return self.getOperationalSpaceInertiaMatrix();
641 template<
typename VectorLike>
644 const_cast<ContactCholeskyDecomposition &
>(
self).
updateDamping(mus);
656 const_cast<ContactCholeskyDecomposition &
>(
self).
updateDamping(mu);
659 Eigen::DenseIndex size()
const
661 return self.constraintDim();
663 Eigen::DenseIndex rows()
const
667 Eigen::DenseIndex cols()
const
673 const ContactCholeskyDecomposition &
self;
685 #if PINOCCHIO_ENABLE_TEMPLATE_INSTANTIATION
686 #include "pinocchio/algorithm/contact-cholesky.txx"
689 #include "pinocchio/algorithm/contact-cholesky.hxx"
Mat & Utiv(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, const DataTpl< Scalar, Options, JointCollectionTpl > &data, const Eigen::MatrixBase< Mat > &v)
Perform the pivot inversion using the Cholesky decomposition stored in data and acting in place.
Mat & Uv(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, const DataTpl< Scalar, Options, JointCollectionTpl > &data, const Eigen::MatrixBase< Mat > &v)
Perform the sparse multiplication using the Cholesky decomposition stored in data and acting in plac...
Mat & Uiv(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, const DataTpl< Scalar, Options, JointCollectionTpl > &data, const Eigen::MatrixBase< Mat > &v)
Perform the pivot inversion using the Cholesky decomposition stored in data and acting in place.
Mat & Utv(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, const DataTpl< Scalar, Options, JointCollectionTpl > &data, const Eigen::MatrixBase< Mat > &v)
Perform the sparse multiplication using the Cholesky decomposition stored in data and acting in plac...
Mat & solve(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, const DataTpl< Scalar, Options, JointCollectionTpl > &data, const Eigen::MatrixBase< Mat > &y)
Return the solution of using the Cholesky decomposition stored in data given the entry ....
Main pinocchio namespace.
struct PINOCCHIO_UNSUPPORTED_MESSAGE("The API will change towards more flexibility") ContactCholeskyDecompositionTpl
Contact Cholesky decomposition structure. This structure allows to compute in a efficient and parsimo...
void copy(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, const DataTpl< Scalar, Options, JointCollectionTpl > &origin, DataTpl< Scalar, Options, JointCollectionTpl > &dest, KinematicLevel kinematic_level)
Copy part of the data from origin to dest. Template parameter can be used to select at which differen...
int nv(const JointModelTpl< Scalar, Options, JointCollectionTpl > &jmodel)
Visit a JointModelTpl through JointNvVisitor to get the dimension of the joint tangent space.
void updateDamping(const Scalar &mu)
Add a damping term to the diagonal of the Delassus matrix. The damping term should be positive.
const ContactCholeskyDecomposition & cholesky() const
Returns the Constraint Cholesky decomposition associated to this DelassusCholeskyExpression.
void updateDamping(const Eigen::MatrixBase< VectorLike > &mus)
Add a damping term to the diagonal of the Delassus matrix. The damping terms should be all positives.
Common traits structure to fully define base classes for CRTP.