- 3.0.2 optimal control module.
MpcTimeKeeper.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 "MpcSettings.h"
10 
12 
16 //#define DEBUG_PRINT_TIMEKEEPER
17 
18 namespace ct {
19 namespace optcon {
20 namespace tpl {
21 
22 
24 
31 template <typename SCALAR = double>
33 {
34 public:
36 
41 
46  MpcTimeKeeper(std::shared_ptr<MpcTimeHorizon<SCALAR>> timeHorizonStrategy, const mpc_settings& mpc_settings)
47  : mpc_settings_(mpc_settings),
48  initialized_(false),
49  finalPointReached_(false),
50  lastMeasuredDelay_(0.0),
51  maxDelayMeasured_(0.0),
52  minDelayMeasured_(std::numeric_limits<SCALAR>::max()),
53  summedDelay_(0.0),
54  timeHorizonStrategy_(timeHorizonStrategy),
55  firstRun_(true)
56  {
57  }
58 
59 
61 
64  void initialize()
65  {
66  firstRun_ = true;
67 
68  timer_.reset();
69  lastSolveTimer_.reset();
70  firstSolveTimer_.reset();
71 
72  ext_timer_.reset();
73  ext_lastSolveTimer_.reset();
74  ext_firstSolveTimer_.reset();
75 
76  lastMeasuredDelay_ = 0.0;
77  maxDelayMeasured_ = 0.0;
78  minDelayMeasured_ = std::numeric_limits<SCALAR>::max();
79  summedDelay_ = 0.0;
80  finalPointReached_ = false;
81 
82  initialized_ = true;
83  }
84 
85 
87 
98  void computeNewTimings(const SCALAR externalTime,
99  const SCALAR current_T,
100  SCALAR& new_T,
101  SCALAR& t_forw_start,
102  SCALAR& t_forw_stop)
103  {
104  if (initialized_ == false)
105  throw std::runtime_error(
106  "Error in MPC time keeper: cannot update timings if MpcTimeKeeper not properly initialized.");
107 
108 
109  SCALAR timeSinceEndedLastSolve;
110  SCALAR timeSinceEndedFirstSolve;
111 
112  if (!firstRun_)
113  {
114  if (mpc_settings_.useExternalTiming_)
115  {
116  ext_firstSolveTimer_.stop(externalTime);
117  ext_lastSolveTimer_.stop(externalTime);
118  timeSinceEndedFirstSolve = ext_firstSolveTimer_.getElapsedTime();
119  timeSinceEndedLastSolve = ext_lastSolveTimer_.getElapsedTime();
120  }
121  else
122  {
123  lastSolveTimer_.stop();
124  firstSolveTimer_.stop();
125  timeSinceEndedLastSolve = lastSolveTimer_.getElapsedTime();
126  timeSinceEndedFirstSolve = firstSolveTimer_.getElapsedTime();
127  }
128  }
129  else
130  {
131  // set zero for the first mpc run
132  timeSinceEndedLastSolve = 0.0;
133  timeSinceEndedFirstSolve = 0.0;
134  }
135 
136 
137  // starting time of forward prediction, relative to previous controller
138  t_forw_start = timeSinceEndedLastSolve;
139 
140 
144  SCALAR delayToApply = computeDelayToApply();
145 
146 
147  // stopping time relative to previous controller/run
148  if (!firstRun_)
149  t_forw_stop = t_forw_start + delayToApply;
150  else
151  t_forw_stop = t_forw_start;
152 
153 
157  if (t_forw_start > current_T)
158  {
159  std::cerr << "WARNING: forward integration start time cannot be bigger than last time horizon. Truncating "
160  "forward integration time."
161  << std::endl;
162  t_forw_start = current_T;
163  }
164  if (t_forw_stop > current_T)
165  {
166  std::cerr << "WARNING: forward integration stop time cannot be bigger than last time horizon. Truncating "
167  "forward integration time."
168  << std::endl;
169  t_forw_stop = current_T;
170  }
171 
172 
173  finalPointReached_ = timeHorizonStrategy_->computeNewTimeHorizon(timeSinceEndedFirstSolve, t_forw_stop, new_T);
174 
175 
176 #ifdef DEBUG_PRINT_TIMEKEEPER
177  std::cout << "DEBUG_PRINT_TIMEKEEPER: Time since first solve(): " << timeSinceEndedFirstSolve << std::endl;
178  std::cout << "DEBUG_PRINT_TIMEKEEPER: Time since last solve(): " << timeSinceEndedLastSolve << std::endl;
179  std::cout << "DEBUG_PRINT_TIMEKEEPER: t_forward_start: " << t_forw_start << std::endl;
180  std::cout << "DEBUG_PRINT_TIMEKEEPER: t_forward_stop: " << t_forw_stop << std::endl;
181  std::cout << "DEBUG_PRINT_TIMEKEEPER: New Time Horizon: " << new_T << std::endl;
182  std::cout << "DEBUG_PRINT_TIMEKEEPER: final point reached_: " << finalPointReached_ << std::endl;
183 #endif
184  }
185 
186 
188 
192  const bool finalPointReached() const { return finalPointReached_; }
194 
198  void updateSettings(const mpc_settings& settings) { mpc_settings_ = settings; }
200  void startDelayMeasurement(const SCALAR& externalTime)
201  {
202  if (mpc_settings_.measureDelay_)
203  {
204  if (mpc_settings_.useExternalTiming_)
205  ext_timer_.start(externalTime);
206  else
207  timer_.start();
208  }
209  }
210 
211 
213  void stopDelayMeasurement(const SCALAR& externalTime)
214  {
215  if (mpc_settings_.useExternalTiming_)
216  {
217  ext_timer_.stop(externalTime);
218  lastMeasuredDelay_ = ext_timer_.getElapsedTime();
219  // measure how much time passed since last successful solve()
220  ext_lastSolveTimer_.start(externalTime);
221  }
222  else
223  {
224  timer_.stop();
225  lastMeasuredDelay_ = timer_.getElapsedTime();
226  // measure how much time passed since last successful solve()
227  lastSolveTimer_.start();
228  }
229 
230  maxDelayMeasured_ = std::max(maxDelayMeasured_, lastMeasuredDelay_);
231  minDelayMeasured_ = std::min(minDelayMeasured_, lastMeasuredDelay_);
232  summedDelay_ += lastMeasuredDelay_;
233 
234  if (lastMeasuredDelay_ < 0)
235  throw std::runtime_error("Fatal: measured delay cannot be < 0");
236 
237 #ifdef DEBUG_PRINT_TIMEKEEPER
238  std::cout << "Measured delay during Solution: " << lastMeasuredDelay_ << " seconds" << std::endl;
239  std::cout << "Max. measured delay during Solution: " << maxDelayMeasured_ << " seconds" << std::endl;
240  std::cout << "Min. measured delay during Solution: " << minDelayMeasured_ << " seconds" << std::endl;
241 #endif
242 
243  if (firstRun_)
244  {
245  // start timer for measuring how much time elapsed since the first successful plan
246  if (mpc_settings_.useExternalTiming_)
247  {
248  ext_firstSolveTimer_.start(externalTime);
249  }
250  else
251  {
252  firstSolveTimer_.start();
253  }
254 
255  firstRun_ = false;
256  }
257  }
258 
259 
261 
266  {
267  if (firstRun_)
268  return 0.0;
269  else
270  {
271  if (mpc_settings_.useExternalTiming_)
272  {
273  ext_lastSolveTimer_.stop(externalTime);
274  return ext_lastSolveTimer_.getElapsedTime();
275  }
276  else
277  {
278  lastSolveTimer_.stop();
279  return lastSolveTimer_.getElapsedTime();
280  }
281  }
282  }
283 
284 
286 
290  const SCALAR timeSinceFirstSuccessfulSolve(const SCALAR& externalTime)
291  {
292  if (firstRun_)
293  return 0.0;
294  else
295  {
296  if (mpc_settings_.useExternalTiming_)
297  {
298  ext_firstSolveTimer_.stop(externalTime);
299  return ext_firstSolveTimer_.getElapsedTime();
300  }
301  else
302  {
303  firstSolveTimer_.stop();
304  return firstSolveTimer_.getElapsedTime();
305  }
306  }
307  }
308 
310  const SCALAR& getMeasuredDelay() const { return lastMeasuredDelay_; }
312  const SCALAR& getMaxMeasuredDelay() const { return maxDelayMeasured_; }
314  const SCALAR& getMinMeasuredDelay() const { return minDelayMeasured_; }
316  const SCALAR& getSummedDelay() const { return summedDelay_; }
317 private:
319 
325  SCALAR computeDelayToApply()
326  {
327  SCALAR fixedDelay = 1e-6 * mpc_settings_.additionalDelayUs_;
328  SCALAR variableDelay = 0.0;
329 
330  if (mpc_settings_.measureDelay_) // use variable, measured delay
331  variableDelay = mpc_settings_.delayMeasurementMultiplier_ * lastMeasuredDelay_;
332  else // using fixed delay
333  fixedDelay += 1e-6 * mpc_settings_.fixedDelayUs_;
334 
335 #ifdef DEBUG_PRINT_TIMEKEEPER
336  std::cout << "Accumulated delay to apply: " << fixedDelay + variableDelay << " seconds" << std::endl;
337 #endif
338 
339  return fixedDelay + variableDelay;
340  }
341 
342 
343  mpc_settings mpc_settings_;
344 
345  bool initialized_;
346 
348  bool finalPointReached_;
349 
353  core::tpl::Timer<SCALAR> lastSolveTimer_;
355  core::tpl::Timer<SCALAR> firstSolveTimer_;
356 
360  core::tpl::ExternallyDrivenTimer<SCALAR> ext_lastSolveTimer_;
362  core::tpl::ExternallyDrivenTimer<SCALAR> ext_firstSolveTimer_;
363 
364  SCALAR lastMeasuredDelay_;
365  SCALAR maxDelayMeasured_;
366  SCALAR minDelayMeasured_;
367  SCALAR summedDelay_;
368 
370  std::shared_ptr<MpcTimeHorizon<SCALAR>> timeHorizonStrategy_;
371 
372  bool firstRun_;
373 };
374 
375 
376 } // namespace tpl
377 
379 
380 } // namespace optcon
381 } // namespace ct
void computeNewTimings(const SCALAR externalTime, const SCALAR current_T, SCALAR &new_T, SCALAR &t_forw_start, SCALAR &t_forw_stop)
compute new mpc timings, based on current time horizon and the given time horizon strategy ...
Definition: MpcTimeKeeper.h:98
bool measureDelay_
Definition: MpcSettings.h:71
const bool finalPointReached() const
query this in order to find out if the final time horizon has been reached.
Definition: MpcTimeKeeper.h:192
void updateSettings(const mpc_settings &settings)
update mpc settings
Definition: MpcTimeKeeper.h:198
SCALAR getElapsedTime() const
SCALAR timeSincePreviousSuccessfulSolve(const SCALAR &externalTime)
retrieve the time that elapsed since the last successful solve() call to an Optimal Control Problem ...
Definition: MpcTimeKeeper.h:265
Time Keeper Class for Model Predictive Control.
Definition: MpcTimeKeeper.h:32
const SCALAR & getMeasuredDelay() const
obtain the delay which was measured during solving the optimal control problem
Definition: MpcTimeKeeper.h:310
double delayMeasurementMultiplier_
Definition: MpcSettings.h:79
void start(const SCALAR &time)
const SCALAR & getMaxMeasuredDelay() const
get the maximum measured delay (maximum over all cycles)
Definition: MpcTimeKeeper.h:312
const SCALAR & getSummedDelay() const
get the sum of all measured delays
Definition: MpcTimeKeeper.h:316
const SCALAR & getMinMeasuredDelay() const
get the smallest measured delay (minimum over all cycles)
Definition: MpcTimeKeeper.h:314
MpcTimeKeeper()
Standard Constructor MpcTimeKeeper.
Definition: MpcTimeKeeper.h:39
CppAD::AD< CppAD::cg::CG< double > > SCALAR
int additionalDelayUs_
Definition: MpcSettings.h:89
MPC Settings struct.
Definition: MpcSettings.h:45
void stop(const SCALAR &time)
Definition: MpcTimeHorizon.h:20
MpcTimeKeeper(std::shared_ptr< MpcTimeHorizon< SCALAR >> timeHorizonStrategy, const mpc_settings &mpc_settings)
Constructor for Mpc Time Keeper class.
Definition: MpcTimeKeeper.h:46
const SCALAR timeSinceFirstSuccessfulSolve(const SCALAR &externalTime)
retrieve the time that elapsed since the first successful solve() call to an Optimal Control Problem ...
Definition: MpcTimeKeeper.h:290
bool useExternalTiming_
Definition: MpcSettings.h:118
int fixedDelayUs_
Definition: MpcSettings.h:84
void startDelayMeasurement(const SCALAR &externalTime)
start measuring time elapsed during planning / solving the optimal control problem ...
Definition: MpcTimeKeeper.h:200
void initialize()
initialize the Mpc Time Keeper (mandatory)
Definition: MpcTimeKeeper.h:64
void stopDelayMeasurement(const SCALAR &externalTime)
stop measuring time elapsed during solving the optimal control problem
Definition: MpcTimeKeeper.h:213