- 3.0.2 core module.
SystemDiscretizerTest.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 <gtest/gtest.h>
9 
10 using namespace ct::core;
11 using std::shared_ptr;
12 
13 
14 double uniformRandomNumber(double min, double max)
15 {
16  std::random_device rd; // obtain a random number from hardware
17  std::mt19937 eng(rd()); // seed the generator
18  std::uniform_real_distribution<> distr(min, max); // define the range
19 
20  return distr(eng);
21 }
22 
23 
24 TEST(SystemDiscretizerTest, IntegratorComparison)
25 {
26  const size_t state_dim = 2;
27  const size_t control_dim = 1;
28 
29  size_t nTests = 10;
30 
31  for (size_t i = 1; i < nTests; ++i)
32  {
33  double w_n = uniformRandomNumber(0, 10);
34  double zeta = uniformRandomNumber(0, 10);
35 
36  // make sure we are not complex
37  while (w_n * w_n - zeta * zeta <= 0)
38  {
39  w_n = uniformRandomNumber(0, 100);
40  zeta = uniformRandomNumber(0, 10);
41  }
42 
43  // dynamic systems for manual integration and discrete propagation
44  shared_ptr<SecondOrderSystem> oscillator1(new SecondOrderSystem(w_n, zeta));
45  shared_ptr<SecondOrderSystem> oscillator2(new SecondOrderSystem(w_n, zeta));
46  oscillator1->checkParameters();
47  oscillator2->checkParameters();
48 
49  // set up a controller for the manually integrated system
50  std::shared_ptr<ConstantController<state_dim, control_dim>> constantController(
52  oscillator1->setController(constantController);
53 
54  // parameters for discretization
55  double dt = 0.001;
56  double startTime = 0.0;
57  size_t nStages = 100;
58  size_t K_sim = i; // gradually increase K_sim according to the test id
59 
60  // integrators for comparison
61  Integrator<state_dim> integratorEuler(oscillator1, EULER);
62  Integrator<state_dim> integratorRK4(oscillator1, RK4);
63 
64  // system discretizer for comparison
65  SystemDiscretizer<state_dim, control_dim> systemDiscretizerEuler(oscillator2, dt, EULER, K_sim);
66  SystemDiscretizer<state_dim, control_dim> systemDiscretizerRK4(oscillator2, dt, RK4, K_sim);
67 
68  // initial states
69  StateVector<state_dim> integratedStateEuler, integratedStateRK4, propagatedStateEuler, propagatedStateRK4;
70  integratedStateEuler << 1.0, 0.0;
71  integratedStateRK4 << 1.0, 0.0;
72  propagatedStateEuler << 1.0, 0.0;
73  propagatedStateRK4 << 1.0, 0.0;
74 
75  for (size_t j = 0; j < nStages; j++)
76  {
78  ctrl(0) = uniformRandomNumber(-1.0, 1.0);
79 
80  // integrate systems
81  constantController->setControl(ctrl);
82  integratorEuler.integrate_n_steps(integratedStateEuler, startTime, K_sim, dt / (double)K_sim);
83  integratorRK4.integrate_n_steps(integratedStateRK4, startTime, K_sim, dt / (double)K_sim);
84 
85  // propagate systems
86  systemDiscretizerEuler.propagateControlledDynamics(propagatedStateEuler, j, ctrl, propagatedStateEuler);
87  systemDiscretizerRK4.propagateControlledDynamics(propagatedStateRK4, j, ctrl, propagatedStateRK4);
88 
89  // the manually integrated as well as the propagated state need to be the same.
90  ASSERT_LT((propagatedStateEuler - integratedStateEuler).array().abs().maxCoeff(), 1e-12);
91  ASSERT_LT((propagatedStateRK4 - integratedStateRK4).array().abs().maxCoeff(), 1e-12);
92  }
93  }
94 }
void integrate_n_steps(StateVector< STATE_DIM, SCALAR > &state, const SCALAR &startTime, size_t numSteps, SCALAR dt, StateVectorArray< STATE_DIM, SCALAR > &stateTrajectory, tpl::TimeArray< SCALAR > &timeTrajectory)
Equidistant integration based on number of time steps and step length.
Definition: Integrator-impl.h:50
Definition: Integrator.h:32
const double zeta
A constant controller.
Definition: ConstantController.h:20
const double w_n
virtual void propagateControlledDynamics(const StateVector< STATE_DIM, SCALAR > &state, const time_t n, const ControlVector< CONTROL_DIM, SCALAR > &control, StateVector< STATE_DIM, SCALAR > &stateNext) override
propagate discrete-time dynamics by performing a numerical forward integration of the continuous-time...
Definition: SystemDiscretizer-impl.h:121
Discretize a general, continuous-time non-linear dynamic system using forward integration.
Definition: SystemDiscretizer.h:44
const double dt
tpl::SecondOrderSystem< double > SecondOrderSystem
harmonic oscillator (double)
Definition: SecondOrderSystem.h:220
double uniformRandomNumber(double min, double max)
Definition: SystemDiscretizerTest.h:14
const size_t state_dim
Definition: SymplecticIntegrationTest.cpp:14
Definition: StateVector.h:12
Standard Integrator.
Definition: Integrator.h:62
for i
Definition: Integrator.h:33
const size_t control_dim
Definition: SymplecticIntegrationTest.cpp:17
TEST(SystemDiscretizerTest, IntegratorComparison)
Definition: SystemDiscretizerTest.h:24