Пример #1
0
/* identitical to same function within the class Process! */
returnValue Actuator::checkInputConsistency(	const VariablesGrid& _u,
												const VariablesGrid& _p
												) const
{
	if ( _u.getNumPoints( ) < 2 )
		return ACADOERROR( RET_INVALID_ARGUMENTS );

	if ( _u.getNumRows( ) != getNU( ) )
		return ACADOERROR( RET_CONTROL_DIMENSION_MISMATCH );

	if ( _p.isEmpty( ) == BT_TRUE )
	{
		if ( getNP( ) > 0 )
			return ACADOERROR( RET_PARAMETER_DIMENSION_MISMATCH );
	}
	else
	{
		if ( _p.getNumPoints( ) < 2 )
			return ACADOERROR( RET_INVALID_ARGUMENTS );

		if ( _p.getNumRows( ) != getNP( ) )
			return ACADOERROR( RET_PARAMETER_DIMENSION_MISMATCH );
	
		if ( acadoIsEqual( _u.getFirstTime( ),_p.getFirstTime( ) ) == BT_FALSE )
			return ACADOERROR( RET_INVALID_ARGUMENTS );
	
		if ( acadoIsEqual( _u.getLastTime( ),_p.getLastTime( ) ) == BT_FALSE )
			return ACADOERROR( RET_INVALID_ARGUMENTS );
	}

	return SUCCESSFUL_RETURN;
}
Пример #2
0
returnValue Actuator::addActuatorNoise(	VariablesGrid& _u,
										VariablesGrid& _p
										) const
{
	if ( hasNoise( ) == BT_FALSE )
		return SUCCESSFUL_RETURN;

	// generate current noise
	VariablesGrid currentNoise;

	if ( generateNoise( _u.getFirstTime(),_u.getLastTime(),currentNoise ) != SUCCESSFUL_RETURN )
		return ACADOERROR( RET_GENERATING_NOISE_FAILED );

	// determine common grid
	Grid commonGrid, tmpGrid;
	currentNoise.getGrid( tmpGrid );
	_u.getGrid( commonGrid );
	commonGrid & tmpGrid;


	// adapt input grids and add noise
	_u.refineGrid( commonGrid );
	currentNoise.refineGrid( commonGrid );
	_u += currentNoise.getValuesSubGrid( 0,getNU()-1 );

	if ( _p.isEmpty( ) == BT_FALSE )
	{
		_p.refineGrid( commonGrid );
		_p += currentNoise.getValuesSubGrid( getNU(),getNU()+getNP()-1 );
	}

	return SUCCESSFUL_RETURN;
}
Пример #3
0
returnValue Actuator::setParameterDeadTimes(	const Vector& _deadTimes
												)
{
	if ( _deadTimes.getDim( ) != getNP( ) )
		return ACADOERROR( RET_INVALID_ARGUMENTS );

	if ( _deadTimes.getMin( ) < 0.0 )
		return ACADOERROR( RET_INVALID_ARGUMENTS );

	if ( deadTimes.getDim( ) == 0 )
		return ACADOERROR( RET_MEMBER_NOT_INITIALISED );

	for( uint i=0; i<getNP(); ++i )
		deadTimes( getNU()+i ) = _deadTimes( i );

	return SUCCESSFUL_RETURN;
}
Пример #4
0
returnValue Actuator::setParameterNoise(	const Noise& _noise,
											double _noiseSamplingTime
											)
{
	if ( _noise.getDim( ) != getNP( ) )
		return ACADOERROR( RET_INVALID_ARGUMENTS );

	for( uint i=0; i<getNP( ); ++i )
	{
		if ( additiveNoise[ getNU()+i ] != 0 )
			delete additiveNoise[ getNU()+i ];

		additiveNoise[ getNU()+i ] = _noise.clone( i );
	}
	
	noiseSamplingTimes.setAll( _noiseSamplingTime );

	return SUCCESSFUL_RETURN;
}
Пример #5
0
returnValue Actuator::setParameterDeadTimes(	double _deadTime
												)
{
	if ( _deadTime < 0.0 )
		return ACADOERROR( RET_INVALID_ARGUMENTS );

	if ( deadTimes.getDim( ) == 0 )
		return ACADOERROR( RET_MEMBER_NOT_INITIALISED );

	for( uint i=0; i<getNP(); ++i )
		deadTimes( getNU()+i ) = _deadTime;

	return SUCCESSFUL_RETURN;
}
Пример #6
0
returnValue Actuator::setParameterNoise(	uint idx,
											const Noise& _noise,
											double _noiseSamplingTime
											)
{
	if ( ( idx >= getNP( ) ) || ( _noise.getDim( ) != 1 ) )
		return ACADOERROR( RET_INVALID_ARGUMENTS );

	if ( additiveNoise[ getNU()+idx ] != 0 )
		delete additiveNoise[ getNU()+idx ];

	additiveNoise[ getNU()+idx ] = _noise.clone( );

	if ( ( idx > 0 ) && ( acadoIsEqual( _noiseSamplingTime, noiseSamplingTimes(0) ) == BT_FALSE ) )
		ACADOWARNING( RET_NO_DIFFERENT_NOISE_SAMPLING_FOR_DISCRETE );

	noiseSamplingTimes.setAll( _noiseSamplingTime ); // should be changed later

	return SUCCESSFUL_RETURN;
}
Пример #7
0
returnValue CondensingExport::setupEvaluation( )
{
	x.setup( "x",        (getN()+1), getNX(), REAL,ACADO_VARIABLES );
	u.setup( "u",        getN(), getNU(),     REAL,ACADO_VARIABLES );
	p.setup( "p",        1, getNP(),          REAL,ACADO_VARIABLES );

	state.setup   ( "state",    1,getNX()*(getNX()+getNU()+1) + getNU() +getNP(), REAL,ACADO_WORKSPACE );

	if ( isInitialStateFixed( ) == BT_FALSE )
	{
		x0Ref.setup ( "x0Ref",  1, getNX(), REAL,ACADO_VARIABLES );
		x0Ref2.setup( "x0Ref2", 1, getNX(), REAL,ACADO_VARIABLES );
	}

	E.setup  ( "E",   getN()*getNX(), getN()*getNU(), REAL,ACADO_WORKSPACE );
	lbA.setup( "lbA", getNumStateBounds(), 1, REAL,ACADO_WORKSPACE );
	ubA.setup( "ubA", getNumStateBounds(), 1, REAL,ACADO_WORKSPACE );

	Matrix zeroXU = zeros( getNX(),getNU() );
	Matrix idX    = eye( getNX() );

	//
	// setupQP
	//
	setupQP.setup( "setupQP" );
    
	if ( performsSingleShooting() == BT_TRUE )
		setupQP.addStatement( state.getCols( 0,getNX() ) == x.getRow(0) );

	// TODO: this part should be preinitialized. More specifically, E & QE matrices should be preinitializes to 0.
	uint run1, run2;
	for( run1 = 0; run1 < getN()-1; run1++ )
		for( run2 = 1+run1; run2 < getN(); run2++ )
			setupQP.addStatement( E.getSubMatrix( run1*getNX(),(run1+1)*getNX(), run2*getNU(),(run2+1)*getNU() ) == zeroXU );


    // Write state bounds to the file
	// TODO: Since the bounds are fixed in this case, they should be preinitialized
	if( getNumStateBounds( ) > 0 )
	{
		Vector xLowerBounds(nxBounds), xUpperBounds(nxBounds);
		for( run1 = 0; run1 < nxBounds; run1++ )
		{
			xLowerBounds(run1) = xBounds.getLowerBound( xBoundsIdx[run1]/getNX(),xBoundsIdx[run1]%getNX() );
			xUpperBounds(run1) = xBounds.getUpperBound( xBoundsIdx[run1]/getNX(),xBoundsIdx[run1]%getNX() );
		}
		
		setupQP.addStatement( lbA == xLowerBounds );
		setupQP.addStatement( ubA == xUpperBounds );
	}
	setupQP.addLinebreak( );


	if ( isInitialStateFixed( ) == BT_FALSE )
	{
		setupQP.addStatement( Dx0  == x.getRow(0) - x0Ref );
		setupQP.addStatement( Dx0b == x.getRow(0) - x0Ref2 );
		setupQP.addLinebreak( );
	}
	
	
	// compute QQF if necessary
	if ( QQF.isGiven( ) == BT_FALSE )
		setupQP.addStatement( QQF == Q + QF );

	ExportIndex reset( String("reset") );
	setupQP.addIndex( reset );
	setupQP.addStatement( reset == 1 );

	ExportIndex run( String("run1") );
	ExportForLoop loop( run, 0,getN() );
	
	setupQP.addIndex( run );

	if ( performsSingleShooting() == BT_FALSE ) {
		loop.addStatement( reset == 1 );
		loop.addStatement( state.getCols( 0,getNX() ) == x.getRow( run ) );
	}
	
	// no free parameters implemented yet!
	uint uIdx = getNX() * ( 1+getNX() );
	uint pIdx = getNX() * ( 1+getNX()+getNU() );
	uIdx = pIdx;
	pIdx = pIdx + getNU();
	loop.addStatement( state.getCols( uIdx,pIdx ) == u.getRow( run ) );
	loop.addStatement( state.getCols( pIdx,pIdx+getNP() ) == p );
	loop.addLinebreak( );
	
	if ( integrator->equidistantControlGrid() )
	{
		loop.addFunctionCall( "integrate", state, reset.makeArgument() );
	}
	else
	{
		loop.addFunctionCall( "integrate", state, reset.makeArgument(), run.makeArgument() );
	}
	if( performsSingleShooting() ) loop.addStatement( reset == 0 );
	
	if ( performsSingleShooting() == BT_TRUE )
	{
		loop.addStatement( x.getRow( run+1 ) == state.getCols( 0,getNX() ) );
	}
	else
	{
		//
		// Multiple shooting
		// TODO: Check the sign here
		//
		loop.addStatement( residuum.getRow( run ) == state.getCols( 0,getNX() ) - x.getRow( run+1 ) );
	}
	
	loop.addLinebreak( );
	
	loop.addFunctionCall( condense1, run.makeArgument(),state );

    setupQP.addStatement( loop );
	setupQP.addLinebreak( );
		
	setupQP.addFunctionCall( condense2 );

	////////////////////////////////////////////////////////////////////////////
	//
	// Get objective value
	//
	////////////////////////////////////////////////////////////////////////////

	ExportVariable tmp("tmp", 1, 1, REAL, ACADO_LOCAL, BT_TRUE);
	ExportVariable tmpDx("tmpDx", 1, getNX(), REAL, ACADO_LOCAL );
	ExportVariable tmpDu("tmpDu", 1, getNU(), REAL, ACADO_LOCAL );

	getObjectiveValue.setup( "getObjectiveValue" );
	getObjectiveValue.setReturnValue( tmp );

	getObjectiveValue.addVariable( tmpDx );
	getObjectiveValue.addVariable( tmpDu );

	getObjectiveValue.addStatement( tmp == 0.0 );
	getObjectiveValue.addLinebreak( );

	for (unsigned i = 0; i < getN(); ++i)
	{
		getObjectiveValue.addStatement( tmpDx == Dx.getRow( i ) * Q );
		getObjectiveValue.addStatement( tmp += Dx.getRow( i ) * tmpDx.getTranspose() );
	}
	getObjectiveValue.addLinebreak( );

	for (unsigned i = 0; i < getN(); ++i)
	{
		getObjectiveValue.addStatement( tmpDu == Du.getRow( i ) * R );
		getObjectiveValue.addStatement( tmp += Du.getRow( i ) * tmpDu.getTranspose() );
	}
	getObjectiveValue.addLinebreak( );

	getObjectiveValue.addStatement( tmp == tmp * Matrix( 0.5 ) );

	return SUCCESSFUL_RETURN;
}
Пример #8
0
returnValue Actuator::getDelayedInputGrids(	const VariablesGrid& _u,
											const VariablesGrid& _p,
											VariablesGrid& _uDelayed,
											VariablesGrid& _pDelayed
											) const
{
	// determine common time grid for delayed inputs:
	Grid delayedInputTimeGrid = lastSignal.getTimePoints( );

	// make sure that last time instant of horizon lies within the grid
	if ( acadoIsEqual( lastSignal.getLastTime(),_u.getLastTime( ) ) == BT_FALSE )
		delayedInputTimeGrid.addTime( _u.getLastTime( ) );

//	delayedInputTimeGrid.print();
	
	// add grids of all delayed input components
	for( uint i=0; i<getNU( ); ++i )
		delayedInputTimeGrid = delayedInputTimeGrid & ( _u.getTimePoints( ).shiftTimes( deadTimes(i) ) );

// 	_u.getTimePoints( ).print();
// 	_u.getTimePoints( ).shiftTimes( deadTimes(0) ).print();
// 	delayedInputTimeGrid.print();
	
	if ( _p.isEmpty( ) == BT_FALSE )
	{
		for( uint i=0; i<getNP( ); ++i )
			delayedInputTimeGrid = delayedInputTimeGrid & ( _p.getTimePoints( ).shiftTimes( deadTimes(getNU()+i) ) );
	}

	VariablesGrid tmp;

	// setup common variables grid for delayed inputs
	_uDelayed.init( );
	_pDelayed.init( );

	for( uint i=0; i<getNU( ); ++i )
	{
// 		tmp.print("tmp");
		tmp = lastSignal( i );
// 		tmp.print("tmp");
		tmp.merge( _u( i ).shiftTimes( deadTimes(i) ),MM_REPLACE,BT_FALSE );
// 		tmp.print("tmp");
		tmp.refineGrid( delayedInputTimeGrid );
// 		tmp.print("tmp");
		
		_uDelayed.appendValues( tmp );
	}

	if ( _p.isEmpty( ) == BT_FALSE )
	{
		for( uint i=0; i<getNP( ); ++i )
		{
			tmp = lastSignal( getNU()+i );
			tmp.merge( _p( i ).shiftTimes( deadTimes(getNU()+i) ),MM_REPLACE,BT_FALSE );
			tmp.refineGrid( delayedInputTimeGrid );

			_pDelayed.appendValues( tmp );
		}
	}

	return SUCCESSFUL_RETURN;
}
Пример #9
0
returnValue SimulationEnvironment::step( )
{
	/* Consistency check. */
	if ( getStatus( ) != BS_READY )
		return ACADOERROR( RET_BLOCK_NOT_READY );


	++nSteps;
	acadoPrintf( "\n*** Simulation Loop No. %d (starting at time %.3f) ***\n",nSteps,simulationClock.getTime( ) );

	/* Perform one single simulation loop */
	Vector u, p;
	Vector uPrevious, pPrevious;

	if ( getNU( ) > 0 )
		feedbackControl.evaluate( simulationClock.getTime( ),uPrevious );

	if ( getNP( ) > 0 )
		feedbackParameter.evaluate( simulationClock.getTime( ),pPrevious );

	VariablesGrid y;
	Vector yPrevious;

	if ( getNY( ) > 0 )
		processOutput.evaluate( simulationClock.getTime( ),yPrevious );


	// step controller
// 	yPrevious.print("controller input y");
	
	if ( controller->step( simulationClock.getTime( ),yPrevious ) != SUCCESSFUL_RETURN )
		return ACADOERROR( RET_ENVIRONMENT_STEP_FAILED );

	double compDelay = determineComputationalDelay( controller->getPreviousRealRuntime( ) );
	double nextSamplingInstant = controller->getNextSamplingInstant( simulationClock.getTime( ) );
	nextSamplingInstant = round( nextSamplingInstant * 1.0e6 ) / 1.0e6;

	// obtain new controls and parameters
	if ( controller->getU( u ) != SUCCESSFUL_RETURN )
		return ACADOERROR( RET_ENVIRONMENT_STEP_FAILED );

// 	u.print("controller output u");

	if ( controller->getP( p ) != SUCCESSFUL_RETURN )
		return ACADOERROR( RET_ENVIRONMENT_STEP_FAILED );

	if ( acadoIsEqual( simulationClock.getTime( ),endTime ) == BT_TRUE )
	{
		simulationClock.init( nextSamplingInstant );
		return SUCCESSFUL_RETURN;
	}
	
	if ( fabs( compDelay ) < 100.0*EPS )
	{
		// step process without computational delay
		if ( process->step( simulationClock.getTime( ),nextSamplingInstant,u,p ) != SUCCESSFUL_RETURN )
			return ACADOERROR( RET_ENVIRONMENT_STEP_FAILED );

		// Obtain current process output
		if ( process->getY( y ) != SUCCESSFUL_RETURN )
			return ACADOERROR( RET_ENVIRONMENT_STEP_FAILED );

// 		y.print("process output y");

		// update history
		if ( getNU( ) > 0 )
			feedbackControl.  add( simulationClock.getTime( ),nextSamplingInstant,u );
		if ( getNP( ) > 0 )
			feedbackParameter.add( simulationClock.getTime( ),nextSamplingInstant,p );
		if ( getNY( ) > 0 )
			processOutput.    add( y,IM_LINEAR );
	}
	else
	{
		// step process WITH computational delay
		if ( simulationClock.getTime( )+compDelay > nextSamplingInstant )
			return ACADOERROR( RET_COMPUTATIONAL_DELAY_TOO_BIG );

		Grid delayGrid( 3 );
		delayGrid.setTime( simulationClock.getTime( ) );
		delayGrid.setTime( simulationClock.getTime( )+compDelay );
		delayGrid.setTime( nextSamplingInstant );

		VariablesGrid uDelayed( u.getDim( ),delayGrid,VT_CONTROL );
		uDelayed.setVector( 0,uPrevious );
		uDelayed.setVector( 1,u );
		uDelayed.setVector( 2,u );

		VariablesGrid pDelayed( p.getDim( ),delayGrid,VT_PARAMETER );
		pDelayed.setVector( 0,pPrevious );
		pDelayed.setVector( 1,p );
		pDelayed.setVector( 2,p );

		if ( process->step( uDelayed,pDelayed ) != SUCCESSFUL_RETURN )
			return ACADOERROR( RET_ENVIRONMENT_STEP_FAILED );

		// Obtain current process output
		if ( process->getY( y ) != SUCCESSFUL_RETURN )
			return ACADOERROR( RET_ENVIRONMENT_STEP_FAILED );

		// update history
		if ( getNU( ) > 0 )
			feedbackControl.  add( uDelayed,IM_CONSTANT );

		if ( getNP( ) > 0 )
			feedbackParameter.add( pDelayed,IM_CONSTANT );

		if ( getNY( ) > 0 )
			processOutput.    add( y,IM_LINEAR );
	}

	// update simulation clock
	simulationClock.init( nextSamplingInstant );

	return SUCCESSFUL_RETURN;
}
Пример #10
0
returnValue SimulationEnvironment::init(	const Vector &x0_,
											const Vector &p_
											)
{
	// 1) initialise all sub-blocks and evaluate process at start time
	Vector uStart, pStart;
	VariablesGrid yStart;
	
	if ( controller != 0 )
	{
		if ( controller->init( startTime,x0_,p_ ) != SUCCESSFUL_RETURN )
			return ACADOERROR( RET_ENVIRONMENT_INIT_FAILED );

		if ( controller->getU( uStart ) != SUCCESSFUL_RETURN )
			return ACADOERROR( RET_ENVIRONMENT_INIT_FAILED );

		if ( controller->getP( pStart ) != SUCCESSFUL_RETURN )
			return ACADOERROR( RET_ENVIRONMENT_INIT_FAILED );
	}
	else
		return ACADOERROR( RET_NO_CONTROLLER_SPECIFIED );
	

	if ( process != 0 )
	{
		if ( process->init( startTime,x0_,uStart,pStart ) != SUCCESSFUL_RETURN )
			return ACADOERROR( RET_ENVIRONMENT_INIT_FAILED );

		if ( process->getY( yStart ) != SUCCESSFUL_RETURN )
			return ACADOERROR( RET_ENVIRONMENT_INIT_FAILED );
	}
	else
		return ACADOERROR( RET_NO_PROCESS_SPECIFIED );

	simulationClock.init( startTime );


	// 2) consistency checks
	if ( ( process != 0 ) && ( controller != 0 ) )
	{
		if ( process->getNY( ) != controller->getNY( ) )
			return ACADOERROR( RET_BLOCK_DIMENSION_MISMATCH );

// 		printf( "%d  %d\n",process->getNU( ),controller->getNU( ) );
			
		if ( process->getNU( ) != controller->getNU( ) )
			return ACADOERROR( RET_BLOCK_DIMENSION_MISMATCH );

		if ( process->getNP( ) > controller->getNP( ) )
			return ACADOERROR( RET_BLOCK_DIMENSION_MISMATCH );
	}


	// initialise history...
	if ( getNU( ) > 0 )
		feedbackControl.  add( startTime-10.0*EPS,startTime,uStart );

	if ( getNP( ) > 0 )
		feedbackParameter.add( startTime-10.0*EPS,startTime,pStart );
	if ( getNY( ) > 0 )
		processOutput.    add( startTime-10.0*EPS,startTime,yStart.getVector(0) );

	// ... and update block status
	setStatus( BS_READY );
	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;
}
Пример #12
0
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;
}
Пример #13
0
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( );
}