GCC Code Coverage Report


Directory: ./
File: unittest/test_contact_costs.cpp
Date: 2025-06-03 08:14:12
Exec Total Coverage
Lines: 0 55 0.0%
Functions: 0 4 0.0%
Branches: 0 252 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_cost.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 ContactCostModelTypes::Type cost_type, PinocchioModelTypes::Type model_type,
22 ActivationModelTypes::Type activation_type,
23 ActuationModelTypes::Type actuation_type) {
24 // create the model
25 const std::shared_ptr<crocoddyl::DifferentialActionModelAbstract>& model =
26 ✗ ContactCostModelFactory().create(cost_type, model_type, activation_type,
27 ✗ actuation_type);
28
29 // create the corresponding data object and set the cost 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->Lx - data_num_diff->Lx).isZero(tol));
50 ✗ BOOST_CHECK((data->Lu - data_num_diff->Lu).isZero(tol));
51 ✗ if (model_num_diff.get_with_gauss_approx()) {
52 ✗ BOOST_CHECK((data->Lxx - data_num_diff->Lxx).isZero(tol));
53 ✗ BOOST_CHECK((data->Lxu - data_num_diff->Lxu).isZero(tol));
54 ✗ BOOST_CHECK((data->Luu - data_num_diff->Luu).isZero(tol));
55 }
56
57 // Computing the action derivatives
58 ✗ x = model->get_state()->rand();
59 ✗ model->calc(data, x);
60 ✗ model->calcDiff(data, x);
61 ✗ model_num_diff.calc(data_num_diff, x);
62 ✗ model_num_diff.calcDiff(data_num_diff, x);
63 ✗ BOOST_CHECK((data->Lx - data_num_diff->Lx).isZero(tol));
64 ✗ if (model_num_diff.get_with_gauss_approx()) {
65 ✗ BOOST_CHECK((data->Lxx - data_num_diff->Lxx).isZero(tol));
66 }
67
68 // Checking that casted computation is the same
69 #ifdef NDEBUG // Run only in release mode
70 const std::shared_ptr<crocoddyl::DifferentialActionModelAbstractTpl<float>>&
71 casted_model = model->cast<float>();
72 const std::shared_ptr<crocoddyl::DifferentialActionDataAbstractTpl<float>>&
73 casted_data = casted_model->createData();
74 Eigen::VectorXf x_f = x.cast<float>();
75 const Eigen::VectorXf u_f = u.cast<float>();
76 model->calc(data, x, u);
77 model->calcDiff(data, x, u);
78 casted_model->calc(casted_data, x_f, u_f);
79 casted_model->calcDiff(casted_data, x_f, u_f);
80 float tol_f = 10.f * std::sqrt(2.0f * std::numeric_limits<float>::epsilon());
81 BOOST_CHECK((data->Lx.cast<float>() - casted_data->Lx).isZero(tol_f));
82 BOOST_CHECK((data->Lu.cast<float>() - casted_data->Lu).isZero(tol_f));
83 BOOST_CHECK((data->Lxx.cast<float>() - casted_data->Lxx).isZero(tol_f));
84 BOOST_CHECK((data->Lxu.cast<float>() - casted_data->Lxu).isZero(tol_f));
85 BOOST_CHECK((data->Luu.cast<float>() - casted_data->Luu).isZero(tol_f));
86 model->calc(data, x);
87 model->calcDiff(data, x);
88 casted_model->calc(casted_data, x_f);
89 casted_model->calcDiff(casted_data, x_f);
90 BOOST_CHECK((data->Lx.cast<float>() - casted_data->Lx).isZero(tol_f));
91 BOOST_CHECK((data->Lxx.cast<float>() - casted_data->Lxx).isZero(tol_f));
92 #endif
93 ✗ }
94
95 //----------------------------------------------------------------------------//
96
97 ✗ void register_contact_cost_model_unit_tests(
98 ContactCostModelTypes::Type cost_type, PinocchioModelTypes::Type model_type,
99 ActivationModelTypes::Type activation_type,
100 ActuationModelTypes::Type actuation_type) {
101 ✗ boost::test_tools::output_test_stream test_name;
102 ✗ test_name << "test_" << cost_type << "_" << activation_type << "_"
103 ✗ << actuation_type << "_" << model_type;
104 ✗ std::cout << "Running " << test_name.str() << std::endl;
105 ✗ test_suite* ts = BOOST_TEST_SUITE(test_name.str());
106 ✗ ts->add(BOOST_TEST_CASE(
107 boost::bind(&test_partial_derivatives_against_contact_numdiff, cost_type,
108 model_type, activation_type, actuation_type)));
109 ✗ framework::master_test_suite().add(ts);
110 ✗ }
111
112 ✗ bool init_function() {
113 // Test all the contact cost model. Note that we can do it only with humanoids
114 // as it needs to test the contact wrench cone
115 ✗ for (std::size_t cost_type = 0; cost_type < ContactCostModelTypes::all.size();
116 ++cost_type) {
117 ✗ for (std::size_t activation_type = 0;
118 ✗ activation_type <
119 ActivationModelTypes::ActivationModelQuadraticBarrier;
120 ++activation_type) {
121 ✗ register_contact_cost_model_unit_tests(
122 ✗ ContactCostModelTypes::all[cost_type], PinocchioModelTypes::Talos,
123 ✗ ActivationModelTypes::all[activation_type],
124 ActuationModelTypes::ActuationModelFloatingBase);
125 ✗ if (ContactCostModelTypes::all[cost_type] ==
126 ✗ ContactCostModelTypes::CostModelResidualContactForce ||
127 ✗ ContactCostModelTypes::all[cost_type] ==
128 ✗ ContactCostModelTypes::CostModelResidualContactFrictionCone ||
129 ✗ ContactCostModelTypes::all[cost_type] ==
130 ContactCostModelTypes::CostModelResidualContactControlGrav) {
131 ✗ register_contact_cost_model_unit_tests(
132 ✗ ContactCostModelTypes::all[cost_type], PinocchioModelTypes::HyQ,
133 ✗ ActivationModelTypes::all[activation_type],
134 ActuationModelTypes::ActuationModelFloatingBase);
135 }
136 }
137 }
138
139 ✗ return true;
140 }
141
142 ✗ int main(int argc, char** argv) {
143 ✗ return ::boost::unit_test::unit_test_main(&init_function, argc, argv);
144 }
145