GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
/////////////////////////////////////////////////////////////////////////////// |
||
2 |
// BSD 3-Clause License |
||
3 |
// |
||
4 |
// Copyright (C) 2019-2023, LAAS-CNRS, New York University, |
||
5 |
// Max Planck Gesellschaft, INRIA, University of |
||
6 |
// Oxford, Heriot-Watt University |
||
7 |
// Copyright note valid unless otherwise stated in individual files. |
||
8 |
// All rights reserved. |
||
9 |
/////////////////////////////////////////////////////////////////////////////// |
||
10 |
|||
11 |
#define BOOST_TEST_NO_MAIN |
||
12 |
#define BOOST_TEST_ALTERNATIVE_INIT_API |
||
13 |
|||
14 |
#include "factory/diff_action.hpp" |
||
15 |
#include "unittest_common.hpp" |
||
16 |
|||
17 |
using namespace boost::unit_test; |
||
18 |
using namespace crocoddyl::unittest; |
||
19 |
|||
20 |
//----------------------------------------------------------------------------// |
||
21 |
|||
22 |
22 |
void test_check_data(DifferentialActionModelTypes::Type action_type) { |
|
23 |
// create the model |
||
24 |
✓✗ | 44 |
DifferentialActionModelFactory factory; |
25 |
boost::shared_ptr<crocoddyl::DifferentialActionModelAbstract> model = |
||
26 |
✓✗ | 44 |
factory.create(action_type); |
27 |
|||
28 |
// Run the print function |
||
29 |
✓✗ | 44 |
std::ostringstream tmp; |
30 |
✓✗ | 22 |
tmp << *model; |
31 |
|||
32 |
// create the corresponding data object |
||
33 |
boost::shared_ptr<crocoddyl::DifferentialActionDataAbstract> data = |
||
34 |
✓✗ | 44 |
model->createData(); |
35 |
|||
36 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
22 |
BOOST_CHECK(model->checkData(data)); |
37 |
22 |
} |
|
38 |
|||
39 |
22 |
void test_calc_returns_state(DifferentialActionModelTypes::Type action_type) { |
|
40 |
// create the model |
||
41 |
✓✗ | 44 |
DifferentialActionModelFactory factory; |
42 |
boost::shared_ptr<crocoddyl::DifferentialActionModelAbstract> model = |
||
43 |
✓✗ | 44 |
factory.create(action_type); |
44 |
|||
45 |
// create the corresponding data object |
||
46 |
boost::shared_ptr<crocoddyl::DifferentialActionDataAbstract> data = |
||
47 |
✓✗ | 44 |
model->createData(); |
48 |
|||
49 |
// Generating random state and control vectors |
||
50 |
✓✗ | 44 |
const Eigen::VectorXd x = model->get_state()->rand(); |
51 |
✓✗✓✗ |
44 |
const Eigen::VectorXd u = Eigen::VectorXd::Random(model->get_nu()); |
52 |
|||
53 |
// Getting the state dimension from calc() call |
||
54 |
✓✗✓✗ ✓✗ |
22 |
model->calc(data, x, u); |
55 |
|||
56 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
22 |
BOOST_CHECK(static_cast<std::size_t>(data->xout.size()) == |
57 |
model->get_state()->get_nv()); |
||
58 |
22 |
} |
|
59 |
|||
60 |
22 |
void test_calc_returns_a_cost(DifferentialActionModelTypes::Type action_type) { |
|
61 |
// create the model |
||
62 |
✓✗ | 44 |
DifferentialActionModelFactory factory; |
63 |
boost::shared_ptr<crocoddyl::DifferentialActionModelAbstract> model = |
||
64 |
✓✗ | 44 |
factory.create(action_type); |
65 |
|||
66 |
// create the corresponding data object and set the cost to nan |
||
67 |
boost::shared_ptr<crocoddyl::DifferentialActionDataAbstract> data = |
||
68 |
✓✗ | 44 |
model->createData(); |
69 |
22 |
data->cost = nan(""); |
|
70 |
|||
71 |
// Getting the cost value computed by calc() |
||
72 |
✓✗ | 44 |
const Eigen::VectorXd x = model->get_state()->rand(); |
73 |
✓✗✓✗ |
44 |
const Eigen::VectorXd u = Eigen::VectorXd::Random(model->get_nu()); |
74 |
✓✗✓✗ ✓✗ |
22 |
model->calc(data, x, u); |
75 |
|||
76 |
// Checking that calc returns a cost value |
||
77 |
✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
22 |
BOOST_CHECK(!std::isnan(data->cost)); |
78 |
22 |
} |
|
79 |
|||
80 |
22 |
void test_quasi_static(DifferentialActionModelTypes::Type action_type) { |
|
81 |
✓✓ | 22 |
if (action_type == |
82 |
DifferentialActionModelTypes:: |
||
83 |
DifferentialActionModelFreeFwdDynamics_TalosArm_Squashed) |
||
84 |
1 |
return; |
|
85 |
// create the model |
||
86 |
✓✗ | 42 |
DifferentialActionModelFactory factory; |
87 |
boost::shared_ptr<crocoddyl::DifferentialActionModelAbstract> model = |
||
88 |
✓✗ | 42 |
factory.create(action_type, false); |
89 |
|||
90 |
// create the corresponding data object and set the cost to nan |
||
91 |
boost::shared_ptr<crocoddyl::DifferentialActionDataAbstract> data = |
||
92 |
✓✗ | 42 |
model->createData(); |
93 |
|||
94 |
// Getting the cost value computed by calc() |
||
95 |
✓✗ | 42 |
Eigen::VectorXd x = model->get_state()->rand(); |
96 |
✓✗✓✗ |
21 |
x.tail(model->get_state()->get_nv()).setZero(); |
97 |
✓✗✓✗ |
42 |
Eigen::VectorXd u = Eigen::VectorXd::Zero(model->get_nu()); |
98 |
✓✗✓✗ ✓✗ |
21 |
model->quasiStatic(data, u, x); |
99 |
✓✗✓✗ ✓✗ |
21 |
model->calc(data, x, u); |
100 |
|||
101 |
// Check for inactive contacts |
||
102 |
✓✓ | 21 |
if (action_type == DifferentialActionModelTypes:: |
103 |
✓✓ | 20 |
DifferentialActionModelContactFwdDynamics_HyQ || |
104 |
action_type == |
||
105 |
DifferentialActionModelTypes:: |
||
106 |
✓✓ | 19 |
DifferentialActionModelContactFwdDynamicsWithFriction_HyQ || |
107 |
action_type == DifferentialActionModelTypes:: |
||
108 |
✓✓ | 18 |
DifferentialActionModelContactFwdDynamics_Talos || |
109 |
action_type == |
||
110 |
DifferentialActionModelTypes:: |
||
111 |
✓✓ | 17 |
DifferentialActionModelContactFwdDynamicsWithFriction_Talos || |
112 |
action_type == DifferentialActionModelTypes:: |
||
113 |
✓✓ | 16 |
DifferentialActionModelContactInvDynamics_HyQ || |
114 |
action_type == |
||
115 |
DifferentialActionModelTypes:: |
||
116 |
✓✓ | 15 |
DifferentialActionModelContactInvDynamicsWithFriction_HyQ || |
117 |
action_type == DifferentialActionModelTypes:: |
||
118 |
✓✓ | 14 |
DifferentialActionModelContactInvDynamics_Talos || |
119 |
action_type == |
||
120 |
DifferentialActionModelTypes:: |
||
121 |
DifferentialActionModelContactInvDynamicsWithFriction_Talos) { |
||
122 |
boost::shared_ptr<crocoddyl::DifferentialActionModelContactFwdDynamics> m = |
||
123 |
boost::static_pointer_cast< |
||
124 |
16 |
crocoddyl::DifferentialActionModelContactFwdDynamics>(model); |
|
125 |
✓✗✓✗ |
8 |
m->get_contacts()->changeContactStatus("lf", false); |
126 |
|||
127 |
✓✗✓✗ ✓✗ |
8 |
model->quasiStatic(data, u, x); |
128 |
✓✗✓✗ ✓✗ |
8 |
model->calc(data, x, u); |
129 |
|||
130 |
// Checking that the acceleration is zero as supposed to be in a quasi |
||
131 |
// static condition |
||
132 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
8 |
BOOST_CHECK(data->xout.norm() <= 1e-8); |
133 |
} |
||
134 |
} |
||
135 |
|||
136 |
22 |
void test_partial_derivatives_against_numdiff( |
|
137 |
DifferentialActionModelTypes::Type action_type) { |
||
138 |
// create the model |
||
139 |
✓✗ | 44 |
DifferentialActionModelFactory factory; |
140 |
boost::shared_ptr<crocoddyl::DifferentialActionModelAbstract> model = |
||
141 |
✓✗ | 44 |
factory.create(action_type); |
142 |
|||
143 |
// create the corresponding data object and set the cost to nan |
||
144 |
boost::shared_ptr<crocoddyl::DifferentialActionDataAbstract> data = |
||
145 |
✓✗ | 44 |
model->createData(); |
146 |
|||
147 |
✓✗ | 44 |
crocoddyl::DifferentialActionModelNumDiff model_num_diff(model); |
148 |
boost::shared_ptr<crocoddyl::DifferentialActionDataAbstract> data_num_diff = |
||
149 |
✓✗ | 44 |
model_num_diff.createData(); |
150 |
|||
151 |
// Generating random values for the state and control |
||
152 |
✓✗ | 44 |
Eigen::VectorXd x = model->get_state()->rand(); |
153 |
✓✗✓✗ |
44 |
const Eigen::VectorXd u = Eigen::VectorXd::Random(model->get_nu()); |
154 |
|||
155 |
// Computing the action derivatives |
||
156 |
✓✗✓✗ ✓✗ |
22 |
model->calc(data, x, u); |
157 |
✓✗✓✗ ✓✗ |
22 |
model->calcDiff(data, x, u); |
158 |
✓✗✓✗ ✓✗ |
22 |
model_num_diff.calc(data_num_diff, x, u); |
159 |
✓✗✓✗ ✓✗ |
22 |
model_num_diff.calcDiff(data_num_diff, x, u); |
160 |
// Tolerance defined as in |
||
161 |
// http://www.it.uom.gr/teaching/linearalgebra/NumericalRecipiesInC/c5-7.pdf |
||
162 |
22 |
double tol = std::pow(model_num_diff.get_disturbance(), 1. / 3.); |
|
163 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
22 |
BOOST_CHECK((data->Fx - data_num_diff->Fx).isZero(tol)); |
164 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
22 |
BOOST_CHECK((data->Fu - data_num_diff->Fu).isZero(tol)); |
165 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
22 |
BOOST_CHECK((data->Lx - data_num_diff->Lx).isZero(tol)); |
166 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
22 |
BOOST_CHECK((data->Lu - data_num_diff->Lu).isZero(tol)); |
167 |
✗✓ | 22 |
if (model_num_diff.get_with_gauss_approx()) { |
168 |
BOOST_CHECK((data->Lxx - data_num_diff->Lxx).isZero(tol)); |
||
169 |
BOOST_CHECK((data->Lxu - data_num_diff->Lxu).isZero(tol)); |
||
170 |
BOOST_CHECK((data->Luu - data_num_diff->Luu).isZero(tol)); |
||
171 |
} |
||
172 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
22 |
BOOST_CHECK((data->Hx - data_num_diff->Hx).isZero(tol)); |
173 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
22 |
BOOST_CHECK((data->Hu - data_num_diff->Hu).isZero(tol)); |
174 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
22 |
BOOST_CHECK((data->Gx - data_num_diff->Gx).isZero(tol)); |
175 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
22 |
BOOST_CHECK((data->Gu - data_num_diff->Gu).isZero(tol)); |
176 |
|||
177 |
// Computing the action derivatives |
||
178 |
✓✗ | 22 |
x = model->get_state()->rand(); |
179 |
✓✗✓✗ |
22 |
model->calc(data, x); |
180 |
✓✗✓✗ |
22 |
model->calcDiff(data, x); |
181 |
✓✗✓✗ |
22 |
model_num_diff.calc(data_num_diff, x); |
182 |
✓✗✓✗ |
22 |
model_num_diff.calcDiff(data_num_diff, x); |
183 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
22 |
BOOST_CHECK((data->Lx - data_num_diff->Lx).isZero(tol)); |
184 |
✗✓ | 22 |
if (model_num_diff.get_with_gauss_approx()) { |
185 |
BOOST_CHECK((data->Lxx - data_num_diff->Lxx).isZero(tol)); |
||
186 |
} |
||
187 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
22 |
BOOST_CHECK((data->Hx - data_num_diff->Hx).isZero(tol)); |
188 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
22 |
BOOST_CHECK((data->Gx - data_num_diff->Gx).isZero(tol)); |
189 |
22 |
} |
|
190 |
|||
191 |
//----------------------------------------------------------------------------// |
||
192 |
|||
193 |
22 |
void register_action_model_unit_tests( |
|
194 |
DifferentialActionModelTypes::Type action_type) { |
||
195 |
✓✗✓✗ |
44 |
boost::test_tools::output_test_stream test_name; |
196 |
✓✗✓✗ |
22 |
test_name << "test_" << action_type; |
197 |
✓✗✓✗ ✓✗✓✗ |
22 |
std::cout << "Running " << test_name.str() << std::endl; |
198 |
✓✗✓✗ ✓✗✓✗ |
22 |
test_suite* ts = BOOST_TEST_SUITE(test_name.str()); |
199 |
✓✗✓✗ ✓✗✓✗ ✓✗ |
22 |
ts->add(BOOST_TEST_CASE(boost::bind(&test_check_data, action_type))); |
200 |
✓✗✓✗ ✓✗✓✗ ✓✗ |
22 |
ts->add(BOOST_TEST_CASE(boost::bind(&test_calc_returns_state, action_type))); |
201 |
✓✗✓✗ ✓✗✓✗ ✓✗ |
22 |
ts->add(BOOST_TEST_CASE(boost::bind(&test_calc_returns_a_cost, action_type))); |
202 |
✓✗✓✗ ✓✗✓✗ ✓✗ |
22 |
ts->add(BOOST_TEST_CASE( |
203 |
boost::bind(&test_partial_derivatives_against_numdiff, action_type))); |
||
204 |
✓✗✓✗ ✓✗✓✗ ✓✗ |
22 |
ts->add(BOOST_TEST_CASE(boost::bind(&test_quasi_static, action_type))); |
205 |
✓✗✓✗ ✓✗ |
22 |
framework::master_test_suite().add(ts); |
206 |
22 |
} |
|
207 |
|||
208 |
1 |
bool init_function() { |
|
209 |
✓✓ | 23 |
for (size_t i = 0; i < DifferentialActionModelTypes::all.size(); ++i) { |
210 |
22 |
register_action_model_unit_tests(DifferentialActionModelTypes::all[i]); |
|
211 |
} |
||
212 |
1 |
return true; |
|
213 |
} |
||
214 |
|||
215 |
1 |
int main(int argc, char** argv) { |
|
216 |
1 |
return ::boost::unit_test::unit_test_main(&init_function, argc, argv); |
|
217 |
} |
Generated by: GCOVR (Version 4.2) |