GCC Code Coverage Report


Directory: ./
File: bindings/python/crocoddyl/core/solvers/ddp.cpp
Date: 2025-01-16 08:47:40
Exec Total Coverage
Lines: 96 98 98.0%
Branches: 96 192 50.0%

Line Branch Exec Source
1 ///////////////////////////////////////////////////////////////////////////////
2 // BSD 3-Clause License
3 //
4 // Copyright (C) 2019-2023, LAAS-CNRS, University of Edinburgh,
5 // Heriot-Watt University
6 // Copyright note valid unless otherwise stated in individual files.
7 // All rights reserved.
8 ///////////////////////////////////////////////////////////////////////////////
9
10 #include "crocoddyl/core/solvers/ddp.hpp"
11
12 #include "python/crocoddyl/core/core.hpp"
13 #include "python/crocoddyl/utils/copyable.hpp"
14 #include "python/crocoddyl/utils/deprecate.hpp"
15
16 namespace crocoddyl {
17 namespace python {
18
19 32 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(SolverDDP_solves, SolverDDP::solve, 0, 5)
20 18 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(SolverDDP_computeDirections,
21 SolverDDP::computeDirection, 0, 1)
22 36 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(SolverDDP_trySteps, SolverDDP::tryStep,
23 0, 1)
24
25 10 void exposeSolverDDP() {
26 10 bp::register_ptr_to_python<boost::shared_ptr<SolverDDP> >();
27
28
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 bp::class_<SolverDDP, bp::bases<SolverAbstract> >(
29 "SolverDDP",
30 "DDP solver.\n\n"
31 "The DDP solver computes an optimal trajectory and control commands by "
32 "iterates\n"
33 "running backward and forward passes. The backward-pass updates locally "
34 "the\n"
35 "quadratic approximation of the problem and computes descent direction,\n"
36 "and the forward-pass rollouts this new policy by integrating the system "
37 "dynamics\n"
38 "along a tuple of optimized control commands U*.\n"
39 ":param shootingProblem: shooting problem (list of action models along "
40 "trajectory.)",
41
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 bp::init<boost::shared_ptr<ShootingProblem> >(
42 20 bp::args("self", "problem"),
43 "Initialize the vector dimension.\n\n"
44 ":param problem: shooting problem."))
45
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 .def("solve", &SolverDDP::solve,
46
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 SolverDDP_solves(
47
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
20 bp::args("self", "init_xs", "init_us", "maxiter", "is_feasible",
48 "init_reg"),
49 "Compute the optimal trajectory xopt, uopt as lists of T+1 and "
50 "T terms.\n\n"
51 "From an initial guess init_xs,init_us (feasible or not), "
52 "iterate\n"
53 "over computeDirection and tryStep until stoppingCriteria is "
54 "below\n"
55 "threshold. It also describes the globalization strategy used\n"
56 "during the numerical optimization.\n"
57 ":param init_xs: initial guess for state trajectory with T+1 "
58 "elements (default []).\n"
59 ":param init_us: initial guess for control trajectory with T "
60 "elements (default []) (default []).\n"
61 ":param maxiter: maximum allowed number of iterations (default "
62 "100).\n"
63 ":param is_feasible: true if the init_xs are obtained from "
64 "integrating the init_us (rollout)\n"
65 "(default False).\n"
66 ":param init_reg: initial guess for the regularization value. "
67 "Very low values are typical\n"
68 " used with very good guess points (default "
69 "1e-9).\n"
70 ":returns the optimal trajectory xopt, uopt and a boolean that "
71 "describes if convergence was reached."))
72
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 .def("computeDirection", &SolverDDP::computeDirection,
73
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 SolverDDP_computeDirections(
74
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
20 bp::args("self", "recalc"),
75 "Compute the search direction (dx, du) for the current guess "
76 "(xs, us).\n\n"
77 "You must call setCandidate first in order to define the "
78 "current\n"
79 "guess. A current guess defines a state and control trajectory\n"
80 "(xs, us) of T+1 and T elements, respectively.\n"
81 ":params recalc: true for recalculating the derivatives at "
82 "current state and control.\n"
83 ":returns the search direction dx, du and the dual lambdas as "
84 "lists of T+1, T and T+1 lengths."))
85
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 .def("tryStep", &SolverDDP::tryStep,
86
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 SolverDDP_trySteps(
87
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
20 bp::args("self", "stepLength"),
88 "Rollout the system with a predefined step length.\n\n"
89 ":param stepLength: step length (default 1)\n"
90 ":returns the cost improvement."))
91
2/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
20 .def("stoppingCriteria", &SolverDDP::stoppingCriteria, bp::args("self"),
92 "Return a sum of positive parameters whose sum quantifies the DDP "
93 "termination.")
94
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 .def("expectedImprovement", &SolverDDP::expectedImprovement,
95 bp::return_value_policy<bp::copy_const_reference>(),
96
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
20 bp::args("self"),
97 "Return two scalars denoting the quadratic improvement model\n\n"
98 "For computing the expected improvement, you need to compute first\n"
99 "the search direction by running computeDirection. The quadratic\n"
100 "improvement model is described as dV = f_0 - f_+ = d1*a + "
101 "d2*a**2/2.")
102
2/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
20 .def("calcDiff", &SolverDDP::calcDiff, bp::args("self"),
103 "Update the Jacobian and Hessian of the optimal control problem\n\n"
104 "These derivatives are computed around the guess state and control\n"
105 "trajectory. These trajectory can be set by using setCandidate.\n"
106 ":return the total cost around the guess trajectory.")
107
2/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
20 .def("backwardPass", &SolverDDP::backwardPass, bp::args("self"),
108 "Run the backward pass (Riccati sweep)\n\n"
109 "It assumes that the Jacobian and Hessians of the optimal control "
110 "problem have been\n"
111 "compute. These terms are computed by running calc.")
112
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 .def("forwardPass", &SolverDDP::forwardPass,
113
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
20 bp::args("self", "stepLength"),
114 "Run the forward pass or rollout\n\n"
115 "It rollouts the action model given the computed policy "
116 "(feedforward terns and feedback\n"
117 "gains) by the backwardPass. We can define different step lengths\n"
118 ":param stepLength: applied step length (<= 1. and >= 0.)")
119
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 .def("computeActionValueFunction", &SolverDDP::computeActionValueFunction,
120
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
20 bp::args("self", "t", "model", "data"),
121 "Compute the linear-quadratic model of the control Hamiltonian\n\n"
122 ":param t: time instance\n"
123 ":param model: action model in the given time instance\n"
124 ":param data: action data in the given time instance")
125
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 .def("computeValueFunction", &SolverDDP::computeValueFunction,
126
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
20 bp::args("self", "t", "model"),
127 "Compute the quadratic model of the value function.\n\n"
128 "This function is called in the backward pass after updating the "
129 "local Hamiltonian.\n"
130 ":param t: time instance\n"
131 ":param model: action model in the given time instance")
132
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 .add_property(
133 "Vxx",
134
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 make_function(&SolverDDP::get_Vxx,
135 10 bp::return_value_policy<bp::copy_const_reference>()),
136 "Vxx")
137
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 .add_property(
138 "Vx",
139
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 make_function(&SolverDDP::get_Vx,
140 10 bp::return_value_policy<bp::copy_const_reference>()),
141 "Vx")
142
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 .add_property(
143 "Qxx",
144
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 make_function(&SolverDDP::get_Qxx,
145 10 bp::return_value_policy<bp::copy_const_reference>()),
146 "Qxx")
147
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 .add_property(
148 "Qxu",
149
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 make_function(&SolverDDP::get_Qxu,
150 10 bp::return_value_policy<bp::copy_const_reference>()),
151 "Qxu")
152
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 .add_property(
153 "Quu",
154
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 make_function(&SolverDDP::get_Quu,
155 10 bp::return_value_policy<bp::copy_const_reference>()),
156 "Quu")
157
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 .add_property(
158 "Qx",
159
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 make_function(&SolverDDP::get_Qx,
160 10 bp::return_value_policy<bp::copy_const_reference>()),
161 "Qx")
162
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 .add_property(
163 "Qu",
164
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 make_function(&SolverDDP::get_Qu,
165 10 bp::return_value_policy<bp::copy_const_reference>()),
166 "Qu")
167
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 .add_property(
168 "K",
169
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 make_function(&SolverDDP::get_K,
170 10 bp::return_value_policy<bp::copy_const_reference>()),
171 "K")
172
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 .add_property(
173 "k",
174
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 make_function(&SolverDDP::get_k,
175 10 bp::return_value_policy<bp::copy_const_reference>()),
176 "k")
177
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 .add_property(
178
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 "reg_incFactor", bp::make_function(&SolverDDP::get_reg_incfactor),
179
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
20 bp::make_function(&SolverDDP::set_reg_incfactor),
180 "regularization factor used for increasing the damping value.")
181
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 .add_property(
182
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 "reg_decFactor", bp::make_function(&SolverDDP::get_reg_decfactor),
183
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
20 bp::make_function(&SolverDDP::set_reg_decfactor),
184 "regularization factor used for decreasing the damping value.")
185
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 .add_property(
186 "regFactor",
187
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 bp::make_function(
188 &SolverDDP::get_reg_incfactor,
189
2/4
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 10 times.
✗ Branch 6 not taken.
20 deprecated<>("Deprecated. Use reg_incfactor or reg_decfactor")),
190
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
20 bp::make_function(
191 &SolverDDP::set_reg_incfactor,
192
2/4
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 10 times.
✗ Branch 6 not taken.
20 deprecated<>("Deprecated. Use reg_incfactor or reg_decfactor")),
193 "regularization factor used for increasing or decreasing the damping "
194 "value.")
195
2/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
10 .add_property("reg_min", bp::make_function(&SolverDDP::get_reg_min),
196
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
20 bp::make_function(&SolverDDP::set_reg_min),
197 "minimum regularization value.")
198
2/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
10 .add_property("reg_max", bp::make_function(&SolverDDP::get_reg_max),
199
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
20 bp::make_function(&SolverDDP::set_reg_max),
200 "maximum regularization value.")
201
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 .add_property("regMin",
202
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 bp::make_function(&SolverDDP::get_reg_min,
203
2/4
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 10 times.
✗ Branch 6 not taken.
20 deprecated<>("Deprecated. Use reg_min")),
204
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
20 bp::make_function(&SolverDDP::set_reg_min,
205
2/4
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 10 times.
✗ Branch 6 not taken.
20 deprecated<>("Deprecated. Use reg_min")),
206 "minimum regularization value.")
207
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 .add_property("regMax",
208
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 bp::make_function(&SolverDDP::get_reg_max,
209
2/4
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 10 times.
✗ Branch 6 not taken.
20 deprecated<>("Deprecated. Use reg_max")),
210
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
20 bp::make_function(&SolverDDP::set_reg_max,
211
2/4
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 10 times.
✗ Branch 6 not taken.
20 deprecated<>("Deprecated. Use reg_max")),
212 "maximum regularization value.")
213
2/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
10 .add_property("th_stepDec", bp::make_function(&SolverDDP::get_th_stepdec),
214
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
20 bp::make_function(&SolverDDP::set_th_stepdec),
215 "threshold for decreasing the regularization after "
216 "approving a step (higher values decreases the "
217 "regularization)")
218
2/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
10 .add_property("th_stepInc", bp::make_function(&SolverDDP::get_th_stepinc),
219
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
20 bp::make_function(&SolverDDP::set_th_stepinc),
220 "threshold for increasing the regularization after "
221 "approving a step (higher values decreases the "
222 "regularization)")
223
2/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
10 .add_property("th_grad", bp::make_function(&SolverDDP::get_th_grad),
224
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
20 bp::make_function(&SolverDDP::set_th_grad),
225 "threshold for accepting step which gradients is lower "
226 "than this value")
227
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 .add_property(
228 "th_gaptol",
229
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 bp::make_function(&SolverDDP::get_th_gaptol,
230
2/4
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 10 times.
✗ Branch 6 not taken.
20 deprecated<>("Deprecated. Use th_gapTol")),
231
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
20 bp::make_function(&SolverDDP::set_th_gaptol,
232
2/4
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 10 times.
✗ Branch 6 not taken.
20 deprecated<>("Deprecated. Use th_gapTol")),
233 "threshold for accepting a gap as non-zero")
234
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 .add_property("alphas",
235
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 bp::make_function(
236 &SolverDDP::get_alphas,
237 bp::return_value_policy<bp::copy_const_reference>()),
238
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
20 bp::make_function(&SolverDDP::set_alphas),
239 "list of step length (alpha) values")
240
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 .def(CopyableVisitor<SolverDDP>());
241 10 }
242
243 } // namespace python
244 } // namespace crocoddyl
245