11 #include "pinocchio/algorithm/contact-cholesky.hxx"
15 #include <boost/test/unit_test.hpp>
16 #include <boost/utility/binary.hpp>
22 template<
typename Scalar,
int Options>
37 return this->parents_fromRow;
41 return this->last_child;
45 return this->nv_subtree_fromRow;
49 return this->joint1_indexes;
53 return this->joint2_indexes;
61 BOOST_AUTO_TEST_SUITE(BOOST_TEST_MODULE)
66 using namespace Eigen;
68 using namespace cholesky;
72 Data humanoid_data(humanoid_model);
76 Data manipulator_data(manipulator_model);
90 humanoid_chol.compute(humanoid_model, humanoid_data, contact_models_empty, contact_datas_empty);
91 manipulator_chol.compute(
92 manipulator_model, manipulator_data, contact_models_empty, contact_datas_empty);
94 BOOST_CHECK(humanoid_chol == humanoid_chol);
95 BOOST_CHECK(humanoid_chol != manipulator_chol);
100 using namespace Eigen;
108 model.lowerPositionLimit.head<3>().
fill(-1.);
109 model.upperPositionLimit.head<3>().
fill(1.);
114 data_ref.
M.triangularView<Eigen::StrictlyLower>() =
115 data_ref.
M.triangularView<Eigen::StrictlyUpper>().transpose();
120 contact_chol_decomposition.allocate(
model, contact_models_empty);
122 BOOST_CHECK(contact_chol_decomposition.D.size() ==
model.nv);
123 BOOST_CHECK(contact_chol_decomposition.Dinv.size() ==
model.nv);
124 BOOST_CHECK(contact_chol_decomposition.U.rows() ==
model.nv);
125 BOOST_CHECK(contact_chol_decomposition.U.cols() ==
model.nv);
126 BOOST_CHECK(contact_chol_decomposition.size() ==
model.nv);
127 BOOST_CHECK(contact_chol_decomposition.U.diagonal().isOnes());
131 data.M.triangularView<Eigen::StrictlyLower>() =
132 data.M.triangularView<Eigen::StrictlyUpper>().transpose();
134 contact_chol_decomposition.compute(
model,
data, contact_models_empty, contact_datas_empty);
136 data_ref.
Minv = data_ref.
M.inverse();
137 Eigen::MatrixXd Minv_test(Eigen::MatrixXd::Zero(
model.nv,
model.nv));
138 contact_chol_decomposition.getInverseMassMatrix(Minv_test);
140 BOOST_CHECK(
data.M.isApprox(data_ref.
M));
141 BOOST_CHECK(Minv_test.isApprox(data_ref.
Minv));
143 BOOST_CHECK(data_ref.
D.isApprox(contact_chol_decomposition.D.tail(
model.nv)));
144 BOOST_CHECK(data_ref.
Dinv.isApprox(contact_chol_decomposition.Dinv.tail(
model.nv)));
146 data_ref.
U.isApprox(contact_chol_decomposition.U.bottomRightCorner(
model.nv,
model.nv)));
149 for (Eigen::DenseIndex k = 0; k <
model.nv; ++k)
154 for (Eigen::DenseIndex k = 0; k <
model.njoints; ++k)
159 for (Eigen::DenseIndex k = 0; k <
model.nv; ++k)
165 VectorXd v_in(VectorXd::Random(
model.nv));
166 MatrixXd mat_in(MatrixXd::Random(contact_chol_decomposition.size(), 20));
169 VectorXd Uv_op_res(v_in), Uv_op_ref(v_in);
171 contact_chol_decomposition.Uv(Uv_op_res);
174 BOOST_CHECK(Uv_op_res.isApprox(Uv_op_ref));
176 MatrixXd Uv_mat_op_res(mat_in), Uv_mat_op_ref(mat_in);
178 contact_chol_decomposition.Uv(Uv_mat_op_res);
181 BOOST_CHECK(Uv_mat_op_res.isApprox(Uv_mat_op_ref));
184 VectorXd Utv_op_res(v_in), Utv_op_ref(v_in);
186 contact_chol_decomposition.Utv(Utv_op_res);
189 BOOST_CHECK(Utv_op_res.isApprox(Utv_op_ref));
191 MatrixXd Utv_mat_op_res(mat_in), Utv_mat_op_ref(mat_in);
193 contact_chol_decomposition.Utv(Utv_mat_op_res);
196 BOOST_CHECK(Utv_mat_op_res.isApprox(Utv_mat_op_ref));
199 VectorXd Uiv_op_res(v_in), Uiv_op_ref(v_in);
201 contact_chol_decomposition.Uiv(Uiv_op_res);
204 BOOST_CHECK(Uiv_op_res.isApprox(Uiv_op_ref));
206 MatrixXd Uiv_mat_op_res(mat_in), Uiv_mat_op_ref(mat_in);
208 contact_chol_decomposition.Uiv(Uiv_mat_op_res);
211 BOOST_CHECK(Uiv_mat_op_res.isApprox(Uiv_mat_op_ref));
214 VectorXd Utiv_op_res(v_in), Utiv_op_ref(v_in);
216 contact_chol_decomposition.Utiv(Utiv_op_res);
219 BOOST_CHECK(Utiv_op_res.isApprox(Utiv_op_ref));
221 MatrixXd Utiv_mat_op_res(mat_in), Utiv_mat_op_ref(mat_in);
223 contact_chol_decomposition.Utiv(Utiv_mat_op_res);
226 BOOST_CHECK(Utiv_mat_op_res.isApprox(Utiv_mat_op_ref));
230 contact_chol_decomposition.solveInPlace(
sol);
232 VectorXd sol_ref(
data.M.inverse() * v_in);
234 BOOST_CHECK(
sol.isApprox(sol_ref));
236 MatrixXd sol_mat(mat_in);
237 contact_chol_decomposition.solveInPlace(sol_mat);
239 MatrixXd sol_mat_ref(
data.M.inverse() * mat_in);
241 BOOST_CHECK(sol_mat.isApprox(sol_mat_ref));
244 MatrixXd sol_copy_mat = contact_chol_decomposition.solve(mat_in);
245 BOOST_CHECK(sol_copy_mat.isApprox(sol_mat));
249 contact_chol_decomposition.inverse(M_inv);
251 MatrixXd M_inv_ref =
data.M.inverse();
252 BOOST_CHECK(M_inv.isApprox(M_inv_ref));
256 contact_chol_decomposition.getMassMatrixChoeslkyDecomposition(
model);
259 MatrixXd iosim = contact_chol_decomposition.getInverseOperationalSpaceInertiaMatrix();
260 MatrixXd osim = contact_chol_decomposition.getOperationalSpaceInertiaMatrix();
261 BOOST_CHECK(iosim.size() == 0);
262 BOOST_CHECK(osim.size() == 0);
264 BOOST_CHECK(mass_matrix_chol == contact_chol_decomposition);
265 BOOST_CHECK(mass_matrix_chol.U.isApprox(data_ref.
U));
266 BOOST_CHECK(mass_matrix_chol.D.isApprox(data_ref.
D));
267 BOOST_CHECK(mass_matrix_chol.Dinv.isApprox(data_ref.
Dinv));
272 using namespace Eigen;
280 model.lowerPositionLimit.head<3>().
fill(-1.);
281 model.upperPositionLimit.head<3>().
fill(1.);
284 const std::string RF =
"rleg6_joint";
285 const std::string LF =
"lleg6_joint";
298 data_ref.
M.triangularView<Eigen::StrictlyLower>() =
299 data_ref.
M.triangularView<Eigen::StrictlyUpper>().transpose();
317 H.middleRows<6>(0).rightCols(
model.nv) = J_RF;
318 H.middleRows<6>(6).rightCols(
model.nv) = J_LF;
320 H.triangularView<Eigen::StrictlyLower>() =
H.triangularView<Eigen::StrictlyUpper>().transpose();
328 for (Eigen::DenseIndex k = 0; k <
model.nv; ++k)
330 if (
data.parents_fromRow[(
size_t)k] == -1)
340 data.M.triangularView<Eigen::StrictlyLower>() =
341 data.M.triangularView<Eigen::StrictlyUpper>().transpose();
343 BOOST_CHECK(data_ref.
D.isApprox(contact_chol_decomposition.D.tail(
model.nv)));
344 BOOST_CHECK(data_ref.
Dinv.isApprox(contact_chol_decomposition.Dinv.tail(
model.nv)));
346 data_ref.
U.isApprox(contact_chol_decomposition.U.bottomRightCorner(
model.nv,
model.nv)));
349 contact_chol_decomposition.U.bottomRightCorner(
model.nv,
model.nv)
350 * contact_chol_decomposition.D.tail(
model.nv).asDiagonal()
351 * contact_chol_decomposition.U.bottomRightCorner(
model.nv,
model.nv).transpose();
352 BOOST_CHECK(M_recomposed.isApprox(
data.M));
355 * contact_chol_decomposition.D.asDiagonal()
356 * contact_chol_decomposition.U.transpose();
358 BOOST_CHECK(H_recomposed.bottomRightCorner(
model.nv,
model.nv).isApprox(
data.M));
361 BOOST_CHECK(H_recomposed.isApprox(
H));
365 MatrixXd JMinvJt =
H.middleRows<12>(0).rightCols(
model.nv) * data_ref.
M.inverse()
366 *
H.middleRows<12>(0).rightCols(
model.nv).transpose();
367 MatrixXd iosim = contact_chol_decomposition.getInverseOperationalSpaceInertiaMatrix();
368 MatrixXd osim = contact_chol_decomposition.getOperationalSpaceInertiaMatrix();
370 contact_chol_decomposition.getJMinv(JMinv_test);
371 MatrixXd JMinv_ref =
H.middleRows<12>(0).rightCols(
model.nv) * data_ref.
M.inverse();
372 BOOST_CHECK(JMinv_ref.isApprox(JMinv_test));
374 BOOST_CHECK(iosim.isApprox(JMinvJt));
375 BOOST_CHECK(osim.isApprox(JMinvJt.inverse()));
377 const MatrixXd
rhs = MatrixXd::Random(12, 12);
378 const MatrixXd res_delassus = contact_chol_decomposition.getDelassusCholeskyExpression() *
rhs;
379 const MatrixXd res_delassus_ref = iosim *
rhs;
381 BOOST_CHECK(res_delassus_ref.isApprox(res_delassus));
383 const MatrixXd res_delassus_inverse =
384 contact_chol_decomposition.getDelassusCholeskyExpression().solve(
rhs);
385 const MatrixXd res_delassus_inverse_ref = osim *
rhs;
387 BOOST_CHECK(res_delassus_inverse_ref.isApprox(res_delassus_inverse));
391 data_ref.
Minv = data_ref.
M.inverse();
392 Eigen::MatrixXd Minv_test(Eigen::MatrixXd::Zero(
model.nv,
model.nv));
393 contact_chol_decomposition.getInverseMassMatrix(Minv_test);
395 BOOST_CHECK(Minv_test.isApprox(data_ref.
Minv));
401 BOOST_CHECK(contact_chol_decomposition_mu.D.isApprox(contact_chol_decomposition.D));
402 BOOST_CHECK(contact_chol_decomposition_mu.Dinv.isApprox(contact_chol_decomposition.Dinv));
403 BOOST_CHECK(contact_chol_decomposition_mu.U.isApprox(contact_chol_decomposition.U));
405 const double mu = 0.1;
412 MatrixXd JMinvJt_mu = H_mu.middleRows<12>(0).rightCols(
model.nv) * data_ref.
M.inverse()
413 * H_mu.middleRows<12>(0).rightCols(
model.nv).transpose()
414 +
mu * MatrixXd::Identity(12, 12);
415 MatrixXd iosim_mu = contact_chol_decomposition_mu.getInverseOperationalSpaceInertiaMatrix();
416 MatrixXd osim_mu = contact_chol_decomposition_mu.getOperationalSpaceInertiaMatrix();
418 BOOST_CHECK(iosim_mu.isApprox(JMinvJt_mu));
419 BOOST_CHECK(osim_mu.isApprox(JMinvJt_mu.inverse()));
421 const MatrixXd
rhs = MatrixXd::Random(12, 1);
422 const MatrixXd
res = contact_chol_decomposition_mu.getDelassusCholeskyExpression() *
rhs;
423 const MatrixXd res_ref = iosim_mu *
rhs;
425 BOOST_CHECK(res_ref.isApprox(
res));
427 const MatrixXd res_no_mu =
428 contact_chol_decomposition_mu.getDelassusCholeskyExpression() *
rhs -
mu *
rhs;
429 const MatrixXd res_no_mu_ref = contact_chol_decomposition.getDelassusCholeskyExpression() *
rhs;
431 BOOST_CHECK(res_no_mu.isApprox(res_no_mu_ref));
435 * contact_chol_decomposition_mu.D.asDiagonal()
436 * contact_chol_decomposition_mu.U.transpose();
438 BOOST_CHECK(H_recomposed_mu.isApprox(H_mu));
441 VectorXd v_in(VectorXd::Random(contact_chol_decomposition.size()));
442 MatrixXd mat_in(MatrixXd::Random(contact_chol_decomposition.size(), 20));
445 VectorXd Uv_op_res(v_in), Uv_op_ref(v_in);
447 contact_chol_decomposition.Uv(Uv_op_res);
448 Uv_op_ref.noalias() = contact_chol_decomposition.U * v_in;
450 BOOST_CHECK(Uv_op_res.isApprox(Uv_op_ref));
452 MatrixXd Uv_mat_op_res(mat_in), Uv_mat_op_ref(mat_in);
454 contact_chol_decomposition.Uv(Uv_mat_op_res);
455 Uv_mat_op_ref.noalias() = contact_chol_decomposition.U * mat_in;
457 BOOST_CHECK(Uv_mat_op_res.isApprox(Uv_mat_op_ref));
460 VectorXd Utv_op_res(v_in), Utv_op_ref(v_in);
462 contact_chol_decomposition.Utv(Utv_op_res);
463 Utv_op_ref.noalias() = contact_chol_decomposition.U.transpose() * v_in;
465 BOOST_CHECK(Utv_op_res.isApprox(Utv_op_ref));
467 MatrixXd Utv_mat_op_res(mat_in), Utv_mat_op_ref(mat_in);
469 contact_chol_decomposition.Utv(Utv_mat_op_res);
470 Utv_mat_op_ref.noalias() = contact_chol_decomposition.U.transpose() * mat_in;
472 BOOST_CHECK(Utv_mat_op_res.isApprox(Utv_mat_op_ref));
475 VectorXd Uiv_op_res(v_in), Uiv_op_ref(v_in);
477 contact_chol_decomposition.Uiv(Uiv_op_res);
478 Uiv_op_ref.noalias() = contact_chol_decomposition.U.inverse() * v_in;
480 BOOST_CHECK(Uiv_op_res.isApprox(Uiv_op_ref));
482 MatrixXd Uiv_mat_op_res(mat_in), Uiv_mat_op_ref(mat_in);
484 contact_chol_decomposition.Uiv(Uiv_mat_op_res);
485 Uiv_mat_op_ref.noalias() = contact_chol_decomposition.U.inverse() * mat_in;
487 BOOST_CHECK(Uiv_mat_op_res.isApprox(Uiv_mat_op_ref));
490 VectorXd Utiv_op_res(v_in), Utiv_op_ref(v_in);
492 contact_chol_decomposition.Utiv(Utiv_op_res);
493 Utiv_op_ref.noalias() = contact_chol_decomposition.U.inverse().transpose() * v_in;
495 BOOST_CHECK(Utiv_op_res.isApprox(Utiv_op_ref));
497 MatrixXd Utiv_mat_op_res(mat_in), Utiv_mat_op_ref(mat_in);
499 contact_chol_decomposition.Utiv(Utiv_mat_op_res);
500 Utiv_mat_op_ref.noalias() = contact_chol_decomposition.U.inverse().transpose() * mat_in;
502 BOOST_CHECK(Utiv_mat_op_res.isApprox(Utiv_mat_op_ref));
506 contact_chol_decomposition.solveInPlace(
sol);
508 VectorXd sol_ref(
H.inverse() * v_in);
510 BOOST_CHECK(
sol.isApprox(sol_ref));
512 MatrixXd sol_mat(mat_in), sol_mat_ref(mat_in);
514 contact_chol_decomposition.solveInPlace(sol_mat);
515 sol_mat_ref.noalias() =
H.inverse() * mat_in;
517 BOOST_CHECK(sol_mat.isApprox(sol_mat_ref));
520 MatrixXd sol_copy_mat = contact_chol_decomposition.solve(mat_in);
521 BOOST_CHECK(sol_copy_mat.isApprox(sol_mat));
524 MatrixXd H_inv(contact_chol_decomposition.size(), contact_chol_decomposition.size());
525 contact_chol_decomposition.inverse(H_inv);
527 MatrixXd H_inv_ref =
H.inverse();
528 BOOST_CHECK(H_inv.isApprox(H_inv_ref));
532 contact_chol_decomposition.matrix(mat1);
533 BOOST_CHECK(mat1.isApprox(
H));
537 BOOST_CHECK(mat2.isApprox(
H));
539 MatrixXd mat3 = contact_chol_decomposition.matrix();
540 BOOST_CHECK(mat3.isApprox(
H));
545 using namespace Eigen;
553 model.lowerPositionLimit.head<3>().
fill(-1.);
554 model.upperPositionLimit.head<3>().
fill(1.);
557 const std::string RF =
"rleg6_joint";
558 const std::string LF =
"lleg6_joint";
559 const std::string RA =
"rarm6_joint";
560 const std::string LA =
"larm6_joint";
579 data_ref.
M.triangularView<Eigen::StrictlyLower>() =
580 data_ref.
M.triangularView<Eigen::StrictlyUpper>().transpose();
602 H.middleRows<6>(0).rightCols(
model.nv) = J_RF;
603 H.middleRows<3>(6).rightCols(
model.nv) = J_LF.middleRows<3>(Motion::LINEAR);
607 H.triangularView<Eigen::StrictlyLower>() =
H.triangularView<Eigen::StrictlyUpper>().transpose();
615 for (Eigen::DenseIndex k = 0; k <
model.nv; ++k)
617 if (
data.parents_fromRow[(
size_t)k] == -1)
627 data.M.triangularView<Eigen::StrictlyLower>() =
628 data.M.triangularView<Eigen::StrictlyUpper>().transpose();
630 BOOST_CHECK(data_ref.
D.isApprox(contact_chol_decomposition.D.tail(
model.nv)));
631 BOOST_CHECK(data_ref.
Dinv.isApprox(contact_chol_decomposition.Dinv.tail(
model.nv)));
633 data_ref.
U.isApprox(contact_chol_decomposition.U.bottomRightCorner(
model.nv,
model.nv)));
636 contact_chol_decomposition.U.bottomRightCorner(
model.nv,
model.nv)
637 * contact_chol_decomposition.D.tail(
model.nv).asDiagonal()
638 * contact_chol_decomposition.U.bottomRightCorner(
model.nv,
model.nv).transpose();
639 BOOST_CHECK(M_recomposed.isApprox(
data.M));
642 * contact_chol_decomposition.D.asDiagonal()
643 * contact_chol_decomposition.U.transpose();
645 BOOST_CHECK(H_recomposed.bottomRightCorner(
model.nv,
model.nv).isApprox(
data.M));
648 BOOST_CHECK(H_recomposed.isApprox(
H));
651 VectorXd v_in(VectorXd::Random(contact_chol_decomposition.size()));
652 MatrixXd mat_in(MatrixXd::Random(contact_chol_decomposition.size(), 20));
655 VectorXd Uv_op_res(v_in), Uv_op_ref(v_in);
657 contact_chol_decomposition.Uv(Uv_op_res);
658 Uv_op_ref.noalias() = contact_chol_decomposition.U * v_in;
660 BOOST_CHECK(Uv_op_res.isApprox(Uv_op_ref));
662 MatrixXd Uv_mat_op_res(mat_in), Uv_mat_op_ref(mat_in);
664 contact_chol_decomposition.Uv(Uv_mat_op_res);
665 Uv_mat_op_ref.noalias() = contact_chol_decomposition.U * mat_in;
667 BOOST_CHECK(Uv_mat_op_res.isApprox(Uv_mat_op_ref));
670 VectorXd Utv_op_res(v_in), Utv_op_ref(v_in);
672 contact_chol_decomposition.Utv(Utv_op_res);
673 Utv_op_ref.noalias() = contact_chol_decomposition.U.transpose() * v_in;
675 BOOST_CHECK(Utv_op_res.isApprox(Utv_op_ref));
677 MatrixXd Utv_mat_op_res(mat_in), Utv_mat_op_ref(mat_in);
679 contact_chol_decomposition.Utv(Utv_mat_op_res);
680 Utv_mat_op_ref.noalias() = contact_chol_decomposition.U.transpose() * mat_in;
682 BOOST_CHECK(Utv_mat_op_res.isApprox(Utv_mat_op_ref));
685 VectorXd Uiv_op_res(v_in), Uiv_op_ref(v_in);
687 contact_chol_decomposition.Uiv(Uiv_op_res);
688 Uiv_op_ref.noalias() = contact_chol_decomposition.U.inverse() * v_in;
690 BOOST_CHECK(Uiv_op_res.isApprox(Uiv_op_ref));
692 MatrixXd Uiv_mat_op_res(mat_in), Uiv_mat_op_ref(mat_in);
694 contact_chol_decomposition.Uiv(Uiv_mat_op_res);
695 Uiv_mat_op_ref.noalias() = contact_chol_decomposition.U.inverse() * mat_in;
697 BOOST_CHECK(Uiv_mat_op_res.isApprox(Uiv_mat_op_ref));
700 VectorXd Utiv_op_res(v_in), Utiv_op_ref(v_in);
702 contact_chol_decomposition.Utiv(Utiv_op_res);
703 Utiv_op_ref.noalias() = contact_chol_decomposition.U.inverse().transpose() * v_in;
705 BOOST_CHECK(Utiv_op_res.isApprox(Utiv_op_ref));
707 MatrixXd Utiv_mat_op_res(mat_in), Utiv_mat_op_ref(mat_in);
709 contact_chol_decomposition.Utiv(Utiv_mat_op_res);
710 Utiv_mat_op_ref.noalias() = contact_chol_decomposition.U.inverse().transpose() * mat_in;
712 BOOST_CHECK(Utiv_mat_op_res.isApprox(Utiv_mat_op_ref));
716 contact_chol_decomposition.solveInPlace(
sol);
718 VectorXd sol_ref(
H.inverse() * v_in);
720 BOOST_CHECK(
sol.isApprox(sol_ref));
722 MatrixXd sol_mat(mat_in), sol_mat_ref(mat_in);
724 contact_chol_decomposition.solveInPlace(sol_mat);
725 sol_mat_ref.noalias() =
H.inverse() * mat_in;
727 BOOST_CHECK(sol_mat.isApprox(sol_mat_ref));
730 MatrixXd sol_copy_mat = contact_chol_decomposition.solve(mat_in);
731 BOOST_CHECK(sol_copy_mat.isApprox(sol_mat));
734 MatrixXd H_inv(contact_chol_decomposition.size(), contact_chol_decomposition.size());
735 contact_chol_decomposition.inverse(H_inv);
737 MatrixXd H_inv_ref =
H.inverse();
738 BOOST_CHECK(H_inv.isApprox(H_inv_ref));
742 contact_chol_decomposition.matrix(mat1);
743 BOOST_CHECK(mat1.isApprox(
H));
747 BOOST_CHECK(mat2.isApprox(
H));
749 MatrixXd mat3 = contact_chol_decomposition.matrix();
750 BOOST_CHECK(mat3.isApprox(
H));
753 MatrixXd JMinvJt =
H.middleRows<9>(0).rightCols(
model.nv) * data_ref.
M.inverse()
754 *
H.middleRows<9>(0).rightCols(
model.nv).transpose();
755 MatrixXd iosim = contact_chol_decomposition.getInverseOperationalSpaceInertiaMatrix();
756 MatrixXd osim = contact_chol_decomposition.getOperationalSpaceInertiaMatrix();
758 BOOST_CHECK(iosim.isApprox(JMinvJt));
759 BOOST_CHECK(osim.isApprox(JMinvJt.inverse()));
762 data_ref.
Minv = data_ref.
M.inverse();
763 Eigen::MatrixXd Minv_test(Eigen::MatrixXd::Zero(
model.nv,
model.nv));
764 contact_chol_decomposition.getInverseMassMatrix(Minv_test);
766 Eigen::MatrixXd JMinv_test(Eigen::MatrixXd::Zero(9,
model.nv));
767 contact_chol_decomposition.getJMinv(JMinv_test);
768 MatrixXd JMinv_ref =
H.middleRows<9>(0).rightCols(
model.nv) * data_ref.
M.inverse();
769 BOOST_CHECK(JMinv_ref.isApprox(JMinv_test));
771 BOOST_CHECK(Minv_test.isApprox(data_ref.
Minv));
776 using namespace Eigen;
784 model.lowerPositionLimit.head<3>().
fill(-1.);
785 model.upperPositionLimit.head<3>().
fill(1.);
788 const std::string RF =
"rleg6_joint";
789 const std::string LF =
"lleg6_joint";
802 data_ref.
M.triangularView<Eigen::StrictlyLower>() =
803 data_ref.
M.triangularView<Eigen::StrictlyUpper>().transpose();
821 H.middleRows<6>(0).rightCols(
model.nv) = J_RF;
822 H.middleRows<6>(6).rightCols(
model.nv) = J_LF;
824 H.triangularView<Eigen::StrictlyLower>() =
H.triangularView<Eigen::StrictlyUpper>().transpose();
832 data.M.triangularView<Eigen::StrictlyLower>() =
833 data.M.triangularView<Eigen::StrictlyUpper>().transpose();
835 Data::MatrixXs H_recomposed = contact_chol_decomposition.matrix();
837 BOOST_CHECK(H_recomposed.bottomRightCorner(
model.nv,
model.nv).isApprox(
data.M));
840 BOOST_CHECK(H_recomposed.isApprox(
H));
843 MatrixXd H_inv(contact_chol_decomposition.size(), contact_chol_decomposition.size());
844 contact_chol_decomposition.inverse(H_inv);
846 MatrixXd H_inv_ref = H_recomposed.inverse();
847 BOOST_CHECK(H_inv.isApprox(H_inv_ref));
850 MatrixXd JMinvJt =
H.middleRows<12>(0).rightCols(
model.nv) * data_ref.
M.inverse()
851 *
H.middleRows<12>(0).rightCols(
model.nv).transpose();
852 MatrixXd iosim = contact_chol_decomposition.getInverseOperationalSpaceInertiaMatrix();
853 MatrixXd osim = contact_chol_decomposition.getOperationalSpaceInertiaMatrix();
855 BOOST_CHECK(iosim.isApprox(JMinvJt));
856 BOOST_CHECK(osim.isApprox(JMinvJt.inverse()));
859 data_ref.
Minv = data_ref.
M.inverse();
860 Eigen::MatrixXd Minv_test(Eigen::MatrixXd::Zero(
model.nv,
model.nv));
861 contact_chol_decomposition.getInverseMassMatrix(Minv_test);
863 Eigen::MatrixXd JMinv_test(Eigen::MatrixXd::Zero(12,
model.nv));
864 contact_chol_decomposition.getJMinv(JMinv_test);
865 MatrixXd JMinv_ref =
H.middleRows<12>(0).rightCols(
model.nv) * data_ref.
M.inverse();
866 BOOST_CHECK(JMinv_ref.isApprox(JMinv_test));
868 BOOST_CHECK(Minv_test.isApprox(data_ref.
Minv));
873 using namespace Eigen;
881 model.lowerPositionLimit.head<3>().
fill(-1.);
882 model.upperPositionLimit.head<3>().
fill(1.);
885 const std::string RF =
"rleg6_joint";
886 const std::string LF =
"lleg6_joint";
887 const std::string RA =
"rarm6_joint";
888 const std::string LA =
"larm6_joint";
907 data_ref.
M.triangularView<Eigen::StrictlyLower>() =
908 data_ref.
M.triangularView<Eigen::StrictlyUpper>().transpose();
927 const SE3 oMRA_wla =
SE3(SE3::Matrix3::Identity(), ci_RA.joint1_placement.translation());
929 const double mu = 0.1;
934 H.middleRows<6>(0).rightCols(
model.nv) = -ci_RF.joint1_placement.toActionMatrixInverse() * J_RF;
935 H.middleRows<6>(6).rightCols(
model.nv) = -ci_LF.joint1_placement.toActionMatrixInverse() * J_LF;
936 H.middleRows<6>(12).rightCols(
model.nv) = -oMRA_wla.toActionMatrixInverse() * J_RA;
937 H.middleRows<6>(18).rightCols(
model.nv) = -ci_LA.joint1_placement.toActionMatrixInverse() * J_LA;
939 H.triangularView<Eigen::StrictlyLower>() =
H.triangularView<Eigen::StrictlyUpper>().transpose();
947 data.M.triangularView<Eigen::StrictlyLower>() =
948 data.M.triangularView<Eigen::StrictlyUpper>().transpose();
950 Data::MatrixXs H_recomposed = contact_chol_decomposition.matrix();
952 BOOST_CHECK(H_recomposed.bottomRightCorner(
model.nv,
model.nv).isApprox(
data.M));
955 BOOST_CHECK(H_recomposed.isApprox(
H));
957 VectorXd v_in(VectorXd::Random(contact_chol_decomposition.size()));
958 MatrixXd mat_in(MatrixXd::Random(contact_chol_decomposition.size(), 20));
961 VectorXd Uv_op_res(v_in), Uv_op_ref(v_in);
963 contact_chol_decomposition.Uv(Uv_op_res);
964 Uv_op_ref.noalias() = contact_chol_decomposition.U * v_in;
966 BOOST_CHECK(Uv_op_res.isApprox(Uv_op_ref));
968 MatrixXd Uv_mat_op_res(mat_in), Uv_mat_op_ref(mat_in);
970 contact_chol_decomposition.Uv(Uv_mat_op_res);
971 Uv_mat_op_ref.noalias() = contact_chol_decomposition.U * mat_in;
973 BOOST_CHECK(Uv_mat_op_res.isApprox(Uv_mat_op_ref));
976 VectorXd Utv_op_res(v_in), Utv_op_ref(v_in);
978 contact_chol_decomposition.Utv(Utv_op_res);
979 Utv_op_ref.noalias() = contact_chol_decomposition.U.transpose() * v_in;
981 BOOST_CHECK(Utv_op_res.isApprox(Utv_op_ref));
983 MatrixXd Utv_mat_op_res(mat_in), Utv_mat_op_ref(mat_in);
985 contact_chol_decomposition.Utv(Utv_mat_op_res);
986 Utv_mat_op_ref.noalias() = contact_chol_decomposition.U.transpose() * mat_in;
988 BOOST_CHECK(Utv_mat_op_res.isApprox(Utv_mat_op_ref));
991 VectorXd Uiv_op_res(v_in), Uiv_op_ref(v_in);
993 contact_chol_decomposition.Uiv(Uiv_op_res);
994 Uiv_op_ref.noalias() = contact_chol_decomposition.U.inverse() * v_in;
996 BOOST_CHECK(Uiv_op_res.isApprox(Uiv_op_ref));
998 MatrixXd Uiv_mat_op_res(mat_in), Uiv_mat_op_ref(mat_in);
1000 contact_chol_decomposition.Uiv(Uiv_mat_op_res);
1001 Uiv_mat_op_ref.noalias() = contact_chol_decomposition.U.inverse() * mat_in;
1003 BOOST_CHECK(Uiv_mat_op_res.isApprox(Uiv_mat_op_ref));
1006 VectorXd Utiv_op_res(v_in), Utiv_op_ref(v_in);
1008 contact_chol_decomposition.Utiv(Utiv_op_res);
1009 Utiv_op_ref.noalias() = contact_chol_decomposition.U.inverse().transpose() * v_in;
1011 BOOST_CHECK(Utiv_op_res.isApprox(Utiv_op_ref));
1013 MatrixXd Utiv_mat_op_res(mat_in), Utiv_mat_op_ref(mat_in);
1015 contact_chol_decomposition.Utiv(Utiv_mat_op_res);
1016 Utiv_mat_op_ref.noalias() = contact_chol_decomposition.U.inverse().transpose() * mat_in;
1018 BOOST_CHECK(Utiv_mat_op_res.isApprox(Utiv_mat_op_ref));
1021 MatrixXd H_inv(contact_chol_decomposition.size(), contact_chol_decomposition.size());
1022 contact_chol_decomposition.inverse(H_inv);
1024 MatrixXd H_inv2 = contact_chol_decomposition.U.transpose().inverse()
1025 * contact_chol_decomposition.Dinv.asDiagonal()
1026 * contact_chol_decomposition.U.inverse();
1029 MatrixXd::Identity(contact_chol_decomposition.size(), contact_chol_decomposition.size());
1030 contact_chol_decomposition.solveInPlace(H_inv3);
1032 MatrixXd H_inv_ref = H_recomposed.inverse();
1035 BOOST_CHECK(H_inv.bottomRightCorner(
model.nv,
model.nv)
1036 .isApprox(H_inv_ref.bottomRightCorner(
model.nv,
model.nv)));
1040 BOOST_CHECK(H_inv_ref.isApprox(H_inv));
1041 BOOST_CHECK(H_inv_ref.isApprox(H_inv2));
1042 BOOST_CHECK(H_inv_ref.isApprox(H_inv3));
1043 const VectorXd ei = VectorXd::Unit(contact_chol_decomposition.size(),
constraint_dim);
1044 VectorXd ei_inv = ei;
1045 contact_chol_decomposition.solveInPlace(ei_inv);
1046 VectorXd ei_inv2 = ei;
1047 contact_chol_decomposition.Uiv(ei_inv2);
1048 ei_inv2 = contact_chol_decomposition.Dinv.asDiagonal() * ei_inv2;
1049 contact_chol_decomposition.Utiv(ei_inv2);
1051 BOOST_CHECK(ei_inv.isApprox(H_inv_ref * ei));
1052 BOOST_CHECK(ei_inv2.isApprox(H_inv_ref * ei));
1053 BOOST_CHECK(ei_inv.isApprox(H_inv * ei));
1054 BOOST_CHECK(ei_inv2.isApprox(H_inv * ei));
1057 MatrixXd JMinvJt =
H.middleRows<24>(0).rightCols(
model.nv) * data_ref.
M.inverse()
1058 *
H.middleRows<24>(0).rightCols(
model.nv).transpose()
1059 +
mu * Eigen::MatrixXd::Identity(24, 24);
1060 MatrixXd iosim = contact_chol_decomposition.getInverseOperationalSpaceInertiaMatrix();
1061 MatrixXd osim = contact_chol_decomposition.getOperationalSpaceInertiaMatrix();
1063 BOOST_CHECK(iosim.isApprox(JMinvJt));
1064 BOOST_CHECK(osim.isApprox(JMinvJt.inverse()));
1067 data_ref.
Minv = data_ref.
M.inverse();
1068 Eigen::MatrixXd Minv_test(Eigen::MatrixXd::Zero(
model.nv,
model.nv));
1069 contact_chol_decomposition.getInverseMassMatrix(Minv_test);
1071 BOOST_CHECK(Minv_test.isApprox(data_ref.
Minv));
1072 Eigen::MatrixXd JMinv_test(Eigen::MatrixXd::Zero(24,
model.nv));
1073 contact_chol_decomposition.getJMinv(JMinv_test);
1074 MatrixXd JMinv_ref =
H.middleRows<24>(0).rightCols(
model.nv) * data_ref.
M.inverse();
1075 BOOST_CHECK(JMinv_ref.isApprox(JMinv_test));
1080 using namespace Eigen;
1088 model.lowerPositionLimit.head<3>().
fill(-1.);
1089 model.upperPositionLimit.head<3>().
fill(1.);
1092 const std::string RF =
"rleg6_joint";
1093 const std::string LF =
"lleg6_joint";
1094 const std::string RA =
"rarm6_joint";
1095 const std::string LA =
"larm6_joint";
1114 data_ref.
M.triangularView<Eigen::StrictlyLower>() =
1115 data_ref.
M.triangularView<Eigen::StrictlyUpper>().transpose();
1137 H.middleRows<6>(0).rightCols(
model.nv) = -ci_RF.joint1_placement.toActionMatrix() * J_RF;
1138 H.middleRows<3>(6).rightCols(
model.nv) =
1139 -data_ref.oMi[
model.getJointId(LF)].rotation() * J_LF.middleRows<3>(Motion::LINEAR);
1140 H.middleRows<3>(9).rightCols(
model.nv) =
1141 -data_ref.oMi[
model.getJointId(RA)].rotation() * J_RA.middleRows<3>(Motion::LINEAR);
1142 H.middleRows<3>(12).rightCols(
model.nv) = -J_LA.middleRows<3>(Motion::LINEAR);
1144 H.triangularView<Eigen::StrictlyLower>() =
H.triangularView<Eigen::StrictlyUpper>().transpose();
1153 data.M.triangularView<Eigen::StrictlyLower>() =
1154 data.M.triangularView<Eigen::StrictlyUpper>().transpose();
1156 BOOST_CHECK(data_ref.
D.isApprox(contact_chol_decomposition.D.tail(
model.nv)));
1157 BOOST_CHECK(data_ref.
Dinv.isApprox(contact_chol_decomposition.Dinv.tail(
model.nv)));
1159 data_ref.
U.isApprox(contact_chol_decomposition.U.bottomRightCorner(
model.nv,
model.nv)));
1162 contact_chol_decomposition.U.bottomRightCorner(
model.nv,
model.nv)
1163 * contact_chol_decomposition.D.tail(
model.nv).asDiagonal()
1164 * contact_chol_decomposition.U.bottomRightCorner(
model.nv,
model.nv).transpose();
1165 BOOST_CHECK(M_recomposed.isApprox(
data.M));
1168 * contact_chol_decomposition.D.asDiagonal()
1169 * contact_chol_decomposition.U.transpose();
1171 BOOST_CHECK(H_recomposed.bottomRightCorner(
model.nv,
model.nv).isApprox(
data.M));
1174 BOOST_CHECK(H_recomposed.isApprox(
H));
1177 MatrixXd JMinvJt =
H.middleRows<15>(0).rightCols(
model.nv) * data_ref.
M.inverse()
1178 *
H.middleRows<15>(0).rightCols(
model.nv).transpose();
1179 MatrixXd iosim = contact_chol_decomposition.getInverseOperationalSpaceInertiaMatrix();
1180 MatrixXd osim = contact_chol_decomposition.getOperationalSpaceInertiaMatrix();
1182 BOOST_CHECK(iosim.isApprox(JMinvJt));
1183 BOOST_CHECK(osim.isApprox(JMinvJt.inverse()));
1186 data_ref.
Minv = data_ref.
M.inverse();
1187 Eigen::MatrixXd Minv_test(Eigen::MatrixXd::Zero(
model.nv,
model.nv));
1188 contact_chol_decomposition.getInverseMassMatrix(Minv_test);
1190 BOOST_CHECK(Minv_test.isApprox(data_ref.
Minv));
1191 Eigen::MatrixXd JMinv_test(Eigen::MatrixXd::Zero(15,
model.nv));
1192 contact_chol_decomposition.getJMinv(JMinv_test);
1193 MatrixXd JMinv_ref =
H.middleRows<15>(0).rightCols(
model.nv) * data_ref.
M.inverse();
1194 BOOST_CHECK(JMinv_ref.isApprox(JMinv_test));
1199 using namespace Eigen;
1207 model.lowerPositionLimit.head<3>().
fill(-1.);
1208 model.upperPositionLimit.head<3>().
fill(1.);
1211 const std::string RF =
"rleg6_joint";
1212 const std::string LF =
"lleg6_joint";
1213 const std::string RA =
"rarm6_joint";
1214 const std::string LA =
"larm6_joint";
1223 loop_RF_LF_local.joint1_placement.setRandom();
1224 loop_RF_LF_local.joint2_placement.setRandom();
1226 loop_RA_LA_lwa.joint1_placement.setRandom();
1227 loop_RA_LA_lwa.joint2_placement.setRandom();
1237 data_ref.
M.triangularView<Eigen::StrictlyLower>() =
1238 data_ref.
M.triangularView<Eigen::StrictlyUpper>().transpose();
1241 const double mu = 0.1;
1246 J_LA_local(6,
model.nv);
1249 Data::Matrix6x J_RF_local = loop_RF_LF_local.joint1_placement.toActionMatrixInverse() * J_RF;
1252 Data::Matrix6x J_LF_local = loop_RF_LF_local.joint2_placement.toActionMatrixInverse() * J_LF;
1253 J_RA_local.setZero();
1255 J_RA_local = loop_RA_LA_lwa.joint1_placement.toActionMatrixInverse() * J_RA_local;
1256 J_LA_local.setZero();
1258 J_LA_local = loop_RA_LA_lwa.joint2_placement.toActionMatrixInverse() * J_LA_local;
1261 J_RF_world.setZero();
1263 J_LF_world.setZero();
1267 const SE3 oM1_loop1 =
1268 data_ref.oMi[loop_RF_LF_local.joint1_id] * loop_RF_LF_local.joint1_placement;
1269 const SE3 oM2_loop1 =
1270 data_ref.oMi[loop_RF_LF_local.joint2_id] * loop_RF_LF_local.joint2_placement;
1271 const SE3 _1M2_loop1 = oM1_loop1.
inverse() * oM2_loop1;
1272 const SE3 oM1_loop2 = data_ref.oMi[loop_RA_LA_lwa.joint1_id] * loop_RA_LA_lwa.joint1_placement;
1273 const SE3 oM2_loop2 = data_ref.oMi[loop_RA_LA_lwa.joint2_id] * loop_RA_LA_lwa.joint2_placement;
1274 const SE3 _1M2_loop2 = oM1_loop2.
inverse() * oM2_loop2;
1283 H.middleRows<6>(0).rightCols(
model.nv) = J_RF_local - _1M2_loop1.toActionMatrix() * J_LF_local;
1284 const SE3 oM1_loop2_lwa =
SE3(oM1_loop2.
rotation(), SE3::Vector3::Zero());
1285 H.middleRows<6>(6).rightCols(
model.nv) =
1286 oM1_loop2_lwa.toActionMatrix() * J_RA_local
1287 - (oM1_loop2_lwa.toActionMatrix() * _1M2_loop2.toActionMatrix()) * J_LA_local;
1289 H.triangularView<Eigen::StrictlyLower>() =
H.triangularView<Eigen::StrictlyUpper>().transpose();
1297 Data::MatrixXs H_recomposed = contact_chol_decomposition.matrix();
1299 data.M.triangularView<Eigen::StrictlyLower>() =
1300 data.M.triangularView<Eigen::StrictlyUpper>().transpose();
1301 BOOST_CHECK(H_recomposed.bottomRightCorner(
model.nv,
model.nv).isApprox(
data.M));
1304 BOOST_CHECK(H_recomposed.isApprox(
H));
1307 MatrixXd H_inv(contact_chol_decomposition.size(), contact_chol_decomposition.size());
1308 contact_chol_decomposition.inverse(H_inv);
1310 MatrixXd H_inv_ref = H_recomposed.inverse();
1312 BOOST_CHECK(H_inv_ref.isApprox(H_inv));
1315 MatrixXd JMinvJt =
H.middleRows<12>(0).rightCols(
model.nv) * data_ref.
M.inverse()
1316 *
H.middleRows<12>(0).rightCols(
model.nv).transpose()
1317 +
mu * Eigen::MatrixXd::Identity(12, 12);
1318 MatrixXd iosim = contact_chol_decomposition.getInverseOperationalSpaceInertiaMatrix();
1319 MatrixXd osim = contact_chol_decomposition.getOperationalSpaceInertiaMatrix();
1321 BOOST_CHECK(iosim.isApprox(JMinvJt));
1322 BOOST_CHECK(osim.isApprox(JMinvJt.inverse()));
1325 data_ref.
Minv = data_ref.
M.inverse();
1326 Eigen::MatrixXd Minv_test(Eigen::MatrixXd::Zero(
model.nv,
model.nv));
1327 contact_chol_decomposition.getInverseMassMatrix(Minv_test);
1329 BOOST_CHECK(Minv_test.isApprox(data_ref.
Minv));
1330 Eigen::MatrixXd JMinv_test(Eigen::MatrixXd::Zero(12,
model.nv));
1331 contact_chol_decomposition.getJMinv(JMinv_test);
1332 MatrixXd JMinv_ref =
H.middleRows<12>(0).rightCols(
model.nv) * data_ref.
M.inverse();
1333 BOOST_CHECK(JMinv_ref.isApprox(JMinv_test));
1338 using namespace Eigen;
1346 model.lowerPositionLimit.head<3>().
fill(-1.);
1347 model.upperPositionLimit.head<3>().
fill(1.);
1350 const std::string RF =
"rleg6_joint";
1351 const std::string LF =
"lleg6_joint";
1352 const std::string RA =
"rarm6_joint";
1353 const std::string LA =
"larm6_joint";
1362 loop_RF_LF_local.joint1_placement.setRandom();
1363 loop_RF_LF_local.joint2_placement.setRandom();
1365 loop_RA_LA_lwa.joint1_placement.setRandom();
1366 loop_RA_LA_lwa.joint2_placement.setRandom();
1376 data_ref.
M.triangularView<Eigen::StrictlyLower>() =
1377 data_ref.
M.triangularView<Eigen::StrictlyUpper>().transpose();
1380 const double mu = 0.1;
1385 J_LA_local(6,
model.nv);
1389 loop_RF_LF_local.joint1_placement.toActionMatrixInverse() * J_RF;
1393 loop_RF_LF_local.joint2_placement.toActionMatrixInverse() * J_LF;
1394 J_RA_local.setZero();
1396 J_RA_local = loop_RA_LA_lwa.joint1_placement.toActionMatrixInverse() * J_RA_local;
1397 J_LA_local.setZero();
1399 J_LA_local = loop_RA_LA_lwa.joint2_placement.toActionMatrixInverse() * J_LA_local;
1402 J_RF_world.setZero();
1404 J_LF_world.setZero();
1408 const SE3 oM1_loop1 =
1409 data_ref.oMi[loop_RF_LF_local.joint1_id] * loop_RF_LF_local.joint1_placement;
1410 const SE3 oM2_loop1 =
1411 data_ref.oMi[loop_RF_LF_local.joint2_id] * loop_RF_LF_local.joint2_placement;
1412 const SE3 _1M2_loop1 = oM1_loop1.
inverse() * oM2_loop1;
1413 const SE3 oM1_loop2 = data_ref.oMi[loop_RA_LA_lwa.joint1_id] * loop_RA_LA_lwa.joint1_placement;
1414 const SE3 oM2_loop2 = data_ref.oMi[loop_RA_LA_lwa.joint2_id] * loop_RA_LA_lwa.joint2_placement;
1415 const SE3 _1M2_loop2 = oM1_loop2.
inverse() * oM2_loop2;
1424 H.middleRows<3>(0).rightCols(
model.nv) =
1425 J_RF_local.middleRows<3>(Motion::LINEAR)
1426 - _1M2_loop1.
rotation() * J_LF_local.middleRows<3>(Motion::LINEAR);
1427 const SE3 oM1_loop2_lwa =
SE3(oM1_loop2.
rotation(), SE3::Vector3::Zero());
1428 const SE3 oM2_loop2_lwa =
SE3(oM2_loop2.
rotation(), SE3::Vector3::Zero());
1429 H.middleRows<3>(3).rightCols(
model.nv) =
1430 (oM1_loop2_lwa.toActionMatrix() * J_RA_local - (oM2_loop2_lwa.toActionMatrix()) * J_LA_local)
1431 .middleRows<3>(Motion::LINEAR);
1433 H.triangularView<Eigen::StrictlyLower>() =
H.triangularView<Eigen::StrictlyUpper>().transpose();
1443 Data::MatrixXs H_recomposed = contact_chol_decomposition.matrix();
1445 data.M.triangularView<Eigen::StrictlyLower>() =
1446 data.M.triangularView<Eigen::StrictlyUpper>().transpose();
1447 BOOST_CHECK(H_recomposed.bottomRightCorner(
model.nv,
model.nv).isApprox(
data.M));
1450 BOOST_CHECK(H_recomposed.isApprox(
H));
1458 MatrixXd H_inv(contact_chol_decomposition.size(), contact_chol_decomposition.size());
1459 contact_chol_decomposition.inverse(H_inv);
1461 MatrixXd H_inv_ref = H_recomposed.inverse();
1463 BOOST_CHECK(H_inv_ref.isApprox(H_inv));
1466 MatrixXd JMinvJt =
H.middleRows<6>(0).rightCols(
model.nv) * data_ref.
M.inverse()
1467 *
H.middleRows<6>(0).rightCols(
model.nv).transpose()
1468 +
mu * Eigen::MatrixXd::Identity(6, 6);
1469 MatrixXd iosim = contact_chol_decomposition.getInverseOperationalSpaceInertiaMatrix();
1470 MatrixXd osim = contact_chol_decomposition.getOperationalSpaceInertiaMatrix();
1472 BOOST_CHECK(iosim.isApprox(JMinvJt));
1473 BOOST_CHECK(osim.isApprox(JMinvJt.inverse()));
1476 data_ref.
Minv = data_ref.
M.inverse();
1477 Eigen::MatrixXd Minv_test(Eigen::MatrixXd::Zero(
model.nv,
model.nv));
1478 contact_chol_decomposition.getInverseMassMatrix(Minv_test);
1480 Eigen::MatrixXd JMinv_test(Eigen::MatrixXd::Zero(6,
model.nv));
1481 contact_chol_decomposition.getJMinv(JMinv_test);
1482 MatrixXd JMinv_ref =
H.middleRows<6>(0).rightCols(
model.nv) * data_ref.
M.inverse();
1483 BOOST_CHECK(JMinv_ref.isApprox(JMinv_test));
1484 BOOST_CHECK(Minv_test.isApprox(data_ref.
Minv));
1489 using namespace Eigen;
1497 model.lowerPositionLimit.head<3>().
fill(-1.);
1498 model.upperPositionLimit.head<3>().
fill(1.);
1501 const std::string RF =
"rleg6_joint";
1502 const std::string LF =
"lleg6_joint";
1516 const double mu1 = 1e-2, mu2 = 1e-10;
1522 contact_chol_decomposition.updateDamping(mu2);
1528 BOOST_CHECK(contact_chol_decomposition.D.isApprox(contact_chol_decomposition_ref.D));
1529 BOOST_CHECK(contact_chol_decomposition.Dinv.isApprox(contact_chol_decomposition_ref.Dinv));
1530 BOOST_CHECK(contact_chol_decomposition.U.isApprox(contact_chol_decomposition_ref.U));
1537 contact_chol_decomposition.getDelassusCholeskyExpression().updateDamping(mu2);
1543 BOOST_CHECK(contact_chol_decomposition.D.isApprox(contact_chol_decomposition_ref.D));
1544 BOOST_CHECK(contact_chol_decomposition.Dinv.isApprox(contact_chol_decomposition_ref.Dinv));
1545 BOOST_CHECK(contact_chol_decomposition.U.isApprox(contact_chol_decomposition_ref.U));
1549 BOOST_AUTO_TEST_SUITE_END()