returnValue DiscreteTimeExport::getCode( ExportStatementBlock& code ) { if( NX1 > 0 ) { code.addFunction( lin_input ); code.addStatement( "\n\n" ); } if( NX2 > 0 ) { code.addFunction( rhs ); code.addStatement( "\n\n" ); code.addFunction( diffs_rhs ); code.addStatement( "\n\n" ); } if( !equidistantControlGrid() ) { ExportVariable numStepsV( "numSteps", numSteps, STATIC_CONST_INT ); code.addDeclaration( numStepsV ); code.addLinebreak( 2 ); } double h = (grid.getLastTime() - grid.getFirstTime())/grid.getNumIntervals(); code.addComment(String("Fixed step size:") << String(h)); code.addFunction( integrate ); if( NX2 != NX ) { prepareFullRhs(); code.addFunction( fullRhs ); } return SUCCESSFUL_RETURN; }
returnValue ExportGaussNewtonForces::getCode( ExportStatementBlock& code ) { setupQPInterface(); code.addStatement( *qpInterface ); code.addLinebreak( 2 ); code.addStatement( "/******************************************************************************/\n" ); code.addStatement( "/* */\n" ); code.addStatement( "/* ACADO code generation */\n" ); code.addStatement( "/* */\n" ); code.addStatement( "/******************************************************************************/\n" ); code.addLinebreak( 2 ); int useOMP; get(CG_USE_OPENMP, useOMP); if ( useOMP ) { code.addDeclaration( state ); } code.addFunction( modelSimulation ); code.addFunction( evaluateStageCost ); code.addFunction( evaluateTerminalCost ); code.addFunction( setObjQ1Q2 ); code.addFunction( setObjR1R2 ); code.addFunction( setObjS1 ); code.addFunction( setObjQN1QN2 ); code.addFunction( setStageH ); code.addFunction( setStagef ); code.addFunction( evaluateObjective ); code.addFunction( conSetGxGu ); code.addFunction( conSetd ); code.addFunction( evaluateConstraints ); code.addFunction( acc ); code.addFunction( preparation ); code.addFunction( feedback ); code.addFunction( initialize ); code.addFunction( initializeNodes ); code.addFunction( shiftStates ); code.addFunction( shiftControls ); code.addFunction( getKKT ); code.addFunction( getObjective ); return SUCCESSFUL_RETURN; }
returnValue ExportGaussNewtonBlockForces::getCode( ExportStatementBlock& code ) { setupQPInterface(); code.addStatement( *qpInterface ); code.addFunction( cleanup ); code.addFunction( shiftQpData ); code.addFunction( evaluateConstraints ); code.addFunction( evaluateAffineConstraints ); return ExportGaussNewtonCN2::getCode( code ); }
returnValue ExportIRK4StageSimplifiedNewton::transformRightHandSide( ExportStatementBlock& code, const ExportIndex& index ) { uint i, j; ExportVariable transf1_var( transf1 ); ExportVariable stepSizeV( 1.0/stepsize ); ExportForLoop loop1( index, 0, dim ); for( j = 0; j < nRightHandSides; j++ ) { loop1.addStatement( b_mem_complex1.getElement(index,j) == 0.0 ); for( i = 0; i < 4; i++ ) { loop1.addStatement( b_mem_complex1.getElement(index,j) += transf1_var.getElement(0,i)*b_full.getElement(index+i*dim,j) ); } stringstream ss1; ss1 << b_mem_complex1.get(index,j) << " += ("; for( i = 0; i < 4; i++ ) { if( i > 0 ) ss1 << " + "; ss1 << transf1_var.get(1,i) << "*" << b_full.get(index+i*dim,j); } ss1 << ")*I;\n"; ss1 << b_mem_complex1.get(index,j) << " *= " << stepSizeV.get(0,0) << ";\n"; loop1 << ss1.str(); loop1.addStatement( b_mem_complex2.getElement(index,j) == 0.0 ); for( i = 0; i < 4; i++ ) { loop1.addStatement( b_mem_complex2.getElement(index,j) += transf1_var.getElement(2,i)*b_full.getElement(index+i*dim,j) ); } stringstream ss2; ss2 << b_mem_complex2.get(index,j) << " += ("; for( i = 0; i < 4; i++ ) { if( i > 0 ) ss2 << " + "; ss2 << transf1_var.get(3,i) << "*" << b_full.get(index+i*dim,j); } ss2 << ")*I;\n"; ss2 << b_mem_complex2.get(index,j) << " *= " << stepSizeV.get(0,0) << ";\n"; loop1 << ss2.str(); } code.addStatement( loop1 ); return SUCCESSFUL_RETURN; }
returnValue ExportIRK4StageSimplifiedNewton::transformSolution( ExportStatementBlock& code, const ExportIndex& index ) { uint j; ExportVariable transf2_var( transf2 ); ExportForLoop loop1( index, 0, dim ); for( j = 0; j < nRightHandSides; j++ ) { stringstream ss; ss << b_full.get(index,j) << " = "; ss << transf2_var.get(0,0) << "*creal(" << b_mem_complex1.get(index,j) << ") + "; ss << transf2_var.get(0,1) << "*cimag(" << b_mem_complex1.get(index,j) << ") + "; ss << transf2_var.get(0,2) << "*creal(" << b_mem_complex2.get(index,j) << ") + "; ss << transf2_var.get(0,3) << "*cimag(" << b_mem_complex2.get(index,j) << ");\n"; ss << b_full.get(index+dim,j) << " = "; ss << transf2_var.get(1,0) << "*creal(" << b_mem_complex1.get(index,j) << ") + "; ss << transf2_var.get(1,1) << "*cimag(" << b_mem_complex1.get(index,j) << ") + "; ss << transf2_var.get(1,2) << "*creal(" << b_mem_complex2.get(index,j) << ") + "; ss << transf2_var.get(1,3) << "*cimag(" << b_mem_complex2.get(index,j) << ");\n"; ss << b_full.get(index+2*dim,j) << " = "; ss << transf2_var.get(2,0) << "*creal(" << b_mem_complex1.get(index,j) << ") + "; ss << transf2_var.get(2,1) << "*cimag(" << b_mem_complex1.get(index,j) << ") + "; ss << transf2_var.get(2,2) << "*creal(" << b_mem_complex2.get(index,j) << ") + "; ss << transf2_var.get(2,3) << "*cimag(" << b_mem_complex2.get(index,j) << ");\n"; ss << b_full.get(index+3*dim,j) << " = "; ss << transf2_var.get(3,0) << "*creal(" << b_mem_complex1.get(index,j) << ") + "; ss << transf2_var.get(3,1) << "*cimag(" << b_mem_complex1.get(index,j) << ") + "; ss << transf2_var.get(3,2) << "*creal(" << b_mem_complex2.get(index,j) << ") + "; ss << transf2_var.get(3,3) << "*cimag(" << b_mem_complex2.get(index,j) << ");\n"; loop1 << ss.str(); } code.addStatement( loop1 ); return SUCCESSFUL_RETURN; }
returnValue ExportGaussNewtonCN2::getCode( ExportStatementBlock& code ) { setupQPInterface(); code.addLinebreak( 2 ); code.addStatement( "/******************************************************************************/\n" ); code.addStatement( "/* */\n" ); code.addStatement( "/* ACADO code generation */\n" ); code.addStatement( "/* */\n" ); code.addStatement( "/******************************************************************************/\n" ); code.addLinebreak( 2 ); int useOMP; get(CG_USE_OPENMP, useOMP); if ( useOMP ) { code.addDeclaration( state ); } code.addFunction( modelSimulation ); code.addFunction( evaluateLSQ ); code.addFunction( evaluateLSQEndTerm ); code.addFunction( setObjQ1Q2 ); code.addFunction( setObjR1R2 ); code.addFunction( setObjS1 ); code.addFunction( setObjQN1QN2 ); code.addFunction( evaluateObjective ); code.addFunction( multGxGu ); code.addFunction( moveGuE ); code.addFunction( multBTW1 ); code.addFunction( mac_S1T_E ); code.addFunction( macBTW1_R1 ); code.addFunction( multGxTGu ); code.addFunction( macQEW2 ); code.addFunction( macATw1QDy ); code.addFunction( macBTw1 ); code.addFunction( macS1TSbar ); code.addFunction( macQSbarW2 ); code.addFunction( macASbar ); code.addFunction( expansionStep ); code.addFunction( copyHTH ); code.addFunction( multRDy ); code.addFunction( multQDy ); code.addFunction( multQN1Gu ); code.addFunction( evaluatePathConstraints ); for (unsigned i = 0; i < evaluatePointConstraints.size(); ++i) { if (evaluatePointConstraints[ i ] == 0) continue; code.addFunction( *evaluatePointConstraints[ i ] ); } code.addFunction( condensePrep ); code.addFunction( condenseFdb ); code.addFunction( expand ); code.addFunction( preparation ); code.addFunction( feedback ); code.addFunction( initialize ); code.addFunction( initializeNodes ); code.addFunction( shiftStates ); code.addFunction( shiftControls ); code.addFunction( getKKT ); code.addFunction( getObjective ); return SUCCESSFUL_RETURN; }
returnValue ExportExactHessianQpDunes::getCode( ExportStatementBlock& code ) { setupQPInterface(); code.addStatement( *qpInterface ); code.addLinebreak( 2 ); code.addStatement( "/******************************************************************************/\n" ); code.addStatement( "/* */\n" ); code.addStatement( "/* ACADO code generation */\n" ); code.addStatement( "/* */\n" ); code.addStatement( "/******************************************************************************/\n" ); code.addLinebreak( 2 ); int useOMP; get(CG_USE_OPENMP, useOMP); if ( useOMP ) { code.addDeclaration( state ); } code.addFunction( modelSimulation ); code.addFunction( evaluateStageCost ); code.addFunction( evaluateTerminalCost ); code.addFunction( setObjQ1Q2 ); code.addFunction( setObjR1R2 ); code.addFunction( setObjQN1QN2 ); code.addFunction( setStageH ); code.addFunction( setStagef ); code.addFunction( evaluateObjective ); code.addFunction( regularizeHessian ); code.addFunction( evaluatePathConstraints ); for (unsigned i = 0; i < evaluatePointConstraints.size(); ++i) { if (evaluatePointConstraints[ i ] == 0) continue; code.addFunction( *evaluatePointConstraints[ i ] ); } code.addFunction( setStagePac ); code.addFunction( evaluateConstraints ); code.addFunction( acc ); code.addFunction( preparation ); code.addFunction( feedback ); code.addFunction( initialize ); code.addFunction( initializeNodes ); code.addFunction( shiftStates ); code.addFunction( shiftControls ); code.addFunction( getKKT ); code.addFunction( getObjective ); code.addFunction( cleanup ); code.addFunction( shiftQpData ); return SUCCESSFUL_RETURN; }
returnValue DiscreteTimeExport::getCode( ExportStatementBlock& code ) { int useOMP; get(CG_USE_OPENMP, useOMP); if ( useOMP ) { ExportVariable max = getAuxVariable(); max.setName( "auxVar" ); max.setDataStruct( ACADO_LOCAL ); if( NX2 > 0 ) { rhs.setGlobalExportVariable( max ); diffs_rhs.setGlobalExportVariable( max ); } if( NX3 > 0 ) { rhs3.setGlobalExportVariable( max ); diffs_rhs3.setGlobalExportVariable( max ); } getDataDeclarations( code, ACADO_LOCAL ); stringstream s; s << "#pragma omp threadprivate( " << max.getFullName() << ", " << rk_xxx.getFullName(); if( NX1 > 0 ) { if( grid.getNumIntervals() > 1 || !equidistantControlGrid() ) s << ", " << rk_diffsPrev1.getFullName(); s << ", " << rk_diffsNew1.getFullName(); } if( NX2 > 0 || NXA > 0 ) { if( grid.getNumIntervals() > 1 || !equidistantControlGrid() ) s << ", " << rk_diffsPrev2.getFullName(); s << ", " << rk_diffsNew2.getFullName(); } if( NX3 > 0 ) { if( grid.getNumIntervals() > 1 || !equidistantControlGrid() ) s << ", " << rk_diffsPrev3.getFullName(); s << ", " << rk_diffsNew3.getFullName(); s << ", " << rk_diffsTemp3.getFullName(); } s << " )" << endl << endl; code.addStatement( s.str().c_str() ); } if( NX1 > 0 ) { code.addFunction( lin_input ); code.addStatement( "\n\n" ); } if( NX2 > 0 ) { code.addFunction( rhs ); code.addStatement( "\n\n" ); code.addFunction( diffs_rhs ); code.addStatement( "\n\n" ); } if( NX3 > 0 ) { code.addFunction( rhs3 ); code.addStatement( "\n\n" ); code.addFunction( diffs_rhs3 ); code.addStatement( "\n\n" ); } if( !equidistantControlGrid() ) { ExportVariable numStepsV( "numSteps", numSteps, STATIC_CONST_INT ); code.addDeclaration( numStepsV ); code.addLinebreak( 2 ); } double h = (grid.getLastTime() - grid.getFirstTime())/grid.getNumIntervals(); code.addComment(std::string("Fixed step size:") + toString(h)); code.addFunction( integrate ); return SUCCESSFUL_RETURN; }
returnValue DiscreteTimeExport::setup( ) { int sensGen; get( DYNAMIC_SENSITIVITY,sensGen ); if ( (ExportSensitivityType)sensGen != FORWARD ) ACADOERROR( RET_INVALID_OPTION ); int useOMP; get(CG_USE_OPENMP, useOMP); ExportStruct structWspace; structWspace = useOMP ? ACADO_LOCAL : ACADO_WORKSPACE; LOG( LVL_DEBUG ) << "Preparing to export DiscreteTimeExport... " << endl; ExportIndex run( "run" ); ExportIndex i( "i" ); ExportIndex j( "j" ); ExportIndex k( "k" ); ExportIndex tmp_index("tmp_index"); diffsDim = NX*(NX+NU); inputDim = NX*(NX+NU+1) + NU + NOD; // setup INTEGRATE function rk_index = ExportVariable( "rk_index", 1, 1, INT, ACADO_LOCAL, true ); rk_eta = ExportVariable( "rk_eta", 1, inputDim, REAL ); if( equidistantControlGrid() ) { integrate = ExportFunction( "integrate", rk_eta, reset_int ); } else { integrate = ExportFunction( "integrate", rk_eta, reset_int, rk_index ); } integrate.setReturnValue( error_code ); rk_eta.setDoc( "Working array to pass the input values and return the results." ); reset_int.setDoc( "The internal memory of the integrator can be reset." ); rk_index.setDoc( "Number of the shooting interval." ); error_code.setDoc( "Status code of the integrator." ); integrate.doc( "Performs the integration and sensitivity propagation for one shooting interval." ); integrate.addIndex( run ); integrate.addIndex( i ); integrate.addIndex( j ); integrate.addIndex( k ); integrate.addIndex( tmp_index ); rhs_in = ExportVariable( "x", inputDim-diffsDim, 1, REAL, ACADO_LOCAL ); rhs_out = ExportVariable( "f", NX, 1, REAL, ACADO_LOCAL ); fullRhs = ExportFunction( "full_rhs", rhs_in, rhs_out ); rhs_in.setDoc( "The state and parameter values." ); rhs_out.setDoc( "Right-hand side evaluation." ); fullRhs.doc( "Evaluates the right-hand side of the full model." ); rk_xxx = ExportVariable( "rk_xxx", 1, inputDim-diffsDim, REAL, structWspace ); if( grid.getNumIntervals() > 1 || !equidistantControlGrid() ) { rk_diffsPrev1 = ExportVariable( "rk_diffsPrev1", NX1, NX1+NU, REAL, structWspace ); rk_diffsPrev2 = ExportVariable( "rk_diffsPrev2", NX2, NX1+NX2+NU, REAL, structWspace ); rk_diffsPrev3 = ExportVariable( "rk_diffsPrev3", NX3, NX+NU, REAL, structWspace ); } rk_diffsNew1 = ExportVariable( "rk_diffsNew1", NX1, NX1+NU, REAL, structWspace ); rk_diffsNew2 = ExportVariable( "rk_diffsNew2", NX2, NX1+NX2+NU, REAL, structWspace ); rk_diffsNew3 = ExportVariable( "rk_diffsNew3", NX3, NX+NU, REAL, structWspace ); rk_diffsTemp3 = ExportVariable( "rk_diffsTemp3", NX3, NX1+NX2+NU, REAL, structWspace ); ExportVariable numInt( "numInts", 1, 1, INT ); if( !equidistantControlGrid() ) { ExportVariable numStepsV( "numSteps", numSteps, STATIC_CONST_INT ); integrate.addStatement( std::string( "int " ) + numInt.getName() + " = " + numStepsV.getName() + "[" + rk_index.getName() + "];\n" ); } integrate.addStatement( rk_xxx.getCols( NX,inputDim-diffsDim ) == rk_eta.getCols( NX+diffsDim,inputDim ) ); integrate.addLinebreak( ); // evaluate sensitivities linear input: if( NX1 > 0 ) { for( uint i1 = 0; i1 < NX1; i1++ ) { for( uint i2 = 0; i2 < NX1; i2++ ) { integrate.addStatement( rk_diffsNew1.getSubMatrix(i1,i1+1,i2,i2+1) == A11(i1,i2) ); } for( uint i2 = 0; i2 < NU; i2++ ) { integrate.addStatement( rk_diffsNew1.getSubMatrix(i1,i1+1,NX1+i2,NX1+i2+1) == B11(i1,i2) ); } } } // evaluate sensitivities linear output: if( NX1 > 0 ) { for( uint i1 = 0; i1 < NX3; i1++ ) { for( uint i2 = 0; i2 < NX3; i2++ ) { integrate.addStatement( rk_diffsNew3.getSubMatrix(i1,i1+1,NX-NX3+i2,NX-NX3+i2+1) == A33(i1,i2) ); } } } integrate.addLinebreak( ); // integrator loop: ExportForLoop tmpLoop( run, 0, grid.getNumIntervals() ); ExportStatementBlock *loop; if( equidistantControlGrid() ) { loop = &tmpLoop; } else { loop = &integrate; loop->addStatement( std::string("for(") + run.getName() + " = 0; " + run.getName() + " < " + numInt.getName() + "; " + run.getName() + "++ ) {\n" ); } loop->addStatement( rk_xxx.getCols( 0,NX ) == rk_eta.getCols( 0,NX ) ); if( grid.getNumIntervals() > 1 || !equidistantControlGrid() ) { // Set rk_diffsPrev: loop->addStatement( std::string("if( run > 0 ) {\n") ); if( NX1 > 0 ) { ExportForLoop loopTemp1( i,0,NX1 ); loopTemp1.addStatement( rk_diffsPrev1.getSubMatrix( i,i+1,0,NX1 ) == rk_eta.getCols( i*NX+NX+NXA,i*NX+NX+NXA+NX1 ) ); if( NU > 0 ) loopTemp1.addStatement( rk_diffsPrev1.getSubMatrix( i,i+1,NX1,NX1+NU ) == rk_eta.getCols( i*NU+(NX+NXA)*(NX+1),i*NU+(NX+NXA)*(NX+1)+NU ) ); loop->addStatement( loopTemp1 ); } if( NX2 > 0 ) { ExportForLoop loopTemp2( i,0,NX2 ); loopTemp2.addStatement( rk_diffsPrev2.getSubMatrix( i,i+1,0,NX1+NX2 ) == rk_eta.getCols( i*NX+NX+NXA+NX1*NX,i*NX+NX+NXA+NX1*NX+NX1+NX2 ) ); if( NU > 0 ) loopTemp2.addStatement( rk_diffsPrev2.getSubMatrix( i,i+1,NX1+NX2,NX1+NX2+NU ) == rk_eta.getCols( i*NU+(NX+NXA)*(NX+1)+NX1*NU,i*NU+(NX+NXA)*(NX+1)+NX1*NU+NU ) ); loop->addStatement( loopTemp2 ); } if( NX3 > 0 ) { ExportForLoop loopTemp3( i,0,NX3 ); loopTemp3.addStatement( rk_diffsPrev3.getSubMatrix( i,i+1,0,NX ) == rk_eta.getCols( i*NX+NX+NXA+(NX1+NX2)*NX,i*NX+NX+NXA+(NX1+NX2)*NX+NX ) ); if( NU > 0 ) loopTemp3.addStatement( rk_diffsPrev3.getSubMatrix( i,i+1,NX,NX+NU ) == rk_eta.getCols( i*NU+(NX+NXA)*(NX+1)+(NX1+NX2)*NU,i*NU+(NX+NXA)*(NX+1)+(NX1+NX2)*NU+NU ) ); loop->addStatement( loopTemp3 ); } loop->addStatement( std::string("}\n") ); } // evaluate states: if( NX1 > 0 ) { loop->addFunctionCall( lin_input.getName(), rk_xxx, rk_eta.getAddress(0,0) ); } if( NX2 > 0 ) { loop->addFunctionCall( getNameRHS(), rk_xxx, rk_eta.getAddress(0,NX1) ); } if( NX3 > 0 ) { loop->addFunctionCall( getNameOutputRHS(), rk_xxx, rk_eta.getAddress(0,NX1+NX2) ); } // evaluate sensitivities if( NX2 > 0 ) { loop->addFunctionCall( getNameDiffsRHS(), rk_xxx, rk_diffsNew2.getAddress(0,0) ); } if( NX3 > 0 ) { loop->addFunctionCall( getNameOutputDiffs(), rk_xxx, rk_diffsTemp3.getAddress(0,0) ); ExportForLoop loop1( i,0,NX3 ); ExportForLoop loop2( j,0,NX1+NX2 ); loop2.addStatement( rk_diffsNew3.getSubMatrix(i,i+1,j,j+1) == rk_diffsTemp3.getSubMatrix(i,i+1,j,j+1) ); loop1.addStatement( loop2 ); loop2 = ExportForLoop( j,0,NU ); loop2.addStatement( rk_diffsNew3.getSubMatrix(i,i+1,NX+j,NX+j+1) == rk_diffsTemp3.getSubMatrix(i,i+1,NX1+NX2+j,NX1+NX2+j+1) ); loop1.addStatement( loop2 ); loop->addStatement( loop1 ); } // computation of the sensitivities using chain rule: if( grid.getNumIntervals() > 1 || !equidistantControlGrid() ) { loop->addStatement( std::string( "if( run == 0 ) {\n" ) ); } // PART 1 updateInputSystem(loop, i, j, tmp_index); // PART 2 updateImplicitSystem(loop, i, j, tmp_index); // PART 3 updateOutputSystem(loop, i, j, tmp_index); if( grid.getNumIntervals() > 1 || !equidistantControlGrid() ) { loop->addStatement( std::string( "}\n" ) ); loop->addStatement( std::string( "else {\n" ) ); // PART 1 propagateInputSystem(loop, i, j, k, tmp_index); // PART 2 propagateImplicitSystem(loop, i, j, k, tmp_index); // PART 3 propagateOutputSystem(loop, i, j, k, tmp_index); loop->addStatement( std::string( "}\n" ) ); } // end of the integrator loop. if( !equidistantControlGrid() ) { loop->addStatement( "}\n" ); } else { integrate.addStatement( *loop ); } // PART 1 if( NX1 > 0 ) { DMatrix zeroR = zeros<double>(1, NX2+NX3); ExportForLoop loop1( i,0,NX1 ); loop1.addStatement( rk_eta.getCols( i*NX+NX+NXA+NX1,i*NX+NX+NXA+NX ) == zeroR ); integrate.addStatement( loop1 ); } // PART 2 DMatrix zeroR = zeros<double>(1, NX3); if( NX2 > 0 ) { ExportForLoop loop2( i,NX1,NX1+NX2 ); loop2.addStatement( rk_eta.getCols( i*NX+NX+NXA+NX1+NX2,i*NX+NX+NXA+NX ) == zeroR ); integrate.addStatement( loop2 ); } LOG( LVL_DEBUG ) << "done" << endl; return SUCCESSFUL_RETURN; }
returnValue DiscreteTimeExport::setup( ) { int useOMP; get(CG_USE_OPENMP, useOMP); ExportStruct structWspace; structWspace = useOMP ? ACADO_LOCAL : ACADO_WORKSPACE; // non equidistant integration grids not implemented for NARX integrators if( !equidistant ) return ACADOERROR( RET_INVALID_OPTION ); String fileName( "integrator.c" ); int printLevel; get( PRINTLEVEL,printLevel ); if ( (PrintLevel)printLevel >= HIGH ) acadoPrintf( "--> Preparing to export %s... ",fileName.getName() ); ExportIndex run( "run" ); ExportIndex i( "i" ); ExportIndex j( "j" ); ExportIndex k( "k" ); ExportIndex tmp_index("tmp_index"); uint diffsDim = NX*(NX+NU); uint inputDim = NX*(NX+NU+1) + NU + NP; // setup INTEGRATE function rk_index = ExportVariable( "rk_index", 1, 1, INT, ACADO_LOCAL, BT_TRUE ); rk_eta = ExportVariable( "rk_eta", 1, inputDim, REAL ); if( equidistantControlGrid() ) { integrate = ExportFunction( "integrate", rk_eta, reset_int ); } else { integrate = ExportFunction( "integrate", rk_eta, reset_int, rk_index ); } integrate.setReturnValue( error_code ); integrate.addIndex( run ); integrate.addIndex( i ); integrate.addIndex( j ); integrate.addIndex( k ); integrate.addIndex( tmp_index ); rhs_in = ExportVariable( "x", inputDim-diffsDim, 1, REAL, ACADO_LOCAL ); rhs_out = ExportVariable( "f", NX, 1, REAL, ACADO_LOCAL ); fullRhs = ExportFunction( "full_rhs", rhs_in, rhs_out ); rk_xxx = ExportVariable( "rk_xxx", 1, inputDim-diffsDim, REAL, structWspace ); if( grid.getNumIntervals() > 1 || !equidistantControlGrid() ) { rk_diffsPrev1 = ExportVariable( "rk_diffsPrev1", NX1, NX1+NU, REAL, structWspace ); rk_diffsPrev2 = ExportVariable( "rk_diffsPrev2", NX2, NX1+NX2+NU, REAL, structWspace ); } rk_diffsNew1 = ExportVariable( "rk_diffsNew1", NX1, NX1+NU, REAL, structWspace ); rk_diffsNew2 = ExportVariable( "rk_diffsNew2", NX2, NX1+NX2+NU, REAL, structWspace ); ExportVariable numInt( "numInts", 1, 1, INT ); if( !equidistantControlGrid() ) { ExportVariable numStepsV( "numSteps", numSteps, STATIC_CONST_INT ); integrate.addStatement( String( "int " ) << numInt.getName() << " = " << numStepsV.getName() << "[" << rk_index.getName() << "];\n" ); } integrate.addStatement( rk_xxx.getCols( NX,inputDim-diffsDim ) == rk_eta.getCols( NX+diffsDim,inputDim ) ); integrate.addLinebreak( ); // integrator loop: ExportForLoop tmpLoop( run, 0, grid.getNumIntervals() ); ExportStatementBlock *loop; if( equidistantControlGrid() ) { loop = &tmpLoop; } else { loop = &integrate; loop->addStatement( String("for(") << run.getName() << " = 0; " << run.getName() << " < " << numInt.getName() << "; " << run.getName() << "++ ) {\n" ); } loop->addStatement( rk_xxx.getCols( 0,NX ) == rk_eta.getCols( 0,NX ) ); if( grid.getNumIntervals() > 1 || !equidistantControlGrid() ) { // Set rk_diffsPrev: loop->addStatement( String("if( run > 0 ) {\n") ); if( NX1 > 0 ) { ExportForLoop loopTemp1( i,0,NX1 ); loopTemp1.addStatement( rk_diffsPrev1.getSubMatrix( i,i+1,0,NX1 ) == rk_eta.getCols( i*NX+NX+NXA,i*NX+NX+NXA+NX1 ) ); if( NU > 0 ) loopTemp1.addStatement( rk_diffsPrev1.getSubMatrix( i,i+1,NX1,NX1+NU ) == rk_eta.getCols( i*NU+(NX+NXA)*(NX+1),i*NU+(NX+NXA)*(NX+1)+NU ) ); loop->addStatement( loopTemp1 ); } if( NX2 > 0 ) { ExportForLoop loopTemp2( i,0,NX2 ); loopTemp2.addStatement( rk_diffsPrev2.getSubMatrix( i,i+1,0,NX1+NX2 ) == rk_eta.getCols( i*NX+NX+NXA+NX1*NX,i*NX+NX+NXA+NX1*NX+NX1+NX2 ) ); if( NU > 0 ) loopTemp2.addStatement( rk_diffsPrev2.getSubMatrix( i,i+1,NX1+NX2,NX1+NX2+NU ) == rk_eta.getCols( i*NU+(NX+NXA)*(NX+1)+NX1*NU,i*NU+(NX+NXA)*(NX+1)+NX1*NU+NU ) ); loop->addStatement( loopTemp2 ); } loop->addStatement( String("}\n") ); } // evaluate states: if( NX1 > 0 ) { loop->addFunctionCall( lin_input.getName(), rk_xxx, rk_eta.getAddress(0,0) ); } if( NX2 > 0 ) { loop->addFunctionCall( getNameRHS(), rk_xxx, rk_eta.getAddress(0,NX1) ); } // evaluate sensitivities: if( NX1 > 0 ) { for( uint i1 = 0; i1 < NX1; i1++ ) { for( uint i2 = 0; i2 < NX1; i2++ ) { loop->addStatement( rk_diffsNew1.getSubMatrix(i1,i1+1,i2,i2+1) == A11(i1,i2) ); } for( uint i2 = 0; i2 < NU; i2++ ) { loop->addStatement( rk_diffsNew1.getSubMatrix(i1,i1+1,NX1+i2,NX1+i2+1) == B11(i1,i2) ); } } } if( NX2 > 0 ) { loop->addFunctionCall( getNameDiffsRHS(), rk_xxx, rk_diffsNew2.getAddress(0,0) ); } // computation of the sensitivities using chain rule: if( grid.getNumIntervals() > 1 || !equidistantControlGrid() ) { loop->addStatement( String( "if( run == 0 ) {\n" ) ); } // PART 1 updateInputSystem(loop, i, j, tmp_index); // PART 2 updateImplicitSystem(loop, i, j, tmp_index); if( grid.getNumIntervals() > 1 || !equidistantControlGrid() ) { loop->addStatement( String( "}\n" ) ); loop->addStatement( String( "else {\n" ) ); // PART 1 propagateInputSystem(loop, i, j, k, tmp_index); // PART 2 propagateImplicitSystem(loop, i, j, k, tmp_index); loop->addStatement( String( "}\n" ) ); } // end of the integrator loop. if( !equidistantControlGrid() ) { loop->addStatement( "}\n" ); } else { integrate.addStatement( *loop ); } // PART 1 if( NX1 > 0 ) { Matrix zeroR = zeros(1, NX2); ExportForLoop loop1( i,0,NX1 ); loop1.addStatement( rk_eta.getCols( i*NX+NX+NXA+NX1,i*NX+NX+NXA+NX ) == zeroR ); integrate.addStatement( loop1 ); } if ( (PrintLevel)printLevel >= HIGH ) acadoPrintf( "done.\n" ); return SUCCESSFUL_RETURN; }