Directory: | ./ |
---|---|
File: | src/core/solvers/ddp.cpp |
Date: | 2025-01-16 08:47:40 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 271 | 391 | 69.3% |
Branches: | 269 | 1228 | 21.9% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | /////////////////////////////////////////////////////////////////////////////// | ||
2 | // BSD 3-Clause License | ||
3 | // | ||
4 | // Copyright (C) 2019-2022, LAAS-CNRS, University of Edinburgh, | ||
5 | // University of Oxford, 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 <iostream> | ||
13 | |||
14 | #include "crocoddyl/core/utils/exception.hpp" | ||
15 | |||
16 | namespace crocoddyl { | ||
17 | |||
18 | 49 | SolverDDP::SolverDDP(boost::shared_ptr<ShootingProblem> problem) | |
19 | : SolverAbstract(problem), | ||
20 | 49 | reg_incfactor_(10.), | |
21 | 49 | reg_decfactor_(10.), | |
22 | 49 | reg_min_(1e-9), | |
23 | 49 | reg_max_(1e9), | |
24 | 49 | cost_try_(0.), | |
25 | 49 | th_grad_(1e-12), | |
26 | 49 | th_stepdec_(0.5), | |
27 |
5/10✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
✓ Branch 10 taken 49 times.
✗ Branch 11 not taken.
✓ Branch 21 taken 49 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 49 times.
✗ Branch 25 not taken.
✓ Branch 28 taken 49 times.
✗ Branch 29 not taken.
|
49 | th_stepinc_(0.01) { |
28 |
1/2✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
|
49 | allocateData(); |
29 | |||
30 | 49 | const std::size_t n_alphas = 10; | |
31 |
1/2✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
|
49 | alphas_.resize(n_alphas); |
32 |
2/2✓ Branch 0 taken 490 times.
✓ Branch 1 taken 49 times.
|
539 | for (std::size_t n = 0; n < n_alphas; ++n) { |
33 | 490 | alphas_[n] = 1. / pow(2., static_cast<double>(n)); | |
34 | } | ||
35 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 49 times.
|
49 | if (th_stepinc_ < alphas_[n_alphas - 1]) { |
36 | ✗ | th_stepinc_ = alphas_[n_alphas - 1]; | |
37 | std::cerr << "Warning: th_stepinc has higher value than lowest alpha " | ||
38 | "value, set to " | ||
39 | ✗ | << std::to_string(alphas_[n_alphas - 1]) << std::endl; | |
40 | } | ||
41 | 49 | } | |
42 | |||
43 | 118 | SolverDDP::~SolverDDP() {} | |
44 | |||
45 | 16 | bool SolverDDP::solve(const std::vector<Eigen::VectorXd>& init_xs, | |
46 | const std::vector<Eigen::VectorXd>& init_us, | ||
47 | const std::size_t maxiter, const bool is_feasible, | ||
48 | const double init_reg) { | ||
49 |
3/16✗ Branch 2 not taken.
✓ Branch 3 taken 16 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 16 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 16 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
|
16 | START_PROFILER("SolverDDP::solve"); |
50 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 16 times.
|
16 | if (problem_->is_updated()) { |
51 | ✗ | resizeData(); | |
52 | } | ||
53 | 16 | xs_try_[0] = | |
54 | 32 | problem_->get_x0(); // it is needed in case that init_xs[0] is infeasible | |
55 | 16 | setCandidate(init_xs, init_us, is_feasible); | |
56 | |||
57 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
16 | if (std::isnan(init_reg)) { |
58 | 16 | preg_ = reg_min_; | |
59 | 16 | dreg_ = reg_min_; | |
60 | } else { | ||
61 | ✗ | preg_ = init_reg; | |
62 | ✗ | dreg_ = init_reg; | |
63 | } | ||
64 | 16 | was_feasible_ = false; | |
65 | |||
66 | 16 | bool recalcDiff = true; | |
67 |
2/2✓ Branch 0 taken 50 times.
✓ Branch 1 taken 6 times.
|
56 | for (iter_ = 0; iter_ < maxiter; ++iter_) { |
68 | while (true) { | ||
69 | try { | ||
70 |
1/2✓ Branch 1 taken 50 times.
✗ Branch 2 not taken.
|
50 | computeDirection(recalcDiff); |
71 | ✗ | } catch (std::exception& e) { | |
72 | ✗ | recalcDiff = false; | |
73 | ✗ | increaseRegularization(); | |
74 | ✗ | if (preg_ == reg_max_) { | |
75 | ✗ | return false; | |
76 | } else { | ||
77 | ✗ | continue; | |
78 | } | ||
79 | } | ||
80 | 50 | break; | |
81 | } | ||
82 | 50 | expectedImprovement(); | |
83 | |||
84 | // We need to recalculate the derivatives when the step length passes | ||
85 | 50 | recalcDiff = false; | |
86 | 50 | for (std::vector<double>::const_iterator it = alphas_.begin(); | |
87 |
1/2✓ Branch 3 taken 50 times.
✗ Branch 4 not taken.
|
50 | it != alphas_.end(); ++it) { |
88 | 50 | steplength_ = *it; | |
89 | |||
90 | try { | ||
91 |
1/2✓ Branch 1 taken 50 times.
✗ Branch 2 not taken.
|
50 | dV_ = tryStep(steplength_); |
92 | ✗ | } catch (std::exception& e) { | |
93 | ✗ | continue; | |
94 | } | ||
95 |
2/4✓ Branch 1 taken 50 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 50 times.
✗ Branch 5 not taken.
|
50 | dVexp_ = steplength_ * (d_[0] + 0.5 * steplength_ * d_[1]); |
96 | |||
97 |
1/2✓ Branch 0 taken 50 times.
✗ Branch 1 not taken.
|
50 | if (dVexp_ >= 0) { // descend direction |
98 |
6/8✓ Branch 1 taken 50 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 39 times.
✓ Branch 5 taken 11 times.
✓ Branch 6 taken 26 times.
✓ Branch 7 taken 13 times.
✓ Branch 8 taken 50 times.
✗ Branch 9 not taken.
|
76 | if (std::abs(d_[0]) < th_grad_ || !is_feasible_ || |
99 |
1/2✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
|
26 | dV_ > th_acceptstep_ * dVexp_) { |
100 | 50 | was_feasible_ = is_feasible_; | |
101 |
1/2✓ Branch 1 taken 50 times.
✗ Branch 2 not taken.
|
50 | setCandidate(xs_try_, us_try_, true); |
102 | 50 | cost_ = cost_try_; | |
103 | 50 | recalcDiff = true; | |
104 | 50 | break; | |
105 | } | ||
106 | } | ||
107 | } | ||
108 | |||
109 |
1/2✓ Branch 0 taken 50 times.
✗ Branch 1 not taken.
|
50 | if (steplength_ > th_stepdec_) { |
110 | 50 | decreaseRegularization(); | |
111 | } | ||
112 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 50 times.
|
50 | if (steplength_ <= th_stepinc_) { |
113 | ✗ | increaseRegularization(); | |
114 | ✗ | if (preg_ == reg_max_) { | |
115 | ✗ | STOP_PROFILER("SolverDDP::solve"); | |
116 | ✗ | return false; | |
117 | } | ||
118 | } | ||
119 | 50 | stoppingCriteria(); | |
120 | |||
121 | 50 | const std::size_t n_callbacks = callbacks_.size(); | |
122 |
2/2✓ Branch 0 taken 22 times.
✓ Branch 1 taken 50 times.
|
72 | for (std::size_t c = 0; c < n_callbacks; ++c) { |
123 | 22 | CallbackAbstract& callback = *callbacks_[c]; | |
124 | 22 | callback(*this); | |
125 | } | ||
126 | |||
127 |
4/4✓ Branch 0 taken 34 times.
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 24 times.
|
50 | if (was_feasible_ && stop_ < th_stop_) { |
128 |
3/16✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 10 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 10 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
|
10 | STOP_PROFILER("SolverDDP::solve"); |
129 | 10 | return true; | |
130 | } | ||
131 | } | ||
132 |
3/16✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 6 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 6 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
|
6 | STOP_PROFILER("SolverDDP::solve"); |
133 | 6 | return false; | |
134 | } | ||
135 | |||
136 | 108 | void SolverDDP::computeDirection(const bool recalcDiff) { | |
137 |
3/16✗ Branch 2 not taken.
✓ Branch 3 taken 108 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 108 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 108 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
|
108 | START_PROFILER("SolverDDP::computeDirection"); |
138 |
1/2✓ Branch 0 taken 108 times.
✗ Branch 1 not taken.
|
108 | if (recalcDiff) { |
139 | 108 | calcDiff(); | |
140 | } | ||
141 | 108 | backwardPass(); | |
142 |
3/16✗ Branch 2 not taken.
✓ Branch 3 taken 108 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 108 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 108 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
|
108 | STOP_PROFILER("SolverDDP::computeDirection"); |
143 | 108 | } | |
144 | |||
145 | 108 | double SolverDDP::tryStep(const double steplength) { | |
146 |
3/16✗ Branch 2 not taken.
✓ Branch 3 taken 108 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 108 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 108 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
|
108 | START_PROFILER("SolverDDP::tryStep"); |
147 | 108 | forwardPass(steplength); | |
148 |
3/16✗ Branch 2 not taken.
✓ Branch 3 taken 108 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 108 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 108 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
|
108 | STOP_PROFILER("SolverDDP::tryStep"); |
149 | 108 | return cost_ - cost_try_; | |
150 | } | ||
151 | |||
152 | 104 | double SolverDDP::stoppingCriteria() { | |
153 | // This stopping criteria represents the expected reduction in the value | ||
154 | // function. If this reduction is less than a certain threshold, then the | ||
155 | // algorithm reaches the local minimum. For more details, see C. Mastalli et | ||
156 | // al. "Inverse-dynamics MPC via Nullspace Resolution". | ||
157 | 104 | stop_ = std::abs(d_[0] + 0.5 * d_[1]); | |
158 | 104 | return stop_; | |
159 | } | ||
160 | |||
161 | 52 | const Eigen::Vector2d& SolverDDP::expectedImprovement() { | |
162 |
1/2✓ Branch 1 taken 52 times.
✗ Branch 2 not taken.
|
52 | d_.fill(0); |
163 | 52 | const std::size_t T = this->problem_->get_T(); | |
164 | const std::vector<boost::shared_ptr<ActionModelAbstract> >& models = | ||
165 | 52 | problem_->get_runningModels(); | |
166 |
2/2✓ Branch 0 taken 487 times.
✓ Branch 1 taken 52 times.
|
539 | for (std::size_t t = 0; t < T; ++t) { |
167 | 487 | const std::size_t nu = models[t]->get_nu(); | |
168 |
1/2✓ Branch 0 taken 487 times.
✗ Branch 1 not taken.
|
487 | if (nu != 0) { |
169 | 487 | d_[0] += Qu_[t].dot(k_[t]); | |
170 | 487 | d_[1] -= k_[t].dot(Quuk_[t]); | |
171 | } | ||
172 | } | ||
173 | 52 | return d_; | |
174 | } | ||
175 | |||
176 | ✗ | void SolverDDP::resizeData() { | |
177 | ✗ | START_PROFILER("SolverDDP::resizeData"); | |
178 | ✗ | SolverAbstract::resizeData(); | |
179 | |||
180 | ✗ | const std::size_t T = problem_->get_T(); | |
181 | ✗ | const std::size_t ndx = problem_->get_ndx(); | |
182 | const std::vector<boost::shared_ptr<ActionModelAbstract> >& models = | ||
183 | ✗ | problem_->get_runningModels(); | |
184 | ✗ | for (std::size_t t = 0; t < T; ++t) { | |
185 | ✗ | const boost::shared_ptr<ActionModelAbstract>& model = models[t]; | |
186 | ✗ | const std::size_t nu = model->get_nu(); | |
187 | ✗ | Qxu_[t].conservativeResize(ndx, nu); | |
188 | ✗ | Quu_[t].conservativeResize(nu, nu); | |
189 | ✗ | Qu_[t].conservativeResize(nu); | |
190 | ✗ | K_[t].conservativeResize(nu, ndx); | |
191 | ✗ | k_[t].conservativeResize(nu); | |
192 | ✗ | us_try_[t].conservativeResize(nu); | |
193 | ✗ | FuTVxx_p_[t].conservativeResize(nu, ndx); | |
194 | ✗ | Quuk_[t].conservativeResize(nu); | |
195 | ✗ | if (nu != 0) { | |
196 | ✗ | FuTVxx_p_[t].setZero(); | |
197 | } | ||
198 | } | ||
199 | ✗ | STOP_PROFILER("SolverDDP::resizeData"); | |
200 | } | ||
201 | |||
202 | 108 | double SolverDDP::calcDiff() { | |
203 |
3/16✗ Branch 2 not taken.
✓ Branch 3 taken 108 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 108 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 108 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
|
108 | START_PROFILER("SolverDDP::calcDiff"); |
204 |
2/2✓ Branch 0 taken 40 times.
✓ Branch 1 taken 68 times.
|
108 | if (iter_ == 0) { |
205 | 40 | problem_->calc(xs_, us_); | |
206 | } | ||
207 | 108 | cost_ = problem_->calcDiff(xs_, us_); | |
208 | |||
209 | 108 | ffeas_ = computeDynamicFeasibility(); | |
210 | 108 | gfeas_ = computeInequalityFeasibility(); | |
211 | 108 | hfeas_ = computeEqualityFeasibility(); | |
212 |
3/16✗ Branch 2 not taken.
✓ Branch 3 taken 108 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 108 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 108 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
|
108 | STOP_PROFILER("SolverDDP::calcDiff"); |
213 | 108 | return cost_; | |
214 | } | ||
215 | |||
216 | 108 | void SolverDDP::backwardPass() { | |
217 |
3/16✗ Branch 2 not taken.
✓ Branch 3 taken 108 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 108 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 108 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
|
108 | START_PROFILER("SolverDDP::backwardPass"); |
218 | const boost::shared_ptr<ActionDataAbstract>& d_T = | ||
219 | 108 | problem_->get_terminalData(); | |
220 | 108 | Vxx_.back() = d_T->Lxx; | |
221 | 108 | Vx_.back() = d_T->Lx; | |
222 | |||
223 |
1/2✓ Branch 1 taken 108 times.
✗ Branch 2 not taken.
|
108 | if (!std::isnan(preg_)) { |
224 |
2/4✓ Branch 3 taken 108 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 108 times.
✗ Branch 7 not taken.
|
108 | Vxx_.back().diagonal().array() += preg_; |
225 | } | ||
226 | |||
227 |
2/2✓ Branch 0 taken 40 times.
✓ Branch 1 taken 68 times.
|
108 | if (!is_feasible_) { |
228 |
2/4✓ Branch 5 taken 40 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 40 times.
✗ Branch 9 not taken.
|
40 | Vx_.back().noalias() += Vxx_.back() * fs_.back(); |
229 | } | ||
230 | const std::vector<boost::shared_ptr<ActionModelAbstract> >& models = | ||
231 | 108 | problem_->get_runningModels(); | |
232 | const std::vector<boost::shared_ptr<ActionDataAbstract> >& datas = | ||
233 | 108 | problem_->get_runningDatas(); | |
234 |
2/2✓ Branch 2 taken 1152 times.
✓ Branch 3 taken 108 times.
|
1260 | for (int t = static_cast<int>(problem_->get_T()) - 1; t >= 0; --t) { |
235 | 1152 | const boost::shared_ptr<ActionModelAbstract>& m = models[t]; | |
236 | 1152 | const boost::shared_ptr<ActionDataAbstract>& d = datas[t]; | |
237 | |||
238 | // Compute the linear-quadratic approximation of the control Hamiltonian | ||
239 | // function | ||
240 | 1152 | computeActionValueFunction(t, m, d); | |
241 | |||
242 | // Compute the feedforward and feedback gains | ||
243 | 1152 | computeGains(t); | |
244 | |||
245 | // Compute the linear-quadratic approximation of the Value function | ||
246 | 1152 | computeValueFunction(t, m); | |
247 | |||
248 |
1/2✗ Branch 3 not taken.
✓ Branch 4 taken 1152 times.
|
1152 | if (raiseIfNaN(Vx_[t].lpNorm<Eigen::Infinity>())) { |
249 | ✗ | throw_pretty("backward_error"); | |
250 | } | ||
251 |
1/2✗ Branch 3 not taken.
✓ Branch 4 taken 1152 times.
|
1152 | if (raiseIfNaN(Vxx_[t].lpNorm<Eigen::Infinity>())) { |
252 | ✗ | throw_pretty("backward_error"); | |
253 | } | ||
254 | } | ||
255 |
3/16✗ Branch 2 not taken.
✓ Branch 3 taken 108 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 108 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 108 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
|
108 | STOP_PROFILER("SolverDDP::backwardPass"); |
256 | 108 | } | |
257 | |||
258 | 43 | void SolverDDP::forwardPass(const double steplength) { | |
259 |
2/4✓ Branch 0 taken 43 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 43 times.
|
43 | if (steplength > 1. || steplength < 0.) { |
260 | ✗ | throw_pretty("Invalid argument: " | |
261 | << "invalid step length, value is between 0. to 1."); | ||
262 | } | ||
263 |
3/16✗ Branch 2 not taken.
✓ Branch 3 taken 43 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 43 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 43 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
|
43 | START_PROFILER("SolverDDP::forwardPass"); |
264 | 43 | cost_try_ = 0.; | |
265 | 43 | const std::size_t T = problem_->get_T(); | |
266 | const std::vector<boost::shared_ptr<ActionModelAbstract> >& models = | ||
267 | 43 | problem_->get_runningModels(); | |
268 | const std::vector<boost::shared_ptr<ActionDataAbstract> >& datas = | ||
269 | 43 | problem_->get_runningDatas(); | |
270 |
2/2✓ Branch 0 taken 408 times.
✓ Branch 1 taken 43 times.
|
451 | for (std::size_t t = 0; t < T; ++t) { |
271 | 408 | const boost::shared_ptr<ActionModelAbstract>& m = models[t]; | |
272 | 408 | const boost::shared_ptr<ActionDataAbstract>& d = datas[t]; | |
273 | |||
274 |
3/6✓ Branch 7 taken 408 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 408 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 408 times.
✗ Branch 15 not taken.
|
408 | m->get_state()->diff(xs_[t], xs_try_[t], dx_[t]); |
275 |
1/2✓ Branch 2 taken 408 times.
✗ Branch 3 not taken.
|
408 | if (m->get_nu() != 0) { |
276 |
1/2✓ Branch 4 taken 408 times.
✗ Branch 5 not taken.
|
408 | us_try_[t].noalias() = us_[t]; |
277 |
2/4✓ Branch 4 taken 408 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 408 times.
✗ Branch 8 not taken.
|
408 | us_try_[t].noalias() -= k_[t] * steplength; |
278 |
2/4✓ Branch 5 taken 408 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 408 times.
✗ Branch 9 not taken.
|
408 | us_try_[t].noalias() -= K_[t] * dx_[t]; |
279 |
2/4✓ Branch 5 taken 408 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 408 times.
✗ Branch 9 not taken.
|
408 | m->calc(d, xs_try_[t], us_try_[t]); |
280 | } else { | ||
281 | ✗ | m->calc(d, xs_try_[t]); | |
282 | } | ||
283 | 408 | xs_try_[t + 1] = d->xnext; | |
284 | 408 | cost_try_ += d->cost; | |
285 | |||
286 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 408 times.
|
408 | if (raiseIfNaN(cost_try_)) { |
287 | ✗ | STOP_PROFILER("SolverDDP::forwardPass"); | |
288 | ✗ | throw_pretty("forward_error"); | |
289 | } | ||
290 |
1/2✗ Branch 3 not taken.
✓ Branch 4 taken 408 times.
|
408 | if (raiseIfNaN(xs_try_[t + 1].lpNorm<Eigen::Infinity>())) { |
291 | ✗ | STOP_PROFILER("SolverDDP::forwardPass"); | |
292 | ✗ | throw_pretty("forward_error"); | |
293 | } | ||
294 | } | ||
295 | |||
296 | const boost::shared_ptr<ActionModelAbstract>& m = | ||
297 | 43 | problem_->get_terminalModel(); | |
298 | 43 | const boost::shared_ptr<ActionDataAbstract>& d = problem_->get_terminalData(); | |
299 |
1/2✓ Branch 4 taken 43 times.
✗ Branch 5 not taken.
|
43 | m->calc(d, xs_try_.back()); |
300 | 43 | cost_try_ += d->cost; | |
301 | |||
302 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 43 times.
|
43 | if (raiseIfNaN(cost_try_)) { |
303 | ✗ | STOP_PROFILER("SolverDDP::forwardPass"); | |
304 | ✗ | throw_pretty("forward_error"); | |
305 | } | ||
306 |
3/16✗ Branch 2 not taken.
✓ Branch 3 taken 43 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 43 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 43 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
|
43 | STOP_PROFILER("SolverDDP::forwardPass"); |
307 | 43 | } | |
308 | |||
309 | 1152 | void SolverDDP::computeActionValueFunction( | |
310 | const std::size_t t, const boost::shared_ptr<ActionModelAbstract>& model, | ||
311 | const boost::shared_ptr<ActionDataAbstract>& data) { | ||
312 |
1/14✗ Branch 2 not taken.
✓ Branch 3 taken 1152 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
|
1152 | assert_pretty(t < problem_->get_T(), |
313 | "Invalid argument: t should be between 0 and " + | ||
314 | std::to_string(problem_->get_T());); | ||
315 | 1152 | const std::size_t nu = model->get_nu(); | |
316 | 1152 | const Eigen::MatrixXd& Vxx_p = Vxx_[t + 1]; | |
317 | 1152 | const Eigen::VectorXd& Vx_p = Vx_[t + 1]; | |
318 | |||
319 |
3/6✓ Branch 3 taken 1152 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1152 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1152 times.
✗ Branch 10 not taken.
|
1152 | FxTVxx_p_.noalias() = data->Fx.transpose() * Vxx_p; |
320 |
3/16✗ Branch 2 not taken.
✓ Branch 3 taken 1152 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 1152 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1152 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
|
1152 | START_PROFILER("SolverDDP::Qx"); |
321 | 1152 | Qx_[t] = data->Lx; | |
322 |
3/6✓ Branch 3 taken 1152 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1152 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1152 times.
✗ Branch 11 not taken.
|
1152 | Qx_[t].noalias() += data->Fx.transpose() * Vx_p; |
323 |
3/16✗ Branch 2 not taken.
✓ Branch 3 taken 1152 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 1152 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1152 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
|
1152 | STOP_PROFILER("SolverDDP::Qx"); |
324 |
3/16✗ Branch 2 not taken.
✓ Branch 3 taken 1152 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 1152 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1152 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
|
1152 | START_PROFILER("SolverDDP::Qxx"); |
325 | 1152 | Qxx_[t] = data->Lxx; | |
326 |
2/4✓ Branch 4 taken 1152 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1152 times.
✗ Branch 8 not taken.
|
1152 | Qxx_[t].noalias() += FxTVxx_p_ * data->Fx; |
327 |
3/16✗ Branch 2 not taken.
✓ Branch 3 taken 1152 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 1152 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1152 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
|
1152 | STOP_PROFILER("SolverDDP::Qxx"); |
328 |
1/2✓ Branch 0 taken 1152 times.
✗ Branch 1 not taken.
|
1152 | if (nu != 0) { |
329 |
3/6✓ Branch 3 taken 1152 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1152 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1152 times.
✗ Branch 11 not taken.
|
1152 | FuTVxx_p_[t].noalias() = data->Fu.transpose() * Vxx_p; |
330 |
3/16✗ Branch 2 not taken.
✓ Branch 3 taken 1152 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 1152 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1152 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
|
1152 | START_PROFILER("SolverDDP::Qu"); |
331 | 1152 | Qu_[t] = data->Lu; | |
332 |
3/6✓ Branch 3 taken 1152 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1152 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1152 times.
✗ Branch 11 not taken.
|
1152 | Qu_[t].noalias() += data->Fu.transpose() * Vx_p; |
333 |
3/16✗ Branch 2 not taken.
✓ Branch 3 taken 1152 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 1152 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1152 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
|
1152 | STOP_PROFILER("SolverDDP::Qu"); |
334 |
3/16✗ Branch 2 not taken.
✓ Branch 3 taken 1152 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 1152 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1152 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
|
1152 | START_PROFILER("SolverDDP::Quu"); |
335 | 1152 | Quu_[t] = data->Luu; | |
336 |
2/4✓ Branch 5 taken 1152 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1152 times.
✗ Branch 9 not taken.
|
1152 | Quu_[t].noalias() += FuTVxx_p_[t] * data->Fu; |
337 |
3/16✗ Branch 2 not taken.
✓ Branch 3 taken 1152 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 1152 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1152 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
|
1152 | STOP_PROFILER("SolverDDP::Quu"); |
338 |
3/16✗ Branch 2 not taken.
✓ Branch 3 taken 1152 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 1152 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1152 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
|
1152 | START_PROFILER("SolverDDP::Qxu"); |
339 | 1152 | Qxu_[t] = data->Lxu; | |
340 |
2/4✓ Branch 4 taken 1152 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1152 times.
✗ Branch 8 not taken.
|
1152 | Qxu_[t].noalias() += FxTVxx_p_ * data->Fu; |
341 |
3/16✗ Branch 2 not taken.
✓ Branch 3 taken 1152 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 1152 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1152 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
|
1152 | STOP_PROFILER("SolverDDP::Qxu"); |
342 |
1/2✓ Branch 1 taken 1152 times.
✗ Branch 2 not taken.
|
1152 | if (!std::isnan(preg_)) { |
343 |
2/4✓ Branch 3 taken 1152 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1152 times.
✗ Branch 7 not taken.
|
1152 | Quu_[t].diagonal().array() += preg_; |
344 | } | ||
345 | } | ||
346 | 1152 | } | |
347 | |||
348 | 1152 | void SolverDDP::computeValueFunction( | |
349 | const std::size_t t, const boost::shared_ptr<ActionModelAbstract>& model) { | ||
350 |
1/14✗ Branch 2 not taken.
✓ Branch 3 taken 1152 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
|
1152 | assert_pretty(t < problem_->get_T(), |
351 | "Invalid argument: t should be between 0 and " + | ||
352 | std::to_string(problem_->get_T());); | ||
353 | 1152 | const std::size_t nu = model->get_nu(); | |
354 | 1152 | Vx_[t] = Qx_[t]; | |
355 | 1152 | Vxx_[t] = Qxx_[t]; | |
356 |
1/2✓ Branch 0 taken 1152 times.
✗ Branch 1 not taken.
|
1152 | if (nu != 0) { |
357 |
3/16✗ Branch 2 not taken.
✓ Branch 3 taken 1152 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 1152 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1152 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
|
1152 | START_PROFILER("SolverDDP::Vx"); |
358 |
2/4✓ Branch 5 taken 1152 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1152 times.
✗ Branch 9 not taken.
|
1152 | Quuk_[t].noalias() = Quu_[t] * k_[t]; |
359 |
3/6✓ Branch 4 taken 1152 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1152 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1152 times.
✗ Branch 12 not taken.
|
1152 | Vx_[t].noalias() -= K_[t].transpose() * Qu_[t]; |
360 |
3/16✗ Branch 2 not taken.
✓ Branch 3 taken 1152 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 1152 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1152 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
|
1152 | STOP_PROFILER("SolverDDP::Vx"); |
361 |
3/16✗ Branch 2 not taken.
✓ Branch 3 taken 1152 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 1152 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1152 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
|
1152 | START_PROFILER("SolverDDP::Vxx"); |
362 |
2/4✓ Branch 5 taken 1152 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1152 times.
✗ Branch 9 not taken.
|
1152 | Vxx_[t].noalias() -= Qxu_[t] * K_[t]; |
363 |
3/16✗ Branch 2 not taken.
✓ Branch 3 taken 1152 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 1152 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1152 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
|
1152 | STOP_PROFILER("SolverDDP::Vxx"); |
364 | } | ||
365 |
3/6✓ Branch 4 taken 1152 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1152 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1152 times.
✗ Branch 11 not taken.
|
1152 | Vxx_tmp_ = 0.5 * (Vxx_[t] + Vxx_[t].transpose()); |
366 | 1152 | Vxx_[t] = Vxx_tmp_; | |
367 | |||
368 |
1/2✓ Branch 1 taken 1152 times.
✗ Branch 2 not taken.
|
1152 | if (!std::isnan(preg_)) { |
369 |
2/4✓ Branch 3 taken 1152 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1152 times.
✗ Branch 7 not taken.
|
1152 | Vxx_[t].diagonal().array() += preg_; |
370 | } | ||
371 | |||
372 | // Compute and store the Vx gradient at end of the interval (rollout state) | ||
373 |
2/2✓ Branch 0 taken 380 times.
✓ Branch 1 taken 772 times.
|
1152 | if (!is_feasible_) { |
374 |
2/4✓ Branch 5 taken 380 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 380 times.
✗ Branch 9 not taken.
|
380 | Vx_[t].noalias() += Vxx_[t] * fs_[t]; |
375 | } | ||
376 | 1152 | } | |
377 | |||
378 | 1152 | void SolverDDP::computeGains(const std::size_t t) { | |
379 |
1/14✗ Branch 2 not taken.
✓ Branch 3 taken 1152 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
|
1152 | assert_pretty(t < problem_->get_T(), |
380 | "Invalid argument: t should be between 0 and " + | ||
381 | std::to_string(problem_->get_T())); | ||
382 |
3/16✗ Branch 2 not taken.
✓ Branch 3 taken 1152 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 1152 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1152 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
|
1152 | START_PROFILER("SolverDDP::computeGains"); |
383 | 1152 | const std::size_t nu = problem_->get_runningModels()[t]->get_nu(); | |
384 |
1/2✓ Branch 0 taken 1152 times.
✗ Branch 1 not taken.
|
1152 | if (nu > 0) { |
385 |
5/20✓ Branch 1 taken 1152 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1152 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1152 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 1152 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 1152 times.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
|
1152 | START_PROFILER("SolverDDP::Quu_inv"); |
386 |
1/2✓ Branch 3 taken 1152 times.
✗ Branch 4 not taken.
|
1152 | Quu_llt_[t].compute(Quu_[t]); |
387 |
5/20✓ Branch 1 taken 1152 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1152 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1152 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 1152 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 1152 times.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
|
1152 | STOP_PROFILER("SolverDDP::Quu_inv"); |
388 | 1152 | const Eigen::ComputationInfo& info = Quu_llt_[t].info(); | |
389 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1152 times.
|
1152 | if (info != Eigen::Success) { |
390 | ✗ | STOP_PROFILER("SolverDDP::computeGains"); | |
391 | ✗ | throw_pretty("backward_error"); | |
392 | } | ||
393 |
2/4✓ Branch 2 taken 1152 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1152 times.
✗ Branch 7 not taken.
|
1152 | K_[t] = Qxu_[t].transpose(); |
394 | |||
395 |
5/20✓ Branch 1 taken 1152 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1152 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1152 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 1152 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 1152 times.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
|
1152 | START_PROFILER("SolverDDP::Quu_inv_Qux"); |
396 |
1/2✓ Branch 3 taken 1152 times.
✗ Branch 4 not taken.
|
1152 | Quu_llt_[t].solveInPlace(K_[t]); |
397 |
5/20✓ Branch 1 taken 1152 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1152 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1152 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 1152 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 1152 times.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
|
1152 | STOP_PROFILER("SolverDDP::Quu_inv_Qux"); |
398 |
1/2✓ Branch 3 taken 1152 times.
✗ Branch 4 not taken.
|
1152 | k_[t] = Qu_[t]; |
399 |
1/2✓ Branch 3 taken 1152 times.
✗ Branch 4 not taken.
|
1152 | Quu_llt_[t].solveInPlace(k_[t]); |
400 | } | ||
401 |
3/16✗ Branch 2 not taken.
✓ Branch 3 taken 1152 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 1152 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1152 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
|
1152 | STOP_PROFILER("SolverDDP::computeGains"); |
402 | 1152 | } | |
403 | |||
404 | ✗ | void SolverDDP::increaseRegularization() { | |
405 | ✗ | preg_ *= reg_incfactor_; | |
406 | ✗ | if (preg_ > reg_max_) { | |
407 | ✗ | preg_ = reg_max_; | |
408 | } | ||
409 | ✗ | dreg_ = preg_; | |
410 | } | ||
411 | |||
412 | 100 | void SolverDDP::decreaseRegularization() { | |
413 | 100 | preg_ /= reg_decfactor_; | |
414 |
1/2✓ Branch 0 taken 100 times.
✗ Branch 1 not taken.
|
100 | if (preg_ < reg_min_) { |
415 | 100 | preg_ = reg_min_; | |
416 | } | ||
417 | 100 | dreg_ = preg_; | |
418 | 100 | } | |
419 | |||
420 | 61 | void SolverDDP::allocateData() { | |
421 | 61 | const std::size_t T = problem_->get_T(); | |
422 | 61 | Vxx_.resize(T + 1); | |
423 | 61 | Vx_.resize(T + 1); | |
424 | 61 | Qxx_.resize(T); | |
425 | 61 | Qxu_.resize(T); | |
426 | 61 | Quu_.resize(T); | |
427 | 61 | Qx_.resize(T); | |
428 | 61 | Qu_.resize(T); | |
429 | 61 | K_.resize(T); | |
430 | 61 | k_.resize(T); | |
431 | |||
432 | 61 | xs_try_.resize(T + 1); | |
433 | 61 | us_try_.resize(T); | |
434 | 61 | dx_.resize(T); | |
435 | |||
436 | 61 | FuTVxx_p_.resize(T); | |
437 | 61 | Quu_llt_.resize(T); | |
438 | 61 | Quuk_.resize(T); | |
439 | |||
440 | 61 | const std::size_t ndx = problem_->get_ndx(); | |
441 | const std::vector<boost::shared_ptr<ActionModelAbstract> >& models = | ||
442 | 61 | problem_->get_runningModels(); | |
443 |
2/2✓ Branch 0 taken 589 times.
✓ Branch 1 taken 61 times.
|
650 | for (std::size_t t = 0; t < T; ++t) { |
444 | 589 | const boost::shared_ptr<ActionModelAbstract>& model = models[t]; | |
445 | 589 | const std::size_t nu = model->get_nu(); | |
446 |
2/4✓ Branch 1 taken 589 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 589 times.
✗ Branch 6 not taken.
|
589 | Vxx_[t] = Eigen::MatrixXd::Zero(ndx, ndx); |
447 |
2/4✓ Branch 1 taken 589 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 589 times.
✗ Branch 6 not taken.
|
589 | Vx_[t] = Eigen::VectorXd::Zero(ndx); |
448 |
2/4✓ Branch 1 taken 589 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 589 times.
✗ Branch 6 not taken.
|
589 | Qxx_[t] = Eigen::MatrixXd::Zero(ndx, ndx); |
449 |
2/4✓ Branch 1 taken 589 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 589 times.
✗ Branch 6 not taken.
|
589 | Qxu_[t] = Eigen::MatrixXd::Zero(ndx, nu); |
450 |
2/4✓ Branch 1 taken 589 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 589 times.
✗ Branch 6 not taken.
|
589 | Quu_[t] = Eigen::MatrixXd::Zero(nu, nu); |
451 |
2/4✓ Branch 1 taken 589 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 589 times.
✗ Branch 6 not taken.
|
589 | Qx_[t] = Eigen::VectorXd::Zero(ndx); |
452 |
2/4✓ Branch 1 taken 589 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 589 times.
✗ Branch 6 not taken.
|
589 | Qu_[t] = Eigen::VectorXd::Zero(nu); |
453 |
2/4✓ Branch 1 taken 589 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 589 times.
✗ Branch 6 not taken.
|
589 | K_[t] = MatrixXdRowMajor::Zero(nu, ndx); |
454 |
2/4✓ Branch 1 taken 589 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 589 times.
✗ Branch 6 not taken.
|
589 | k_[t] = Eigen::VectorXd::Zero(nu); |
455 | |||
456 |
2/2✓ Branch 0 taken 61 times.
✓ Branch 1 taken 528 times.
|
589 | if (t == 0) { |
457 |
1/2✓ Branch 4 taken 61 times.
✗ Branch 5 not taken.
|
61 | xs_try_[t] = problem_->get_x0(); |
458 | } else { | ||
459 |
1/2✓ Branch 4 taken 528 times.
✗ Branch 5 not taken.
|
528 | xs_try_[t] = model->get_state()->zero(); |
460 | } | ||
461 |
2/4✓ Branch 1 taken 589 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 589 times.
✗ Branch 6 not taken.
|
589 | us_try_[t] = Eigen::VectorXd::Zero(nu); |
462 |
2/4✓ Branch 1 taken 589 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 589 times.
✗ Branch 6 not taken.
|
589 | dx_[t] = Eigen::VectorXd::Zero(ndx); |
463 | |||
464 |
2/4✓ Branch 1 taken 589 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 589 times.
✗ Branch 6 not taken.
|
589 | FuTVxx_p_[t] = MatrixXdRowMajor::Zero(nu, ndx); |
465 |
1/2✓ Branch 1 taken 589 times.
✗ Branch 2 not taken.
|
589 | Quu_llt_[t] = Eigen::LLT<Eigen::MatrixXd>(nu); |
466 |
1/2✓ Branch 1 taken 589 times.
✗ Branch 2 not taken.
|
589 | Quuk_[t] = Eigen::VectorXd(nu); |
467 | } | ||
468 |
1/2✓ Branch 3 taken 61 times.
✗ Branch 4 not taken.
|
61 | Vxx_.back() = Eigen::MatrixXd::Zero(ndx, ndx); |
469 |
1/2✓ Branch 2 taken 61 times.
✗ Branch 3 not taken.
|
61 | Vxx_tmp_ = Eigen::MatrixXd::Zero(ndx, ndx); |
470 |
1/2✓ Branch 3 taken 61 times.
✗ Branch 4 not taken.
|
61 | Vx_.back() = Eigen::VectorXd::Zero(ndx); |
471 | 61 | xs_try_.back() = problem_->get_terminalModel()->get_state()->zero(); | |
472 | |||
473 |
1/2✓ Branch 2 taken 61 times.
✗ Branch 3 not taken.
|
61 | FxTVxx_p_ = MatrixXdRowMajor::Zero(ndx, ndx); |
474 |
1/2✓ Branch 2 taken 61 times.
✗ Branch 3 not taken.
|
61 | fTVxx_p_ = Eigen::VectorXd::Zero(ndx); |
475 | 61 | } | |
476 | |||
477 | ✗ | double SolverDDP::get_reg_incfactor() const { return reg_incfactor_; } | |
478 | |||
479 | ✗ | double SolverDDP::get_reg_decfactor() const { return reg_decfactor_; } | |
480 | |||
481 | ✗ | double SolverDDP::get_regfactor() const { return reg_incfactor_; } | |
482 | |||
483 | ✗ | double SolverDDP::get_reg_min() const { return reg_min_; } | |
484 | |||
485 | ✗ | double SolverDDP::get_regmin() const { return reg_min_; } | |
486 | |||
487 | ✗ | double SolverDDP::get_reg_max() const { return reg_max_; } | |
488 | |||
489 | ✗ | double SolverDDP::get_regmax() const { return reg_max_; } | |
490 | |||
491 | ✗ | const std::vector<double>& SolverDDP::get_alphas() const { return alphas_; } | |
492 | |||
493 | ✗ | double SolverDDP::get_th_stepdec() const { return th_stepdec_; } | |
494 | |||
495 | ✗ | double SolverDDP::get_th_stepinc() const { return th_stepinc_; } | |
496 | |||
497 | ✗ | double SolverDDP::get_th_grad() const { return th_grad_; } | |
498 | |||
499 | 4 | const std::vector<Eigen::MatrixXd>& SolverDDP::get_Vxx() const { return Vxx_; } | |
500 | |||
501 | 4 | const std::vector<Eigen::VectorXd>& SolverDDP::get_Vx() const { return Vx_; } | |
502 | |||
503 | 4 | const std::vector<Eigen::MatrixXd>& SolverDDP::get_Qxx() const { return Qxx_; } | |
504 | |||
505 | 4 | const std::vector<Eigen::MatrixXd>& SolverDDP::get_Qxu() const { return Qxu_; } | |
506 | |||
507 | 4 | const std::vector<Eigen::MatrixXd>& SolverDDP::get_Quu() const { return Quu_; } | |
508 | |||
509 | 4 | const std::vector<Eigen::VectorXd>& SolverDDP::get_Qx() const { return Qx_; } | |
510 | |||
511 | 4 | const std::vector<Eigen::VectorXd>& SolverDDP::get_Qu() const { return Qu_; } | |
512 | |||
513 | const std::vector<typename MathBaseTpl<double>::MatrixXsRowMajor>& | ||
514 | ✗ | SolverDDP::get_K() const { | |
515 | ✗ | return K_; | |
516 | } | ||
517 | |||
518 | 4 | const std::vector<Eigen::VectorXd>& SolverDDP::get_k() const { return k_; } | |
519 | |||
520 | ✗ | void SolverDDP::set_reg_incfactor(const double regfactor) { | |
521 | ✗ | if (regfactor <= 1.) { | |
522 | ✗ | throw_pretty( | |
523 | "Invalid argument: " << "reg_incfactor value is higher than 1."); | ||
524 | } | ||
525 | ✗ | reg_incfactor_ = regfactor; | |
526 | } | ||
527 | |||
528 | ✗ | void SolverDDP::set_reg_decfactor(const double regfactor) { | |
529 | ✗ | if (regfactor <= 1.) { | |
530 | ✗ | throw_pretty( | |
531 | "Invalid argument: " << "reg_decfactor value is higher than 1."); | ||
532 | } | ||
533 | ✗ | reg_decfactor_ = regfactor; | |
534 | } | ||
535 | |||
536 | ✗ | void SolverDDP::set_regfactor(const double regfactor) { | |
537 | ✗ | if (regfactor <= 1.) { | |
538 | ✗ | throw_pretty("Invalid argument: " << "regfactor value is higher than 1."); | |
539 | } | ||
540 | ✗ | set_reg_incfactor(regfactor); | |
541 | ✗ | set_reg_decfactor(regfactor); | |
542 | } | ||
543 | |||
544 | ✗ | void SolverDDP::set_reg_min(const double regmin) { | |
545 | ✗ | if (0. > regmin) { | |
546 | ✗ | throw_pretty("Invalid argument: " << "regmin value has to be positive."); | |
547 | } | ||
548 | ✗ | reg_min_ = regmin; | |
549 | } | ||
550 | |||
551 | ✗ | void SolverDDP::set_regmin(const double regmin) { | |
552 | ✗ | if (0. > regmin) { | |
553 | ✗ | throw_pretty("Invalid argument: " << "regmin value has to be positive."); | |
554 | } | ||
555 | ✗ | reg_min_ = regmin; | |
556 | } | ||
557 | |||
558 | ✗ | void SolverDDP::set_reg_max(const double regmax) { | |
559 | ✗ | if (0. > regmax) { | |
560 | ✗ | throw_pretty("Invalid argument: " << "regmax value has to be positive."); | |
561 | } | ||
562 | ✗ | reg_max_ = regmax; | |
563 | } | ||
564 | |||
565 | ✗ | void SolverDDP::set_regmax(const double regmax) { | |
566 | ✗ | if (0. > regmax) { | |
567 | ✗ | throw_pretty("Invalid argument: " << "regmax value has to be positive."); | |
568 | } | ||
569 | ✗ | reg_max_ = regmax; | |
570 | } | ||
571 | |||
572 | ✗ | void SolverDDP::set_alphas(const std::vector<double>& alphas) { | |
573 | ✗ | double prev_alpha = alphas[0]; | |
574 | ✗ | if (prev_alpha != 1.) { | |
575 | ✗ | std::cerr << "Warning: alpha[0] should be 1" << std::endl; | |
576 | } | ||
577 | ✗ | for (std::size_t i = 1; i < alphas.size(); ++i) { | |
578 | ✗ | double alpha = alphas[i]; | |
579 | ✗ | if (0. >= alpha) { | |
580 | ✗ | throw_pretty("Invalid argument: " << "alpha values has to be positive."); | |
581 | } | ||
582 | ✗ | if (alpha >= prev_alpha) { | |
583 | ✗ | throw_pretty( | |
584 | "Invalid argument: " << "alpha values are monotonously decreasing."); | ||
585 | } | ||
586 | ✗ | prev_alpha = alpha; | |
587 | } | ||
588 | ✗ | alphas_ = alphas; | |
589 | } | ||
590 | |||
591 | ✗ | void SolverDDP::set_th_stepdec(const double th_stepdec) { | |
592 | ✗ | if (0. >= th_stepdec || th_stepdec > 1.) { | |
593 | ✗ | throw_pretty( | |
594 | "Invalid argument: " << "th_stepdec value should between 0 and 1."); | ||
595 | } | ||
596 | ✗ | th_stepdec_ = th_stepdec; | |
597 | } | ||
598 | |||
599 | ✗ | void SolverDDP::set_th_stepinc(const double th_stepinc) { | |
600 | ✗ | if (0. >= th_stepinc || th_stepinc > 1.) { | |
601 | ✗ | throw_pretty( | |
602 | "Invalid argument: " << "th_stepinc value should between 0 and 1."); | ||
603 | } | ||
604 | ✗ | th_stepinc_ = th_stepinc; | |
605 | } | ||
606 | |||
607 | ✗ | void SolverDDP::set_th_grad(const double th_grad) { | |
608 | ✗ | if (0. > th_grad) { | |
609 | ✗ | throw_pretty("Invalid argument: " << "th_grad value has to be positive."); | |
610 | } | ||
611 | ✗ | th_grad_ = th_grad; | |
612 | } | ||
613 | |||
614 | } // namespace crocoddyl | ||
615 |