blob: 37442cf4cc8c8a1be3f4c13e2028b84688235b0f [file] [log] [blame]
Austin Schuh7400da02018-01-28 19:54:58 -08001
2#include <ct/optcon/optcon.h>
3#include "exampleDir.h"
4#include "plotResultsOscillator.h"
5
6/*!
7 * This example shows how to use classical Direct Multiple Shooting with an oscillator system,
8 * using IPOPT as NLP solver.
9 *
10 * \example DMS.cpp
11 */
12int main(int argc, char **argv)
13{
14 using namespace ct::optcon;
15 using namespace ct::core;
16
17 const size_t state_dim = SecondOrderSystem::STATE_DIM;
18 const size_t control_dim = SecondOrderSystem::CONTROL_DIM;
19
20
21 /**
22 * STEP 1 : set up the optimal control problem
23 * */
24
25 StateVector<state_dim> x_0;
26 StateVector<state_dim> x_final;
27
28 x_0 << 0.0, 0.0;
29 x_final << 2.0, -1.0;
30
31 double w_n = 0.5; // oscillator frequency
32 double zeta = 0.01; // oscillator damping
33
34 // create oscillator system
35 std::shared_ptr<SecondOrderSystem> oscillator(new SecondOrderSystem(w_n, zeta));
36
37
38 // load the cost weighting matrices from file and store them in terms. Note that we only use intermediate cost
39 std::shared_ptr<ct::optcon::TermQuadratic<state_dim, control_dim>> intermediateCost(
40 new ct::optcon::TermQuadratic<state_dim, control_dim>());
41 intermediateCost->loadConfigFile(ct::optcon::exampleDir + "/dmsCost.info", "intermediateCost", true);
42
43 // create a cost function and add the terms to it.
44 std::shared_ptr<CostFunctionQuadratic<state_dim, control_dim>> costFunction(
45 new CostFunctionAnalytical<state_dim, control_dim>());
46 costFunction->addIntermediateTerm(intermediateCost);
47
48
49 // we include the desired terminal state as a hard constraint
50 std::shared_ptr<ct::optcon::ConstraintContainerAnalytical<state_dim, control_dim>> finalConstraints(
51 new ct::optcon::ConstraintContainerAnalytical<2, 1>());
52
53 std::shared_ptr<TerminalConstraint<state_dim, control_dim>> terminalConstraint(
54 new TerminalConstraint<2, 1>(x_final));
55 terminalConstraint->setName("TerminalConstraint");
56 finalConstraints->addTerminalConstraint(terminalConstraint, true);
57 finalConstraints->initialize();
58
59
60 // define optcon problem and add constraint
61 OptConProblem<state_dim, control_dim> optConProblem(oscillator, costFunction);
62 optConProblem.setInitialState(x_0);
63 optConProblem.setGeneralConstraints(finalConstraints);
64
65
66 /**
67 * STEP 2 : determine solver settings
68 */
69 DmsSettings settings;
70 settings.N_ = 25; // number of nodes
71 settings.T_ = 5.0; // final time horizon
72 settings.nThreads_ = 4; // number of threads for multi-threading
73 settings.splineType_ = DmsSettings::PIECEWISE_LINEAR;
74 settings.costEvaluationType_ = DmsSettings::FULL; // we evaluate the full cost and use no trapezoidal approximation
75 settings.objectiveType_ = DmsSettings::KEEP_TIME_AND_GRID; // don't optimize the time spacing between the nodes
76 settings.h_min_ = 0.1; // minimum admissible distance between two nodes in [sec]
77 settings.integrationType_ = DmsSettings::RK4; // type of the shot integrator
78 settings.dt_sim_ = 0.01; // forward simulation dt
79 settings.solverSettings_.solverType_ = NlpSolverSettings::SolverType::IPOPT; // use IPOPT
80 settings.absErrTol_ = 1e-8;
81 settings.relErrTol_ = 1e-8;
82
83 settings.print();
84
85
86 /**
87 * STEP 3 : Calculate an appropriate initial guess
88 */
89 StateVectorArray<state_dim> x_initguess;
90 ControlVectorArray<control_dim> u_initguess;
91 DmsPolicy<state_dim, control_dim> initialPolicy;
92
93
94 x_initguess.resize(settings.N_ + 1, StateVector<state_dim>::Zero());
95 u_initguess.resize(settings.N_ + 1, ControlVector<control_dim>::Zero());
96 for (size_t i = 0; i < settings.N_ + 1; ++i)
97 {
98 x_initguess[i] = x_0 + (x_final - x_0) * (i / settings.N_);
99 }
100
101 initialPolicy.xSolution_ = x_initguess;
102 initialPolicy.uSolution_ = u_initguess;
103
104
105 /**
106 * STEP 4: solve DMS with IPOPT
107 */
108
109 optConProblem.setTimeHorizon(settings.T_);
110
111 std::shared_ptr<DmsSolver<state_dim, control_dim>> dmsSolver(
112 new DmsSolver<state_dim, control_dim>(optConProblem, settings));
113
114 dmsSolver->setInitialGuess(initialPolicy);
115 dmsSolver->solve();
116
117 // retrieve the solution
118 DmsPolicy<state_dim, control_dim> solution = dmsSolver->getSolution();
119
120 // let's plot the output
121 plotResultsOscillator<state_dim, control_dim>(solution.xSolution_, solution.uSolution_, solution.tSolution_);
122}