returnValue FunctionEvaluationTree::exportCode( FILE *file, const char *fcnName, const char *realString, int precision, uint _numX, uint _numXA, uint _numU ) const{ int run1; int nni = 0; for( run1 = 0; run1 < n; run1++ ) if( lhs_comp[run1]+1 > nni ) nni = lhs_comp[run1]+1; uint numX; if( _numX > 0 ) { numX = _numX; } else { numX = getNX(); } uint numXA; if( _numXA > 0 ) { numXA = _numXA; } else { numXA = getNXA(); } uint numU; if( _numU > 0 ) { numU = _numU; } else { numU = getNU(); } acadoFPrintf(file,"void %s( const %s* acado_x, %s* acado_f ){\n", fcnName,realString,realString ); if( numX > 0 ){ acadoFPrintf(file,"const %s* acado_xd = acado_x;\n", realString ); } if( numXA > 0 ){ acadoFPrintf(file,"const %s* acado_xa = acado_x + %d;\n", realString,numX ); } if( getNU() > 0 ){ acadoFPrintf(file,"const %s* acado_u = acado_x + %d;\n", realString,numX+numXA ); } if( getNUI() > 0 ){ acadoFPrintf(file,"const %s* acado_v = acado_x + %d;\n", realString,numX+numXA+numU ); } if( getNP() > 0 ){ acadoFPrintf(file,"const %s* acado_p = acado_x + %d;\n", realString,numX+numXA+numU+getNUI() ); } if( getNPI() > 0 ){ acadoFPrintf(file,"const %s* acado_q = acado_x + %d;\n", realString,numX+numXA+numU+getNUI()+getNP() ); } if( getNW() > 0 ){ acadoFPrintf(file,"const %s* acado_w = acado_x + %d;\n", realString,numX+numXA+numU+getNUI()+getNP()+getNPI() ); } if( getNDX() > 0 ){ acadoFPrintf(file,"const %s* acado_dx = acado_x + %d;\n", realString,numX+numXA+numU+getNUI()+getNP()+getNPI()+getNW() ); } acadoFPrintf(file,"\n"); acadoFPrintf(file,"/* COMPUTE INTERMEDIATE STATES: */\n"); acadoFPrintf(file,"/* ---------------------------- */\n"); // // This is a (not so quick) hack to have a flexible name for interm. // quantities, but helps. It general case it should be done with // ExportVariable -- to be able to set a working structure, too. So: // // TODO: setGlobalExportvariable should set the full name once.... // String auxVarName; if ( auxVariableStructName.isEmpty() ) { auxVarName = auxVariableName; } else { auxVarName = auxVariableStructName; auxVarName += "."; auxVarName += auxVariableName; } Stream *auxVarIndividualNames = new Stream[nni]; for( run1 = 0; run1 < n; run1++ ) auxVarIndividualNames[lhs_comp[run1]] << auxVarName << "[" << run1 << "]"; // Export intermediate quantities for( run1 = 0; run1 < n; run1++ ) { // Convert the name for intermediate variables for subexpressions sub[ run1 ]->setVariableExportName(VT_INTERMEDIATE_STATE, auxVarIndividualNames ); acadoFPrintf(file,"%s[%d] = ", auxVarName.getName(), run1 ); file << *sub[run1]; acadoFPrintf(file,";\n"); } acadoFPrintf(file,"\n"); acadoFPrintf(file,"/* COMPUTE OUTPUT: */\n"); acadoFPrintf(file,"/* --------------- */\n"); // Export output quantities for( run1 = 0; run1 < dim; run1++ ) { // Convert names for interm. quantities for output expressions f[ run1 ]->setVariableExportName(VT_INTERMEDIATE_STATE, auxVarIndividualNames ); acadoFPrintf(file,"acado_f[%d] = ", run1 ); file << *f[run1]; acadoFPrintf(file,";\n"); } acadoFPrintf(file,"}\n\n"); delete [] auxVarIndividualNames; return SUCCESSFUL_RETURN; }
returnValue FunctionEvaluationTree::exportCode( FILE *file, const char *fcnName, const char *realString, int precision, uint _numX, uint _numXA, uint _numU, uint _numP, uint _numDX ) const{ int run1; int nni = 0; for (run1 = 0; run1 < n; run1++) if (lhs_comp[run1] + 1 > nni) nni = lhs_comp[run1] + 1; unsigned numX = _numX > 0 ? _numX : getNX(); unsigned numXA = _numXA > 0 ? _numXA : getNXA(); unsigned numU = _numU > 0 ? _numU : getNU(); unsigned numP = _numP > 0 ? _numP : getNP(); unsigned numDX = _numDX > 0 ? _numDX : getNDX(); acadoFPrintf(file, "void %s(const %s* in, %s* out)\n{\n", fcnName, realString, realString); if( numX > 0 ){ acadoFPrintf(file,"const %s* xd = in;\n", realString ); } if( numXA > 0 ){ acadoFPrintf(file,"const %s* xa = in + %d;\n", realString,numX ); } if( getNU() > 0 ){ acadoFPrintf(file,"const %s* u = in + %d;\n", realString,numX+numXA ); } if( getNUI() > 0 ){ acadoFPrintf(file,"const %s* v = in + %d;\n", realString,numX+numXA+numU ); } if( numP > 0 ){ acadoFPrintf(file,"const %s* p = in + %d;\n", realString,numX+numXA+numU+getNUI() ); } if( getNPI() > 0 ){ acadoFPrintf(file,"const %s* q = in + %d;\n", realString,numX+numXA+numU+getNUI()+numP ); } if( getNW() > 0 ){ acadoFPrintf(file,"const %s* w = in + %d;\n", realString,numX+numXA+numU+getNUI()+numP+getNPI() ); } if( numDX > 0 ){ acadoFPrintf(file,"const %s* dx = in + %d;\n", realString,numX+numXA+numU+getNUI()+numP+getNPI()+getNW() ); } if( getNT() > 0 ){ acadoFPrintf(file,"const %s* t = in + %d;\n", realString,numX+numXA+numU+getNUI()+numP+getNPI()+getNW()+numDX ); } if (n > 0) { acadoFPrintf(file, "/* Vector of auxiliary variables; number of elements: %d. */\n", n); acadoFPrintf(file, "%s* a = %s;\n", realString, globalExportVariableName.getName() ); acadoFPrintf(file, "\n/* Compute intermediate quantities; */\n"); } Stream *auxVarIndividualNames = new Stream[nni]; for( run1 = 0; run1 < n; run1++ ) auxVarIndividualNames[lhs_comp[run1]] << "a" << "[" << run1 << "]"; // Export intermediate quantities for (run1 = 0; run1 < n; run1++) { // Convert the name for intermediate variables for subexpressions sub[run1]->setVariableExportName(VT_INTERMEDIATE_STATE, auxVarIndividualNames); acadoFPrintf(file, "%s[%d] = ", "a", run1); file << *sub[run1]; acadoFPrintf(file, ";\n"); } acadoFPrintf(file,"\n/* Compute outputs: */\n"); // Export output quantities for (run1 = 0; run1 < dim; run1++) { // Convert names for interm. quantities for output expressions f[run1]->setVariableExportName(VT_INTERMEDIATE_STATE, auxVarIndividualNames); acadoFPrintf(file, "out[%d] = ", run1); file << *f[run1]; acadoFPrintf(file, ";\n"); } acadoFPrintf(file,"}\n\n"); delete [] auxVarIndividualNames; return SUCCESSFUL_RETURN; }
returnValue SIMexport::exportAcadoHeader( const String& _dirName, const String& _fileName, const String& _realString, const String& _intString, int _precision ) const { int qpSolver; get( QP_SOLVER,qpSolver ); int operatingSystem; get( OPERATING_SYSTEM,operatingSystem ); int useSinglePrecision; get( USE_SINGLE_PRECISION,useSinglePrecision ); int fixInitialState; get( FIX_INITIAL_STATE,fixInitialState ); String fileName( _dirName ); fileName << "/" << _fileName; ExportFile acadoHeader( fileName,"", _realString,_intString,_precision ); acadoHeader.addStatement( "#include <stdio.h>\n" ); acadoHeader.addStatement( "#include <math.h>\n" ); if ( (OperatingSystem)operatingSystem == OS_WINDOWS ) { acadoHeader.addStatement( "#include <windows.h>\n" ); } else { // OS_UNIX acadoHeader.addStatement( "#include <time.h>\n" ); acadoHeader.addStatement( "#include <sys/stat.h>\n" ); acadoHeader.addStatement( "#include <sys/time.h>\n" ); } acadoHeader.addLinebreak( ); acadoHeader.addStatement( "#ifndef ACADO_H\n" ); acadoHeader.addStatement( "#define ACADO_H\n" ); acadoHeader.addLinebreak( ); switch ( (QPSolverName)qpSolver ) { case QP_CVXGEN: acadoHeader.addStatement( "#define USE_CVXGEN\n" ); acadoHeader.addStatement( "#include \"cvxgen/solver.h\"\n" ); acadoHeader.addLinebreak( 2 ); if ( (BooleanType)useSinglePrecision == BT_TRUE ) acadoHeader.addStatement( "typedef float real_t;\n" ); else acadoHeader.addStatement( "typedef double real_t;\n" ); acadoHeader.addLinebreak( 2 ); break; case QP_QPOASES: acadoHeader.addStatement( "#ifndef __MATLAB__\n" ); acadoHeader.addStatement( "#ifdef __cplusplus\n" ); acadoHeader.addStatement( "extern \"C\"\n" ); acadoHeader.addStatement( "{\n" ); acadoHeader.addStatement( "#endif\n" ); acadoHeader.addStatement( "#endif\n" ); acadoHeader.addStatement( "#include \"qpoases/solver.hpp\"\n" ); acadoHeader.addLinebreak( 2 ); break; case QP_QPOASES3: acadoHeader.addStatement( "#include \"qpoases3/solver.h\"\n" ); acadoHeader.addLinebreak( 2 ); break; case QP_NONE: if ( (BooleanType)useSinglePrecision == BT_TRUE ) acadoHeader.addStatement( "typedef float real_t;\n" ); else acadoHeader.addStatement( "typedef double real_t;\n" ); acadoHeader.addLinebreak( 2 ); break; default: return ACADOERROR( RET_INVALID_OPTION ); } Vector nMeasV = getNumMeas(); Vector nOutV = getDimOutputs(); if( nMeasV.getDim() != nOutV.getDim() ) return ACADOERROR( RET_INVALID_OPTION ); // // Some common defines // acadoHeader.addComment( "COMMON DEFINITIONS: " ); acadoHeader.addComment( "--------------------------------" ); acadoHeader.addLinebreak( 2 ); if( (uint)nOutV.getDim() > 0 ) { acadoHeader.addComment( "Dimension of the output functions" ); acadoHeader.addDeclaration( ExportVariable( "NOUT",nOutV,STATIC_CONST_INT ) ); acadoHeader.addComment( "Measurements of the output functions per shooting interval" ); acadoHeader.addDeclaration( ExportVariable( "NMEAS",nMeasV,STATIC_CONST_INT ) ); } acadoHeader.addLinebreak( 2 ); acadoHeader.addComment( "Number of control intervals" ); acadoHeader.addStatement( (String)"#define ACADO_N " << getN() << "\n"); acadoHeader.addComment( "Number of differential states" ); acadoHeader.addStatement( (String)"#define ACADO_NX " << getNX() << "\n" ); acadoHeader.addComment( "Number of differential state derivatives" ); acadoHeader.addStatement( (String)"#define ACADO_NDX " << getNDX() << "\n" ); acadoHeader.addComment( "Number of algebraic states" ); acadoHeader.addStatement( (String)"#define ACADO_NXA " << getNXA() << "\n" ); acadoHeader.addComment( "Number of controls" ); acadoHeader.addStatement( (String)"#define ACADO_NU " << getNU() << "\n" ); acadoHeader.addComment( "Number of parameters" ); acadoHeader.addStatement( (String)"#define ACADO_NP " << getNP() << "\n" ); acadoHeader.addComment( "Number of output functions" ); acadoHeader.addStatement( (String)"#define NUM_OUTPUTS " << (uint)nOutV.getDim() << "\n" ); acadoHeader.addLinebreak( 2 ); acadoHeader.addComment( "GLOBAL VARIABLES: " ); acadoHeader.addComment( "--------------------------------" ); ExportStatementBlock tempHeader; if ( collectDataDeclarations( tempHeader,ACADO_VARIABLES ) != SUCCESSFUL_RETURN ) return ACADOERROR( RET_UNABLE_TO_EXPORT_CODE ); acadoHeader.addStatement( "typedef struct ACADOvariables_ {\n" ); acadoHeader.addStatement( tempHeader ); #ifdef WIN32 if( tempHeader.getNumStatements() == 0 ) { acadoHeader.addStatement( "int dummy; \n" ); } #endif acadoHeader.addLinebreak( ); acadoHeader.addStatement( "} ACADOvariables;\n" ); acadoHeader.addLinebreak( 2 ); acadoHeader.addComment( "GLOBAL WORKSPACE: " ); acadoHeader.addComment( "--------------------------------" ); acadoHeader.addStatement( "typedef struct ACADOworkspace_ {\n" ); if ( collectDataDeclarations( acadoHeader,ACADO_WORKSPACE ) != SUCCESSFUL_RETURN ) return ACADOERROR( RET_UNABLE_TO_EXPORT_CODE ); acadoHeader.addLinebreak( ); acadoHeader.addStatement( "} ACADOworkspace;\n" ); acadoHeader.addLinebreak( 2 ); acadoHeader.addComment( "GLOBAL FORWARD DECLARATIONS: " ); acadoHeader.addComment( "-------------------------------------" ); if ( collectFunctionDeclarations( acadoHeader ) != SUCCESSFUL_RETURN ) return ACADOERROR( RET_UNABLE_TO_EXPORT_CODE ); acadoHeader.addComment( "-------------------------------------" ); acadoHeader.addLinebreak( 2 ); acadoHeader.addComment( "EXTERN DECLARATIONS: " ); acadoHeader.addComment( "-------------------------------------" ); acadoHeader.addStatement( "extern ACADOworkspace acadoWorkspace;\n" ); acadoHeader.addStatement( "extern ACADOvariables acadoVariables;\n" ); acadoHeader.addComment( "-------------------------------------" ); switch ( (QPSolverName) qpSolver ) { case QP_CVXGEN: break; case QP_QPOASES: acadoHeader.addStatement( "#ifndef __MATLAB__\n"); acadoHeader.addStatement( "#ifdef __cplusplus\n" ); acadoHeader.addLinebreak( ); acadoHeader.addStatement( "} /* extern \"C\" */\n" ); acadoHeader.addStatement( "#endif\n" ); acadoHeader.addStatement( "#endif\n" ); break; case QP_QPOASES3: break; case QP_NONE: break; default: return ACADOERROR( RET_INVALID_OPTION ); } acadoHeader.addStatement( "#endif\n" ); acadoHeader.addLinebreak( ); acadoHeader.addComment( "END OF FILE." ); acadoHeader.addLinebreak( ); return acadoHeader.exportCode( ); }