- 3.0.2 optimal control module.
NLOCBackendST-impl.hpp
Go to the documentation of this file.
1 /**********************************************************************************************************************
2 This file is part of the Control Toolbox (https://github.com/ethz-adrl/control-toolbox), copyright by ETH Zurich.
3 Licensed under the BSD-2 license (see LICENSE file in main directory)
4 **********************************************************************************************************************/
5 
6 #pragma once
7 
8 namespace ct {
9 namespace optcon {
10 
11 
12 template <size_t STATE_DIM, size_t CONTROL_DIM, size_t P_DIM, size_t V_DIM, typename SCALAR, bool CONTINUOUS>
14  const OptConProblem_t& optConProblem,
15  const NLOptConSettings& settings)
16  : Base(optConProblem, settings)
17 {
18 }
19 
20 
21 template <size_t STATE_DIM, size_t CONTROL_DIM, size_t P_DIM, size_t V_DIM, typename SCALAR, bool CONTINUOUS>
23  const OptConProblem_t& optConProblem,
24  const std::string& settingsFile,
25  bool verbose,
26  const std::string& ns)
27  : Base(optConProblem, settingsFile, verbose, ns)
28 {
29 }
30 
31 
32 template <size_t STATE_DIM, size_t CONTROL_DIM, size_t P_DIM, size_t V_DIM, typename SCALAR, bool CONTINUOUS>
34 {
35 }
36 
37 
38 template <size_t STATE_DIM, size_t CONTROL_DIM, size_t P_DIM, size_t V_DIM, typename SCALAR, bool CONTINUOUS>
40  size_t lastIndex)
41 {
42  if (lastIndex == static_cast<size_t>(this->K_) - 1)
43  this->initializeCostToGo();
44 
45  for (size_t k = firstIndex; k <= lastIndex; k++)
46  {
48 
49  if (this->generalConstraints_[this->settings_.nThreads] != nullptr)
51  }
52 }
53 
54 template <size_t STATE_DIM, size_t CONTROL_DIM, size_t P_DIM, size_t V_DIM, typename SCALAR, bool CONTINUOUS>
56  size_t lastIndex)
57 {
58  for (size_t k = firstIndex; k <= lastIndex; k = k + this->getNumStepsPerShot())
59  {
60  // rollout the shot
61  this->rolloutSingleShot(this->settings_.nThreads, k, this->u_ff_, this->x_, this->x_ref_lqr_, this->xShot_,
62  *this->substepsX_, *this->substepsU_);
63 
64  this->computeSingleDefect(k, this->x_, this->xShot_, this->d_);
65  }
66 }
67 
68 
69 template <size_t STATE_DIM, size_t CONTROL_DIM, size_t P_DIM, size_t V_DIM, typename SCALAR, bool CONTINUOUS>
71 {
72  // we start with extrapolation
73  double alpha = this->settings_.lineSearchSettings.alpha_0;
74  double alphaBest = 0.0;
75  size_t iterations = 0;
76 
77  this->lx_norm_ = 0.0;
78  this->lu_norm_ = 0.0;
79 
80 
81  while (iterations < this->settings_.lineSearchSettings.maxIterations)
82  {
84  std::cout << "[LineSearch]: Iteration: " << iterations << ", try alpha: " << alpha << " out of maximum "
85  << this->settings_.lineSearchSettings.maxIterations << " iterations. " << std::endl;
86 
87  iterations++;
88 
89  SCALAR cost = std::numeric_limits<SCALAR>::max();
90  SCALAR intermediateCost = std::numeric_limits<SCALAR>::max();
91  SCALAR finalCost = std::numeric_limits<SCALAR>::max();
92  SCALAR defectNorm = std::numeric_limits<SCALAR>::max();
93  SCALAR e_box_norm = std::numeric_limits<SCALAR>::max();
94  SCALAR e_gen_norm = std::numeric_limits<SCALAR>::max();
95 
97  ct::core::StateVectorArray<STATE_DIM, SCALAR> x_shot_search(this->K_ + 1);
101 
102  typename Base::StateSubstepsPtr substepsX =
103  typename Base::StateSubstepsPtr(new typename Base::StateSubsteps(this->K_ + 1));
104  typename Base::ControlSubstepsPtr substepsU =
105  typename Base::ControlSubstepsPtr(new typename Base::ControlSubsteps(this->K_ + 1));
106 
107 
108  this->executeLineSearch(this->settings_.nThreads, alpha, x_search, x_shot_search, defects_recorded, u_recorded,
109  intermediateCost, finalCost, defectNorm, e_box_norm, e_gen_norm, *substepsX, *substepsU);
110 
111  // compute new merit and check for step acceptance
112  bool stepAccepted =
113  this->acceptStep(alpha, intermediateCost, finalCost, defectNorm, e_box_norm, e_gen_norm, this->lowestCost_, cost);
114 
115  // catch the case that a rollout might be unstable
116  if (!stepAccepted)
117  {
119  {
120  std::cout << "[LineSearch]: No better cost/merit found at alpha " << alpha << ":" << std::endl;
121  std::cout << "[LineSearch]: Cost:\t" << intermediateCost + finalCost << std::endl;
122  std::cout << "[LineSearch]: Defect:\t" << defectNorm << std::endl;
123  std::cout << "[LineSearch]: err box constr:\t" + std::to_string(e_box_norm) << std::endl;
124  std::cout << "[LineSearch]: err gen constr:\t" + std::to_string(e_gen_norm) << std::endl;
125  std::cout << "[LineSearch]: Merit:\t" << cost << std::endl;
126  }
127 
128  // compute new alpha
129  alpha = alpha * this->settings_.lineSearchSettings.n_alpha;
130  }
131  else
132  {
133  // step accepted
134 
136  {
137  std::cout << "Lower cost/merit found at alpha: " << alpha << ":" << std::endl;
138  std::cout << "[LineSearch]: Cost:\t" << intermediateCost + finalCost << std::endl;
139  std::cout << "[LineSearch]: Defect:\t" << defectNorm << std::endl;
140  std::cout << "[LineSearch]: err box constr:\t" + std::to_string(e_box_norm) << std::endl;
141  std::cout << "[LineSearch]: err gen constr:\t" + std::to_string(e_gen_norm) << std::endl;
142  std::cout << "[LineSearch]: Merit:\t" << cost << std::endl;
143  }
144 
145  // compute update norms separately, as they are typically different from pure lqoc solver updates
146  this->lu_norm_ =
147  this->template computeDiscreteArrayNorm<ct::core::ControlVectorArray<CONTROL_DIM, SCALAR>, 2>(
148  u_recorded, this->u_ff_prev_);
149  this->lx_norm_ = this->template computeDiscreteArrayNorm<ct::core::StateVectorArray<STATE_DIM, SCALAR>, 2>(
150  x_search, this->x_prev_);
151 
152  alphaBest = alpha;
153  this->intermediateCostBest_ = intermediateCost;
154  this->finalCostBest_ = finalCost;
155  this->d_norm_ = defectNorm;
156  this->e_box_norm_ = e_box_norm;
157  this->e_gen_norm_ = e_gen_norm;
158  this->x_prev_ = x_search;
159  this->lowestCost_ = cost;
160  this->x_.swap(x_search);
161  this->xShot_.swap(x_shot_search);
162  this->u_ff_.swap(u_recorded);
163  this->d_.swap(defects_recorded);
164  this->substepsX_ = substepsX;
165  this->substepsU_ = substepsU;
166  break;
167  }
168  } // end while
169 
170  return alphaBest;
171 }
172 
173 
174 } // namespace optcon
175 } // namespace ct
LineSearchSettings lineSearchSettings
number of threads for eigen parallelization (applies both to MP and ST) Note. in order to activate Ei...
Definition: NLOptConSettings.hpp:275
StateVectorArray xShot_
state array variables
Definition: NLOCBackendBase.hpp:564
void computeSingleDefect(size_t k, const StateVectorArray &x_local, const StateVectorArray &xShot, StateVectorArray &d) const
computes the defect between shot and trajectory
Definition: NLOCBackendBase-impl.hpp:556
void executeLQApproximation(size_t threadId, size_t k)
Computes the linearized Dynamics and quadratic cost approximation at a specific point of the trajecto...
Definition: NLOCBackendBase-impl.hpp:685
int K_
Definition: NLOCBackendBase.hpp:561
scalar_t lowestCost_
Definition: NLOCBackendBase.hpp:588
scalar_t finalCostBest_
Definition: NLOCBackendBase.hpp:587
bool rolloutSingleShot(const size_t threadId, const size_t k, ControlVectorArray &u_ff_local, StateVectorArray &x_local, const StateVectorArray &x_ref_lqr, StateVectorArray &xShot, StateSubsteps &substepsX, ControlSubsteps &substepsU, std::atomic_bool *terminationFlag=nullptr) const
integrate the individual shots
Definition: NLOCBackendBase-impl.hpp:436
SCALAR performLineSearch() override
performLineSearch: execute the line search, possibly with different threading schemes ...
Definition: NLOCBackendST-impl.hpp:70
StateVectorArray d_
rolled-out state (at the end of a time step forward)
Definition: NLOCBackendBase.hpp:565
double alpha_0
Definition: NLOptConSettings.hpp:61
void computeLinearizedConstraints(size_t threadId, size_t k)
Computes the linearized general constraints at a specific point of the trajectory.
Definition: NLOCBackendBase-impl.hpp:790
bool debugPrint
Definition: NLOptConSettings.hpp:66
StateVectorArray x_
the time trajectory
Definition: NLOCBackendBase.hpp:563
SCALAR lu_norm_
sum of the norms of state update
Definition: NLOCBackendBase.hpp:584
int getNumStepsPerShot() const
Definition: NLOCBackendBase-impl.hpp:1659
virtual void computeLQApproximation(size_t firstIndex, size_t lastIndex) override
build LQ approximation around trajectory (linearize dynamics and general constraints, quadratize cost, etc)
Definition: NLOCBackendST-impl.hpp:39
StateVectorArray x_prev_
defects in between end of rollouts and subsequent state decision vars
Definition: NLOCBackendBase.hpp:566
ControlVectorArray u_ff_prev_
feed forward controls
Definition: NLOCBackendBase.hpp:570
std::vector< typename OptConProblem_t::ConstraintPtr_t > generalConstraints_
Definition: NLOCBackendBase.hpp:612
virtual ~NLOCBackendST()
Definition: NLOCBackendST-impl.hpp:33
Settings for the NLOptCon algorithm.
Definition: NLOptConSettings.hpp:198
std::conditional< CONTINUOUS, ContinuousOptConProblem< STATE_DIM, CONTROL_DIM, SCALAR >, DiscreteOptConProblem< STATE_DIM, CONTROL_DIM, SCALAR > >::type OptConProblem_t
Definition: NLOCBackendBase.hpp:62
CppAD::AD< CppAD::cg::CG< double > > SCALAR
NLOCBackendST(const OptConProblem_t &optConProblem, const NLOptConSettings &settings)
Definition: NLOCBackendST-impl.hpp:13
Settings_t settings_
Definition: NLOCBackendBase.hpp:559
void executeLineSearch(const size_t threadId, const scalar_t alpha, ct::core::StateVectorArray< STATE_DIM, SCALAR > &x_recorded, ct::core::StateVectorArray< STATE_DIM, SCALAR > &x_shot_recorded, ct::core::StateVectorArray< STATE_DIM, SCALAR > &defects_recorded, ct::core::ControlVectorArray< CONTROL_DIM, SCALAR > &u_recorded, scalar_t &intermediateCost, scalar_t &finalCost, scalar_t &defectNorm, scalar_t &e_box_norm, scalar_t &e_gen_norm, StateSubsteps &substepsX, ControlSubsteps &substepsU, std::atomic_bool *terminationFlag=nullptr) const
Check if controller with particular alpha is better.
Definition: NLOCBackendBase-impl.hpp:1107
virtual void rolloutShots(size_t firstIndex, size_t lastIndex) override
integrates the specified shots and computes the corresponding defects
Definition: NLOCBackendST-impl.hpp:55
ControlVectorArray u_ff_
reference for lqr
Definition: NLOCBackendBase.hpp:569
size_t maxIterations
Definition: NLOptConSettings.hpp:60
EIGEN_MAKE_ALIGNED_OPERATOR_NEW typedef NLOCBackendBase< STATE_DIM, CONTROL_DIM, P_DIM, V_DIM, SCALAR, CONTINUOUS > Base
Definition: NLOCBackendST.hpp:30
bool acceptStep(const SCALAR alpha, const SCALAR intermediateCost, const SCALAR finalCost, const SCALAR defectNorm, const SCALAR e_box_norm, const SCALAR e_gen_norm, const SCALAR lowestMeritPrevious, SCALAR &new_merit)
in case of line-search compute new merit and check if to accept step. Returns true if accept step ...
Definition: NLOCBackendBase-impl.hpp:1187
StateSubstepsPtr substepsX_
state array from previous iteration
Definition: NLOCBackendBase.hpp:577
SCALAR e_gen_norm_
sum of the norms of all box constraint violations
Definition: NLOCBackendBase.hpp:582
scalar_t intermediateCostBest_
sum of the norms of control update
Definition: NLOCBackendBase.hpp:586
SCALAR lx_norm_
sum of the norms of all general constraint violations
Definition: NLOCBackendBase.hpp:583
ControlSubstepsPtr substepsU_
state substeps recorded by integrator during rollouts
Definition: NLOCBackendBase.hpp:578
void initializeCostToGo()
Initializes cost to go.
Definition: NLOCBackendBase-impl.hpp:819
const bool verbose
Definition: ConstraintComparison.h:18
int nThreads
save the smallest eigenvalue of the Hessian
Definition: NLOptConSettings.hpp:272
double n_alpha
Definition: NLOptConSettings.hpp:64
SCALAR d_norm_
control substeps recorded by integrator during rollouts
Definition: NLOCBackendBase.hpp:580
void swap(DiscreteArray &other)
SCALAR e_box_norm_
sum of the norms of all defects (internal constraint)
Definition: NLOCBackendBase.hpp:581