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/ocp/model_data.hpp>
00034
00035
00036 BEGIN_NAMESPACE_ACADO
00037
00038
00039
00040
00041
00042
00043
00044 ModelData::ModelData() {
00045
00046 NX1 = 0;
00047 NX2 = 0;
00048 NX3 = 0;
00049 NDX = 0;
00050 NDX3 = 0;
00051 NXA = 0;
00052 NXA3 = 0;
00053 NU = 0;
00054 NP = 0;
00055 N = 0;
00056 NOD = 0;
00057 model_dimensions_set = BT_FALSE;
00058 export_rhs = BT_TRUE;
00059 delay = 1;
00060 }
00061
00062
00063 returnValue ModelData::setDimensions( uint _NX1, uint _NX2, uint _NX3, uint _NDX, uint _NDX3, uint _NXA, uint _NXA3, uint _NU, uint _NOD, uint _NP )
00064 {
00065 NX1 = _NX1;
00066 NX2 = _NX2;
00067 NX3 = _NX3;
00068 NDX = _NDX;
00069 NDX3 = _NDX3;
00070 NXA = _NXA;
00071 NXA3 = _NXA3;
00072 NU = _NU;
00073 NP = _NP;
00074 NOD = _NOD;
00075 model_dimensions_set = BT_TRUE;
00076 return SUCCESSFUL_RETURN;
00077 }
00078
00079
00080 uint ModelData::addOutput( const OutputFcn& outputEquation_, const Grid& grid ){
00081
00082 if( rhs_name.empty() && outputNames.size() == 0 ) {
00083 Expression next;
00084 outputEquation_.getExpression( next );
00085 outputExpressions.push_back( next );
00086 dim_outputs.push_back( next.getDim() );
00087
00088 if( NDX == 0 ) NDX = outputEquation_.getNDX();
00089 if( NU == 0 ) NU = outputEquation_.getNU();
00090 if( NP == 0 ) NP = outputEquation_.getNP();
00091 if( NOD == 0 ) NOD = outputEquation_.getNOD();
00092
00093 outputGrids.push_back( grid );
00094
00095 uint numOuts = (int) ceil((double)grid.getNumIntervals());
00096 num_meas.push_back( numOuts );
00097 }
00098 else {
00099 return ACADOERROR( RET_INVALID_OPTION );
00100 }
00101
00102 return dim_outputs.size();
00103 }
00104
00105
00106 uint ModelData::addOutput( const std::string& output, const std::string& diffs_output, const uint dim, const Grid& grid ){
00107
00108 if( outputExpressions.size() == 0 && differentialEquation.getNumDynamicEquations() == 0 ) {
00109 outputNames.push_back( output );
00110 diffs_outputNames.push_back( diffs_output );
00111 dim_outputs.push_back( dim );
00112
00113 outputGrids.push_back( grid );
00114
00115 uint numOuts = (int) ceil((double)grid.getNumIntervals());
00116 num_meas.push_back( numOuts );
00117 }
00118 else {
00119 return ACADOERROR( RET_INVALID_OPTION );
00120 }
00121
00122 return dim_outputs.size();
00123 }
00124
00125
00126 uint ModelData::addOutput( const std::string& output, const std::string& diffs_output, const uint dim,
00127 const Grid& grid, const std::string& colInd, const std::string& rowPtr ){
00128
00129
00130 DVector colIndV, rowPtrV;
00131
00132 colIndV.read( colInd.c_str() );
00133 rowPtrV.read( rowPtr.c_str() );
00134
00135 if( rowPtrV.getDim() != (dim+1) ) {
00136 return ACADOERROR( RET_INVALID_OPTION );
00137 }
00138 colInd_outputs.push_back( colIndV );
00139 rowPtr_outputs.push_back( rowPtrV );
00140
00141 return addOutput( output, diffs_output, dim, grid );
00142 }
00143
00144
00145 BooleanType ModelData::hasOutputs() const{
00146
00147 if( outputExpressions.size() == 0 && outputNames.size() == 0 ) return BT_FALSE;
00148 return BT_TRUE;
00149 }
00150
00151
00152 returnValue ModelData::getNumSteps( DVector& _numSteps ) const {
00153
00154 _numSteps = numSteps;
00155 return SUCCESSFUL_RETURN;
00156 }
00157
00158
00159 returnValue ModelData::setNumSteps( const DVector& _numSteps ) {
00160
00161 numSteps = _numSteps;
00162 return SUCCESSFUL_RETURN;
00163 }
00164
00165
00166 returnValue ModelData::getOutputExpressions( std::vector<Expression>& outputExpressions_ ) const {
00167
00168 outputExpressions_ = outputExpressions;
00169 return SUCCESSFUL_RETURN;
00170 }
00171
00172
00173 std::vector<DMatrix> ModelData::getOutputDependencies( ) const {
00174 std::vector<DMatrix> outputDependencies;
00175 if( hasCompressedStorage() ) {
00176 for( uint i = 0; i < outputNames.size(); i++ ) {
00177 DVector colIndV = colInd_outputs[i];
00178 DVector rowPtrV = rowPtr_outputs[i];
00179
00180 DMatrix dependencyMat = zeros<double>( dim_outputs[i],getNX()+NXA+NU+NDX );
00181 int index = 1;
00182 for( uint j = 0; j < dim_outputs[i]; j++ ) {
00183 uint upper = (uint)rowPtrV(j+1);
00184 for( uint k = (uint)rowPtrV(j); k < upper; k++ ) {
00185 dependencyMat(j,(uint)colIndV(k-1)-1) = index++;
00186 }
00187 }
00188
00189 outputDependencies.push_back( dependencyMat );
00190 }
00191 }
00192 return outputDependencies;
00193 }
00194
00195
00196 returnValue ModelData::getOutputGrids( std::vector<Grid>& outputGrids_ ) const {
00197
00198 outputGrids_ = outputGrids;
00199 return SUCCESSFUL_RETURN;
00200 }
00201
00202
00203 returnValue ModelData::getModel( DifferentialEquation& _f ) const{
00204
00205 _f = differentialEquation;
00206 return SUCCESSFUL_RETURN;
00207 }
00208
00209
00210 returnValue ModelData::getNARXmodel( uint& _delay, DMatrix& _parms ) const{
00211
00212 _delay = delay;
00213 _parms = parms;
00214
00215 return SUCCESSFUL_RETURN;
00216 }
00217
00218
00219 returnValue ModelData::getLinearInput( DMatrix& M1_, DMatrix& A1_, DMatrix& B1_ ) const {
00220 M1_ = M1;
00221 A1_ = A1;
00222 B1_ = B1;
00223
00224 return SUCCESSFUL_RETURN;
00225 }
00226
00227
00228 returnValue ModelData::getLinearOutput( DMatrix& M3_, DMatrix& A3_, OutputFcn& rhs_ ) const {
00229 M3_ = M3;
00230 A3_ = A3;
00231 rhs_ = rhs3;
00232
00233 return SUCCESSFUL_RETURN;
00234 }
00235
00236
00237 returnValue ModelData::getLinearOutput( DMatrix& M3_, DMatrix& A3_ ) const {
00238 M3_ = M3;
00239 A3_ = A3;
00240
00241 return SUCCESSFUL_RETURN;
00242 }
00243
00244
00245 returnValue ModelData::setModel( const DifferentialEquation& _f )
00246 {
00247 if( rhs_name.empty() && NX2 == 0 ) {
00248 differentialEquation = _f;
00249 Expression rhs;
00250 differentialEquation.getExpression( rhs );
00251
00252 NXA = differentialEquation.getNXA();
00253 NX2 = rhs.getDim() - NXA;
00254 if( NDX == 0 ) NDX = _f.getNDX();
00255
00256
00257
00258
00259 if( NU == 0 ) NU = _f.getNU();
00260 if( NP == 0 ) NP = _f.getNP();
00261 if( NOD == 0 ) NOD = _f.getNOD();
00262
00263 export_rhs = BT_TRUE;
00264 }
00265 else {
00266 return ACADOERROR( RET_INVALID_OPTION );
00267 }
00268 return SUCCESSFUL_RETURN;
00269 }
00270
00271
00272 returnValue ModelData::setNARXmodel( const uint _delay, const DMatrix& _parms ) {
00273
00274 if( rhs_name.empty() && NX2 == 0 && NX3 == 0 ) {
00275 NX2 = _parms.getNumRows();
00276 delay = _delay;
00277 uint numParms = 1;
00278 uint n = delay*getNX();
00279 if( delay >= 1 ) {
00280 numParms = numParms + n;
00281 }
00282 for( uint i = 1; i < delay; i++ ) {
00283 numParms = numParms + (n+1)*(uint)pow((double)n,(int)i)/2;
00284 }
00285 if( _parms.getNumCols() == numParms ) {
00286 parms = _parms;
00287 }
00288 else {
00289 return ACADOERROR( RET_UNABLE_TO_EXPORT_CODE );
00290 }
00291
00292 export_rhs = BT_TRUE;
00293 }
00294 else {
00295 return ACADOERROR( RET_INVALID_OPTION );
00296 }
00297 return SUCCESSFUL_RETURN;
00298 }
00299
00300
00301 returnValue ModelData::setLinearInput( const DMatrix& M1_, const DMatrix& A1_, const DMatrix& B1_ )
00302 {
00303 M1 = M1_;
00304 A1 = A1_;
00305 B1 = B1_;
00306 NX1 = A1.getNumCols();
00307 NU = B1.getNumCols();
00308 export_rhs = BT_TRUE;
00309
00310 return SUCCESSFUL_RETURN;
00311 }
00312
00313
00314 returnValue ModelData::setLinearOutput( const DMatrix& M3_, const DMatrix& A3_, const OutputFcn& rhs3_ )
00315 {
00316 M3 = M3_;
00317 A3 = A3_;
00318 NX3 = A3.getNumCols();
00319
00320 rhs3 = rhs3_;
00321 if( NDX == 0 ) NDX = rhs3_.getNDX();
00322 if( NU == 0 ) NU = rhs3_.getNU();
00323 if( NP == 0 ) NP = rhs3_.getNP();
00324 if( NOD == 0 ) NOD = rhs3_.getNOD();
00325
00326 export_rhs = BT_TRUE;
00327
00328 return SUCCESSFUL_RETURN;
00329 }
00330
00331
00332 returnValue ModelData::setLinearOutput( const DMatrix& M3_, const DMatrix& A3_, const std::string& rhs3_, const std::string& diffs3_ )
00333 {
00334 if( !export_rhs ) {
00335 M3 = M3_;
00336 A3 = A3_;
00337 NX3 = A3.getNumCols();
00338
00339 rhs3_name = std::string(rhs3_);
00340 diffs3_name = std::string(diffs3_);
00341 }
00342 else {
00343 return ACADOERROR( RET_INVALID_OPTION );
00344 }
00345
00346 return SUCCESSFUL_RETURN;
00347 }
00348
00349
00350 returnValue ModelData::setModel( const std::string& fileName, const std::string& _rhs_ODE, const std::string& _diffs_ODE )
00351 {
00352 if( differentialEquation.getNumDynamicEquations() == 0 )
00353 {
00354 externModel = fileName;
00355 rhs_name = _rhs_ODE;
00356 diffs_name = _diffs_ODE;
00357
00358 export_rhs = BT_FALSE;
00359 }
00360 else
00361 {
00362 return ACADOERROR( RET_INVALID_OPTION );
00363 }
00364
00365 return SUCCESSFUL_RETURN;
00366 }
00367
00368
00369 returnValue ModelData::getIntegrationGrid( Grid& integrationGrid_ ) const
00370 {
00371 integrationGrid_ = integrationGrid;
00372 return SUCCESSFUL_RETURN;
00373 }
00374
00375
00376 returnValue ModelData::setIntegrationGrid( const Grid& _ocpGrid, const uint _numSteps
00377 )
00378 {
00379 uint i;
00380 N = _ocpGrid.getNumIntervals();
00381 BooleanType equidistantControl = _ocpGrid.isEquidistant();
00382 double T = _ocpGrid.getLastTime() - _ocpGrid.getFirstTime();
00383 double h = T/((double)_numSteps);
00384 DVector stepsVector( N );
00385
00386 if (integrationGrid.isEmpty() == BT_TRUE)
00387 {
00388 for( i = 0; i < stepsVector.getDim(); i++ )
00389 {
00390 stepsVector(i) = (int) acadoRound((_ocpGrid.getTime(i+1)-_ocpGrid.getTime(i))/h);
00391 }
00392
00393 if( equidistantControl )
00394 {
00395
00396 integrationGrid = Grid( 0.0, ((double) T)/((double) N), (int) ceil((double)_numSteps/((double) N) - 10.0*EPS) + 1 );
00397 }
00398 else
00399 {
00400
00401
00402
00403 integrationGrid = Grid( 0.0, h, 2 );
00404 numSteps = stepsVector;
00405 }
00406 }
00407 return SUCCESSFUL_RETURN;
00408 }
00409
00410
00411 returnValue ModelData::clearIntegrationGrid( )
00412 {
00413 integrationGrid = Grid();
00414
00415 return SUCCESSFUL_RETURN;
00416 }
00417
00418
00419 BooleanType ModelData::hasEquidistantControlGrid( ) const
00420 {
00421 return numSteps.isEmpty();
00422 }
00423
00424
00425 BooleanType ModelData::hasOutputFunctions() const {
00426
00427 if( outputExpressions.size() == 0 ) return BT_FALSE;
00428 return BT_TRUE;
00429 }
00430
00431
00432 BooleanType ModelData::hasDifferentialEquation() const {
00433
00434 if( differentialEquation.getDim() == 0 ) return BT_FALSE;
00435 return BT_TRUE;
00436 }
00437
00438
00439 BooleanType ModelData::modelDimensionsSet() const {
00440
00441 return model_dimensions_set;
00442 }
00443
00444
00445 BooleanType ModelData::exportRhs() const {
00446
00447 return export_rhs;
00448 }
00449
00450
00451 BooleanType ModelData::hasCompressedStorage() const {
00452
00453 if( colInd_outputs.size() == 0 ) return BT_FALSE;
00454 return BT_TRUE;
00455 }
00456
00457
00458 uint ModelData::getNX( ) const
00459 {
00460 if( parms.isEmpty() ) {
00461 return NX1+NX2+NX3;
00462 }
00463 else {
00464 return delay*(NX1+NX2)+NX3;
00465 }
00466 }
00467
00468
00469 uint ModelData::getNX1( ) const
00470 {
00471 return NX1;
00472 }
00473
00474
00475 uint ModelData::getNX2( ) const
00476 {
00477 return NX2;
00478 }
00479
00480
00481 uint ModelData::getNX3( ) const
00482 {
00483 return NX3;
00484 }
00485
00486
00487 uint ModelData::getNDX( ) const
00488 {
00489 if( NDX > 0 ) {
00490 return getNX();
00491 }
00492 return NDX;
00493 }
00494
00495
00496 uint ModelData::getNDX3( ) const
00497 {
00498 if( NDX3 > 0 ) {
00499 return NX1+NX2;
00500 }
00501 return NDX3;
00502 }
00503
00504
00505 uint ModelData::getNXA( ) const
00506 {
00507 return NXA;
00508 }
00509
00510
00511 uint ModelData::getNXA3( ) const
00512 {
00513 if( NXA3 > 0 ) {
00514 return NXA;
00515 }
00516 return NXA3;
00517 }
00518
00519
00520 uint ModelData::getNU( ) const
00521 {
00522 return NU;
00523 }
00524
00525
00526 uint ModelData::getNP( ) const
00527 {
00528 return NP;
00529 }
00530
00531 uint ModelData::getNOD( ) const
00532 {
00533 return NOD;
00534 }
00535
00536
00537 uint ModelData::getN( ) const
00538 {
00539 return N;
00540 }
00541
00542
00543 returnValue ModelData::setN( const uint N_ )
00544 {
00545 N = N_;
00546 return SUCCESSFUL_RETURN;
00547 }
00548
00549
00550 DVector ModelData::getDimOutputs( ) const
00551 {
00552 DVector nOutV( (uint)dim_outputs.size() );
00553 for( uint i = 0; i < dim_outputs.size(); i++ ) {
00554 nOutV(i) = dim_outputs[i];
00555 }
00556 return nOutV;
00557 }
00558
00559
00560 uint ModelData::getNumOutputs( ) const
00561 {
00562 return (uint)outputGrids.size();
00563 }
00564
00565
00566 returnValue ModelData::getDimOutputs( std::vector<uint>& dims ) const
00567 {
00568 dims = dim_outputs;
00569 return SUCCESSFUL_RETURN;
00570 }
00571
00572
00573 DVector ModelData::getNumMeas( ) const
00574 {
00575 DVector nMeasV( (uint)num_meas.size() );
00576 for( uint i = 0; i < num_meas.size(); i++ ) {
00577 nMeasV(i) = num_meas[i];
00578 }
00579 return nMeasV;
00580 }
00581
00582
00583 const std::string ModelData::getFileNameModel() const {
00584 return externModel;
00585 }
00586
00587
00588 const std::string ModelData::getNameRhs() const {
00589 return rhs_name;
00590 }
00591
00592
00593 const std::string ModelData::getNameDiffsRhs() const {
00594 return diffs_name;
00595 }
00596
00597
00598 const std::string ModelData::getNameOutput() const {
00599 return rhs3_name;
00600 }
00601
00602
00603 const std::string ModelData::getNameDiffsOutput() const {
00604 return diffs3_name;
00605 }
00606
00607
00608 returnValue ModelData::getNameOutputs( std::vector<std::string>& names ) const {
00609 names = outputNames;
00610 return SUCCESSFUL_RETURN;
00611 }
00612
00613
00614 returnValue ModelData::getNameDiffsOutputs( std::vector<std::string>& names ) const {
00615 names = diffs_outputNames;
00616 return SUCCESSFUL_RETURN;
00617 }
00618
00619
00620
00621
00622
00623
00624
00625
00626 CLOSE_NAMESPACE_ACADO
00627
00628