aligator  0.6.1
A primal-dual augmented Lagrangian-type solver for nonlinear trajectory optimization.
Loading...
Searching...
No Matches
solver-proxddp.hpp
Go to the documentation of this file.
1
4#pragma once
5
10#include "aligator/threads.hpp"
12
13#include "workspace.hpp"
14#include "results.hpp"
15#include "merit-function.hpp"
16
17#include <proxsuite-nlp/bcl-params.hpp>
18
19#include <unordered_map>
20
21namespace aligator {
22namespace gar {
23template <typename Scalar> class RiccatiSolverBase;
24} // namespace gar
25
27template <typename Scalar> struct DefaultScaling {
28 void operator()(ConstraintProximalScalerTpl<Scalar> &scaler) {
29 for (std::size_t j = 0; j < scaler.size(); j++)
30 scaler.setWeight(scale, j);
31 }
32 static constexpr Scalar scale = 10.;
33};
34
36
45template <typename _Scalar> struct SolverProxDDPTpl {
46public:
47 // typedefs
48
49 using Scalar = _Scalar;
51 using Problem = TrajOptProblemTpl<Scalar>;
52 using Workspace = WorkspaceTpl<Scalar>;
53 using Results = ResultsTpl<Scalar>;
54 using StageFunctionData = StageFunctionDataTpl<Scalar>;
55 using DynamicsData = DynamicsDataTpl<Scalar>;
56 using CostData = CostDataAbstractTpl<Scalar>;
57 using StageModel = StageModelTpl<Scalar>;
58 using ConstraintType = StageConstraintTpl<Scalar>;
59 using StageData = StageDataTpl<Scalar>;
60 using CallbackPtr = shared_ptr<CallbackBaseTpl<Scalar>>;
61 using CallbackMap = std::unordered_map<std::string, CallbackPtr>;
62 using ConstraintStack = ConstraintStackTpl<Scalar>;
63 using CstrSet = ConstraintSetBase<Scalar>;
64 using TrajOptData = TrajOptDataTpl<Scalar>;
65 using LinesearchOptions = typename Linesearch<Scalar>::Options;
66 using CstrProximalScaler = ConstraintProximalScalerTpl<Scalar>;
67 using LinesearchType = proxsuite::nlp::ArmijoLinesearch<Scalar>;
69 using Filter = FilterTpl<Scalar>;
70
77
78 Scalar mu_init = 0.01; //< Initial AL parameter
80
82
83 Scalar reg_min = 1e-10; //< Minimal nonzero regularization
84 Scalar reg_max = 1e9; //< Maximum regularization value
85 Scalar reg_init = 1e-9; //< Initial regularization value (can be zero)
86 Scalar reg_inc_k_ = 10.; //< Regularization increase factor
87 Scalar reg_inc_first_k_ = 100.; //< Regularization increase (critical)
88 Scalar reg_dec_k_ = 1. / 3.; //< Regularization decrease factor
89 Scalar preg_ = reg_init; //< Primal regularization value
90 Scalar preg_last_ = 0.; //< Last "good" regularization value
91
93
96
99
101 VerboseLevel verbose_;
104 bool lq_print_detailed = false;
110 LinesearchStrategy ls_strat = LinesearchStrategy::ARMIJO;
120 BCLParamsTpl<Scalar> bcl_params;
123
127
129 0; //< Max number of KKT system refinement iters
130 Scalar refinementThreshold_ = 1e-13; //< Target tol. for the KKT system.
131 std::size_t max_iters; //< Max number of Newton iterations.
132 std::size_t max_al_iters = 100; //< Maximum number of ALM iterations.
133 Scalar mu_lower_bound = 1e-8; //< Minimum possible penalty parameter.
134 uint rollout_max_iters; //< Nonlinear rollout options
135
141 unique_ptr<gar::RiccatiSolverBase<Scalar>> linearSolver_;
143
144private:
146 std::size_t num_threads_ = 1;
150 Scalar mu_penal_ = mu_init;
152 Scalar rho_penal_ = rho_init;
154 LinesearchType linesearch_;
155
156public:
157 SolverProxDDPTpl(const Scalar tol = 1e-6, const Scalar mu_init = 0.01,
158 const Scalar rho_init = 0.,
159 const std::size_t max_iters = 1000,
160 VerboseLevel verbose = VerboseLevel::QUIET,
162
163 void setNumThreads(const std::size_t num_threads) {
164 if (linearSolver_) {
166 "SolverProxDDP",
167 "Linear solver already set: setNumThreads() should be called before "
168 "you call setup() if you want to use the parallel linear solver.\n");
169 }
170 num_threads_ = num_threads;
171 omp::set_default_options(num_threads);
172 }
173 std::size_t getNumThreads() const { return num_threads_; }
174
175 ALIGATOR_DEPRECATED const Results &getResults() { return results_; }
176 ALIGATOR_DEPRECATED const Workspace &getWorkspace() { return workspace_; }
177
183 static Scalar tryLinearStep(const Problem &problem, Workspace &workspace,
184 const Results &results, const Scalar alpha);
185
190 Scalar tryNonlinearRollout(const Problem &problem, const Scalar alpha);
191
192 Scalar forwardPass(const Problem &problem, const Scalar alpha);
193
195
200 void setup(const Problem &problem);
201
209 bool run(const Problem &problem, const std::vector<VectorXs> &xs_init = {},
210 const std::vector<VectorXs> &us_init = {},
211 const std::vector<VectorXs> &lams_init = {});
212
215 bool innerLoop(const Problem &problem);
216
221 void computeInfeasibilities(const Problem &problem);
224
227
229 void registerCallback(const std::string &name, CallbackPtr cb) {
230 callbacks_[name] = cb;
231 }
232
234 void clearCallbacks() noexcept { callbacks_.clear(); }
235
236 const CallbackMap &getCallbacks() const { return callbacks_; }
237 void removeCallback(const std::string &name) { callbacks_.erase(name); }
238 auto getCallback(const std::string &name) -> CallbackPtr {
239 auto cb = callbacks_.find(name);
240 if (cb != end(callbacks_)) {
241 return cb->second;
242 }
243 return nullptr;
244 }
245
247 void invokeCallbacks(Workspace &workspace, Results &results) {
248 for (const auto &cb : callbacks_) {
249 cb.second->call(workspace, results);
250 }
251 }
253
257 void computeMultipliers(const Problem &problem,
258 const std::vector<VectorXs> &lams,
259 const std::vector<VectorXs> &vs);
260
262 ALIGATOR_INLINE Scalar mu() const { return mu_penal_; }
263
265 ALIGATOR_INLINE Scalar mu_inv() const { return 1. / mu_penal_; }
266
268 ALIGATOR_INLINE Scalar rho() const { return rho_penal_; }
269
272 inline void updateGains();
273
274protected:
275 void updateTolsOnFailure() noexcept {
276 prim_tol_ = prim_tol0 * std::pow(mu_penal_, bcl_params.prim_alpha);
277 inner_tol_ = inner_tol0 * std::pow(mu_penal_, bcl_params.dual_alpha);
278 }
279
280 void updateTolsOnSuccess() noexcept {
281 prim_tol_ = prim_tol_ * std::pow(mu_penal_, bcl_params.prim_beta);
282 inner_tol_ = inner_tol_ * std::pow(mu_penal_, bcl_params.dual_beta);
283 }
284
286 ALIGATOR_INLINE void setAlmPenalty(Scalar new_mu) noexcept {
287 mu_penal_ = std::max(new_mu, mu_lower_bound);
288 }
289
290 ALIGATOR_INLINE void setRho(Scalar new_rho) noexcept { rho_penal_ = new_rho; }
291
292 // See sec. 3.1 of the IPOPT paper [Wächter, Biegler 2006]
293 // called before first bwd pass attempt
294 inline void initializeRegularization() noexcept {
295 if (preg_last_ == 0.) {
296 // this is the 1st iteration
297 preg_ = reg_init;
298 } else {
299 // attempt decrease from last "good" value
300 preg_ = std::max(reg_min, preg_last_ * reg_dec_k_);
301 }
302 }
303
304 inline void increaseRegularization() noexcept {
305 if (preg_last_ == 0.)
307 else
308 preg_ *= reg_inc_k_;
309 }
310};
311
312} // namespace aligator
313
314#include "solver-proxddp.hxx"
315
316#ifdef ALIGATOR_ENABLE_TEMPLATE_INSTANTIATION
317#include "solver-proxddp.txx"
318#endif
#define ALIGATOR_WARNING(loc, msg)
#define ALIGATOR_INLINE
Definition macros.hpp:13
void set_default_options(std::size_t, bool=true)
Definition threads.hpp:38
Main package namespace.
MultiplierUpdateMode
Definition enums.hpp:23
StepAcceptanceStrategy
Whether to use linesearch or filter during step acceptance phase.
Definition enums.hpp:29
RolloutType
Definition enums.hpp:5
@ NONLINEAR
Nonlinear rollout, using the full dynamics.
unsigned int uint
Definition logger.hpp:11
HessianApprox
Definition enums.hpp:14
@ GAUSS_NEWTON
Use the Gauss-Newton approximation.
LinesearchMode
Whether to use merit functions in primal or primal-dual mode.
Definition enums.hpp:26
Define workspace for the ProxDDP solver.
TODO: NEW G.A.R. BACKEND CAN'T HANDLE DIFFERENT WEIGHTS, PLS FIX.
static constexpr Scalar scale
void operator()(ConstraintProximalScalerTpl< Scalar > &scaler)
A table logging utility to log the trace of the numerical solvers.
Definition logger.hpp:37
A proximal, augmented Lagrangian-type solver for trajectory optimization.
ConstraintSetBase< Scalar > CstrSet
MultiplierUpdateMode multiplier_update_mode
Type of Lagrange multiplier update.
void updateGains()
Update primal-dual feedback gains (control, costate, path multiplier)
StageConstraintTpl< Scalar > ConstraintType
void computeCriterion()
Compute stationarity criterion (dual infeasibility).
bool run(const Problem &problem, const std::vector< VectorXs > &xs_init={}, const std::vector< VectorXs > &us_init={}, const std::vector< VectorXs > &lams_init={})
Run the numerical solver.
void removeCallback(const std::string &name)
std::unordered_map< std::string, CallbackPtr > CallbackMap
Scalar prim_tol_
Desired primal feasibility.
proxsuite::nlp::ArmijoLinesearch< Scalar > LinesearchType
std::size_t getNumThreads() const
ALIGATOR_INLINE Scalar mu() const
Scalar dual_weight
Weight of the dual variables in the primal-dual linesearch.
shared_ptr< CallbackBaseTpl< Scalar > > CallbackPtr
void invokeCallbacks(Workspace &workspace, Results &results)
Invoke callbacks.
LinesearchStrategy ls_strat
Type of linesearch strategy. Default is Armijo.
ALIGATOR_INLINE Scalar rho() const
Primal proximal parameter .
void clearCallbacks() noexcept
Remove all callbacks from the instance.
unique_ptr< gar::RiccatiSolverBase< Scalar > > linearSolver_
LQR subproblem solver.
ALIGATOR_INLINE void setRho(Scalar new_rho) noexcept
CallbackMap callbacks_
Callbacks.
LQSolverChoice linear_solver_choice
Choice of linear solver.
Scalar forwardPass(const Problem &problem, const Scalar alpha)
ALIGATOR_DEPRECATED const Workspace & getWorkspace()
RolloutType rollout_type_
Type of rollout for the forward pass.
void computeMultipliers(const Problem &problem, const std::vector< VectorXs > &lams, const std::vector< VectorXs > &vs)
ConstraintProximalScalerTpl< Scalar > CstrProximalScaler
auto getCallback(const std::string &name) -> CallbackPtr
LinesearchOptions ls_params
Linesearch options, as in proxsuite-nlp.
ConstraintStackTpl< Scalar > ConstraintStack
Scalar target_tol_
Solver tolerance .
void setup(const Problem &problem)
Allocate new workspace and results instances according to the specifications of problem.
Scalar inner_tol_
Subproblem tolerance.
HessianApprox hess_approx_
Type of Hessian approximation. Default is Gauss-Newton.
ALIGATOR_DEPRECATED const Results & getResults()
const CallbackMap & getCallbacks() const
void setNumThreads(const std::size_t num_threads)
void initializeRegularization() noexcept
void updateTolsOnSuccess() noexcept
static Scalar tryLinearStep(const Problem &problem, Workspace &workspace, const Results &results, const Scalar alpha)
Try a step of size .
LinesearchMode ls_mode
Linesearch mode.
ALIGATOR_INLINE Scalar mu_inv() const
ALIGATOR_INLINE void setAlmPenalty(Scalar new_mu) noexcept
Set dual proximal/ALM penalty parameter.
SolverProxDDPTpl(const Scalar tol=1e-6, const Scalar mu_init=0.01, const Scalar rho_init=0., const std::size_t max_iters=1000, VerboseLevel verbose=VerboseLevel::QUIET, HessianApprox hess_approx=HessianApprox::GAUSS_NEWTON)
TrajOptProblemTpl< Scalar > Problem
bool innerLoop(const Problem &problem)
Perform the inner loop of the algorithm (augmented Lagrangian minimization).
FilterTpl< Scalar > Filter
void increaseRegularization() noexcept
VerboseLevel verbose_
Solver verbosity level.
void registerCallback(const std::string &name, CallbackPtr cb)
Add a callback to the solver instance.
Scalar tryNonlinearRollout(const Problem &problem, const Scalar alpha)
Policy rollout using the full nonlinear dynamics. The feedback gains need to be computed first....
void updateTolsOnFailure() noexcept
DynamicsDataTpl< Scalar > DynamicsData
void computeInfeasibilities(const Problem &problem)
Compute the primal infeasibility measures.
WorkspaceTpl< Scalar > Workspace
typename Linesearch< Scalar >::Options LinesearchOptions
StepAcceptanceStrategy sa_strategy
Step acceptance mode.
BCLParamsTpl< Scalar > bcl_params
Parameters for the BCL outer loop of the augmented Lagrangian algorithm.