- 3.0.2 optimal control module.
MultipleShooting-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 template <size_t STATE_DIM, size_t CONTROL_DIM, size_t P_DIM, size_t V_DIM, typename SCALAR, bool CONTINUOUS>
13  const Settings_t& settings)
14  : Base(backend_)
15 {
16 }
17 
18 template <size_t STATE_DIM, size_t CONTROL_DIM, size_t P_DIM, size_t V_DIM, typename SCALAR, bool CONTINUOUS>
20 {
21  this->backend_->configure(settings);
22 }
23 
24 template <size_t STATE_DIM, size_t CONTROL_DIM, size_t P_DIM, size_t V_DIM, typename SCALAR, bool CONTINUOUS>
26 {
27  this->backend_->setInitialGuess(initialGuess);
28 }
29 
30 template <size_t STATE_DIM, size_t CONTROL_DIM, size_t P_DIM, size_t V_DIM, typename SCALAR, bool CONTINUOUS>
32 {
34 
35  return finishIteration();
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 {
41  bool debugPrint = this->backend_->getSettings().debugPrint;
42 
43  auto startPrepare = std::chrono::steady_clock::now();
44 
45  if (!this->backend_->isInitialized())
46  throw std::runtime_error("MultipleShooting is not initialized!");
47 
48  if (!this->backend_->isConfigured())
49  throw std::runtime_error("MultipleShooting is not configured!");
50 
51  this->backend_->checkProblem();
52 
53  int K = this->backend_->getNumSteps();
54  int K_shot = this->backend_->getNumStepsPerShot();
55 
56  // if first iteration, compute shots and rollout and cost!
57  if (this->backend_->iteration() == 0)
58  {
59  this->backend_->rolloutShots(K_shot, K - 1);
60  }
61 
62  auto start = std::chrono::steady_clock::now();
63  this->backend_->setInputBoxConstraintsForLQOCProblem();
64  this->backend_->setStateBoxConstraintsForLQOCProblem();
65  this->backend_->computeLQApproximation(K_shot, K - 1);
66  auto end = std::chrono::steady_clock::now();
67  auto diff = end - start;
68  if (debugPrint)
69  std::cout << "[MultipleShooting]: computing LQ Approximation from index " << K_shot << " to N-1 took "
70  << std::chrono::duration<double, std::milli>(diff).count() << " ms" << std::endl;
71 
72  if (debugPrint)
73  std::cout << "[MultipleShooting]: Solving prepare stage of LQOC Problem" << std::endl;
74 
75  start = std::chrono::steady_clock::now();
76  this->backend_->prepareSolveLQProblem(K_shot);
77  end = std::chrono::steady_clock::now();
78  diff = end - start;
79  if (debugPrint)
80  std::cout << "[MultipleShooting]: Prepare phase of LQOC problem took "
81  << std::chrono::duration<double, std::milli>(diff).count() << " ms" << std::endl;
82 
83  auto endPrepare = std::chrono::steady_clock::now();
84  if (debugPrint)
85  std::cout << "[MultipleShooting]: prepareIteration() took "
86  << std::chrono::duration<double, std::milli>(endPrepare - startPrepare).count() << " ms" << std::endl;
87 
88 }
89 
90 
91 template <size_t STATE_DIM, size_t CONTROL_DIM, size_t P_DIM, size_t V_DIM, typename SCALAR, bool CONTINUOUS>
93 {
94  int K_shot = this->backend_->getNumStepsPerShot();
95 
96  bool debugPrint = this->backend_->getSettings().debugPrint;
97 
98  auto startFinish = std::chrono::steady_clock::now();
99 
100  // if first iteration, compute shots and rollout and cost!
101  if (this->backend_->iteration() == 0)
102  {
103  this->backend_->rolloutShots(0, K_shot - 1);
104  this->backend_->updateCosts();
105  this->backend_->computeDefectsNorm();
106  }
107 
108 #ifdef MATLAB_FULL_LOG
109  if (this->backend_->iteration() == 0)
110  this->backend_->logInitToMatlab();
111 #endif
112 
113  auto start = std::chrono::steady_clock::now();
114  this->backend_->computeLQApproximation(0, K_shot - 1);
115  auto end = std::chrono::steady_clock::now();
116  auto diff = end - start;
117  if (debugPrint)
118  std::cout << "[MultipleShooting]: computing LQ approximation for first multiple-shooting interval took "
119  << std::chrono::duration<double, std::milli>(diff).count() << " ms" << std::endl;
120 
121  if (debugPrint)
122  std::cout << "[MultipleShooting]: Finish phase LQOC Problem" << std::endl;
123 
124  start = std::chrono::steady_clock::now();
125  this->backend_->finishSolveLQProblem(K_shot - 1);
126  this->backend_->extractSolution();
127  end = std::chrono::steady_clock::now();
128  diff = end - start;
129  if (debugPrint)
130  std::cout << "[MultipleShooting]: Finish solving LQOC problem took "
131  << std::chrono::duration<double, std::milli>(diff).count() << " ms" << std::endl;
132 
133  start = std::chrono::steady_clock::now();
134  bool foundBetter = this->backend_->lineSearch();
135  end = std::chrono::steady_clock::now();
136  diff = end - start;
137  if (debugPrint)
138  std::cout << "[MultipleShooting]: Line search took " << std::chrono::duration<double, std::milli>(diff).count() << " ms"
139  << std::endl;
140 
141 
142  if (debugPrint)
143  {
144  auto endFinish = std::chrono::steady_clock::now();
145  std::cout << "[MultipleShooting]: finishIteration() took "
146  << std::chrono::duration<double, std::milli>(endFinish - startFinish).count() << " ms" << std::endl;
147  }
148 
149 
150  this->backend_->printSummary();
151 
152 #ifdef MATLAB_FULL_LOG
153  this->backend_->logToMatlab(this->backend_->iteration());
154 #endif //MATLAB_FULL_LOG
155 
156  this->backend_->iteration()++;
157 
158  return foundBetter;
159 
160 }
161 
162 
163 template <size_t STATE_DIM, size_t CONTROL_DIM, size_t P_DIM, size_t V_DIM, typename SCALAR, bool CONTINUOUS>
165 {
166  bool debugPrint = this->backend_->getSettings().debugPrint;
167 
168  auto startPrepare = std::chrono::steady_clock::now();
169 
170  if (!this->backend_->isInitialized())
171  throw std::runtime_error("MultipleShooting is not initialized!");
172 
173  if (!this->backend_->isConfigured())
174  throw std::runtime_error("MultipleShooting is not configured!");
175 
176  this->backend_->checkProblem();
177 
178  int K = this->backend_->getNumSteps();
179  int K_shot = this->backend_->getNumStepsPerShot();
180 
181  this->backend_->resetDefects();
182 
183  this->backend_->rolloutShots(K_shot, K - 1);
184 
185  auto start = std::chrono::steady_clock::now();
186  this->backend_->setInputBoxConstraintsForLQOCProblem();
187  this->backend_->setStateBoxConstraintsForLQOCProblem();
188  this->backend_->computeLQApproximation(K_shot, K - 1);
189  auto end = std::chrono::steady_clock::now();
190  auto diff = end - start;
191  if (debugPrint)
192  std::cout << "[MultipleShooting-MPC]: computing LQ approximation from index " << K_shot << " to N-1 took "
193  << std::chrono::duration<double, std::milli>(diff).count() << " ms" << std::endl;
194 
195  if (debugPrint)
196  std::cout << "[MultipleShooting-MPC]: Solving prepare stage of LQOC Problem" << std::endl;
197 
198  start = std::chrono::steady_clock::now();
199  this->backend_->prepareSolveLQProblem(K_shot);
200  end = std::chrono::steady_clock::now();
201  diff = end - start;
202  if (debugPrint)
203  std::cout << "[MultipleShooting-MPC]: Prepare phase of LQOC problem took "
204  << std::chrono::duration<double, std::milli>(diff).count() << " ms" << std::endl;
205 
206 
207  auto endPrepare = std::chrono::steady_clock::now();
208  if (debugPrint)
209  std::cout << "[MultipleShooting-MPC]: prepareIteration() took "
210  << std::chrono::duration<double, std::milli>(endPrepare - startPrepare).count() << " ms" << std::endl;
211 
212 
213 }
214 
215 
216 template <size_t STATE_DIM, size_t CONTROL_DIM, size_t P_DIM, size_t V_DIM, typename SCALAR, bool CONTINUOUS>
218 {
219  int K_shot = this->backend_->getNumStepsPerShot();
220 
221  bool debugPrint = this->backend_->getSettings().debugPrint;
222 
223  auto startFinish = std::chrono::steady_clock::now();
224 
225 
226  this->backend_->rolloutShots(0, K_shot - 1);
227  this->backend_->updateCosts();
228  this->backend_->computeDefectsNorm();
229 
230 
231 #ifdef MATLAB_FULL_LOG
232  if (this->backend_->iteration() == 0)
233  this->backend_->logInitToMatlab();
234 #endif
235 
236  auto start = std::chrono::steady_clock::now();
237  this->backend_->computeLQApproximation(0, K_shot - 1);
238  auto end = std::chrono::steady_clock::now();
239  auto diff = end - start;
240  if (debugPrint)
241  std::cout << "[MultipleShooting-MPC]: computing LQ approximation for first multiple-shooting interval took "
242  << std::chrono::duration<double, std::milli>(diff).count() << " ms" << std::endl;
243 
244  if (debugPrint)
245  std::cout << "[MultipleShooting-MPC]: Finish phase LQOC Problem" << std::endl;
246 
247  start = std::chrono::steady_clock::now();
248  this->backend_->finishSolveLQProblem(K_shot - 1);
249  this->backend_->extractSolution();
250  end = std::chrono::steady_clock::now();
251  diff = end - start;
252  if (debugPrint)
253  std::cout << "[MultipleShooting-MPC]: Finish solving LQOC problem took "
254  << std::chrono::duration<double, std::milli>(diff).count() << " ms" << std::endl;
255 
256 
258  start = std::chrono::steady_clock::now();
259  this->backend_->doFullStepUpdate();
260 
261  end = std::chrono::steady_clock::now();
262  diff = end - start;
263  if (debugPrint)
264  std::cout << "[MultipleShooting-MPC]: Solution update took " << std::chrono::duration<double, std::milli>(diff).count()
265  << " ms" << std::endl;
266 
267 
268  if (debugPrint)
269  {
270  auto endFinish = std::chrono::steady_clock::now();
271  std::cout << "[MultipleShooting-MPC]: finishIteration() took "
272  << std::chrono::duration<double, std::milli>(endFinish - startFinish).count() << " ms" << std::endl;
273  }
274 
275  this->backend_->printSummary();
276 
277 #ifdef MATLAB_FULL_LOG
278  this->backend_->logToMatlab(this->backend_->iteration());
279 #endif //MATLAB_FULL_LOG
280 
281  this->backend_->iteration()++;
282 
283  return true; // note: will always return foundBetter
284 
285 }
286 
287 } // namespace optcon
288 } // namespace ct
Definition: NLOCAlgorithm.hpp:19
virtual void prepareIteration() override
Definition: MultipleShooting-impl.hpp:39
MultipleShooting(std::shared_ptr< Backend_t > &backend_, const Settings_t &settings)
constructor
Definition: MultipleShooting-impl.hpp:12
virtual bool finishMPCIteration() override
finish iteration, dedicated to MPC
Definition: MultipleShooting-impl.hpp:217
virtual void configure(const Settings_t &settings) override
configure the solver
Definition: MultipleShooting-impl.hpp:19
Base::Policy_t Policy_t
Definition: MultipleShooting.hpp:31
std::shared_ptr< Backend_t > backend_
Definition: NLOCAlgorithm.hpp:47
Settings for the NLOptCon algorithm.
Definition: NLOptConSettings.hpp:198
virtual void prepareMPCIteration() override
prepare iteration, dedicated to MPC.
Definition: MultipleShooting-impl.hpp:164
virtual bool finishIteration() override
finish iteration for unconstrained MultipleShooting
Definition: MultipleShooting-impl.hpp:92
virtual void setInitialGuess(const Policy_t &initialGuess) override
set an initial guess
Definition: MultipleShooting-impl.hpp:25
virtual bool runIteration() override
runIteration combines prepareIteration and finishIteration
Definition: MultipleShooting-impl.hpp:31