00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00033 #include <acado/controller/controller.hpp>
00034
00035
00036
00037
00038
00039 BEGIN_NAMESPACE_ACADO
00040
00041
00042
00043
00044
00045 Controller::Controller( ) : SimulationBlock( BN_CONTROLLER )
00046 {
00047 setupOptions( );
00048 setupLogging( );
00049
00050 controlLaw = 0;
00051 estimator = 0;
00052 referenceTrajectory = 0;
00053
00054 isEnabled = BT_TRUE;
00055
00056 setStatus( BS_NOT_INITIALIZED );
00057 }
00058
00059
00060 Controller::Controller( ControlLaw& _controlLaw,
00061 Estimator& _estimator,
00062 ReferenceTrajectory& _referenceTrajectory
00063 ) : SimulationBlock( BN_CONTROLLER )
00064 {
00065 setupOptions( );
00066 setupLogging( );
00067
00068 if ( _controlLaw.isDefined( ) == BT_TRUE )
00069 {
00070 controlLaw = &_controlLaw;
00071 setStatus( BS_NOT_INITIALIZED );
00072 }
00073 else
00074 controlLaw = 0;
00075
00076 if ( _estimator.isDefined( ) == BT_TRUE )
00077 estimator = &_estimator;
00078 else
00079 estimator = 0;
00080
00081 if ( _referenceTrajectory.isDefined( ) == BT_TRUE )
00082 referenceTrajectory = &_referenceTrajectory;
00083 else
00084 referenceTrajectory = 0;
00085
00086 isEnabled = BT_TRUE;
00087
00088 setStatus( BS_NOT_INITIALIZED );
00089 }
00090
00091
00092 Controller::Controller( ControlLaw& _controlLaw,
00093 ReferenceTrajectory& _referenceTrajectory
00094 ) : SimulationBlock( BN_CONTROLLER )
00095 {
00096 setupOptions( );
00097 setupLogging( );
00098
00099 if ( _controlLaw.isDefined( ) == BT_TRUE )
00100 {
00101 controlLaw = &_controlLaw;
00102 setStatus( BS_NOT_INITIALIZED );
00103 }
00104 else
00105 controlLaw = 0;
00106
00107 estimator = 0;
00108
00109 if ( _referenceTrajectory.isDefined( ) == BT_TRUE )
00110 referenceTrajectory = &_referenceTrajectory;
00111 else
00112 referenceTrajectory = 0;
00113
00114 isEnabled = BT_TRUE;
00115
00116 setStatus( BS_NOT_INITIALIZED );
00117 }
00118
00119
00120 Controller::Controller( const Controller& rhs ) : SimulationBlock( rhs )
00121 {
00122 if ( rhs.controlLaw != 0 )
00123 controlLaw = rhs.controlLaw;
00124 else
00125 controlLaw = 0;
00126
00127 if ( rhs.estimator != 0 )
00128 estimator = rhs.estimator;
00129 else
00130 estimator = 0;
00131
00132 if ( rhs.referenceTrajectory != 0 )
00133 referenceTrajectory = rhs.referenceTrajectory;
00134 else
00135 referenceTrajectory = 0;
00136
00137 isEnabled = rhs.isEnabled;
00138 }
00139
00140
00141 Controller::~Controller( )
00142 {
00143
00144
00145
00146
00147
00148
00149
00150
00151 }
00152
00153
00154 Controller& Controller::operator=( const Controller& rhs )
00155 {
00156 if ( this != &rhs )
00157 {
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 SimulationBlock::operator=( rhs );
00168
00169 if ( rhs.controlLaw != 0 )
00170 controlLaw = rhs.controlLaw;
00171 else
00172 controlLaw = 0;
00173
00174 if ( rhs.estimator != 0 )
00175 estimator = rhs.estimator;
00176 else
00177 estimator = 0;
00178
00179 if ( rhs.referenceTrajectory != 0 )
00180 referenceTrajectory = rhs.referenceTrajectory;
00181 else
00182 referenceTrajectory = 0;
00183
00184 isEnabled = rhs.isEnabled;
00185 }
00186
00187 return *this;
00188 }
00189
00190
00191
00192 returnValue Controller::setControlLaw( ControlLaw& _controlLaw
00193 )
00194 {
00195 if ( _controlLaw.isDefined( ) == BT_TRUE )
00196 {
00197 if ( controlLaw == 0 )
00198 controlLaw = &_controlLaw;
00199 else
00200 *controlLaw = _controlLaw;
00201
00202 setStatus( BS_NOT_INITIALIZED );
00203 }
00204
00205 return SUCCESSFUL_RETURN;
00206 }
00207
00208
00209 returnValue Controller::setEstimator( Estimator& _estimator
00210 )
00211 {
00212 if ( _estimator.isDefined( ) == BT_TRUE )
00213 {
00214 if ( estimator == 0 )
00215 estimator = &_estimator;
00216 else
00217 *estimator = _estimator;
00218
00219 if ( getStatus( ) > BS_NOT_INITIALIZED )
00220 setStatus( BS_NOT_INITIALIZED );
00221 }
00222
00223 return SUCCESSFUL_RETURN;
00224 }
00225
00226
00227 returnValue Controller::setReferenceTrajectory( ReferenceTrajectory& _referenceTrajectory
00228 )
00229 {
00230 if ( _referenceTrajectory.isDefined( ) == BT_TRUE )
00231 {
00232 if ( referenceTrajectory == 0 )
00233 referenceTrajectory = &_referenceTrajectory;
00234 else
00235 *referenceTrajectory = _referenceTrajectory;
00236
00237 if ( getStatus( ) > BS_NOT_INITIALIZED )
00238 setStatus( BS_NOT_INITIALIZED );
00239 }
00240
00241 return SUCCESSFUL_RETURN;
00242 }
00243
00244
00245
00246 returnValue Controller::initializeAlgebraicStates( const VariablesGrid& _xa_init
00247 )
00248 {
00249 if ( controlLaw != 0 )
00250 controlLaw->initializeAlgebraicStates( _xa_init.getVector(0) );
00251
00252 return SUCCESSFUL_RETURN;
00253 }
00254
00255
00256 returnValue Controller::initializeAlgebraicStates( const char* fileName
00257 )
00258 {
00259 VariablesGrid tmp;
00260 tmp.read( fileName );
00261
00262 if ( tmp.isEmpty( ) == BT_TRUE )
00263 return ACADOERROR( RET_FILE_CAN_NOT_BE_OPENED );
00264
00265 return initializeAlgebraicStates( tmp );
00266 }
00267
00268
00269
00270 returnValue Controller::init( double startTime,
00271 const DVector& _x0,
00272 const DVector& _p,
00273 const VariablesGrid& _yRef
00274 )
00275 {
00276 if ( controlLaw == 0 )
00277 return ACADOERROR( RET_NO_CONTROLLAW_SPECIFIED );
00278
00279
00280
00281 DVector xEst( _x0 );
00282 DVector pEst( _p );
00283 DVector xaEst, uEst, wEst;
00284
00285 if ( estimator != 0 )
00286 {
00287 if ( estimator->init( startTime,_x0,_p ) != SUCCESSFUL_RETURN )
00288 return ACADOERROR( RET_CONTROLLER_INIT_FAILED );
00289
00290 if ( estimator->getOutputs( xEst,xaEst,uEst,pEst,wEst ) != SUCCESSFUL_RETURN )
00291 return ACADOERROR( RET_CONTROLLER_INIT_FAILED );
00292 }
00293
00294
00295 if ( ( referenceTrajectory != 0 ) && ( _yRef.isEmpty( ) == BT_TRUE ) )
00296 if ( referenceTrajectory->init( startTime,xEst,xaEst,uEst,pEst,wEst ) != SUCCESSFUL_RETURN )
00297 return ACADOERROR( RET_CONTROLLER_INIT_FAILED );
00298
00299 VariablesGrid yRef( _yRef );
00300 getCurrentReference( startTime,yRef );
00301 #ifdef SIM_DEBUG
00302 yRef.print( "yRef init" );
00303 #endif
00304
00305
00306
00307 if ( controlLaw->init( startTime,_x0,_p,yRef ) != SUCCESSFUL_RETURN )
00308 return ACADOERROR( RET_CONTROLLER_INIT_FAILED );
00309
00310
00311
00312 if ( estimator != 0 )
00313 {
00314 if ( estimator->getNX( ) != controlLaw->getNX( ) )
00315 return ACADOERROR( RET_BLOCK_DIMENSION_MISMATCH );
00316
00317 if ( estimator->getNXA( ) != controlLaw->getNXA( ) )
00318 return ACADOERROR( RET_BLOCK_DIMENSION_MISMATCH );
00319
00320 if ( estimator->getNU( ) != controlLaw->getNU( ) )
00321 return ACADOERROR( RET_BLOCK_DIMENSION_MISMATCH );
00322
00323 if ( estimator->getNP( ) != controlLaw->getNP( ) )
00324 return ACADOERROR( RET_BLOCK_DIMENSION_MISMATCH );
00325
00326 if ( estimator->getNW( ) != controlLaw->getNW( ) )
00327 return ACADOERROR( RET_BLOCK_DIMENSION_MISMATCH );
00328 }
00329
00330 realClock.reset( );
00331 setStatus( BS_READY );
00332
00333 return SUCCESSFUL_RETURN;
00334 }
00335
00336
00337
00338 returnValue Controller::step( double currentTime,
00339 const DVector& _y,
00340 const VariablesGrid& _yRef
00341 )
00342 {
00343
00344 if ( getStatus( ) != BS_READY )
00345 return ACADOERROR( RET_BLOCK_NOT_READY );
00346
00347 if ( controlLaw == 0 )
00348 return ACADOERROR( RET_NO_CONTROLLAW_SPECIFIED );
00349
00350
00351 if ( isEnabled == BT_FALSE )
00352 {
00353 setLast( LOG_TIME_CONTROLLER,0.0 );
00354 setLast( LOG_TIME_CONTROL_LAW,0.0 );
00355 setLast( LOG_TIME_ESTIMATOR,0.0 );
00356 return SUCCESSFUL_RETURN;
00357 }
00358
00359 if ( feedbackStep( currentTime,_y,_yRef ) != SUCCESSFUL_RETURN )
00360 return ACADOERROR( RET_CONTROLLER_STEP_FAILED );
00361
00362 double nextTime = currentTime + controlLaw->getSamplingTime( );
00363
00364 if ( preparationStep( nextTime,_yRef ) != SUCCESSFUL_RETURN )
00365 return ACADOERROR( RET_CONTROLLER_STEP_FAILED );
00366
00367 return SUCCESSFUL_RETURN;
00368 }
00369
00370
00371 returnValue Controller::step( double currentTime,
00372 uint dim,
00373 const double* const _y,
00374 const VariablesGrid& _yRef
00375 )
00376 {
00377
00378 DVector tmp( dim,_y );
00379 return step( currentTime,tmp,_yRef );
00380 }
00381
00382
00383 returnValue Controller::obtainEstimates( double currentTime,
00384 const DVector& _y,
00385 DVector& xEst,
00386 DVector& pEst
00387 )
00388 {
00389
00390 RealClock clock;
00391 DVector xaEst, uEst, wEst;
00392
00393 clock.reset();
00394 clock.start();
00395
00396 if ( estimator != 0 )
00397 {
00398 if ( estimator->step( currentTime,_y ) != SUCCESSFUL_RETURN )
00399 return ACADOERROR( RET_CONTROLLER_STEP_FAILED );
00400
00401 if ( estimator->getOutputs( xEst,xaEst,uEst,pEst,wEst ) != SUCCESSFUL_RETURN )
00402 return ACADOERROR( RET_CONTROLLER_STEP_FAILED );
00403 }
00404 else
00405 {
00406
00407 xEst = _y;
00408 }
00409
00410 clock.stop();
00411 setLast(LOG_TIME_ESTIMATOR, clock.getTime());
00412
00413
00414 if ( referenceTrajectory != 0 )
00415 {
00416 if ( referenceTrajectory->step( currentTime,_y,xEst,xaEst,uEst,pEst,wEst ) != SUCCESSFUL_RETURN )
00417 return ACADOERROR( RET_CONTROLLER_STEP_FAILED );
00418 }
00419
00420 return SUCCESSFUL_RETURN;
00421 }
00422
00423
00424 returnValue Controller::feedbackStep( double currentTime,
00425 const DVector& _y,
00426 const VariablesGrid& _yRef
00427 )
00428 {
00429 realClock.reset( );
00430
00431 if ( controlLaw == 0 )
00432 return ACADOERROR( RET_NO_CONTROLLAW_SPECIFIED );
00433
00434
00435 if ( isEnabled == BT_FALSE )
00436 return SUCCESSFUL_RETURN;
00437
00438
00439 realClock.start( );
00440
00441 DVector xEst, pEst;
00442
00443
00444 if ( obtainEstimates( currentTime,_y,xEst,pEst ) != SUCCESSFUL_RETURN )
00445 return ACADOERROR( RET_CONTROLLER_STEP_FAILED );
00446
00447
00448 VariablesGrid yRef( _yRef );
00449 getCurrentReference( currentTime,yRef );
00450 #ifdef SIM_DEBUG
00451 yRef.print( "yRef feedback" );
00452 #endif
00453
00454 controlLawClock.reset();
00455 controlLawClock.start();
00456
00457
00458 if ( controlLaw->feedbackStep( currentTime,xEst,pEst,yRef ) != SUCCESSFUL_RETURN )
00459 return ACADOERROR( RET_CONTROLLER_STEP_FAILED );
00460
00461 controlLawClock.stop();
00462 realClock.stop( );
00463
00464 #ifdef SIM_DEBUG
00465 DVector uTmp;
00466 getU( uTmp );
00467 uTmp.print("u(0) after feedbackStep");
00468 #endif
00469
00470 return SUCCESSFUL_RETURN;
00471 }
00472
00473
00474 returnValue Controller::preparationStep( double nextTime,
00475 const VariablesGrid& _yRef
00476 )
00477 {
00478 if ( controlLaw == 0 )
00479 return ACADOERROR( RET_NO_CONTROLLAW_SPECIFIED );
00480
00481
00482 if ( isEnabled == BT_FALSE )
00483 return SUCCESSFUL_RETURN;
00484
00485 realClock.start();
00486 controlLawClock.start();
00487
00488
00489 VariablesGrid yRef( _yRef );
00490 getCurrentReference( nextTime,yRef );
00491 #ifdef SIM_DEBUG
00492 yRef.print( "yRef preparation" );
00493 #endif
00494
00495
00496 if ( controlLaw->preparationStep( nextTime,yRef ) != SUCCESSFUL_RETURN )
00497 return ACADOERROR( RET_CONTROLLER_STEP_FAILED );
00498
00499 controlLawClock.stop();
00500 setLast(LOG_TIME_CONTROL_LAW, controlLawClock.getTime());
00501
00502
00503 realClock.stop();
00504 setLast(LOG_TIME_CONTROLLER, realClock.getTime());
00505
00506
00507 #ifdef SIM_DEBUG
00508 DVector uTmp;
00509 getU( uTmp );
00510 uTmp.print("u(0) after preparationStep");
00511 #endif
00512
00513 return SUCCESSFUL_RETURN;
00514 }
00515
00516
00517
00518 double Controller::getNextSamplingInstant( double currentTime
00519 )
00520 {
00521 double nextControlLaw = INFTY;
00522 double nextEstimator = INFTY;
00523
00524 if ( controlLaw != 0 )
00525 {
00526 if ( acadoIsInteger( (currentTime-0.0) / getSamplingTimeControlLaw( ) ) == BT_TRUE )
00527 nextControlLaw = currentTime + getSamplingTimeControlLaw( );
00528 else
00529 nextControlLaw = ceil( (currentTime-0.0) / getSamplingTimeControlLaw( ) ) * getSamplingTimeControlLaw( );
00530 }
00531
00532 if ( estimator != 0 )
00533 {
00534 if ( acadoIsInteger( (currentTime-0.0) / getSamplingTimeEstimator( ) ) == BT_TRUE )
00535 nextEstimator = currentTime + getSamplingTimeEstimator( );
00536 else
00537 nextEstimator = ceil( (currentTime-0.0) / getSamplingTimeEstimator( ) ) * getSamplingTimeEstimator( );
00538 }
00539
00540 return acadoMin( nextControlLaw,nextEstimator );
00541 }
00542
00543
00544
00545
00546
00547
00548
00549
00550 returnValue Controller::setupOptions( )
00551 {
00552 addOption( USE_REFERENCE_PREDICTION,defaultUseReferencePrediction );
00553
00554 return SUCCESSFUL_RETURN;
00555 }
00556
00557
00558 returnValue Controller::setupLogging( )
00559 {
00560 LogRecord tmp(LOG_AT_EACH_ITERATION, PS_DEFAULT);
00561
00562 tmp.addItem( LOG_FEEDBACK_CONTROL );
00563 tmp.addItem( LOG_TIME_CONTROLLER );
00564 tmp.addItem( LOG_TIME_ESTIMATOR );
00565 tmp.addItem( LOG_TIME_CONTROL_LAW );
00566
00567 addLogRecord( tmp );
00568
00569 return SUCCESSFUL_RETURN;
00570 }
00571
00572
00573 returnValue Controller::getCurrentReference( double tStart,
00574 VariablesGrid& _yRef
00575 ) const
00576 {
00577 double tEnd = tStart + controlLaw->getLengthPredictionHorizon( );
00578
00579
00580 if ( _yRef.isEmpty( ) == BT_TRUE )
00581 {
00582 if ( referenceTrajectory != 0 )
00583 referenceTrajectory->getReference( tStart,tEnd, _yRef );
00584 }
00585
00586
00587 int useReferencePrediction = 0;
00588 get( USE_REFERENCE_PREDICTION,useReferencePrediction );
00589
00590 if ( (BooleanType)useReferencePrediction == BT_FALSE )
00591 {
00592 DVector firstVector = _yRef.getFirstVector( );
00593 Grid predictionGrid( tStart,tEnd );
00594 _yRef.init( firstVector,predictionGrid );
00595 }
00596
00597 return SUCCESSFUL_RETURN;
00598 }
00599
00600
00601 CLOSE_NAMESPACE_ACADO
00602
00603