Directory: | ./ |
---|---|
File: | src/core/solvers/fddp.cpp |
Date: | 2025-03-26 19:23:43 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 137 | 172 | 79.7% |
Branches: | 129 | 462 | 27.9% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | /////////////////////////////////////////////////////////////////////////////// | ||
2 | // BSD 3-Clause License | ||
3 | // | ||
4 | // Copyright (C) 2019-2022, 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 | #ifdef CROCODDYL_WITH_MULTITHREADING | ||
11 | #include <omp.h> | ||
12 | #endif // CROCODDYL_WITH_MULTITHREADING | ||
13 | |||
14 | #include "crocoddyl/core/solvers/fddp.hpp" | ||
15 | |||
16 | namespace crocoddyl { | ||
17 | |||
18 | 25 | SolverFDDP::SolverFDDP(std::shared_ptr<ShootingProblem> problem) | |
19 |
1/2✓ Branch 2 taken 25 times.
✗ Branch 3 not taken.
|
25 | : SolverDDP(problem), dg_(0), dq_(0), dv_(0), th_acceptnegstep_(2) {} |
20 | |||
21 | 62 | SolverFDDP::~SolverFDDP() {} | |
22 | |||
23 | 16 | bool SolverFDDP::solve(const std::vector<Eigen::VectorXd>& init_xs, | |
24 | const std::vector<Eigen::VectorXd>& init_us, | ||
25 | const std::size_t maxiter, const bool is_feasible, | ||
26 | const double init_reg) { | ||
27 |
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("SolverFDDP::solve"); |
28 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 16 times.
|
16 | if (problem_->is_updated()) { |
29 | ✗ | resizeData(); | |
30 | } | ||
31 | 16 | xs_try_[0] = | |
32 | 16 | problem_->get_x0(); // it is needed in case that init_xs[0] is infeasible | |
33 | 16 | setCandidate(init_xs, init_us, is_feasible); | |
34 | |||
35 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
16 | if (std::isnan(init_reg)) { |
36 | 16 | preg_ = reg_min_; | |
37 | 16 | dreg_ = reg_min_; | |
38 | } else { | ||
39 | ✗ | preg_ = init_reg; | |
40 | ✗ | dreg_ = init_reg; | |
41 | } | ||
42 | 16 | was_feasible_ = false; | |
43 | |||
44 | 16 | bool recalcDiff = true; | |
45 |
2/2✓ Branch 0 taken 51 times.
✓ Branch 1 taken 6 times.
|
57 | for (iter_ = 0; iter_ < maxiter; ++iter_) { |
46 | while (true) { | ||
47 | try { | ||
48 |
1/2✓ Branch 1 taken 51 times.
✗ Branch 2 not taken.
|
51 | computeDirection(recalcDiff); |
49 | ✗ | } catch (std::exception& e) { | |
50 | ✗ | recalcDiff = false; | |
51 | ✗ | increaseRegularization(); | |
52 | ✗ | if (preg_ == reg_max_) { | |
53 | ✗ | return false; | |
54 | } else { | ||
55 | ✗ | continue; | |
56 | } | ||
57 | } | ||
58 | 51 | break; | |
59 | } | ||
60 | 51 | updateExpectedImprovement(); | |
61 | |||
62 | // We need to recalculate the derivatives when the step length passes | ||
63 | 51 | recalcDiff = false; | |
64 | 51 | for (std::vector<double>::const_iterator it = alphas_.begin(); | |
65 |
1/2✓ Branch 3 taken 53 times.
✗ Branch 4 not taken.
|
53 | it != alphas_.end(); ++it) { |
66 | 53 | steplength_ = *it; | |
67 | |||
68 | try { | ||
69 |
1/2✓ Branch 1 taken 53 times.
✗ Branch 2 not taken.
|
53 | dV_ = tryStep(steplength_); |
70 | ✗ | } catch (std::exception& e) { | |
71 | ✗ | continue; | |
72 | } | ||
73 |
1/2✓ Branch 1 taken 53 times.
✗ Branch 2 not taken.
|
53 | expectedImprovement(); |
74 |
2/4✓ Branch 1 taken 53 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 53 times.
✗ Branch 5 not taken.
|
53 | dVexp_ = steplength_ * (d_[0] + 0.5 * steplength_ * d_[1]); |
75 | |||
76 |
2/2✓ Branch 0 taken 39 times.
✓ Branch 1 taken 14 times.
|
53 | if (dVexp_ >= 0) { // descend direction |
77 |
7/8✓ Branch 1 taken 39 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 30 times.
✓ Branch 5 taken 9 times.
✓ Branch 6 taken 29 times.
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 38 times.
✓ Branch 9 taken 1 times.
|
39 | if (std::abs(d_[0]) < th_grad_ || dV_ > th_acceptstep_ * dVexp_) { |
78 | 38 | was_feasible_ = is_feasible_; | |
79 |
5/6✓ Branch 0 taken 5 times.
✓ Branch 1 taken 33 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 1 times.
✓ Branch 5 taken 38 times.
✗ Branch 6 not taken.
|
38 | setCandidate(xs_try_, us_try_, (was_feasible_) || (steplength_ == 1)); |
80 | 38 | cost_ = cost_try_; | |
81 | 38 | recalcDiff = true; | |
82 | 38 | break; | |
83 | } | ||
84 | } else { // reducing the gaps by allowing a small increment in the cost | ||
85 | // value | ||
86 |
3/4✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13 times.
✓ Branch 3 taken 1 times.
|
14 | if (!is_feasible_ && dV_ > th_acceptnegstep_ * dVexp_) { |
87 | 13 | was_feasible_ = is_feasible_; | |
88 |
4/6✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 1 times.
✓ Branch 5 taken 13 times.
✗ Branch 6 not taken.
|
13 | setCandidate(xs_try_, us_try_, (was_feasible_) || (steplength_ == 1)); |
89 | 13 | cost_ = cost_try_; | |
90 | 13 | recalcDiff = true; | |
91 | 13 | break; | |
92 | } | ||
93 | } | ||
94 | } | ||
95 | |||
96 |
2/2✓ Branch 0 taken 49 times.
✓ Branch 1 taken 2 times.
|
51 | if (steplength_ > th_stepdec_) { |
97 | 49 | decreaseRegularization(); | |
98 | } | ||
99 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
|
51 | if (steplength_ <= th_stepinc_) { |
100 | ✗ | increaseRegularization(); | |
101 | ✗ | if (preg_ == reg_max_) { | |
102 | ✗ | STOP_PROFILER("SolverFDDP::solve"); | |
103 | ✗ | return false; | |
104 | } | ||
105 | } | ||
106 | 51 | stoppingCriteria(); | |
107 | |||
108 | 51 | const std::size_t n_callbacks = callbacks_.size(); | |
109 |
2/2✓ Branch 0 taken 23 times.
✓ Branch 1 taken 51 times.
|
74 | for (std::size_t c = 0; c < n_callbacks; ++c) { |
110 | 23 | CallbackAbstract& callback = *callbacks_[c]; | |
111 | 23 | callback(*this); | |
112 | } | ||
113 | |||
114 |
4/4✓ Branch 0 taken 33 times.
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 23 times.
|
51 | if (was_feasible_ && stop_ < th_stop_) { |
115 |
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("SolverFDDP::solve"); |
116 | 10 | return true; | |
117 | } | ||
118 | } | ||
119 |
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("SolverFDDP::solve"); |
120 | 6 | return false; | |
121 | } | ||
122 | |||
123 | 55 | const Eigen::Vector2d& SolverFDDP::expectedImprovement() { | |
124 | 55 | dv_ = 0; | |
125 | 55 | const std::size_t T = this->problem_->get_T(); | |
126 |
2/2✓ Branch 0 taken 20 times.
✓ Branch 1 taken 35 times.
|
55 | if (!is_feasible_) { |
127 | // NB: The dimension of vectors xs_try_ and xs_ are T+1, whereas the | ||
128 | // dimension of dx_ is T. Here, we are re-using the final element of dx_ for | ||
129 | // the computation of the difference at the terminal node. Using the access | ||
130 | // iterator back() this re-use of the final element is fine. Cf. the | ||
131 | // discussion at https://github.com/loco-3d/crocoddyl/issues/1022 | ||
132 |
3/6✓ Branch 8 taken 20 times.
✗ Branch 9 not taken.
✓ Branch 12 taken 20 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 20 times.
✗ Branch 16 not taken.
|
40 | problem_->get_terminalModel()->get_state()->diff(xs_try_.back(), xs_.back(), |
133 | 20 | dx_.back()); | |
134 |
2/4✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 20 times.
✗ Branch 8 not taken.
|
20 | fTVxx_p_.noalias() = Vxx_.back() * dx_.back(); |
135 | 20 | dv_ -= fs_.back().dot(fTVxx_p_); | |
136 | const std::vector<std::shared_ptr<ActionModelAbstract> >& models = | ||
137 | 20 | problem_->get_runningModels(); | |
138 | |||
139 |
2/2✓ Branch 0 taken 211 times.
✓ Branch 1 taken 20 times.
|
231 | for (std::size_t t = 0; t < T; ++t) { |
140 |
3/6✓ Branch 8 taken 211 times.
✗ Branch 9 not taken.
✓ Branch 12 taken 211 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 211 times.
✗ Branch 16 not taken.
|
211 | models[t]->get_state()->diff(xs_try_[t], xs_[t], dx_[t]); |
141 |
2/4✓ Branch 4 taken 211 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 211 times.
✗ Branch 8 not taken.
|
211 | fTVxx_p_.noalias() = Vxx_[t] * dx_[t]; |
142 | 211 | dv_ -= fs_[t].dot(fTVxx_p_); | |
143 | } | ||
144 | } | ||
145 | 55 | d_[0] = dg_ + dv_; | |
146 | 55 | d_[1] = dq_ - 2 * dv_; | |
147 | 55 | return d_; | |
148 | } | ||
149 | |||
150 | 51 | void SolverFDDP::updateExpectedImprovement() { | |
151 | 51 | dg_ = 0; | |
152 | 51 | dq_ = 0; | |
153 | 51 | const std::size_t T = this->problem_->get_T(); | |
154 |
2/2✓ Branch 0 taken 18 times.
✓ Branch 1 taken 33 times.
|
51 | if (!is_feasible_) { |
155 | 18 | dg_ -= Vx_.back().dot(fs_.back()); | |
156 |
2/4✓ Branch 4 taken 18 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 18 times.
✗ Branch 8 not taken.
|
18 | fTVxx_p_.noalias() = Vxx_.back() * fs_.back(); |
157 | 18 | dq_ += fs_.back().dot(fTVxx_p_); | |
158 | } | ||
159 | const std::vector<std::shared_ptr<ActionModelAbstract> >& models = | ||
160 | 51 | problem_->get_runningModels(); | |
161 |
2/2✓ Branch 0 taken 616 times.
✓ Branch 1 taken 51 times.
|
667 | for (std::size_t t = 0; t < T; ++t) { |
162 | 616 | const std::size_t nu = models[t]->get_nu(); | |
163 |
1/2✓ Branch 0 taken 616 times.
✗ Branch 1 not taken.
|
616 | if (nu != 0) { |
164 | 616 | dg_ += Qu_[t].dot(k_[t]); | |
165 | 616 | dq_ -= k_[t].dot(Quuk_[t]); | |
166 | } | ||
167 |
2/2✓ Branch 0 taken 186 times.
✓ Branch 1 taken 430 times.
|
616 | if (!is_feasible_) { |
168 | 186 | dg_ -= Vx_[t].dot(fs_[t]); | |
169 |
2/4✓ Branch 4 taken 186 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 186 times.
✗ Branch 8 not taken.
|
186 | fTVxx_p_.noalias() = Vxx_[t] * fs_[t]; |
170 | 186 | dq_ += fs_[t].dot(fTVxx_p_); | |
171 | } | ||
172 | } | ||
173 | 51 | } | |
174 | |||
175 | 46 | void SolverFDDP::forwardPass(const double steplength) { | |
176 |
2/4✓ Branch 0 taken 46 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 46 times.
|
46 | if (steplength > 1. || steplength < 0.) { |
177 | ✗ | throw_pretty("Invalid argument: " | |
178 | << "invalid step length, value is between 0. to 1."); | ||
179 | } | ||
180 |
3/16✗ Branch 2 not taken.
✓ Branch 3 taken 46 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 46 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 46 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
|
46 | START_PROFILER("SolverFDDP::forwardPass"); |
181 | 46 | cost_try_ = 0.; | |
182 | 46 | xnext_ = problem_->get_x0(); | |
183 | 46 | const std::size_t T = problem_->get_T(); | |
184 | const std::vector<std::shared_ptr<ActionModelAbstract> >& models = | ||
185 | 46 | problem_->get_runningModels(); | |
186 | const std::vector<std::shared_ptr<ActionDataAbstract> >& datas = | ||
187 | 46 | problem_->get_runningDatas(); | |
188 |
4/4✓ Branch 0 taken 19 times.
✓ Branch 1 taken 27 times.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 4 times.
|
46 | if ((is_feasible_) || (steplength == 1)) { |
189 |
2/2✓ Branch 0 taken 532 times.
✓ Branch 1 taken 42 times.
|
574 | for (std::size_t t = 0; t < T; ++t) { |
190 | 532 | const std::shared_ptr<ActionModelAbstract>& m = models[t]; | |
191 | 532 | const std::shared_ptr<ActionDataAbstract>& d = datas[t]; | |
192 | 532 | const std::size_t nu = m->get_nu(); | |
193 | |||
194 | 532 | xs_try_[t] = xnext_; | |
195 |
3/6✓ Branch 7 taken 532 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 532 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 532 times.
✗ Branch 15 not taken.
|
532 | m->get_state()->diff(xs_[t], xs_try_[t], dx_[t]); |
196 |
1/2✓ Branch 0 taken 532 times.
✗ Branch 1 not taken.
|
532 | if (nu != 0) { |
197 |
5/10✓ Branch 5 taken 532 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 532 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 532 times.
✗ Branch 13 not taken.
✓ Branch 16 taken 532 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 532 times.
✗ Branch 20 not taken.
|
532 | us_try_[t].noalias() = us_[t] - k_[t] * steplength - K_[t] * dx_[t]; |
198 |
2/4✓ Branch 5 taken 532 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 532 times.
✗ Branch 9 not taken.
|
532 | m->calc(d, xs_try_[t], us_try_[t]); |
199 | } else { | ||
200 | ✗ | m->calc(d, xs_try_[t]); | |
201 | } | ||
202 | 532 | xnext_ = d->xnext; | |
203 | 532 | cost_try_ += d->cost; | |
204 | |||
205 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 532 times.
|
532 | if (raiseIfNaN(cost_try_)) { |
206 | ✗ | STOP_PROFILER("SolverFDDP::forwardPass"); | |
207 | ✗ | throw_pretty("forward_error"); | |
208 | } | ||
209 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 532 times.
|
532 | if (raiseIfNaN(xnext_.lpNorm<Eigen::Infinity>())) { |
210 | ✗ | STOP_PROFILER("SolverFDDP::forwardPass"); | |
211 | ✗ | throw_pretty("forward_error"); | |
212 | } | ||
213 | } | ||
214 | |||
215 | const std::shared_ptr<ActionModelAbstract>& m = | ||
216 | 42 | problem_->get_terminalModel(); | |
217 | 42 | const std::shared_ptr<ActionDataAbstract>& d = problem_->get_terminalData(); | |
218 | 42 | xs_try_.back() = xnext_; | |
219 |
1/2✓ Branch 4 taken 42 times.
✗ Branch 5 not taken.
|
42 | m->calc(d, xs_try_.back()); |
220 | 42 | cost_try_ += d->cost; | |
221 | |||
222 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 42 times.
|
42 | if (raiseIfNaN(cost_try_)) { |
223 | ✗ | STOP_PROFILER("SolverFDDP::forwardPass"); | |
224 | ✗ | throw_pretty("forward_error"); | |
225 | } | ||
226 | 42 | } else { | |
227 |
2/2✓ Branch 0 taken 51 times.
✓ Branch 1 taken 4 times.
|
55 | for (std::size_t t = 0; t < T; ++t) { |
228 | 51 | const std::shared_ptr<ActionModelAbstract>& m = models[t]; | |
229 | 51 | const std::shared_ptr<ActionDataAbstract>& d = datas[t]; | |
230 | 51 | const std::size_t nu = m->get_nu(); | |
231 |
4/8✓ Branch 7 taken 51 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 51 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 51 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 51 times.
✗ Branch 17 not taken.
|
51 | m->get_state()->integrate(xnext_, fs_[t] * (steplength - 1), xs_try_[t]); |
232 |
3/6✓ Branch 7 taken 51 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 51 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 51 times.
✗ Branch 15 not taken.
|
51 | m->get_state()->diff(xs_[t], xs_try_[t], dx_[t]); |
233 |
1/2✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
|
51 | if (nu != 0) { |
234 |
5/10✓ Branch 5 taken 51 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 51 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 51 times.
✗ Branch 13 not taken.
✓ Branch 16 taken 51 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 51 times.
✗ Branch 20 not taken.
|
51 | us_try_[t].noalias() = us_[t] - k_[t] * steplength - K_[t] * dx_[t]; |
235 |
2/4✓ Branch 5 taken 51 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 51 times.
✗ Branch 9 not taken.
|
51 | m->calc(d, xs_try_[t], us_try_[t]); |
236 | } else { | ||
237 | ✗ | m->calc(d, xs_try_[t]); | |
238 | } | ||
239 | 51 | xnext_ = d->xnext; | |
240 | 51 | cost_try_ += d->cost; | |
241 | |||
242 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 51 times.
|
51 | if (raiseIfNaN(cost_try_)) { |
243 | ✗ | STOP_PROFILER("SolverFDDP::forwardPass"); | |
244 | ✗ | throw_pretty("forward_error"); | |
245 | } | ||
246 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 51 times.
|
51 | if (raiseIfNaN(xnext_.lpNorm<Eigen::Infinity>())) { |
247 | ✗ | STOP_PROFILER("SolverFDDP::forwardPass"); | |
248 | ✗ | throw_pretty("forward_error"); | |
249 | } | ||
250 | } | ||
251 | |||
252 | const std::shared_ptr<ActionModelAbstract>& m = | ||
253 | 4 | problem_->get_terminalModel(); | |
254 | 4 | const std::shared_ptr<ActionDataAbstract>& d = problem_->get_terminalData(); | |
255 |
4/8✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 4 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 4 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 4 times.
✗ Branch 16 not taken.
|
8 | m->get_state()->integrate(xnext_, fs_.back() * (steplength - 1), |
256 | 4 | xs_try_.back()); | |
257 |
1/2✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
|
4 | m->calc(d, xs_try_.back()); |
258 | 4 | cost_try_ += d->cost; | |
259 | |||
260 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
|
4 | if (raiseIfNaN(cost_try_)) { |
261 | ✗ | STOP_PROFILER("SolverFDDP::forwardPass"); | |
262 | ✗ | throw_pretty("forward_error"); | |
263 | } | ||
264 | } | ||
265 |
3/16✗ Branch 2 not taken.
✓ Branch 3 taken 46 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 46 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 46 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
|
46 | STOP_PROFILER("SolverFDDP::forwardPass"); |
266 | 46 | } | |
267 | |||
268 | ✗ | double SolverFDDP::get_th_acceptnegstep() const { return th_acceptnegstep_; } | |
269 | |||
270 | ✗ | void SolverFDDP::set_th_acceptnegstep(const double th_acceptnegstep) { | |
271 | ✗ | if (0. > th_acceptnegstep) { | |
272 | ✗ | throw_pretty( | |
273 | "Invalid argument: " << "th_acceptnegstep value has to be positive."); | ||
274 | } | ||
275 | ✗ | th_acceptnegstep_ = th_acceptnegstep; | |
276 | } | ||
277 | |||
278 | } // namespace crocoddyl | ||
279 |