- 3.0.2 optimal control module.
LinearSystemSolverComparison.h
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 #include <chrono>
9 
10 #include <gtest/gtest.h>
11 
12 #include "../testSystems/LinearOscillator.h"
13 
14 namespace ct {
15 namespace optcon {
16 namespace example {
17 
18 using namespace ct::core;
19 using namespace ct::optcon;
20 
21 using std::shared_ptr;
22 
23 
28 TEST(LinearSystemsSolverComparison, LinearSystemsSolverComparison)
29 {
30  typedef NLOptConSolver<state_dim, control_dim, state_dim / 2, state_dim / 2> NLOptConSolver;
31 
32  // count executed tests
33  size_t testCounter = 0;
34 
35  // desired final state
36  Eigen::Vector2d x_final;
37  x_final << 20, 0;
38 
39  // given initial state
40  StateVector<state_dim> initState;
41  initState.setZero();
42  initState(1) = 1.0;
43 
44  // provide algorithm settings
45  NLOptConSettings nloc_settings;
46  nloc_settings.epsilon = 0.0;
47  nloc_settings.recordSmallestEigenvalue = false;
48  nloc_settings.fixedHessianCorrection = false;
49  nloc_settings.dt = 0.01;
50  nloc_settings.discretization = NLOptConSettings::APPROXIMATION::FORWARD_EULER; // default approximation
51  nloc_settings.printSummary = false;
52 
53  // loop through all solver classes
54  for (int algClass = 0; algClass < NLOptConSettings::NLOCP_ALGORITHM::NUM_TYPES; algClass++)
55  {
56  nloc_settings.nlocp_algorithm = static_cast<NLOptConSettings::NLOCP_ALGORITHM>(algClass);
57 
58  // switch line search on or off
59  for (int toggleLS = 0; toggleLS <= 1; toggleLS++)
60  {
61  nloc_settings.lineSearchSettings.type = static_cast<LineSearchSettings::TYPE>(toggleLS);
62 
63  // toggle between single and multi-threading
64  for (size_t nThreads = 1; nThreads < 5; nThreads = nThreads + 3)
65  {
66  nloc_settings.nThreads = nThreads;
67 
68  // toggle between iLQR/GNMS and hybrid methods with K_shot !=1
69  for (size_t kshot = 1; kshot < 11; kshot = kshot + 9)
70  {
71  nloc_settings.K_shot = kshot;
72 
73  if (kshot > 1 && nloc_settings.nlocp_algorithm == NLOptConSettings::NLOCP_ALGORITHM::ILQR)
74  continue; // proceed to next test case
75 
76  // toggle sensitivity integrator
77  for (size_t sensInt = 0; sensInt <= 1; sensInt++)
78  {
79  nloc_settings.useSensitivityIntegrator = bool(sensInt);
80 
81  // toggle over simulation time-steps
82  for (size_t ksim = 1; ksim <= 5; ksim = ksim + 4)
83  {
84  nloc_settings.K_sim = ksim;
85 
86  // catch special case, simulation sub-time steps only make sense when sensitivity integrator active
87  if ((nloc_settings.useSensitivityIntegrator == false) && (ksim > 1))
88  continue; // proceed to next test case
89 
90  // toggle integrator type
91  for (size_t integratortype = 0; integratortype <= 1; integratortype++)
92  {
93  if (integratortype == 0)
94  nloc_settings.integrator = ct::core::IntegrationType::EULERCT;
95  else if (integratortype == 1 && nloc_settings.useSensitivityIntegrator == true)
96  {
97  // use RK4 with exactly integrated sensitivities
98  nloc_settings.integrator = ct::core::IntegrationType::RK4CT;
99  }
100  else
101  continue; // proceed to next test case
102 
103  shared_ptr<ControlledSystem<state_dim, control_dim>> nonlinearSystem(
104  new LinearOscillator());
105  shared_ptr<LinearSystem<state_dim, control_dim>> analyticLinearSystem(
106  new LinearOscillatorLinear());
107  shared_ptr<CostFunctionQuadratic<state_dim, control_dim>> costFunction =
108  tpl::createCostFunctionLinearOscillator<double>(x_final);
109 
110  // times
111  ct::core::Time tf = 1.0;
112  size_t nSteps = nloc_settings.computeK(tf);
113 
114  // initial controller
115  StateVectorArray<state_dim> x0(nSteps + 1, initState);
117  uff << kStiffness * initState(0);
118  ControlVectorArray<control_dim> u0(nSteps, uff);
119 
123 
124  NLOptConSolver::Policy_t initController(x0, u0, u0_fb, nloc_settings.dt);
125 
126  // construct OptCon Problem
128  tf, x0[0], nonlinearSystem, costFunction, analyticLinearSystem);
129 
130  // NLOC solver employing GNRiccati
131  nloc_settings.lqocp_solver = NLOptConSettings::LQOCP_SOLVER::GNRICCATI_SOLVER;
132  NLOptConSolver solver_gnriccati(optConProblem, nloc_settings);
133  solver_gnriccati.configure(nloc_settings);
134  solver_gnriccati.setInitialGuess(initController);
136  solver_gnriccati.runIteration();
137  solver_gnriccati.runIteration();
138 
139 
140  // NLOC solver employing HPIPM
141  nloc_settings.lqocp_solver = NLOptConSettings::LQOCP_SOLVER::HPIPM_SOLVER;
142  NLOptConSolver solver_hpipm(optConProblem, nloc_settings);
143  solver_hpipm.configure(nloc_settings);
144  solver_hpipm.setInitialGuess(initController);
146  solver_hpipm.runIteration();
147  solver_hpipm.runIteration();
148 
150  const SummaryAllIterations<double>& sumGn = solver_gnriccati.getBackend()->getSummary();
151  const SummaryAllIterations<double>& sumHpipm = solver_hpipm.getBackend()->getSummary();
152 
154  // first iteration
155  ASSERT_NEAR(sumGn.lx_norms.back(), sumHpipm.lx_norms.back(), 1e-6);
156  ASSERT_NEAR(sumGn.lu_norms.back(), sumHpipm.lu_norms.back(), 1e-6);
157  ASSERT_NEAR(sumGn.defect_l1_norms.back(), sumHpipm.defect_l1_norms.back(), 1e-6);
158  ASSERT_NEAR(sumGn.defect_l2_norms.back(), sumHpipm.defect_l2_norms.back(), 1e-6);
159  ASSERT_NEAR(sumGn.merits.back(), sumHpipm.merits.back(), 1e-6);
160 
161  // second iteration
162  ASSERT_NEAR(sumGn.lx_norms.front(), sumHpipm.lx_norms.front(), 1e-6);
163  ASSERT_NEAR(sumGn.lu_norms.front(), sumHpipm.lu_norms.front(), 1e-6);
164  ASSERT_NEAR(sumGn.defect_l1_norms.front(), sumHpipm.defect_l1_norms.front(), 1e-6);
165  ASSERT_NEAR(sumGn.defect_l2_norms.front(), sumHpipm.defect_l2_norms.front(), 1e-6);
166  ASSERT_NEAR(sumGn.merits.front(), sumHpipm.merits.front(), 1e-6);
167 
168  testCounter++;
169 
170  } // toggle integrator type
171  } // toggle simulation time steps
172  } // toggle sensitivity integrator
173  } // toggle k_shot
174  } // toggle multi-threading / single-threading
175  } // toggle line-search
176  } // toggle solver class
177 
178  std::cout << "Performed " << testCounter << " successful NLOC tests with linear systems" << std::endl;
179 
180 } // end TEST
181 
182 
183 } // namespace example
184 } // namespace optcon
185 } // 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
LQOCP_SOLVER lqocp_solver
which nonlinear optimal control algorithm is to be used
Definition: NLOptConSettings.hpp:259
bool printSummary
Definition: NLOptConSettings.hpp:278
double dt
Eigenvalue correction factor for Hessian regularization.
Definition: NLOptConSettings.hpp:262
TYPE type
Definition: NLOptConSettings.hpp:58
const std::shared_ptr< Backend_t > & getBackend()
get a reference to the backend (
Definition: NLOptConSolver-impl.hpp:237
std::vector< SCALAR > merits
Definition: NLOCResults.hpp:37
const size_t state_dim
Definition: ConstraintComparison.h:20
double epsilon
the prefix to be stored before the matfile name for logging
Definition: NLOptConSettings.hpp:261
NLOCAlgorithm_t::Policy_t Policy_t
Definition: NLOptConSolver.hpp:62
void configure(const Settings_t &settings) override
Definition: NLOptConSolver-impl.hpp:62
NLOCP_ALGORITHM
algorithm types for solving the NLOC problem
Definition: NLOptConSettings.hpp:202
std::vector< SCALAR > defect_l2_norms
Definition: NLOCResults.hpp:25
void setInitialGuess(const Policy_t &initialGuess) override
Definition: NLOptConSolver-impl.hpp:118
Definition: NLOCResults.hpp:18
NLOCP_ALGORITHM nlocp_algorithm
Definition: NLOptConSettings.hpp:258
bool useSensitivityIntegrator
Definition: NLOptConSettings.hpp:279
Settings for the NLOptCon algorithm.
Definition: NLOptConSettings.hpp:198
TEST(ConstraintComparison, comparisonAnalyticAD)
Definition: ConstraintComparison.h:158
const double kStiffness
Definition: SymplecticTest.h:34
APPROXIMATION discretization
which integrator to use during the NLOptCon forward rollout
Definition: NLOptConSettings.hpp:256
bool fixedHessianCorrection
the maximum admissible number of NLOptCon main iterations
Definition: NLOptConSettings.hpp:270
int K_sim
sampling time for the control input (seconds)
Definition: NLOptConSettings.hpp:263
std::vector< SCALAR > lx_norms
step update norms
Definition: NLOCResults.hpp:30
virtual bool runIteration() override
Definition: NLOptConSolver-impl.hpp:102
int computeK(double timeHorizon) const
log to matlab (true/false)
Definition: NLOptConSettings.hpp:290
tpl::LinearOscillator< double > LinearOscillator
Definition: LinearOscillator.h:105
std::vector< SCALAR > defect_l1_norms
different overall defect norms
Definition: NLOCResults.hpp:24
bool recordSmallestEigenvalue
perform Hessian regularization by incrementing the eigenvalues by epsilon.
Definition: NLOptConSettings.hpp:271
StateVector< state_dim > x0
Definition: ConstrainedNLOCTest.cpp:14
tpl::LinearOscillatorLinear< double > LinearOscillatorLinear
Definition: LinearOscillator.h:106
ct::core::IntegrationType integrator
Definition: NLOptConSettings.hpp:255
std::vector< SCALAR > lu_norms
Definition: NLOCResults.hpp:31
int nThreads
save the smallest eigenvalue of the Hessian
Definition: NLOptConSettings.hpp:272
int K_shot
number of sub-integration-steps
Definition: NLOptConSettings.hpp:264
Definition: NLOptConSolver.hpp:29
TYPE
types of backtracking line-search
Definition: NLOptConSettings.hpp:25
Definition: OptConProblemBase.h:40
const size_t control_dim
Definition: ConstraintComparison.h:21
Definition: exampleDir.h:9
double Time