real_time_algorithm.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 
36 
37 
38 
39 // #define SIM_DEBUG
40 
41 
42 
44 
45 
46 //
47 // PUBLIC MEMBER FUNCTIONS:
48 //
49 
51 {
52  setupOptions( );
53  setupLogging( );
54 
55  x0 = 0;
56  p0 = 0;
57  reference = 0;
58 
61  set( MAX_NUM_ITERATIONS,1 );
64 
66 }
67 
68 
70  double _samplingTime
71  ) : OptimizationAlgorithmBase( ocp_ ), ControlLaw( _samplingTime )
72 {
73  setupOptions( );
74  setupLogging( );
75 
76  x0 = 0;
77  p0 = 0;
78  reference = 0;
79 
82  set( MAX_NUM_ITERATIONS,1 );
85 
87 }
88 
89 
90 
92 {
93  if( rhs.x0 != 0 ) x0 = new DVector(*rhs.x0);
94  else x0 = 0 ;
95 
96  if( rhs.p0 != 0 ) p0 = new DVector(*rhs.p0);
97  else p0 = 0 ;
98 
99  if( rhs.reference != 0 ) reference = new VariablesGrid(*rhs.reference);
100  else reference = 0 ;
101 }
102 
103 
105 {
106  clear( );
107 }
108 
109 
110 
112 
113  if( this != &rhs ){
114 
115  clear( );
116 
118  ControlLaw::operator=( rhs );
119 
120  if( rhs.x0 != 0 ) x0 = new DVector(*rhs.x0);
121  else x0 = 0 ;
122 
123  if( rhs.p0 != 0 ) p0 = new DVector(*rhs.p0);
124  else p0 = 0 ;
125 
126  if( rhs.reference != 0 ) reference = new VariablesGrid(*rhs.reference);
127  else reference = 0 ;
128  }
129  return *this;
130 }
131 
132 
134 {
135  return new RealTimeAlgorithm( *this );
136 }
137 
138 
139 
141  )
142 {
144 }
145 
146 
148  )
149 {
151 }
152 
153 
155  )
156 {
158 }
159 
160 
162  )
163 {
165 }
166 
167 
168 
170 {
171  if ( ( getStatus( ) == BS_READY ) && ( haveOptionsChanged( ) == BT_FALSE ) )
172  return SUCCESSFUL_RETURN;
173 
174  returnValue returnvalue = OptimizationAlgorithmBase::init( this );
175 
176  setStatus( BS_READY );
178 
179  return returnvalue;
180 }
181 
182 
184  const DVector& _x,
185  const DVector& _p,
186  const VariablesGrid& _yRef
187  )
188 {
189  /* 0) Consistency checks */
190  int useImmediateFeedback = 0;
191  get( USE_IMMEDIATE_FEEDBACK,useImmediateFeedback );
192 
193  int maxNumberOfSteps;
194  get( MAX_NUM_ITERATIONS, maxNumberOfSteps );
195 
196 // if ( ( (BooleanType)useImmediateFeedback == BT_TRUE ) && ( isInRealTimeMode( ) == BT_FALSE ) )
197 // return ACADOERROR( RET_NEED_TO_ACTIVATE_RTI );
198 
199  if ( ( (BooleanType)useImmediateFeedback == BT_TRUE ) && ( maxNumberOfSteps != 1 ) )
200  {
201  set( MAX_NUM_ITERATIONS,1 );
203  }
204 
205 
206  /* 1) Initialize reference trajectory and real-time parameters. */
207  clear( );
208 
209  if ( _yRef.isEmpty( ) == BT_FALSE )
210  reference = new VariablesGrid( _yRef );
211 
212  x0 = new DVector(_x);
213 
214  if ( _p.isEmpty( ) == BT_FALSE )
215  p0 = new DVector(_p);
216 
217 
218  /* 2) Initialize all sub-blocks. */
219  if ( init( ) != SUCCESSFUL_RETURN )
221 
223  u.setZero( );
224 
226  p.setZero( );
227 
228  setStatus( BS_READY );
229 
230  return SUCCESSFUL_RETURN;
231 }
232 
233 
234 
236  const DVector& _x,
237  const DVector& _p,
238  const VariablesGrid& _yRef
239  )
240 {
241  if ( feedbackStep( currentTime,_x,_p ) != SUCCESSFUL_RETURN )
243 
244  if ( preparationStep( currentTime+getSamplingTime(),_yRef ) != SUCCESSFUL_RETURN )
246 
247  return SUCCESSFUL_RETURN;
248 }
249 
250 
252  const DVector &_x,
253  const DVector &_p,
254  const VariablesGrid& _yRef
255  )
256 {
257  if ( getStatus( ) != BS_READY )
259 
260  if ( _x.getDim( ) != getNX() )
262 
263  if ( _p.getDim( ) > getNP() )
265 
267 
268 
269  if ( isInRealTimeMode( ) == BT_TRUE )
270  {
271  if ( ( x0 != 0 ) && ( _x.isEmpty() == BT_FALSE ) )
272  *x0 = _x;
273 
274  if ( ( p0 != 0 ) && ( _p.isEmpty() == BT_FALSE ) )
275  *p0 = _p;
276  }
277 
278 
279  if ( performFeedbackStep( currentTime,_x,_p ) != SUCCESSFUL_RETURN )
281 
282 
283  // if real-time mode is NOT enabled, perform usual step
284  // otherwise ignore current reference trajectory as it is
285  // expected to be set during previous call to preparationStep
286  if ( isInRealTimeMode( ) == BT_FALSE )
287  {
288  // solve at currentTime
289 // if ( solve( currentTime,_x,_p,_yRef ) != SUCCESSFUL_RETURN )
290 // return ACADOERROR( RET_CONTROLLAW_STEP_FAILED );
291  returnValue returnvalue;
292 
293  int maxNumberOfSteps;
294  get( MAX_NUM_ITERATIONS, maxNumberOfSteps );
295 
296  int terminateAtConvergence = 0;
297  get( TERMINATE_AT_CONVERGENCE,terminateAtConvergence );
298 
299  while( nlpSolver->getNumberOfSteps( ) < maxNumberOfSteps )
300  {
301  returnvalue = performPreparationStep( _yRef,BT_FALSE );
302 
303  if ( ( returnvalue != CONVERGENCE_ACHIEVED ) && ( returnvalue != CONVERGENCE_NOT_YET_ACHIEVED ) )
305 
306  if ( ((BooleanType)terminateAtConvergence == BT_TRUE ) && ( returnvalue == CONVERGENCE_ACHIEVED ) )
307  break;
308 
309  if ( performFeedbackStep( currentTime,_x,_p ) != SUCCESSFUL_RETURN )
311  }
312  }
313 
314  return SUCCESSFUL_RETURN;
315 }
316 
317 
319  const VariablesGrid& _yRef
320  )
321 {
322  returnValue returnvalue = performPreparationStep( _yRef,BT_TRUE );
323  if ( ( returnvalue != CONVERGENCE_ACHIEVED ) && ( returnvalue != CONVERGENCE_NOT_YET_ACHIEVED ) )
325 
326  return SUCCESSFUL_RETURN;
327 }
328 
329 
330 
332  const DVector &_x,
333  const DVector &_p,
334  const VariablesGrid& _yRef
335  )
336 {
337  if ( getStatus( ) == BS_NOT_INITIALIZED )
338  {
339  if ( init( startTime,_x ) != SUCCESSFUL_RETURN )
341  }
342 
343  if ( getStatus( ) != BS_READY )
345 
346  returnValue returnvalue;
348 
349  int maxNumberOfSteps;
350  get( MAX_NUM_ITERATIONS, maxNumberOfSteps );
351 
352  int terminateAtConvergence = 0;
353  get( TERMINATE_AT_CONVERGENCE,terminateAtConvergence );
354 
355  while( nlpSolver->getNumberOfSteps( ) < maxNumberOfSteps )
356  {
357  if ( performFeedbackStep( startTime,_x,_p ) != SUCCESSFUL_RETURN )
359 
360  if ( nlpSolver->getNumberOfSteps( ) == maxNumberOfSteps )
361  returnvalue = performPreparationStep( _yRef,BT_TRUE );
362  else
363  returnvalue = performPreparationStep( _yRef,BT_FALSE );
364 
365  if ( ( returnvalue != CONVERGENCE_ACHIEVED ) && ( returnvalue != CONVERGENCE_NOT_YET_ACHIEVED ) )
367 
368  if ( ((BooleanType)terminateAtConvergence == BT_TRUE ) && ( returnvalue == CONVERGENCE_ACHIEVED ) )
369  break;
370  }
371 
372  replot( PLOT_AT_END );
373 
374  return SUCCESSFUL_RETURN;
375 }
376 
377 
378 
380  )
381 {
382  if ( acadoIsNegative( timeShift ) == BT_TRUE )
383  timeShift = getSamplingTime( );
384 
385 // printf( "shift!\n" );
386 
387  return nlpSolver->shiftVariables( timeShift );
388 }
389 
390 
392 {
393  if ( ( getStatus() != BS_READY ) && ( getStatus() != BS_RUNNING ) )
395 
396 // printf( "new ref!\n" );
397 // ref.print();
398  return nlpSolver->setReference( ref );
399 }
400 
401 
402 
404 {
406 }
407 
409 {
411 }
412 
414 {
416 }
417 
419 {
421 }
422 
424 {
426 }
427 
428 
430 {
432 }
433 
434 
435 
437 {
438  return getEndTime( ) - getStartTime( );
439 }
440 
441 
443 {
444  return getLengthPredictionHorizon( );
445 }
446 
447 
448 
450 {
451  return BT_TRUE;
452 }
453 
454 
456 {
457  if ( isDynamic() == BT_TRUE )
458  return BT_FALSE;
459  else
460  return BT_TRUE;
461 }
462 
463 
465 {
466  int maxNumIterations;
467  get( MAX_NUM_ITERATIONS,maxNumIterations );
468 
469  if ( maxNumIterations > 1 )
470  return BT_FALSE;
471 
472  int useRealtimeIterations;
473  get( USE_REALTIME_ITERATIONS,useRealtimeIterations );
474 
475  return (BooleanType)useRealtimeIterations;
476 }
477 
478 
479 
480 //
481 // PROTECTED MEMBER FUNCTIONS:
482 //
483 
485 {
486  // add NLP solver options
513 
514  // add integration options
519 
520  // add integrator options
534 
535  return SUCCESSFUL_RETURN;
536 }
537 
538 
540 {
541 // LogRecord tmp( LOG_AT_EACH_ITERATION,stdout,PS_DEFAULT,BT_FALSE );
542 //
543 // tmp.addItem( LOG_NUM_NLP_ITERATIONS );
544 //
545 // addLogRecord( tmp );
546 
547  return SUCCESSFUL_RETURN;
548 }
549 
550 
552 {
553  if( x0 != 0 )
554  {
555  delete x0;
556  x0 = 0;
557  }
558 
559  if( p0 != 0 )
560  {
561  delete p0;
562  p0 = 0;
563  }
564 
565  if( reference != 0 )
566  {
567  delete reference;
568  reference = 0;
569  }
570 
571  return SUCCESSFUL_RETURN;
572 }
573 
574 
575 
577 {
578  if( nlpSolver != 0 )
579  delete nlpSolver;
580 
581  nlpSolver = new SCPmethod( this, F,G,H, isLinearQuadratic( F,G,H ) );
582 
583  return SUCCESSFUL_RETURN;
584 }
585 
586 
588  )
589 {
590  returnValue returnvalue = SUCCESSFUL_RETURN;
591 
592  if( x0 != 0 ) returnvalue = _userInit.x->setVector( 0,x0[0] );
593  if( p0 != 0 ) returnvalue = _userInit.p->setAllVectors( p0[0] );
594 
595  if( returnvalue != SUCCESSFUL_RETURN )
596  return ACADOERROR(returnvalue);
597 
598  ACADO_TRY( nlpSolver->init( _userInit.x, _userInit.xa, _userInit.p, _userInit.u, _userInit.w ) );
599  return SUCCESSFUL_RETURN;
600 }
601 
602 
604 {
605  returnValue returnvalue = SUCCESSFUL_RETURN;
606 
607  if ( ( reference != 0 ) && ( F != 0 ) )
608  {
609 // reference->print( "refer init" );
610  returnvalue = F->setReference( *reference );
611  }
612 
613  return returnvalue;
614 }
615 
616 
617 
619  const DVector &_x,
620  const DVector &_p
621  )
622 {
623  if ( getStatus( ) == BS_NOT_INITIALIZED )
624  {
625  if ( init( currentTime,_x ) != SUCCESSFUL_RETURN )
627  }
628 
629  if ( getStatus( ) != BS_READY )
631 
632 
633  if ( nlpSolver->feedbackStep( _x ) != SUCCESSFUL_RETURN ) //,_p
635 
636 // #ifdef SIM_DEBUG
639 // u.print("u after feedbackStep");
640 // #endif
641 
643 
644  return SUCCESSFUL_RETURN;
645 }
646 
647 
649  BooleanType isLastIteration
650  )
651 {
652 // _yRef.print( "yRef" );
653 
654  if ( getStatus( ) != BS_RUNNING )
656 
657  int useRealTimeShifts = 0;
658  get( USE_REALTIME_SHIFTS,useRealTimeShifts );
659 
660  // perform current step and check for convergence if desired
661  returnValue returnvalueStep = nlpSolver->performCurrentStep( );
662 
663  if ( ( returnvalueStep != CONVERGENCE_ACHIEVED ) && ( returnvalueStep != CONVERGENCE_NOT_YET_ACHIEVED ) )
664  return ACADOERROR( returnvalueStep );
665 
666  if ( isLastIteration == BT_TRUE )
667  {
668  if ( _yRef.isEmpty() == BT_FALSE )
669  setReference( _yRef );
670 
671  if ( (BooleanType)useRealTimeShifts == BT_TRUE )
672  shift( );
673  }
674 
675  // prepare next step
676  int terminateAtConvergence = 0;
677  get( TERMINATE_AT_CONVERGENCE,terminateAtConvergence );
678 
679  if ( ((BooleanType)terminateAtConvergence == BT_TRUE ) && ( returnvalueStep == CONVERGENCE_ACHIEVED ) )
680  {
681  if ( _yRef.isEmpty() == BT_FALSE )
682  setReference( _yRef );
683 
684  if ( (BooleanType)useRealTimeShifts == BT_TRUE )
685  shift( );
686  }
687 
688  returnValue returnvalue = nlpSolver->prepareNextStep( );
689  if ( ( returnvalue != CONVERGENCE_ACHIEVED ) && ( returnvalue != CONVERGENCE_NOT_YET_ACHIEVED ) )
690  return ACADOERROR( returnvalue );
691 
692  if ( ((BooleanType)terminateAtConvergence == BT_TRUE ) && ( returnvalueStep == CONVERGENCE_ACHIEVED ) )
693  returnvalue = CONVERGENCE_ACHIEVED;
694 
695  setStatus( BS_READY );
696 
697  return returnvalue;
698 }
699 
700 
701 
703 
704 // end of file.
BooleanType haveOptionsChanged() const
Definition: options.cpp:251
const int defaultDiscretizationType
returnValue setReference(const VariablesGrid &ref)
virtual returnValue preparationStep(double nextTime=0.0, const VariablesGrid &_yRef=emptyConstVariablesGrid)
virtual returnValue initializeObjective(Objective *F)
const int defaultPrintlevel
Data class for storing generic optimization variables.
Definition: ocp_iterate.hpp:57
virtual returnValue replot(PlotFrequency _frequency=PLOT_IN_ANY_CASE)
ControlLaw & operator=(const ControlLaw &rhs)
Definition: control_law.cpp:68
OptimizationAlgorithmBase & operator=(const OptimizationAlgorithmBase &arg)
const int defaultFeasibilityCheck
const double defaultKKTtoleranceSafeguard
virtual returnValue feedbackStep(double currentTime, const DVector &_x, const DVector &_p=emptyConstVector, const VariablesGrid &_yRef=emptyConstVariablesGrid)
VariablesGrid * x
const double defaultRelaxationParameter
returnValue performPreparationStep(const VariablesGrid &_yRef=emptyConstVariablesGrid, BooleanType isLastIteration=BT_TRUE)
const double defaultMaxStepsize
virtual returnValue feedbackStep(const DVector &x0_, const DVector &p_=emptyConstVector)
Definition: nlp_solver.cpp:89
virtual returnValue performCurrentStep()
Definition: nlp_solver.cpp:95
returnValue initializeControls(const char *fileName)
VariablesGrid * u
virtual returnValue setupLogging()
returnValue setStatus(BlockStatus _status)
BooleanType acadoIsNegative(double x, double TOL)
const int defaultObjectiveSensitivity
virtual uint getNP() const
void init(unsigned _dim=0)
Definition: vector.hpp:155
const int defaultFreezeIntegrator
Stores and evaluates the constraints of optimal control problems.
Definition: constraint.hpp:60
virtual returnValue initializeNlpSolver(const OCPiterate &userInit)
Provides a time grid consisting of vector-valued optimization variables at each grid point...
Allows to pass back messages to the calling function.
virtual returnValue prepareNextStep()
Definition: nlp_solver.cpp:101
virtual returnValue setReference(const VariablesGrid &ref)
Definition: nlp_solver.cpp:125
RealTimeAlgorithm & operator=(const RealTimeAlgorithm &rhs)
const double defaultStepsizeTuning
BEGIN_NAMESPACE_ACADO typedef unsigned int uint
Definition: acado_types.hpp:42
const double defaultMinStepsize
BooleanType isEmpty() const
User-interface to formulate and solve model predictive control problems.
const int defaultMaxNumSteps
const int defaultDynamicSensitivity
virtual returnValue init(VariablesGrid *xd, VariablesGrid *xa, VariablesGrid *p, VariablesGrid *u, VariablesGrid *w)=0
virtual returnValue allocateNlpSolver(Objective *F, DynamicDiscretization *G, Constraint *H)
const double defaultMinLinesearchParameter
#define CLOSE_NAMESPACE_ACADO
virtual uint getNY() const
virtual returnValue setupOptions()
bool isEmpty() const
Definition: vector.hpp:176
const int defaultHotstartQP
Base class for user-interfaces to formulate and solve optimal control problems and static NLPs...
Base class for discretizing a DifferentialEquation for use in optimal control algorithms.
const double defaultIntegratorTolerance
returnValue performFeedbackStep(double currentTime, const DVector &_x, const DVector &_p=emptyConstVector)
VariablesGrid * xa
const int defaultIntegratorPrintlevel
virtual BooleanType isDynamic() const
#define ACADO_TRY(X)
BlockStatus getStatus() const
const int defaultTerminateAtConvergence
virtual returnValue shiftVariables(double timeShift, DVector lastX=emptyVector, DVector lastXA=emptyVector, DVector lastP=emptyVector, DVector lastU=emptyVector, DVector lastW=emptyVector)
Definition: nlp_solver.cpp:114
const int defaultHessianApproximation
virtual uint getNX() const
returnValue setVector(uint pointIdx, const DVector &_values)
virtual returnValue setReference(const VariablesGrid &ref)
unsigned getDim() const
Definition: vector.hpp:172
BooleanType isLinearQuadratic(Objective *F, DynamicDiscretization *G, Constraint *H) const
virtual double getLengthPredictionHorizon() const
virtual ControlLaw * clone() const
virtual returnValue shift(double timeShift=-1.0)
virtual BooleanType isStatic() const
virtual uint getNU() const
const double defaultHessianProjectionFactor
returnValue setAllVectors(const DVector &_values)
const double defaultCorrectorTolerance
int getNumberOfSteps() const
const double defaultInfeasibleQPrelaxation
virtual double getLengthControlHorizon() const
Derived & setZero(Index size)
const double defaultLinesearchTolerance
Data class for defining optimal control problems.
Definition: ocp.hpp:89
void rhs(const real_t *x, real_t *f)
Implements different sequential convex programming methods for solving NLPs.
Definition: scp_method.hpp:67
double getSamplingTime() const
returnValue declareOptionsUnchanged()
Definition: options.cpp:276
const double defaultInitialStepsize
const int defaultprintSCPmethodProfile
const int defaultprintIntegratorProfile
const int defaultDynamicHessianApproximation
returnValue initializeAlgebraicStates(const char *fileName, BooleanType autoinit=BT_FALSE)
virtual uint getNXA() const
virtual returnValue step(double currentTime, const DVector &_x, const DVector &_p=emptyConstVector, const VariablesGrid &_yRef=emptyConstVariablesGrid)
const double defaultLevenbergMarguardt
VariablesGrid * p
#define BT_TRUE
Definition: acado_types.hpp:47
virtual returnValue solve(double startTime, const DVector &_x, const DVector &_p=emptyConstVector, const VariablesGrid &_yRef=emptyConstVariablesGrid)
const int defaultGlobalizationStrategy
returnValue resetNumberOfSteps()
const int defaultAlgebraicRelaxation
virtual BooleanType isInRealTimeMode() const
GenericVector< double > DVector
Definition: vector.hpp:329
virtual uint getNW() const
VariablesGrid * reference
const int defaultConstraintSensitivity
#define ACADOWARNING(retval)
VariablesGrid * w
virtual returnValue getFirstControl(DVector &u0_) const
Definition: nlp_solver.cpp:160
#define BEGIN_NAMESPACE_ACADO
const int defaultSparseQPsolution
#define BT_FALSE
Definition: acado_types.hpp:49
const int defaultPlotResoltion
const int defaultLinearAlgebraSolver
const int defaultIntegratorType
virtual returnValue initializeControls(const VariablesGrid &_u_init)
const int defaultUseImmediateFeedback
const double defaultKKTtolerance
returnValue init(UserInteraction *_userIteraction)
returnValue addOption(OptionsName name, int value)
Definition: options.cpp:301
const int defaultPrintCopyright
virtual returnValue initializeAlgebraicStates(const VariablesGrid &_xa_init)
const int defaultUseRealtimeIterations
BEGIN_NAMESPACE_ACADO const int defaultMaxNumIterations
virtual returnValue init()
Base class for interfacing online feedback laws to be used within a Controller.
Definition: control_law.hpp:64
const int defaultUseRealtimeShifts
const double defaultAbsoluteTolerance
const int defaultInfeasibleQPhandling
Stores and evaluates the objective function of optimal control problems.
Definition: objective.hpp:123
const int defaultMaxNumQPiterations
#define ACADOERROR(retval)


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