controller.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ACADO Toolkit.
3  *
4  * ACADO Toolkit -- A Toolkit for Automatic Control and Dynamic Optimization.
5  * Copyright (C) 2008-2014 by Boris Houska, Hans Joachim Ferreau,
6  * Milan Vukov, Rien Quirynen, KU Leuven.
7  * Developed within the Optimization in Engineering Center (OPTEC)
8  * under supervision of Moritz Diehl. All rights reserved.
9  *
10  * ACADO Toolkit is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 3 of the License, or (at your option) any later version.
14  *
15  * ACADO Toolkit is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with ACADO Toolkit; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23  *
24  */
25 
26 
34 
35 
36 // #define SIM_DEBUG
37 
38 
40 
41 //
42 // PUBLIC MEMBER FUNCTIONS:
43 //
44 
46 {
47  setupOptions( );
48  setupLogging( );
49 
50  controlLaw = 0;
51  estimator = 0;
53 
55 
57 }
58 
59 
61  Estimator& _estimator,
62  ReferenceTrajectory& _referenceTrajectory
64 {
65  setupOptions( );
66  setupLogging( );
67 
68  if ( _controlLaw.isDefined( ) == BT_TRUE )
69  {
70  controlLaw = &_controlLaw;
72  }
73  else
74  controlLaw = 0;
75 
76  if ( _estimator.isDefined( ) == BT_TRUE )
77  estimator = &_estimator;
78  else
79  estimator = 0;
80 
81  if ( _referenceTrajectory.isDefined( ) == BT_TRUE )
82  referenceTrajectory = &_referenceTrajectory;
83  else
85 
87 
89 }
90 
91 
93  ReferenceTrajectory& _referenceTrajectory
95 {
96  setupOptions( );
97  setupLogging( );
98 
99  if ( _controlLaw.isDefined( ) == BT_TRUE )
100  {
101  controlLaw = &_controlLaw;
103  }
104  else
105  controlLaw = 0;
106 
107  estimator = 0;
108 
109  if ( _referenceTrajectory.isDefined( ) == BT_TRUE )
110  referenceTrajectory = &_referenceTrajectory;
111  else
113 
114  isEnabled = BT_TRUE;
115 
117 }
118 
119 
121 {
122  if ( rhs.controlLaw != 0 )
123  controlLaw = rhs.controlLaw;
124  else
125  controlLaw = 0;
126 
127  if ( rhs.estimator != 0 )
128  estimator = rhs.estimator;
129  else
130  estimator = 0;
131 
132  if ( rhs.referenceTrajectory != 0 )
134  else
136 
137  isEnabled = rhs.isEnabled;
138 }
139 
140 
142 {
143 // if ( controlLaw != 0 )
144 // delete controlLaw;
145 //
146 // if ( estimator != 0 )
147 // delete estimator;
148 //
149 // if ( referenceTrajectory != 0 )
150 // delete referenceTrajectory;
151 }
152 
153 
155 {
156  if ( this != &rhs )
157  {
158 // if ( controlLaw != 0 )
159 // delete controlLaw;
160 //
161 // if ( estimator != 0 )
162 // delete estimator;
163 //
164 // if ( referenceTrajectory != 0 )
165 // delete referenceTrajectory;
166 
168 
169  if ( rhs.controlLaw != 0 )
170  controlLaw = rhs.controlLaw;
171  else
172  controlLaw = 0;
173 
174  if ( rhs.estimator != 0 )
175  estimator = rhs.estimator;
176  else
177  estimator = 0;
178 
179  if ( rhs.referenceTrajectory != 0 )
181  else
183 
184  isEnabled = rhs.isEnabled;
185  }
186 
187  return *this;
188 }
189 
190 
191 
193  )
194 {
195  if ( _controlLaw.isDefined( ) == BT_TRUE )
196  {
197  if ( controlLaw == 0 )
198  controlLaw = &_controlLaw;
199  else
200  *controlLaw = _controlLaw;
201 
203  }
204 
205  return SUCCESSFUL_RETURN;
206 }
207 
208 
210  )
211 {
212  if ( _estimator.isDefined( ) == BT_TRUE )
213  {
214  if ( estimator == 0 )
215  estimator = &_estimator;
216  else
217  *estimator = _estimator;
218 
219  if ( getStatus( ) > BS_NOT_INITIALIZED )
221  }
222 
223  return SUCCESSFUL_RETURN;
224 }
225 
226 
228  )
229 {
230  if ( _referenceTrajectory.isDefined( ) == BT_TRUE )
231  {
232  if ( referenceTrajectory == 0 )
233  referenceTrajectory = &_referenceTrajectory;
234  else
235  *referenceTrajectory = _referenceTrajectory;
236 
237  if ( getStatus( ) > BS_NOT_INITIALIZED )
239  }
240 
241  return SUCCESSFUL_RETURN;
242 }
243 
244 
245 
247  )
248 {
249  if ( controlLaw != 0 )
251 
252  return SUCCESSFUL_RETURN;
253 }
254 
255 
257  )
258 {
259  VariablesGrid tmp;
260  tmp.read( fileName );
261 
262  if ( tmp.isEmpty( ) == BT_TRUE )
264 
265  return initializeAlgebraicStates( tmp );
266 }
267 
268 
269 
270 returnValue Controller::init( double startTime,
271  const DVector& _x0,
272  const DVector& _p,
273  const VariablesGrid& _yRef
274  )
275 {
276  if ( controlLaw == 0 )
278 
279  /* 1) Initialize all sub-blocks. */
280  /* a) Estimator */
281  DVector xEst( _x0 );
282  DVector pEst( _p );
283  DVector xaEst, uEst, wEst;
284 
285  if ( estimator != 0 )
286  {
287  if ( estimator->init( startTime,_x0,_p ) != SUCCESSFUL_RETURN )
289 
290  if ( estimator->getOutputs( xEst,xaEst,uEst,pEst,wEst ) != SUCCESSFUL_RETURN )
292  }
293 
294  /* b) Reference trajectory */
295  if ( ( referenceTrajectory != 0 ) && ( _yRef.isEmpty( ) == BT_TRUE ) )
296  if ( referenceTrajectory->init( startTime,xEst,xaEst,uEst,pEst,wEst ) != SUCCESSFUL_RETURN )
298 
299  VariablesGrid yRef( _yRef );
300  getCurrentReference( startTime,yRef );
301  #ifdef SIM_DEBUG
302  yRef.print( "yRef init" );
303  #endif
304 
305  /* c) Control law */
306 // _x0.print( "x0 init" );
307  if ( controlLaw->init( startTime,_x0,_p,yRef ) != SUCCESSFUL_RETURN )
309 
310 
311  /* 2) Consistency checks. */
312  if ( estimator != 0 )
313  {
314  if ( estimator->getNX( ) != controlLaw->getNX( ) )
316 
317  if ( estimator->getNXA( ) != controlLaw->getNXA( ) )
319 
320  if ( estimator->getNU( ) != controlLaw->getNU( ) )
322 
323  if ( estimator->getNP( ) != controlLaw->getNP( ) )
325 
326  if ( estimator->getNW( ) != controlLaw->getNW( ) )
328  }
329 
330  realClock.reset( );
331  setStatus( BS_READY );
332 
333  return SUCCESSFUL_RETURN;
334 }
335 
336 
337 
338 returnValue Controller::step( double currentTime,
339  const DVector& _y,
340  const VariablesGrid& _yRef
341  )
342 {
343  /* Consistency check. */
344  if ( getStatus( ) != BS_READY )
346 
347  if ( controlLaw == 0 )
349 
350  /* Do nothing if controller is disabled */
351  if ( isEnabled == BT_FALSE )
352  {
356  return SUCCESSFUL_RETURN;
357  }
358 
359  if ( feedbackStep( currentTime,_y,_yRef ) != SUCCESSFUL_RETURN )
361 
362  double nextTime = currentTime + controlLaw->getSamplingTime( );
363 
364  if ( preparationStep( nextTime,_yRef ) != SUCCESSFUL_RETURN )
366 
367  return SUCCESSFUL_RETURN;
368 }
369 
370 
371 returnValue Controller::step( double currentTime,
372  uint dim,
373  const double* const _y,
374  const VariablesGrid& _yRef
375  )
376 {
377  /* Convert double array to vector and call standard step routine. */
378  DVector tmp( dim,_y );
379  return step( currentTime,tmp,_yRef );
380 }
381 
382 
384  const DVector& _y,
385  DVector& xEst,
386  DVector& pEst
387  )
388 {
389  /* 1) Call Estimator */
390  RealClock clock;
391  DVector xaEst, uEst, wEst;
392 
393  clock.reset();
394  clock.start();
395 
396  if ( estimator != 0 )
397  {
398  if ( estimator->step( currentTime,_y ) != SUCCESSFUL_RETURN )
400 
401  if ( estimator->getOutputs( xEst,xaEst,uEst,pEst,wEst ) != SUCCESSFUL_RETURN )
403  }
404  else
405  {
406  /* If no estimator is specified, assume full state feedback. */
407  xEst = _y;
408  }
409 
410  clock.stop();
412 
413  // step internal reference trajectory
414  if ( referenceTrajectory != 0 )
415  {
416  if ( referenceTrajectory->step( currentTime,_y,xEst,xaEst,uEst,pEst,wEst ) != SUCCESSFUL_RETURN )
418  }
419 
420  return SUCCESSFUL_RETURN;
421 }
422 
423 
425  const DVector& _y,
426  const VariablesGrid& _yRef
427  )
428 {
429  realClock.reset( );
430 
431  if ( controlLaw == 0 )
433 
434  /* Do nothing if controller is disabled */
435  if ( isEnabled == BT_FALSE )
436  return SUCCESSFUL_RETURN;
437 
438  // start real runtime measurement
439  realClock.start( );
440 
441  DVector xEst, pEst;
442 
443  /* 1) Call Estimator */
444  if ( obtainEstimates( currentTime,_y,xEst,pEst ) != SUCCESSFUL_RETURN )
446 
447  /* 2) Evaluate reference trajectory */
448  VariablesGrid yRef( _yRef );
449  getCurrentReference( currentTime,yRef );
450  #ifdef SIM_DEBUG
451  yRef.print( "yRef feedback" );
452  #endif
453 
456 
457  /* 3) Perform feedback step of control law */
458  if ( controlLaw->feedbackStep( currentTime,xEst,pEst,yRef ) != SUCCESSFUL_RETURN )
460 
462  realClock.stop( );
463 
464  #ifdef SIM_DEBUG
465  DVector uTmp;
466  getU( uTmp );
467  uTmp.print("u(0) after feedbackStep");
468  #endif
469 
470  return SUCCESSFUL_RETURN;
471 }
472 
473 
475  const VariablesGrid& _yRef
476  )
477 {
478  if ( controlLaw == 0 )
480 
481  /* Do nothing if controller is disabled */
482  if ( isEnabled == BT_FALSE )
483  return SUCCESSFUL_RETURN;
484 
485  realClock.start();
487 
488  /* 1) Evaluate reference trajectory */
489  VariablesGrid yRef( _yRef );
490  getCurrentReference( nextTime,yRef );
491  #ifdef SIM_DEBUG
492  yRef.print( "yRef preparation" );
493  #endif
494 
495  /* 2) Perform preparation step of control law */
496  if ( controlLaw->preparationStep( nextTime,yRef ) != SUCCESSFUL_RETURN )
498 
501 
502  // stop real runtime measurement
503  realClock.stop();
505 
506 
507  #ifdef SIM_DEBUG
508  DVector uTmp;
509  getU( uTmp );
510  uTmp.print("u(0) after preparationStep");
511  #endif
512 
513  return SUCCESSFUL_RETURN;
514 }
515 
516 
517 
518 double Controller::getNextSamplingInstant( double currentTime
519  )
520 {
521  double nextControlLaw = INFTY;
522  double nextEstimator = INFTY;
523 
524  if ( controlLaw != 0 )
525  {
526  if ( acadoIsInteger( (currentTime-0.0) / getSamplingTimeControlLaw( ) ) == BT_TRUE )
527  nextControlLaw = currentTime + getSamplingTimeControlLaw( );
528  else
529  nextControlLaw = ceil( (currentTime-0.0) / getSamplingTimeControlLaw( ) ) * getSamplingTimeControlLaw( );
530  }
531 
532  if ( estimator != 0 )
533  {
534  if ( acadoIsInteger( (currentTime-0.0) / getSamplingTimeEstimator( ) ) == BT_TRUE )
535  nextEstimator = currentTime + getSamplingTimeEstimator( );
536  else
537  nextEstimator = ceil( (currentTime-0.0) / getSamplingTimeEstimator( ) ) * getSamplingTimeEstimator( );
538  }
539 
540  return acadoMin( nextControlLaw,nextEstimator );
541 }
542 
543 
544 
545 //
546 // PROTECTED MEMBER FUNCTIONS:
547 //
548 
549 
551 {
553 
554  return SUCCESSFUL_RETURN;
555 }
556 
557 
559 {
561 
566 
567  addLogRecord( tmp );
568 
569  return SUCCESSFUL_RETURN;
570 }
571 
572 
574  VariablesGrid& _yRef
575  ) const
576 {
577  double tEnd = tStart + controlLaw->getLengthPredictionHorizon( );
578 
579  // if no external reference trajectory is given, evaluate internal one
580  if ( _yRef.isEmpty( ) == BT_TRUE )
581  {
582  if ( referenceTrajectory != 0 )
583  referenceTrajectory->getReference( tStart,tEnd, _yRef );
584  }
585 
586  // if prediction shall not be used, only use first value
587  int useReferencePrediction = 0;
588  get( USE_REFERENCE_PREDICTION,useReferencePrediction );
589 
590  if ( (BooleanType)useReferencePrediction == BT_FALSE )
591  {
592  DVector firstVector = _yRef.getFirstVector( );
593  Grid predictionGrid( tStart,tEnd );
594  _yRef.init( firstVector,predictionGrid );
595  }
596 
597  return SUCCESSFUL_RETURN;
598 }
599 
600 
602 
603 // end of file.
virtual returnValue preparationStep(double nextTime=0.0, const VariablesGrid &_yRef=emptyConstVariablesGrid)
Definition: controller.cpp:474
Calculates the control inputs of the Process based on the Process outputs.
Definition: controller.hpp:71
returnValue print(std::ostream &stream=std::cout, const char *const name=DEFAULT_LABEL, const char *const startString=DEFAULT_START_STRING, const char *const endString=DEFAULT_END_STRING, uint width=DEFAULT_WIDTH, uint precision=DEFAULT_PRECISION, const char *const colSeparator=DEFAULT_COL_SEPARATOR, const char *const rowSeparator=DEFAULT_ROW_SEPARATOR) const
virtual ~Controller()
Definition: controller.cpp:141
returnValue addItem(LogName _name, const char *const _label=DEFAULT_LABEL)
Definition: log_record.cpp:70
uint getNW() const
Abstract base class to define a reference trajectory that the ControlLaw aims to track.
virtual returnValue setupLogging()
Definition: controller.cpp:558
uint getNU() const
Allows real time measurements based on the system's clock.
Definition: real_clock.hpp:53
returnValue setEstimator(Estimator &_estimator)
Definition: controller.cpp:209
BooleanType isEnabled
Definition: controller.hpp:428
const double INFTY
virtual uint getNX() const
virtual returnValue step(double currentTime, const DVector &_y)=0
virtual returnValue reset()
Definition: clock.cpp:86
virtual returnValue getCurrentReference(double tStart, VariablesGrid &_yRef) const
Definition: controller.cpp:573
returnValue setStatus(BlockStatus _status)
BooleanType isDefined() const
returnValue initializeAlgebraicStates(const VariablesGrid &_xa_init)
Definition: controller.cpp:246
virtual returnValue init(double startTime=0.0, const DVector &_x=emptyConstVector, const DVector &_xa=emptyConstVector, const DVector &_u=emptyConstVector, const DVector &_p=emptyConstVector, const DVector &_w=emptyConstVector)=0
Provides a time grid consisting of vector-valued optimization variables at each grid point...
int addLogRecord(LogRecord &record)
Definition: logging.cpp:58
Allows to pass back messages to the calling function.
BEGIN_NAMESPACE_ACADO typedef unsigned int uint
Definition: acado_types.hpp:42
ReferenceTrajectory * referenceTrajectory
Definition: controller.hpp:426
Allows to conveniently handle (one-dimensional) grids consisting of time points.
Definition: grid.hpp:58
BooleanType isEmpty() const
const int defaultUseReferencePrediction
virtual returnValue obtainEstimates(double currentTime, const DVector &_y, DVector &xEst, DVector &pEst)
Definition: controller.cpp:383
virtual returnValue feedbackStep(double currentTime, const DVector &_x, const DVector &_p=emptyConstVector, const VariablesGrid &_yRef=emptyConstVariablesGrid)
virtual returnValue init(double startTime=0.0, const DVector &x0_=emptyConstVector, const DVector &p_=emptyConstVector)
Definition: estimator.cpp:89
#define CLOSE_NAMESPACE_ACADO
virtual uint getNXA() const
returnValue getOutputs(DVector &_x, DVector &_xa, DVector &_u, DVector &_p, DVector &_w) const
virtual uint getNU() const
RealClock controlLawClock
Definition: controller.hpp:430
ControlLaw * controlLaw
Definition: controller.hpp:424
returnValue setLast(LogName _name, const DMatrix &value, double time=-INFTY)
BlockStatus getStatus() const
virtual returnValue step(double currentTime, const DVector &_y, const VariablesGrid &_yRef=emptyConstVariablesGrid)
Definition: controller.cpp:338
BooleanType isDefined() const
Controller & operator=(const Controller &rhs)
Definition: controller.cpp:154
returnValue setReferenceTrajectory(ReferenceTrajectory &_referenceTrajectory)
Definition: controller.cpp:227
double getSamplingTimeEstimator()
BEGIN_NAMESPACE_ACADO BooleanType acadoIsInteger(double x)
Definition: acado_utils.cpp:37
virtual returnValue initializeAlgebraicStates(const VariablesGrid &_xa_init)
Definition: control_law.cpp:83
virtual returnValue init(double startTime=0.0, const DVector &_x0=emptyConstVector, const DVector &_p=emptyConstVector, const VariablesGrid &_yRef=emptyConstVariablesGrid)
Definition: controller.cpp:270
DVector getFirstVector() const
virtual returnValue print(std::ostream &stream=std::cout, const std::string &name=DEFAULT_LABEL, const std::string &startString=DEFAULT_START_STRING, const std::string &endString=DEFAULT_END_STRING, uint width=DEFAULT_WIDTH, uint precision=DEFAULT_PRECISION, const std::string &colSeparator=DEFAULT_COL_SEPARATOR, const std::string &rowSeparator=DEFAULT_ROW_SEPARATOR) const
Definition: vector.cpp:97
Base class for interfacing online state/parameter estimators.
Definition: estimator.hpp:56
virtual returnValue preparationStep(double nextTime=0.0, const VariablesGrid &_yRef=emptyConstVariablesGrid)
returnValue init()
virtual uint getNP() const
void rhs(const real_t *x, real_t *f)
double getNextSamplingInstant(double currentTime)
Definition: controller.cpp:518
double getSamplingTime() const
double getSamplingTimeControlLaw()
virtual returnValue start()
Definition: real_clock.cpp:78
uint getNP() const
returnValue read(std::istream &stream)
int acadoMin(const int x, const int y)
Definition: acado_utils.cpp:76
#define BT_TRUE
Definition: acado_types.hpp:47
Base class for building-blocks of the SimulationEnvironment.
virtual returnValue stop()
Definition: real_clock.cpp:107
DVector getVector(uint pointIdx) const
uint getNXA() const
returnValue setControlLaw(ControlLaw &_controlLaw)
Definition: controller.cpp:192
Allows to setup and store user-specified log records of algorithmic information.
Definition: log_record.hpp:72
#define BEGIN_NAMESPACE_ACADO
uint getNX() const
#define BT_FALSE
Definition: acado_types.hpp:49
virtual uint getNW() const
virtual returnValue feedbackStep(double currentTime, const DVector &_y, const VariablesGrid &_yRef=emptyConstVariablesGrid)
Definition: controller.cpp:424
SimulationBlock & operator=(const SimulationBlock &rhs)
Estimator * estimator
Definition: controller.hpp:425
virtual returnValue setupOptions()
Definition: controller.cpp:550
returnValue getU(DVector &_u) const
virtual double getLengthPredictionHorizon() const
returnValue addOption(OptionsName name, int value)
Definition: options.cpp:301
virtual returnValue init(double startTime=0.0, const DVector &_x=emptyConstVector, const DVector &_p=emptyConstVector, const VariablesGrid &_yRef=emptyConstVariablesGrid)=0
virtual returnValue step(double _currentTime, const DVector &_y, const DVector &_x=emptyConstVector, const DVector &_xa=emptyConstVector, const DVector &_u=emptyConstVector, const DVector &_p=emptyConstVector, const DVector &_w=emptyConstVector)=0
Base class for interfacing online feedback laws to be used within a Controller.
Definition: control_law.hpp:64
virtual returnValue getReference(double tStart, double tEnd, VariablesGrid &_yRef) const =0
#define ACADOERROR(retval)
virtual returnValue getTime(double &_elapsedTime)
Definition: clock.cpp:92


acado
Author(s): Milan Vukov, Rien Quirynen
autogenerated on Mon Jun 10 2019 12:34:31