GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
/////////////////////////////////////////////////////////////////////////////// |
||
2 |
// BSD 3-Clause License |
||
3 |
// |
||
4 |
// Copyright (C) 2019-2024, 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/actuation.hpp" |
||
13 |
#include "unittest_common.hpp" |
||
14 |
|||
15 |
using namespace boost::unit_test; |
||
16 |
using namespace crocoddyl::unittest; |
||
17 |
|||
18 |
//----------------------------------------------------------------------------// |
||
19 |
|||
20 |
18 |
void test_construct_data(ActuationModelTypes::Type actuation_type, |
|
21 |
StateModelTypes::Type state_type) { |
||
22 |
// create the model |
||
23 |
✓✗ | 36 |
ActuationModelFactory factory; |
24 |
const boost::shared_ptr<crocoddyl::ActuationModelAbstract>& model = |
||
25 |
✓✗ | 36 |
factory.create(actuation_type, state_type); |
26 |
|||
27 |
// create the corresponding data object |
||
28 |
const boost::shared_ptr<crocoddyl::ActuationDataAbstract>& data = |
||
29 |
✓✗ | 36 |
model->createData(); |
30 |
✗✓ | 18 |
if (!data) |
31 |
throw std::runtime_error("[test_construct_data] Data pointer is dead."); |
||
32 |
18 |
} |
|
33 |
|||
34 |
18 |
void test_calc_returns_tau(ActuationModelTypes::Type actuation_type, |
|
35 |
StateModelTypes::Type state_type) { |
||
36 |
// create the model |
||
37 |
✓✗ | 36 |
ActuationModelFactory factory; |
38 |
const boost::shared_ptr<crocoddyl::ActuationModelAbstract>& model = |
||
39 |
✓✗ | 36 |
factory.create(actuation_type, state_type); |
40 |
|||
41 |
// create the corresponding data object |
||
42 |
const boost::shared_ptr<crocoddyl::ActuationDataAbstract>& data = |
||
43 |
✓✗ | 36 |
model->createData(); |
44 |
|||
45 |
// Generating random state and control vectors |
||
46 |
✓✗ | 36 |
const Eigen::VectorXd x = model->get_state()->rand(); |
47 |
✓✗✓✗ |
36 |
const Eigen::VectorXd u = Eigen::VectorXd::Random(model->get_nu()); |
48 |
|||
49 |
// Getting the state dimension from calc() call |
||
50 |
✓✗✓✗ ✓✗ |
18 |
model->calc(data, x, u); |
51 |
|||
52 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
18 |
BOOST_CHECK(static_cast<std::size_t>(data->tau.size()) == |
53 |
model->get_state()->get_nv()); |
||
54 |
18 |
} |
|
55 |
|||
56 |
18 |
void test_actuationSet(ActuationModelTypes::Type actuation_type, |
|
57 |
StateModelTypes::Type state_type) { |
||
58 |
// create the model |
||
59 |
✓✗ | 36 |
ActuationModelFactory factory; |
60 |
const boost::shared_ptr<crocoddyl::ActuationModelAbstract>& model = |
||
61 |
✓✗ | 36 |
factory.create(actuation_type, state_type); |
62 |
|||
63 |
// create the corresponding data object and set the cost to nan |
||
64 |
const boost::shared_ptr<crocoddyl::ActuationDataAbstract>& data = |
||
65 |
✓✗ | 36 |
model->createData(); |
66 |
|||
67 |
✓✗ | 36 |
crocoddyl::ActuationModelNumDiff model_num_diff(model); |
68 |
const boost::shared_ptr<crocoddyl::ActuationDataAbstract>& data_num_diff = |
||
69 |
✓✗ | 36 |
model_num_diff.createData(); |
70 |
|||
71 |
// Generating random values for the state and control |
||
72 |
✓✗ | 36 |
Eigen::VectorXd x = model->get_state()->rand(); |
73 |
✓✗✓✗ |
36 |
const Eigen::VectorXd u = Eigen::VectorXd::Random(model->get_nu()); |
74 |
|||
75 |
// Computing the selection matrix |
||
76 |
✓✗✓✗ ✓✗ |
18 |
model->calc(data, x, u); |
77 |
✓✗✓✗ ✓✗ |
18 |
model_num_diff.calc(data_num_diff, x, u); |
78 |
✓✗✓✗ ✓✗ |
18 |
model_num_diff.calcDiff(data_num_diff, x, u); |
79 |
|||
80 |
18 |
const std::size_t nv = model->get_state()->get_nv(); |
|
81 |
Eigen::MatrixXd S = |
||
82 |
✓✗✓✗ ✓✗ |
36 |
data_num_diff->dtau_du * pseudoInverse(data_num_diff->dtau_du); |
83 |
✓✓ | 376 |
for (std::size_t k = 0; k < nv; ++k) { |
84 |
✓✗✓✓ |
358 |
if (fabs(S(k, k)) < std::numeric_limits<double>::epsilon()) { |
85 |
✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
22 |
BOOST_CHECK(data->tau_set[k] == false); |
86 |
} else { |
||
87 |
✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
336 |
BOOST_CHECK(data->tau_set[k] == true); |
88 |
} |
||
89 |
} |
||
90 |
18 |
} |
|
91 |
|||
92 |
18 |
void test_partial_derivatives_against_numdiff( |
|
93 |
ActuationModelTypes::Type actuation_type, |
||
94 |
StateModelTypes::Type state_type) { |
||
95 |
// create the model |
||
96 |
✓✗ | 36 |
ActuationModelFactory factory; |
97 |
const boost::shared_ptr<crocoddyl::ActuationModelAbstract>& model = |
||
98 |
✓✗ | 36 |
factory.create(actuation_type, state_type); |
99 |
|||
100 |
// create the corresponding data object and set the cost to nan |
||
101 |
const boost::shared_ptr<crocoddyl::ActuationDataAbstract>& data = |
||
102 |
✓✗ | 36 |
model->createData(); |
103 |
|||
104 |
✓✗ | 36 |
crocoddyl::ActuationModelNumDiff model_num_diff(model); |
105 |
const boost::shared_ptr<crocoddyl::ActuationDataAbstract>& data_num_diff = |
||
106 |
✓✗ | 36 |
model_num_diff.createData(); |
107 |
|||
108 |
// Generating random values for the state and control |
||
109 |
✓✗ | 36 |
Eigen::VectorXd x = model->get_state()->rand(); |
110 |
✓✗✓✗ |
36 |
const Eigen::VectorXd u = Eigen::VectorXd::Random(model->get_nu()); |
111 |
|||
112 |
// Computing the actuation derivatives |
||
113 |
✓✗✓✗ ✓✗ |
18 |
model->calc(data, x, u); |
114 |
✓✗✓✗ ✓✗ |
18 |
model->calcDiff(data, x, u); |
115 |
✓✗✓✗ ✓✗ |
18 |
model_num_diff.calc(data_num_diff, x, u); |
116 |
✓✗✓✗ ✓✗ |
18 |
model_num_diff.calcDiff(data_num_diff, x, u); |
117 |
// Tolerance defined as in |
||
118 |
// http://www.it.uom.gr/teaching/linearalgebra/NumericalRecipiesInC/c5-7.pdf |
||
119 |
18 |
double tol = std::pow(model_num_diff.get_disturbance(), 1. / 3.); |
|
120 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
18 |
BOOST_CHECK((data->dtau_dx - data_num_diff->dtau_dx).isZero(tol)); |
121 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
18 |
BOOST_CHECK((data->dtau_du - data_num_diff->dtau_du).isZero(tol)); |
122 |
|||
123 |
// Computing the actuation derivatives |
||
124 |
✓✗ | 18 |
x = model->get_state()->rand(); |
125 |
✓✗ | 18 |
model->calc(data, x); |
126 |
✓✗ | 18 |
model->calcDiff(data, x); |
127 |
✓✗✓✗ |
18 |
model_num_diff.calc(data_num_diff, x); |
128 |
✓✗✓✗ |
18 |
model_num_diff.calcDiff(data_num_diff, x); |
129 |
|||
130 |
// Checking the partial derivatives against numdiff |
||
131 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
18 |
BOOST_CHECK((data->dtau_dx - data_num_diff->dtau_dx).isZero(tol)); |
132 |
18 |
} |
|
133 |
|||
134 |
18 |
void test_commands(ActuationModelTypes::Type actuation_type, |
|
135 |
StateModelTypes::Type state_type) { |
||
136 |
// create the model |
||
137 |
✓✗ | 36 |
ActuationModelFactory factory; |
138 |
const boost::shared_ptr<crocoddyl::ActuationModelAbstract>& model = |
||
139 |
✓✗ | 36 |
factory.create(actuation_type, state_type); |
140 |
|||
141 |
// create the corresponding data object and set the cost to nan |
||
142 |
const boost::shared_ptr<crocoddyl::ActuationDataAbstract>& data = |
||
143 |
✓✗ | 36 |
model->createData(); |
144 |
|||
145 |
✓✗ | 36 |
crocoddyl::ActuationModelNumDiff model_num_diff(model); |
146 |
const boost::shared_ptr<crocoddyl::ActuationDataAbstract>& data_num_diff = |
||
147 |
✓✗ | 36 |
model_num_diff.createData(); |
148 |
|||
149 |
// Generating random values for the state and control |
||
150 |
✓✗ | 36 |
Eigen::VectorXd x = model->get_state()->rand(); |
151 |
const Eigen::VectorXd tau = |
||
152 |
✓✗✓✗ |
36 |
Eigen::VectorXd::Random(model->get_state()->get_nv()); |
153 |
|||
154 |
// Computing the actuation commands |
||
155 |
✓✗✓✗ ✓✗ |
18 |
model->commands(data, x, tau); |
156 |
✓✗✓✗ ✓✗ |
18 |
model_num_diff.commands(data_num_diff, x, tau); |
157 |
|||
158 |
// Checking the joint torques |
||
159 |
18 |
double tol = sqrt(model_num_diff.get_disturbance()); |
|
160 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
18 |
BOOST_CHECK((data->u - data_num_diff->u).isZero(tol)); |
161 |
18 |
} |
|
162 |
|||
163 |
18 |
void test_torqueTransform(ActuationModelTypes::Type actuation_type, |
|
164 |
StateModelTypes::Type state_type) { |
||
165 |
// create the model |
||
166 |
✓✗ | 36 |
ActuationModelFactory factory; |
167 |
const boost::shared_ptr<crocoddyl::ActuationModelAbstract>& model = |
||
168 |
✓✗ | 36 |
factory.create(actuation_type, state_type); |
169 |
|||
170 |
// create the corresponding data object and set the cost to nan |
||
171 |
const boost::shared_ptr<crocoddyl::ActuationDataAbstract>& data = |
||
172 |
✓✗ | 36 |
model->createData(); |
173 |
|||
174 |
✓✗ | 36 |
crocoddyl::ActuationModelNumDiff model_num_diff(model); |
175 |
const boost::shared_ptr<crocoddyl::ActuationDataAbstract>& data_num_diff = |
||
176 |
✓✗ | 36 |
model_num_diff.createData(); |
177 |
|||
178 |
// Generating random values for the state and control |
||
179 |
✓✗ | 36 |
Eigen::VectorXd x = model->get_state()->rand(); |
180 |
✓✗✓✗ |
36 |
const Eigen::VectorXd u = Eigen::VectorXd::Random(model->get_nu()); |
181 |
|||
182 |
// Computing the torque transform |
||
183 |
✓✗✓✗ ✓✗ |
18 |
model->torqueTransform(data, x, u); |
184 |
✓✗✓✗ ✓✗ |
18 |
model_num_diff.torqueTransform(data_num_diff, x, u); |
185 |
|||
186 |
// Checking the torque transform |
||
187 |
// Tolerance defined as in |
||
188 |
// http://www.it.uom.gr/teaching/linearalgebra/NumericalRecipiesInC/c5-7.pdf |
||
189 |
18 |
double tol = std::pow(model_num_diff.get_disturbance(), 1. / 3.); |
|
190 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✓ |
18 |
BOOST_CHECK((data->Mtau - data_num_diff->Mtau).isZero(tol)); |
191 |
18 |
} |
|
192 |
|||
193 |
//----------------------------------------------------------------------------// |
||
194 |
|||
195 |
18 |
void register_actuation_model_unit_tests( |
|
196 |
ActuationModelTypes::Type actuation_type, |
||
197 |
StateModelTypes::Type state_type) { |
||
198 |
✓✗✓✗ |
36 |
boost::test_tools::output_test_stream test_name; |
199 |
✓✗✓✗ ✓✗✓✗ |
18 |
test_name << "test_" << actuation_type << "_" << state_type; |
200 |
✓✗✓✗ ✓✗✓✗ |
18 |
std::cout << "Running " << test_name.str() << std::endl; |
201 |
✓✗✓✗ ✓✗✓✗ |
18 |
test_suite* ts = BOOST_TEST_SUITE(test_name.str()); |
202 |
✓✗✓✗ ✓✗✓✗ ✓✗ |
18 |
ts->add(BOOST_TEST_CASE( |
203 |
boost::bind(&test_construct_data, actuation_type, state_type))); |
||
204 |
✓✗✓✗ ✓✗✓✗ ✓✗ |
18 |
ts->add(BOOST_TEST_CASE( |
205 |
boost::bind(&test_calc_returns_tau, actuation_type, state_type))); |
||
206 |
✓✗✓✗ ✓✗✓✗ ✓✗ |
18 |
ts->add(BOOST_TEST_CASE( |
207 |
boost::bind(&test_actuationSet, actuation_type, state_type))); |
||
208 |
✓✗✓✗ ✓✗✓✗ ✓✗ |
18 |
ts->add(BOOST_TEST_CASE(boost::bind(&test_partial_derivatives_against_numdiff, |
209 |
actuation_type, state_type))); |
||
210 |
18 |
ts->add( |
|
211 |
✓✗✓✗ ✓✗✓✗ ✓✗ |
18 |
BOOST_TEST_CASE(boost::bind(&test_commands, actuation_type, state_type))); |
212 |
✓✗✓✗ ✓✗✓✗ ✓✗ |
18 |
ts->add(BOOST_TEST_CASE( |
213 |
boost::bind(&test_torqueTransform, actuation_type, state_type))); |
||
214 |
✓✗✓✗ ✓✗ |
18 |
framework::master_test_suite().add(ts); |
215 |
18 |
} |
|
216 |
|||
217 |
1 |
bool init_function() { |
|
218 |
✓✓ | 8 |
for (size_t i = 0; i < StateModelTypes::all.size(); ++i) { |
219 |
7 |
register_actuation_model_unit_tests(ActuationModelTypes::ActuationModelFull, |
|
220 |
7 |
StateModelTypes::all[i]); |
|
221 |
} |
||
222 |
✓✓ | 8 |
for (size_t i = 0; i < StateModelTypes::all.size(); ++i) { |
223 |
✓✓✓✓ |
13 |
if (StateModelTypes::all[i] != StateModelTypes::StateVector && |
224 |
✓✓ | 6 |
StateModelTypes::all[i] != StateModelTypes::StateMultibody_Hector) { |
225 |
5 |
register_actuation_model_unit_tests( |
|
226 |
ActuationModelTypes::ActuationModelFloatingBase, |
||
227 |
5 |
StateModelTypes::all[i]); |
|
228 |
5 |
register_actuation_model_unit_tests( |
|
229 |
ActuationModelTypes::ActuationModelSquashingFull, |
||
230 |
5 |
StateModelTypes::all[i]); |
|
231 |
} |
||
232 |
} |
||
233 |
|||
234 |
1 |
register_actuation_model_unit_tests( |
|
235 |
ActuationModelTypes::ActuationModelFloatingBaseThrusters, |
||
236 |
StateModelTypes::StateMultibody_Hector); |
||
237 |
1 |
return true; |
|
238 |
} |
||
239 |
|||
240 |
1 |
int main(int argc, char** argv) { |
|
241 |
1 |
return ::boost::unit_test::unit_test_main(&init_function, argc, argv); |
|
242 |
} |
Generated by: GCOVR (Version 4.2) |