GCC Code Coverage Report


Directory: ./
File: unittest/test_contact_constraints.cpp
Date: 2025-05-13 10:30:51
Exec Total Coverage
Lines: 0 49 0.0%
Branches: 0 220 0.0%

Line Branch Exec Source
1 ///////////////////////////////////////////////////////////////////////////////
2 // BSD 3-Clause License
3 //
4 // Copyright (C) 2021-2025, University of Edinburgh, Heriot-Watt University
5 // Copyright note valid unless otherwise stated in individual files.
6 // All rights reserved.
7 ///////////////////////////////////////////////////////////////////////////////
8
9 #define BOOST_TEST_NO_MAIN
10 #define BOOST_TEST_ALTERNATIVE_INIT_API
11
12 #include "factory/contact_constraint.hpp"
13 #include "unittest_common.hpp"
14
15 using namespace boost::unit_test;
16 using namespace crocoddyl::unittest;
17
18 //----------------------------------------------------------------------------//
19
20 void test_partial_derivatives_against_contact_numdiff(
21 ContactConstraintModelTypes::Type constraint_type,
22 PinocchioModelTypes::Type model_type,
23 ActuationModelTypes::Type actuation_type) {
24 // create the model
25 const std::shared_ptr<crocoddyl::DifferentialActionModelAbstract> &model =
26 ContactConstraintModelFactory().create(constraint_type, model_type,
27 actuation_type);
28
29 // create the corresponding data object and set the constraint to nan
30 const std::shared_ptr<crocoddyl::DifferentialActionDataAbstract> &data =
31 model->createData();
32
33 crocoddyl::DifferentialActionModelNumDiff model_num_diff(model);
34 const std::shared_ptr<crocoddyl::DifferentialActionDataAbstract>
35 &data_num_diff = model_num_diff.createData();
36
37 // Generating random values for the state and control
38 Eigen::VectorXd x = model->get_state()->rand();
39 const Eigen::VectorXd u = Eigen::VectorXd::Random(model->get_nu());
40
41 // Computing the action derivatives
42 model->calc(data, x, u);
43 model->calcDiff(data, x, u);
44 model_num_diff.calc(data_num_diff, x, u);
45 model_num_diff.calcDiff(data_num_diff, x, u);
46 // Tolerance defined as in
47 // http://www.it.uom.gr/teaching/linearalgebra/NumericalRecipiesInC/c5-7.pdf
48 double tol = std::pow(model_num_diff.get_disturbance(), 1. / 3.);
49 BOOST_CHECK((data->Gx - data_num_diff->Gx).isZero(tol));
50 BOOST_CHECK((data->Gu - data_num_diff->Gu).isZero(tol));
51 BOOST_CHECK((data->Hx - data_num_diff->Hx).isZero(tol));
52 BOOST_CHECK((data->Hu - data_num_diff->Hu).isZero(tol));
53
54 // Computing the action derivatives
55 x = model->get_state()->rand();
56 model->calc(data, x);
57 model->calcDiff(data, x);
58 model_num_diff.calc(data_num_diff, x);
59 model_num_diff.calcDiff(data_num_diff, x);
60 BOOST_CHECK((data->Gx - data_num_diff->Gx).isZero(tol));
61 BOOST_CHECK((data->Hx - data_num_diff->Hx).isZero(tol));
62
63 // Checking that casted computation is the same
64 #ifdef NDEBUG // Run only in release mode
65 const std::shared_ptr<crocoddyl::DifferentialActionModelAbstractTpl<float>>
66 &casted_model = model->cast<float>();
67 const std::shared_ptr<crocoddyl::DifferentialActionDataAbstractTpl<float>>
68 &casted_data = casted_model->createData();
69 Eigen::VectorXf x_f = x.cast<float>();
70 const Eigen::VectorXf u_f = u.cast<float>();
71 model->calc(data, x, u);
72 model->calcDiff(data, x, u);
73 casted_model->calc(casted_data, x_f, u_f);
74 casted_model->calcDiff(casted_data, x_f, u_f);
75 float tol_f = 10.f * std::sqrt(2.0f * std::numeric_limits<float>::epsilon());
76 BOOST_CHECK((data->Gx.cast<float>() - casted_data->Gx).isZero(tol_f));
77 BOOST_CHECK((data->Gu.cast<float>() - casted_data->Gu).isZero(tol_f));
78 BOOST_CHECK((data->Hx.cast<float>() - casted_data->Hx).isZero(tol_f));
79 BOOST_CHECK((data->Hu.cast<float>() - casted_data->Hu).isZero(tol_f));
80 model->calc(data, x);
81 model->calcDiff(data, x);
82 casted_model->calc(casted_data, x_f);
83 casted_model->calcDiff(casted_data, x_f);
84 BOOST_CHECK((data->Gx.cast<float>() - casted_data->Gx).isZero(tol_f));
85 BOOST_CHECK((data->Hx.cast<float>() - casted_data->Hx).isZero(tol_f));
86 #endif
87 }
88
89 //----------------------------------------------------------------------------//
90
91 void register_contact_constraint_model_unit_tests(
92 ContactConstraintModelTypes::Type constraint_type,
93 PinocchioModelTypes::Type model_type,
94 ActuationModelTypes::Type actuation_type) {
95 boost::test_tools::output_test_stream test_name;
96 test_name << "test_" << constraint_type << "_" << actuation_type << "_"
97 << model_type;
98 std::cout << "Running " << test_name.str() << std::endl;
99 test_suite *ts = BOOST_TEST_SUITE(test_name.str());
100 ts->add(BOOST_TEST_CASE(
101 boost::bind(&test_partial_derivatives_against_contact_numdiff,
102 constraint_type, model_type, actuation_type)));
103 framework::master_test_suite().add(ts);
104 }
105
106 bool init_function() {
107 // Test all the contact constraint model. Note that we can do it only with
108 // humanoids as it needs to test the contact wrench cone
109 for (size_t constraint_type = 0;
110 constraint_type < ContactConstraintModelTypes::all.size();
111 ++constraint_type) {
112 register_contact_constraint_model_unit_tests(
113 ContactConstraintModelTypes::all[constraint_type],
114 PinocchioModelTypes::Talos,
115 ActuationModelTypes::ActuationModelFloatingBase);
116 register_contact_constraint_model_unit_tests(
117 ContactConstraintModelTypes::all[constraint_type],
118 PinocchioModelTypes::RandomHumanoid,
119 ActuationModelTypes::ActuationModelFloatingBase);
120 if (ContactConstraintModelTypes::all[constraint_type] ==
121 ContactConstraintModelTypes::
122 ConstraintModelResidualContactForceEquality ||
123 ContactConstraintModelTypes::all[constraint_type] ==
124 ContactConstraintModelTypes::
125 ConstraintModelResidualContactFrictionConeInequality ||
126 ContactConstraintModelTypes::all[constraint_type] ==
127 ContactConstraintModelTypes::
128 ConstraintModelResidualContactControlGravInequality) {
129 register_contact_constraint_model_unit_tests(
130 ContactConstraintModelTypes::all[constraint_type],
131 PinocchioModelTypes::HyQ,
132 ActuationModelTypes::ActuationModelFloatingBase);
133 }
134 }
135 return true;
136 }
137
138 int main(int argc, char **argv) {
139 return ::boost::unit_test::unit_test_main(&init_function, argc, argv);
140 }
141