| 28 | BOOST_AUTO_TEST_SUITE(BOOST_TEST_MODULE) |
| 29 | |
| 30 | BOOST_AUTO_TEST_CASE(humanoid_with_bilateral_constraint_minimal) |
| 31 | { |
| 32 | // Construct humanoid |
| 33 | Model model; |
| 34 | buildModels::humanoid(model, true); |
| 35 | Data data(model); |
| 36 | |
| 37 | // Initial state |
| 38 | Eigen::VectorXd q = pinocchio::neutral(model); |
| 39 | Eigen::VectorXd v = Eigen::VectorXd::Zero(model.nv); |
| 40 | Eigen::VectorXd tau = Eigen::VectorXd::Zero(model.nv); |
| 41 | const double dt = 1e-3; |
| 42 | |
| 43 | // Compute vfree and crba for G and g |
| 44 | crba(model, data, q, Convention::WORLD); |
| 45 | const Eigen::VectorXd v_free = dt * aba(model, data, q, v, tau, Convention::WORLD); |
| 46 | |
| 47 | // Bilateral constraint on the robot right wrist |
| 48 | pinocchio::forwardKinematics(model, data, q); |
| 49 | const JointIndex joint1_id = 0; |
| 50 | const GeomIndex joint2_id = 14; |
| 51 | assert((int)joint2_id < model.njoints); |
| 52 | assert(model.nvs[joint2_id] == 1); // make sure its a bilaterable joint |
| 53 | ::pinocchio::SE3 Mc = data.oMi[joint2_id]; |
| 54 | const SE3 joint1_placement = Mc; |
| 55 | const SE3 joint2_placement = SE3::Identity(); |
| 56 | |
| 57 | using ConstraintModel = BilateralPointConstraintModel; |
| 58 | using ConstraintData = typename ConstraintModel::ConstraintData; |
| 59 | std::vector<ConstraintModel> constraint_models; |
| 60 | std::vector<ConstraintData> constraint_datas; |
| 61 | ConstraintModel cm(model, joint1_id, joint1_placement, joint2_id, joint2_placement); |
| 62 | constraint_models.push_back(cm); |
| 63 | constraint_datas.push_back(cm.createData()); |
| 64 | const Eigen::DenseIndex constraint_size = getTotalConstraintSize(constraint_models); |
| 65 | |
| 66 | // Delassus |
| 67 | ContactCholeskyDecomposition chol(model, constraint_models); |
| 68 | chol.compute(model, data, constraint_models, constraint_datas, 1e-10); |
| 69 | |
| 70 | // Solve constraint |
| 71 | const Eigen::MatrixXd delassus = chol.getDelassusCholeskyExpression().matrix(); |
| 72 | const DelassusOperatorDense G(delassus); |
| 73 | |
| 74 | Eigen::MatrixXd constraint_jacobian(delassus.rows(), model.nv); |
| 75 | constraint_jacobian.setZero(); |
| 76 | getConstraintsJacobian(model, data, constraint_models, constraint_datas, constraint_jacobian); |
| 77 | |
| 78 | const Eigen::VectorXd g = constraint_jacobian * v_free; |
| 79 | |
| 80 | PGSContactSolver pgs_solver(int(delassus.rows())); |
| 81 | pgs_solver.setAbsolutePrecision(1e-10); |
| 82 | pgs_solver.setRelativePrecision(1e-14); |
| 83 | pgs_solver.setMaxIterations(1000); |
| 84 | Eigen::VectorXd primal_solution = Eigen::VectorXd::Zero(constraint_size); |
| 85 | const bool has_converged = |
| 86 | pgs_solver.solve(G, g, constraint_models, dt, boost::make_optional((Eigen::Ref<const Eigen::VectorXd>)primal_solution)); |
| 87 | BOOST_CHECK(has_converged); |
nothing calls this directly
no outgoing calls
no test coverage detected