- 3.0.2 optimal control module.
SystemInterfaceTest.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 
10 #pragma once
11 
12 #include <gtest/gtest.h>
13 
14 #include "../testSystems/LinearOscillator.h"
15 
16 namespace ct {
17 namespace optcon {
18 namespace example {
19 
20 TEST(SystemInterfaceTest, ContinuousSystemInterface)
21 {
22  const size_t STATE_DIM = state_dim;
23  const size_t CONTROL_DIM = control_dim;
24  const size_t P_DIM = STATE_DIM / 2;
25  const size_t V_DIM = STATE_DIM / 2;
26  typedef double SCALAR;
27 
29 
30  // nonlinear and linear system instances
31  std::shared_ptr<ControlledSystem<STATE_DIM, CONTROL_DIM>> nonlinearSystem(new LinearOscillator());
32  std::shared_ptr<LinearSystem<STATE_DIM, CONTROL_DIM>> analyticLinearSystem(new LinearOscillatorLinear());
33 
34  Eigen::Vector2d x_final;
35  x_final << 1.0, 0.0;
36 
37  std::shared_ptr<CostFunctionQuadratic<state_dim, control_dim>> costFunction =
38  tpl::createCostFunctionLinearOscillator<SCALAR>(x_final);
39 
40  // fill minimal version of optconproblem
41  OptConProblem_t optConProblem(nonlinearSystem, costFunction, analyticLinearSystem);
42 
43  // settings
44  NLOptConSettings nloc_settings;
45  nloc_settings.dt = 0.01;
46 
47  // toggle sensitivity integrator
48  for (size_t sensInt = 0; sensInt <= 1; sensInt++)
49  {
50  nloc_settings.useSensitivityIntegrator = bool(sensInt);
51 
52  // toggle over simulation time-steps
53  for (size_t ksim = 1; ksim <= 5; ksim = ksim + 4)
54  {
55  nloc_settings.K_sim = ksim;
56 
57  // catch special case, simulation sub-time steps only make sense when sensitivity integrator active
58  if ((nloc_settings.useSensitivityIntegrator == false) && (ksim > 1))
59  continue; // proceed to next test case
60 
61  // toggle integrator type
62  for (size_t integratortype = 0; integratortype <= 1; integratortype++)
63  {
64  if (integratortype == 0)
65  nloc_settings.integrator = ct::core::IntegrationType::EULERCT;
66  else if (integratortype == 1 && nloc_settings.useSensitivityIntegrator == true)
67  {
68  // use RK4 with exactly integrated sensitivities
69  nloc_settings.integrator = ct::core::IntegrationType::RK4CT;
70  }
71  else
72  continue; // proceed to next test case
73 
74 
75  // nloc_settings.print();
76 
77  // creat the system interface
79  typedef std::shared_ptr<systemInterface_t> systemInterfacePtr_t;
80  systemInterfacePtr_t systemInterface(
82  optConProblem, nloc_settings));
83  systemInterface->initialize();
84 
85  // propagate the dynamics inside systemInterface and find sensitivities
86  systemInterface_t::state_vector_t x_start, x_next;
87  x_start.setRandom();
88  systemInterface_t::control_vector_t control;
89  control.setRandom();
90 
91  systemInterface_t::StateSubstepsPtr subStepsX(new systemInterface_t::StateSubsteps());
92  systemInterface_t::ControlSubstepsPtr subStepsU(new systemInterface_t::ControlSubsteps());
93  subStepsX->resize(1);
94  subStepsU->resize(1);
95 
96  systemInterface->propagateControlledDynamics(x_start, 0, control, x_next, 0);
97 
98  systemInterface->getSubstates(subStepsX->at(0), 0);
99  systemInterface->getSubcontrols(subStepsU->at(0), 0);
100 
101 
102  // calculate linearization
103  systemInterface_t::state_matrix_t A;
104  systemInterface_t::state_control_matrix_t B;
105  systemInterface->setSubstepTrajectoryReference(subStepsX, subStepsU, 0);
106  systemInterface->getAandB(x_start, control, x_next, 0, nloc_settings.K_sim, A, B, 0);
107 
108  // use discretizer and check against systemInterface
110  discretizer_t discretizer(
111  nonlinearSystem, nloc_settings.dt, nloc_settings.integrator, nloc_settings.K_sim);
112  discretizer.initialize();
113 
114  systemInterface_t::state_vector_t x_next_discretizer;
115  systemInterface_t::StateSubstepsPtr subStepsX_discretizer(new systemInterface_t::StateSubsteps());
116  systemInterface_t::ControlSubstepsPtr subStepsU_discretizer(new systemInterface_t::ControlSubsteps());
117  subStepsX_discretizer->resize(1);
118  subStepsU_discretizer->resize(1);
119  discretizer.propagateControlledDynamics(x_start, 0, control, x_next_discretizer);
120  subStepsX_discretizer->at(0) = discretizer.getSubstates();
121  subStepsU_discretizer->at(0) = discretizer.getSubcontrols();
122 
123  ASSERT_TRUE(x_next.isApprox(x_next_discretizer, 1e-8));
124 
125  ASSERT_TRUE(subStepsX->at(0)->size() == subStepsX_discretizer->at(0)->size());
126  ASSERT_TRUE(subStepsU->at(0)->size() == subStepsU_discretizer->at(0)->size());
127  ASSERT_TRUE(subStepsX->at(0)->size() == subStepsU_discretizer->at(0)->size());
128 
129  for (size_t i = 0; i < subStepsX->at(0)->size(); ++i)
130  {
131  ASSERT_TRUE(subStepsX->at(0)->at(i).isApprox(subStepsX_discretizer->at(0)->at(i), 1e-8));
132  ASSERT_TRUE(subStepsU->at(0)->at(i).isApprox(subStepsU_discretizer->at(0)->at(i), 1e-8));
133 
134  ASSERT_TRUE(subStepsU->at(0)->at(i).isApprox(control, 1e-8)); // constant controller
135  }
136 
137  // use sensitivity and check against systemInterface
139  typedef std::shared_ptr<Sensitivity_t> SensitivityPtr;
140  SensitivityPtr sensitivity;
141 
142  if (nloc_settings.useSensitivityIntegrator)
143  {
144  if (nloc_settings.integrator != ct::core::IntegrationType::EULER &&
145  nloc_settings.integrator != ct::core::IntegrationType::EULERCT &&
146  nloc_settings.integrator != ct::core::IntegrationType::RK4 &&
147  nloc_settings.integrator != ct::core::IntegrationType::RK4CT &&
148  nloc_settings.integrator != ct::core::IntegrationType::EULER_SYM)
149  throw std::runtime_error("sensitivity integrator only available for Euler and RK4 integrators");
150 
152  typedef std::shared_ptr<constant_controller_t> ConstantControllerPtr;
153  ConstantControllerPtr controller(new constant_controller_t());
154 
155  sensitivity.reset(new ct::core::SensitivityIntegrator<STATE_DIM, CONTROL_DIM, STATE_DIM / 2,
156  STATE_DIM / 2, SCALAR>(nloc_settings.getSimulationTimestep(), analyticLinearSystem, controller,
157  nloc_settings.integrator, nloc_settings.timeVaryingDiscretization));
158  //TODO double check simulationTimeStep vs dt
159  }
160  else
161  {
162  sensitivity.reset(new ct::core::SensitivityApproximation<STATE_DIM, CONTROL_DIM, STATE_DIM / 2,
163  STATE_DIM / 2, SCALAR>(nloc_settings.dt, analyticLinearSystem, nloc_settings.discretization));
164  }
165 
166  systemInterface_t::state_matrix_t A_sensitivity;
167  systemInterface_t::state_control_matrix_t B_sensitivity;
168  sensitivity->setSubstepTrajectoryReference(subStepsX.get(), subStepsU.get());
169  sensitivity->getAandB(x_start, control, x_next, 0, nloc_settings.K_sim, A_sensitivity, B_sensitivity);
170 
171  ASSERT_TRUE(A.isApprox(A_sensitivity, 1e-8));
172  ASSERT_TRUE(B.isApprox(B_sensitivity, 1e-8));
173  }
174  }
175  }
176 }
177 
178 TEST(SystemInterfaceTest, DiscreteSystemInterface)
179 {
180  //TODO
181 }
182 
183 } // namespace example
184 } // namespace optcon
185 } // namespace ct
double dt
Eigenvalue correction factor for Hessian regularization.
Definition: NLOptConSettings.hpp:262
const size_t state_dim
Definition: ConstraintComparison.h:20
double getSimulationTimestep() const
compute the simulation timestep
Definition: NLOptConSettings.hpp:300
interface base class for optimal control algorithms
Definition: OptconSystemInterface.h:25
bool useSensitivityIntegrator
Definition: NLOptConSettings.hpp:279
Settings for the NLOptCon algorithm.
Definition: NLOptConSettings.hpp:198
CppAD::AD< CppAD::cg::CG< double > > SCALAR
interface class for optimal control algorithms
Definition: OptconContinuousSystemInterface.h:28
TEST(ConstraintComparison, comparisonAnalyticAD)
Definition: ConstraintComparison.h:158
for i
Definition: mpc_unittest_plotting.m:14
APPROXIMATION discretization
which integrator to use during the NLOptCon forward rollout
Definition: NLOptConSettings.hpp:256
int K_sim
sampling time for the control input (seconds)
Definition: NLOptConSettings.hpp:263
bool timeVaryingDiscretization
Definition: NLOptConSettings.hpp:257
tpl::LinearOscillator< double > LinearOscillator
Definition: LinearOscillator.h:105
tpl::LinearOscillatorLinear< double > LinearOscillatorLinear
Definition: LinearOscillator.h:106
ct::core::IntegrationType integrator
Definition: NLOptConSettings.hpp:255
Definition: OptConProblemBase.h:40
const size_t control_dim
Definition: ConstraintComparison.h:21