示例#1
0
	/*******************************************************//**
	 * Loads the DLL.
	 *
	 * @return	The DLL.
	 *******************************************************/
	int MainController::loadDll( ) {
		Logger::getInstance()->printDebug2 (_T("MainController::loadDll unzipFolderPath_: %s\n"), unzipFolderPath_);
		const char* modelId = getModelIdentifier(fmu_->modelDescription);
		
		int len = strlen(unzipFolderPath_) + strlen(DLL_DIR_STR)
			+ strlen(modelId) + strlen(_T(".dll")) + 1;

		dllFilePath_ = (char *)calloc(sizeof(char), len);


		sprintf_s(dllFilePath_,
			len,
			_T("%s%s%s.dll"),
			unzipFolderPath_,
			DLL_DIR_STR,
			modelId
			);

		if (dllFilePath_ == NULL){
			Logger::getInstance()->printfError(_T("Failed to allocate memory for wText\n"), dllFilePath_);
			return 1;
		}

		Logger::getInstance()->printDebug2 (_T("dllFilePath_: %s \n"), dllFilePath_);

		HINSTANCE h;
		h = LoadLibrary(dllFilePath_);

		if(!h) {
			Logger::getInstance()->printfError(_T("Can not load %s\n"), dllFilePath_);
			exit(EXIT_FAILURE);
		}

		fmu_->dllHandle = h;
		fmu_->getVersion = (fGetVersion) getAdr("fmiGetVersion");
		fmu_->instantiateSlave = (fInstantiateSlave) getAdr("fmiInstantiateSlave");
		fmu_->freeSlaveInstance = (fFreeSlaveInstance) getAdr( "fmiFreeSlaveInstance");
		fmu_->setDebugLogging = (fSetDebugLogging) getAdr( "fmiSetDebugLogging");
		fmu_->setReal = (fSetReal) getAdr( "fmiSetReal");
		fmu_->setInteger = (fSetInteger) getAdr( "fmiSetInteger");
		fmu_->setBoolean = (fSetBoolean) getAdr( "fmiSetBoolean");
		fmu_->setString = (fSetString) getAdr( "fmiSetString");
		fmu_->initializeSlave = (fInitializeSlave) getAdr("fmiInitializeSlave");
		fmu_->getReal = (fGetReal) getAdr( "fmiGetReal");
		fmu_->getInteger = (fGetInteger) getAdr( "fmiGetInteger");
		fmu_->getBoolean = (fGetBoolean) getAdr("fmiGetBoolean");
		fmu_->getString = (fGetString) getAdr( "fmiGetString");
		fmu_->doStep = (fDoStep) getAdr("fmiDoStep");
		fmu_->terminateSlave = (fTerminateSlave) getAdr("fmiTerminateSlave");
		
		//resetSlave does not seem to be implented 
		fmu_->resetSlave = (fResetSlave) getAdr("fmiResetSlave");

		setState_( simStateNative_3_init_dllLoaded );

		return 0;
	}
示例#2
0
文件: main.c 项目: mtiller/fmusdk
static void* getAdr(FMU *fmu, const char* functionName) {
    char name[BUFSIZE];
    void* fp;
    sprintf(name, "%s_%s", getModelIdentifier(fmu->modelDescription), functionName);
    fp = GetProcAddress(fmu->dllHandle, name);
    if (!fp) {
        printf ("error: Function %s not found in dll\n", name);
    }
    return fp;
}
示例#3
0
///////////////////////////////////////////////////////////////////////////////
/// Get address of specific function from specific dll
///
///\param fmu Name of dll file.
///\param funnam Function name .
///\return Address of the specific function.
//////////////////////////////////////////////////////////////////////////////
static void* getAdr(FMU *fmu, const char* funNam){
    char name[BUFSIZE];
    void* fp;
    sprintf(name, "%s_%s", getModelIdentifier(fmu->modelDescription), funNam); // Zuo: adding the model name in front of funciton name

    fp = GetProcAddress(fmu->dllHandle, name);
    if (!fp) {
        printfError("Function %s not found in dll.\n", name);        
    }
    return fp;
}
示例#4
0
	/*******************************************************//**
	 * Gets the address.
	 *
	 * @param	funNam	The fun nam.
	 *
	 * @return	null if it fails, else the address.
	 *******************************************************/
	void* MainController::getAdr(const char* funNam){
		char name[MSG_BUFFER_SIZE];
		void* fp;
		sprintf_s(name, MSG_BUFFER_SIZE, _T("%s_%s"), getModelIdentifier(fmu_->modelDescription), funNam); // Zuo: adding the model name in front of function name

		fp = GetProcAddress(fmu_->dllHandle, name);

		if (!fp) {
			Logger::getInstance()->printfError(_T("Function %s not found in dll\n"), name);
		}
		return fp;
	}
示例#5
0
	/*******************************************************//**
	 * Gets the instantiate slave.
	 *
	 * @return	.
	 *******************************************************/
	int MainController::instantiateSlave_() {

		Logger::getInstance()->printDebug(_T("-=MainController::instantiateSlave_=-\n"));
		Logger::getInstance()->printDebug(_T("MainController::simulateHelperInit\n"));

		_TCHAR currentDirectory[MAX_PATH] =  _T("");
		_TCHAR currentDirectory2[MAX_PATH] =  _T("");
		_TCHAR exeDirectory[MAX_PATH] =  _T("");

		isLoggingEnabled_ = 1;
		const char* guid;                // global unique id of the fmu
		const char* modelIdentifier;                //
		fmiCallbackFunctions callbackFunctions;  // called by the model during simulation
		fmiBoolean toleranceControlled = fmiFalse;
		nSteps_ = 0;
		fmiReal timeout = 100.0;
		fmiBoolean visible = false;
		fmiBoolean interactive = true;

		// Set the start time and initialize
		time_ = getStartTime();

		GetCurrentDirectory(MAX_PATH, currentDirectory);
		Logger::getInstance()->printDebug2(_T("currentDirectory: %s\n"), currentDirectory);

		this->getModuleFolderPath(exeDirectory);

		callbackFunctions.logger = FMUlogger::log;
		callbackFunctions.allocateMemory = calloc;
		callbackFunctions.freeMemory = free;

		guid = getString(fmu_->modelDescription, att_guid);
		modelIdentifier =  getModelIdentifier(fmu_->modelDescription);

		Logger::getInstance()->printDebug2(_T("exeDirectory: %s\n"), exeDirectory);
		Logger::getInstance()->printDebug2(_T("unzipFolderPath_%s\n"), unzipFolderPath_);

		Logger::getInstance()->printDebugDouble(_T("stepDelta: %s\n"), getStepDelta());
		Logger::getInstance()->printDebugDouble(_T("time_: %s\n"), time_);
		Logger::getInstance()->printDebugDouble(_T("stopTime: %s\n"), getStopTime());

		Logger::getInstance()->printDebug2(_T("instanceName is %s\n"), modelIdentifier);
		Logger::getInstance()->printDebug2(_T("GUID = %s!\n"), guid);

		BOOL isSet = SetCurrentDirectory(unzipFolderPath_);
		int bufferLength = GetCurrentDirectory(MAX_PATH, currentDirectory2);
		Logger::getInstance()->printDebug2(_T("currentDirectory2: %s\n"), currentDirectory2);

		fmiComponent_ = fmu_->instantiateSlave (
			modelIdentifier,		//fmiString  instanceName
			guid,					//fmiString  fmuGUID
			"Model1",				//fmuLocation
			"",						//fmiString  mimeType
			timeout,				//fmiReal timeout
			visible,				//fmiBoolean visible
			interactive,			//fmiBoolean interactive
			callbackFunctions,
			isLoggingEnabled_		//
			);

		if (!fmiComponent_) {
			setStateError_(_T("Could not instantiate slaves\n"));
			return 1;
		} else {
			Logger::getInstance()->printDebug(_T("Successfully instantiated one slave\n"));
			mainDataModel_->setFmiComponent(fmiComponent_);
			setState_( simStateNative_3_init_instantiatedSlaves );

			return 0;
		}
	}
示例#6
0
文件: fmusim.c 项目: iakovn/fmusdk
// simulate the given FMU using the forward euler method.
// time events are processed by reducing step size to exactly hit tNext.
// state events are checked and fired only at the end of an Euler step. 
// the simulator may therefore miss state events and fires state events typically too late.
int fmuSimulate(FMU* fmu, double tEnd, double h, fmiBoolean loggingOn, char separator, const char* resultFileName) {
    int i;
    double dt, tPre;
    fmiBoolean timeEvent, stateEvent, stepEvent;
    double simtime;
    int nx;                          // number of state variables
    int nz;                          // number of state event indicators
    double *x;                       // continuous states
    double *xdot;                    // the crresponding derivatives in same order
    double *z = NULL;                // state event indicators
    double *prez = NULL;             // previous values of state event indicators
    fmiEventInfo eventInfo;          // updated by calls to initialize and eventUpdate
    ModelDescription* md;            // handle to the parsed XML file        
    const char* guid;                // global unique id of the fmu
    fmiCallbackFunctions callbacks;  // called by the model during simulation
    fmiComponent c;                  // instance of the fmu 
    fmiStatus fmiFlag;               // return code of the fmu functions
    fmiReal t0 = 0;                  // start time
    fmiBoolean toleranceControlled = fmiFalse;
    int nSteps = 0;
    int nTimeEvents = 0;
    int nStepEvents = 0;
    int nStateEvents = 0;
    FILE* file = 0;
    clock_t timing;

    // instantiate the fmu
    md = fmu->modelDescription;
    guid = getString(md, att_guid);
    callbacks.logger = fmuLogger;
    callbacks.allocateMemory = calloc;
    callbacks.freeMemory = free;
    c = fmu->instantiateModel(getModelIdentifier(md), guid, callbacks, loggingOn);
    if (!c) return fmuError("could not instantiate model");
    
    // allocate memory 
    nx = getNumberOfStates(md);
    nz = getNumberOfEventIndicators(md);
    x    = (double *) calloc(nx, sizeof(double));
    xdot = (double *) calloc(nx, sizeof(double));
    if (nz>0) {
        z    =  (double *) calloc(nz, sizeof(double));
        prez =  (double *) calloc(nz, sizeof(double));
    }
    if (!x || !xdot || ((nz>0) && (!z || !prez))) return fmuError("out of memory");

    // open result file
    if(resultFileName != 0) {
        if((strlen(resultFileName)==1) && (resultFileName[0]=='-') )
            file = stdout;
        else {
            if (!(file=fopen(resultFileName, "w"))) {
                fprintf(stderr,"could not write %s\n", resultFileName);
                return 0; // failure
            }
        }
    }

    timing = clock();
    fprintf(stderr,"timing start %ld\n", timing);

    // set the start time and initialize
    simtime = t0;
    fmiFlag =  fmu->setTime(c, t0);
    if (fmiFlag > fmiWarning) return fmuError("could not set time");
    fmiFlag =  fmu->initialize(c, toleranceControlled, t0, &eventInfo);
    if (fmiFlag > fmiWarning)  fmuError("could not initialize model");
    if (eventInfo.terminateSimulation) {
        fprintf(stderr,"model requested termination at init");
        tEnd = simtime;
    }
  
    // output solution for simtime t0
    if(file) {
        outputRow(fmu, c, t0, file, separator, TRUE);  // output column names
        outputRow(fmu, c, t0, file, separator, FALSE); // output values
    }

    // enter the simulation loop
    while (simtime < tEnd) {
     // get current state and derivatives
     fmiFlag = fmu->getContinuousStates(c, x, nx);
     if (fmiFlag > fmiWarning) return fmuError("could not retrieve states");
     fmiFlag = fmu->getDerivatives(c, xdot, nx);
     if (fmiFlag > fmiWarning) return fmuError("could not retrieve derivatives");

     // advance simtime
     tPre = simtime;
     simtime = min(simtime+h, tEnd);
     timeEvent = eventInfo.upcomingTimeEvent && eventInfo.nextEventTime < simtime;
     if (timeEvent) simtime = eventInfo.nextEventTime;
     dt = simtime - tPre;
     fmiFlag = fmu->setTime(c, simtime);
     if (fmiFlag > fmiWarning) fmuError("could not set time");

     // perform one step
     for (i=0; i<nx; i++) x[i] += dt*xdot[i]; // forward Euler method
     fmiFlag = fmu->setContinuousStates(c, x, nx);
     if (fmiFlag > fmiWarning) return fmuError("could not set states");
     if (loggingOn) fprintf(stderr,"Step %d to t=%.16g\n", nSteps, simtime);
    
     // Check for step event, e.g. dynamic state selection
     fmiFlag = fmu->completedIntegratorStep(c, &stepEvent);
     if (fmiFlag > fmiWarning) return fmuError("could not complete intgrator step");

     // Check for state event
     for (i=0; i<nz; i++) prez[i] = z[i]; 
     fmiFlag = fmu->getEventIndicators(c, z, nz);
     if (fmiFlag > fmiWarning) return fmuError("could not retrieve event indicators");
     stateEvent = FALSE;
     for (i=0; i<nz; i++) 
         stateEvent = stateEvent || (prez[i] * z[i] < 0);  
     
     // handle events
     if (timeEvent || stateEvent || stepEvent) {
        
        if (timeEvent) {
            nTimeEvents++;
            if (loggingOn) fprintf(stderr,"time event at t=%.16g\n", simtime);
        }
        if (stateEvent) {
            nStateEvents++;
            if (loggingOn) for (i=0; i<nz; i++)
                fprintf(stderr,"state event %s z[%d] at t=%.16g\n",
                        (prez[i]>0 && z[i]<0) ? "-\\-" : "-/-", i, simtime);
        }
        if (stepEvent) {
            nStepEvents++;
            if (loggingOn) fprintf(stderr,"step event at t=%.16g\n", simtime);
        }

        // event iteration in one step, ignoring intermediate results
        fmiFlag = fmu->eventUpdate(c, fmiFalse, &eventInfo);
        if (fmiFlag > fmiWarning) return fmuError("could not perform event update");
        
        // terminate simulation, if requested by the model
        if (eventInfo.terminateSimulation) {
            fprintf(stderr,"model requested termination at t=%.16g\n", simtime);
            break; // success
        }

        // check for change of value of states
        if (eventInfo.stateValuesChanged && loggingOn) {
            fprintf(stderr,"state values changed at t=%.16g\n", simtime);
        }
        
        // check for selection of new state variables
        if (eventInfo.stateValueReferencesChanged && loggingOn) {
            fprintf(stderr,"new state variables selected at t=%.16g\n", simtime);
        }
       
     } // if event
     if(file)
        outputRow(fmu, c, simtime, file, separator, FALSE); // output values for this step
     nSteps++;
  } // while  

  timing = clock() - timing;

  // cleanup
  fmu->freeModelInstance(c);
  if(file)
    fclose(file);

  if (x!=NULL) free(x);
  if (xdot!= NULL) free(xdot);
  if (z!= NULL) free(z);
  if (prez!= NULL) free(prez);

  // print simulation summary 
  fprintf(stderr,"Simulation from %g to %g terminated successful\n", t0, tEnd);
  fprintf(stderr,"  steps ............ %d\n", nSteps);
  fprintf(stderr,"  fixed step size .. %g\n", h);
  fprintf(stderr,"  time events ...... %d\n", nTimeEvents);
  fprintf(stderr,"  state events ..... %d\n", nStateEvents);
  fprintf(stderr,"  step events ...... %d\n", nStepEvents);
  if(resultFileName && ((strlen(resultFileName)!=1) || (resultFileName[0] != '-')))
        fprintf(stderr,"CSV file '%s' written.\n", resultFileName);
  fprintf(stderr,"  simultation time.. %g seconds (resolution %g sec) \n",
          ((double)timing * 1.0) / CLOCKS_PER_SEC, 1.0/CLOCKS_PER_SEC);

  return 1; // success
}
示例#7
0
///////////////////////////////////////////////////////////////////////////////
/// main routine of the demo code
///
///\param argc Number of arguments
///\param argv Arguments
///\return 0 if no error occurred
///////////////////////////////////////////////////////////////////////////////
int main(int argc, char *argv[]) {
    const char* fmuFilNam;
    char* fmuPat;
    char* tmpPat;
    char* xmlPat;
    char* dllPat;
    
    // define default argument values
    double tEnd = 1.0;
    double h=0.1;
    int loggingOn = 0;
    char csv_separator = ',';  
   
    // parse command line arguments
    if (argc>1) {
        fmuFilNam = argv[1];
        
        if(!strcmp(fmuFilNam, "-h") | !strcmp(fmuFilNam, "--help")) {
          printHelp(argv[0]);
          return 0;
        }

        /*if(!strstr(fmuFilNam,"DoubleInputDoubleOutput.fmu")) {
          printf("Sorry, this demo only works with the FMU file DoubleInputDoubleOutput.fmu");
          return 0;
        }*/
    }
    else {
        printError("No fmu file.\n");
        printHelp(argv[0]);
        exit(EXIT_FAILURE);
    }
    if (argc>2) {
        if (sscanf(argv[2],"%lf", &tEnd) != 1) {
            printfError("The given end time (%s) is not a number.\n", argv[2]);
            exit(EXIT_FAILURE);
        }
    }
    if (argc>3) {
        if (sscanf(argv[3],"%lf", &h) != 1) {
            printfError("The given stepsize (%s) is not a number.\n", argv[3]);
            exit(EXIT_FAILURE);
        }
    }
    if (argc>4) {
        if (sscanf(argv[4],"%d", &loggingOn) != 1 || loggingOn<0 || loggingOn>1) {
            printfError("The given logging flag (%s) is not boolean.\n", argv[4]);
            exit(EXIT_FAILURE);
        }
        if(loggingOn) setDebug();
    }
    if (argc>5) {
        if (strlen(argv[5]) != 1) {
            printfError("The given CSV separator char (%s) is not valid.\n", argv[5]);
            exit(EXIT_FAILURE);
        }
        csv_separator = argv[5][0];
    }
    if (argc>6) {
        printf("warning: Ignoring %d additional arguments: %s ...\n", argc-6, argv[6]);
        printHelp(argv[0]);
    }

    // Get absolute path to FMU, NULL if not found  
    tmpPat = getTmpPath(fmuFilNam, strlen(fmuFilNam)-4);
    if(tmpPat==NULL){
      printError("Cannot allocate temporary path.\n");
      exit(EXIT_FAILURE);
    }

    // Unzip the FMU to the tmpPat directory
    if (unpack(fmuFilNam, tmpPat)) {  
        printfError("Fail to unpack fmu \"%s\".\n", fmuFilNam);
        exit(EXIT_FAILURE);
    }

    printDebug("parse tmpPat\\modelDescription.xml.\n");
    xmlPat = calloc(sizeof(char), strlen(tmpPat) + strlen(XML_FILE) + 1);
    sprintf(xmlPat, "%s%s", tmpPat, XML_FILE);

    // Parse only parses the model description and store in structure fmu.modelDescription
    fmu.modelDescription = parse(xmlPat); 
    free(xmlPat);
    if (!fmu.modelDescription) exit(EXIT_FAILURE);

    // Allocate the memory for dllPat
    dllPat = calloc(sizeof(char), strlen(tmpPat) + strlen(DLL_DIR) 
            + strlen( getModelIdentifier(fmu.modelDescription)) +  strlen(".dll") + 1); 
    sprintf(dllPat,"%s%s%s.dll", tmpPat, DLL_DIR, getModelIdentifier(fmu.modelDescription)); 

    // Load the FMU dll
    if (loadDll(dllPat, &fmu)) exit(EXIT_FAILURE); 
	  printfDebug("Loaded \"%s\"\n", dllPat); 

    free(dllPat);
    free(tmpPat);

    // Run the simulation
    printf("FMU Simulator: run '%s' from t=0..%g with step size h=%g, loggingOn=%d, csv separator='%c'\n", 
            fmuFilNam, tEnd, h, loggingOn, csv_separator);
    if (simulate(&fmu, tEnd, h, loggingOn, csv_separator)){
      printError("Simulation failed.\n");
      exit(EXIT_FAILURE);
    }

    printf("CSV file '%s' written", RESULT_FILE);

    // Release FMU 
    FreeLibrary(fmu.dllHandle);
    freeElement(fmu.modelDescription);
    return EXIT_SUCCESS;
}
示例#8
0
///////////////////////////////////////////////////////////////////////////////
/// Simulate the given FMU using the forward euler method.
/// Time events are processed by reducing step size to exactly hit tNext.
/// State events are checked and fired only at the end of an Euler step. 
/// The simulator may therefore miss state events and fires state events typically too late.
///
///\param fmu FMU.
///\param tEnd Ending time of simulation.
///\param h Tiem step size.
///\param loggingOn Controller for logging.
///\param separator Separator character.
///\return 0 if there is no error occurred.
///////////////////////////////////////////////////////////////////////////////
static int simulate(FMU* fmu, double tEnd, double h, fmiBoolean loggingOn, char separator) {
		
  int i, n;
  fmiBoolean timeEvent, stateEvent, stepEvent;
  double time;  
  ModelDescription* md;            // handle to the parsed XML file        
  const char* guid;                // global unique id of the fmu
  fmiCallbackFunctions callbacks;  // called by the model during simulation
  fmiComponent c;                  // instance of the fmu 
  fmiStatus fmiFlag;               // return code of the fmu functions
  fmiReal t0 = 0;                  // start time
	fmiBoolean toleranceControlled = fmiFalse;
  int nSteps = 0;
  FILE* file;

	fmiValueReference vr;			// add it to get value reference for variables

  //Note: User defined references
  //Begin------------------------------------------------------------------
  fmiValueReference vru[1], vry[1]; // value references for two input and two output variables 
  //End--------------------------------------------------------------------

	ScalarVariable** vars = fmu->modelDescription->modelVariables;		// add it to get variables
	int k;							// add a counter for variables
	fmiReal ru1, ru2, ry, ry1, ry2;	// add real variables for input and output
	fmiInteger ix, iy;				// add integer variables for input and output
	fmiBoolean bx, by;				// add boolean variables for input and output
	fmiString sx, sy;				// Zuo: add string variables for input and output
	fmiStatus status;				// Zuo: add stauus for fmi

	printDebug("Instantiate the fmu.\n");		
  // instantiate the fmu
  md = fmu->modelDescription;
  guid = getString(md, att_guid);
	printfDebug("Got GUID = %s!\n", guid);	
  callbacks.logger = fmuLogger;
  callbacks.allocateMemory = calloc;
  callbacks.freeMemory = free;
	printDebug("Got callbacks!\n");
	printfDebug("Model Identifer is %s\n", getModelIdentifier(md));
 	c = fmu->instantiateSlave(getModelIdentifier(md), guid, "Model1", "", 10, fmiFalse, fmiFalse, callbacks, loggingOn);
  if (!c) {
    printError("could not instantiate slaves.\n");
    return 1;
  }
  printDebug("Instantiated slaves!\n");	

  // Open result file
  if (!(file=fopen(RESULT_FILE, "w"))) {
    printfError("could not write %s because:\n", RESULT_FILE);
    printfError("    %s\n", strerror(errno));
    return 1;
  }
  printDebug("Open results file!\n");    

  // Set the start time and initialize
  time = t0;

	printDebug("start to initialize fmu!\n");	   
	fmiFlag =  fmu->initializeSlave(c, t0, fmiTrue, tEnd);	
	printDebug("Initialized fmu!\n");
  if (fmiFlag > fmiWarning) {
    printError("could not initialize model");
    return 1;
  }
 
  // Output solution for time t0 
  printDebug("start to outputRow");
  //outputRow(fmu, c, t0, file, separator, TRUE);  // output column names
  //outputRow(fmu, c, t0, file, separator, FALSE); // output initla value of fmu 
  outputdata(t0, file, separator, 0, 0, TRUE);
  
  printDebug("start to getValueReference");
  ///////////////////////////////////////////////////////////////////////////// 
  // Get value references for input and output varibles
  // Note: User needs to specify the name of variables for their own fmus
  //Begin------------------------------------------------------------------
  vru[0] = getValueReference(getVariableByName(md, "Toa"));
  //vru[1] = getValueReference(getVariableByName(md, "u2"));
  vry[0] = getValueReference(getVariableByName(md, "TrmSou"));
  //vry[1] = getValueReference(getVariableByName(md, "y2"));
  //End--------------------------------------------------------------------
  
  printDebug("Enter in simulation loop.\n");	

  // enter the simulation loop
  while (time < tEnd) {
    if (loggingOn) printf("Step %d to t=%.4f\n", nSteps, time);		  

    ///////////////////////////////////////////////////////////////////////////
    // Step 1: get values of output variables	from slaves
    for (k=0; vars[k]; k++) {
	    ScalarVariable* sv = vars[k];
	    if (getAlias(sv)!=enu_noAlias) continue;	
	    if (getCausality(sv) != enu_output) continue; // only get output variable
      vr = getValueReference(sv);

      switch (sv->typeSpec->type){
        case elm_Real:
          fmu->getReal(c, &vr, 1, &ry); 
          break;
        case elm_Integer:
          fmu->getInteger(c, &vr, 1, &iy);  
          break;
        case elm_Boolean:
          fmu->getBoolean(c, &vr, 1, &by);
          break;
        case elm_String:
          fmu->getString(c, &vr, 1, &sy);
          break;
      }


      // Allocate values to cooresponding varibles on master program
      // Note: User needs to specify the output variables for their own fmu 
      //Begin------------------------------------------------------------------
      if (vr == vry[0]) ry1 = ry;
      //else if(vr == vry[1]) ry2 = ry;
      //End--------------------------------------------------------------------
    } 
    
    ///////////////////////////////////////////////////////////////////////////
    // Step 2: compute on master side 
    // Note: User can adjust the computing schemes of mater program
    //Begin------------------------------------------------------------------
     printf("Dymola output = %f\n", ry1);
	 //= ry2 + 3.0; 
    ru1 = 293;
    //End--------------------------------------------------------------------

    //////////////////////////////////////////////////////////////////////////
    // Step 3: set input variables back to slaves
    for (k=0; vars[k]; k++) {
      ScalarVariable* sv = vars[k];
      if (getAlias(sv)!=enu_noAlias) continue;
	    if (getCausality(sv) != enu_input) continue; // only set input variable
        vr = getValueReference(sv);
        // Note: User can adjust the settings for input variables
        //Begin------------------------------------------------------------------
        switch (sv->typeSpec->type){
          case elm_Real:

            if(vr == vru[0]) {
              fmu->setReal(c, &vr, 1, &ru1); 				
              printDebug("Set u1.\n");
            }
            //else if (vr == vru[1]) {
            //  fmu->setReal(c, &vr, 1, &ru2);
            //  printDebug("Set u2.\n");
            //}
            else
              printf("Warning: no data given for input variable.\n");
            break;
          case elm_Integer:
            fmu->setInteger(c, &vr, 1, &ix);  
            break;
          case elm_Boolean:
            fmu->setBoolean(c, &vr, 1, &bx);
            break;
          case elm_String:
		    printDebug("Get string in simulatio()");
            fmu->setString(c, &vr, 1, &sx);
            break;        
        }
        //End--------------------------------------------------------------------        
    } 
    
    // Advance to next time step
    status = fmu->doStep(c, time, h, fmiTrue);  
    // Terminate this row
    // fprintf(file, "\n");  (comment out this line to get rid of the blank line between the results in the csv file.)    
   
    time = min(time+h, tEnd);
    //outputRow(fmu, c, time, file, separator, FALSE); // output values for this step
	outputdata(time, file, separator, ru1, ry1, FALSE);
    nSteps++;
   
  } // end of while  

  // Cleanup
  fclose(file);

  // Print simulation summary 
  if (loggingOn) printf("Step %d to t=%.4f\n", nSteps, time);		
  printf("Simulation from %g to %g terminated successful\n", t0, tEnd);
  printf("  steps ............ %d\n", nSteps);
  printf("  fixed step size .. %g\n", h);

  return 0; // success
}
示例#9
0
// simulate the given FMU from tStart = 0 to tEnd.
static int simulate(FMU* fmu, double tEnd, double h, fmiBoolean loggingOn, char separator) {
    double time;
    double tStart = 0;               // start time
    const char* guid;                // global unique id of the fmu
    fmiComponent c;                  // instance of the fmu 
    fmiStatus fmiFlag;               // return code of the fmu functions
    char* fmuLocation = getTempFmuLocation(); // path to the fmu as URL, "file://C:\QTronic\sales"
    const char* mimeType = "application/x-fmu-sharedlibrary"; // denotes tool in case of tool coupling
    fmiReal timeout = 1000;          // wait period in milli seconds, 0 for unlimited wait period"
    fmiBoolean visible = fmiFalse;   // no simulator user interface
    fmiBoolean interactive = fmiFalse; // simulation run without user interaction
    fmiCallbackFunctions callbacks;  // called by the model during simulation
    ModelDescription* md;            // handle to the parsed XML file
    int nSteps = 0;
    FILE* file;

    // instantiate the fmu
    md = fmu->modelDescription;
    guid = getString(md, att_guid);
    callbacks.logger = fmuLogger;
    callbacks.allocateMemory = calloc;
    callbacks.freeMemory = free;
    callbacks.stepFinished = NULL; // fmiDoStep has to be carried out synchronously
    c = fmu->instantiateSlave(getModelIdentifier(md), guid, fmuLocation, mimeType,
                              timeout, visible, interactive, callbacks, loggingOn);
    free(fmuLocation);
    if (!c) return error("could not instantiate model");

    // open result file
    if (!(file=fopen(RESULT_FILE, "w"))) {
        printf("could not write %s because:\n", RESULT_FILE);
        printf("    %s\n", strerror(errno));
        return 0; // failure
    }

    // StopTimeDefined=fmiFalse means: ignore value of tEnd
    fmiFlag = fmu->initializeSlave(c, tStart, fmiTrue, tEnd);
    if (fmiFlag > fmiWarning)  return error("could not initialize model");
    
    // output solution for time t0
    outputRow(fmu, c, tStart, file, separator, fmiTrue);  // output column names
    outputRow(fmu, c, tStart, file, separator, fmiFalse); // output values

    // enter the simulation loop
    time = tStart;
    while (time < tEnd) {
        fmiFlag = fmu->doStep(c, time, h, fmiTrue);
        if (fmiFlag != fmiOK)  return error("could not complete simulation of the model");
        time += h;
        outputRow(fmu, c, time, file, separator, fmiFalse); // output values for this step
        nSteps++;
    }

    // end simulation
    fmiFlag = fmu->terminateSlave(c);
    fmu->freeSlaveInstance(c);
    fclose(file);

    // print simulation summary 
    printf("Simulation from %g to %g terminated successful\n", tStart, tEnd);
    printf("  steps ............ %d\n", nSteps);
    printf("  fixed step size .. %g\n", h);
    return 1; // success
}
示例#10
0
文件: main.c 项目: iakovn/fmusdk
int main(int argc, char *argv[]) {
    const char* fmuFileName = 0;
    char* fmuPath = 0;
    char* tmpPath = 0;
    char* xmlPath = 0;
    char* dllPath = 0;
    char* cmd = 0;
    
    // define default argument values
    double tEnd = 1.0;
    double h=0.1;
    int loggingOn = 0;
    char csv_separator = ';';
    const char* resultFileName = "-";

    // parse command line arguments
    if (argc>1) {
        fmuFileName = argv[1];
    }
    else {
        fprintf(stderr,"error: no fmu file\n");
        printHelp(argv[0]);
        exit(EXIT_FAILURE);
    }
    if (argc>2) {
        if (sscanf(argv[2],"%lf", &tEnd) != 1) {
            fprintf(stderr,"error: The given end time (%s) is not a number\n", argv[2]);
            exit(EXIT_FAILURE);
        }
    }
    if (argc>3) {
        if (sscanf(argv[3],"%lf", &h) != 1) {
            fprintf(stderr,"error: The given stepsize (%s) is not a number\n", argv[3]);
            exit(EXIT_FAILURE);
        }
    }
    if (argc>4) {
        if (sscanf(argv[4],"%d", &loggingOn) != 1 || loggingOn<0 || loggingOn>1) {
            fprintf(stderr,"error: The given logging option (%s) must be 0 or 1\n", argv[4]);
            exit(EXIT_FAILURE);
        }
    }
    if (argc>5) {
        if (strlen(argv[5]) != 1) {
            fprintf(stderr,"error: The given CSV separator char (%s) is not valid\n", argv[5]);
            exit(EXIT_FAILURE);
        }
        csv_separator = argv[5][0];
    }
    if (argc>6) {
        resultFileName = argv[6];
        if(strlen(resultFileName)==0) resultFileName = 0; // no output
    }

    if (argc>7) {
        fprintf(stderr,"warning: Ignoring %d additional arguments: %s ...\n", argc-6, argv[6]);
        printHelp(argv[0]);
    }

    // get absolute path to FMU, NULL if not found
    fmuPath = getFmuPath(fmuFileName);
    if (!fmuPath) exit(EXIT_FAILURE);

    // unzip the FMU to the tmpPath directory
    tmpPath = getTmpPath();
    if (!fmuUnzip(fmuPath, tmpPath)) exit(EXIT_FAILURE);

    // parse tmpPath\modelDescription.xml
    xmlPath = calloc(sizeof(char), strlen(tmpPath) + strlen(XML_FILE) + 1);
    sprintf(xmlPath, "%s%s", tmpPath, XML_FILE);
    fmu.modelDescription = parse(xmlPath);
    free(xmlPath);
    if (!fmu.modelDescription) exit(EXIT_FAILURE);

    // load the FMU dll
    dllPath = calloc(sizeof(char), strlen(tmpPath) + strlen(DLL_DIR) 
            + strlen( getModelIdentifier(fmu.modelDescription)) +  strlen(DLL_SUFFIX) + 1);
    sprintf(dllPath,"%s%s%s%s", tmpPath, DLL_DIR, getModelIdentifier(fmu.modelDescription), DLL_SUFFIX);
    if (!fmuLoadDll(dllPath, &fmu)) exit(EXIT_FAILURE); 
    free(dllPath);
    free(fmuPath);

    // run the simulation
    fprintf(stderr,"FMU Simulator: run '%s' from t=0..%g with step size h=%g, loggingOn=%d, csv separator='%c'\n", 
            fmuFileName, tEnd, h, loggingOn, csv_separator);
    if(resultFileName)
        if(strlen(resultFileName)==1 && resultFileName[0]=='-')
            fprintf(stderr, "Output will be written to standard output\n");
        else
            fprintf(stderr, "Output will be written to file %s\n", resultFileName);
    else
        fprintf(stderr, "No output file will be produced\n");

    fmuSimulate(&fmu, tEnd, h, loggingOn, csv_separator, resultFileName);

#if WINDOWS
    /* Remove temp file directory? Not tested*/
    cmd = calloc(sizeof(char), strlen(tmpPath)+20);
    sprintf(cmd, "rmdir %s /s /q", tmpPath);
    fprintf(stderr,"Removing %s\n", tmpPath);
    system(cmd);
    free(cmd);
#else
    cmd = calloc(sizeof(char), strlen(tmpPath)+8);
    sprintf(cmd, "rm -rf %s", tmpPath);
    fprintf(stderr,"Removing %s\n", tmpPath);
    system(cmd);
    free(cmd);
#endif
    free(tmpPath);

    // release FMU 
    fmuFree(&fmu);
    return EXIT_SUCCESS;
}
示例#11
0
文件: main.c 项目: mtiller/fmusdk
int main(int argc, char *argv[]) {
    const char* fmuFileName;
    char* fmuPath;
    char* tmpPath;
    char* xmlPath;
    char* dllPath;

    // define default argument values
    double tEnd = 1.0;
    double h=0.1;
    int loggingOn = 0;
    char csv_separator = ';';

    // parse command line arguments
    if (argc>1) {
        fmuFileName = argv[1];
    }
    else {
        printf("error: no fmu file\n");
        printHelp(argv[0]);
        exit(EXIT_FAILURE);
    }
    if (argc>2) {
        if (sscanf(argv[2],"%lf", &tEnd) != 1) {
            printf("error: The given end time (%s) is not a number\n", argv[2]);
            exit(EXIT_FAILURE);
        }
    }
    if (argc>3) {
        if (sscanf(argv[3],"%lf", &h) != 1) {
            printf("error: The given stepsize (%s) is not a number\n", argv[3]);
            exit(EXIT_FAILURE);
        }
    }
    if (argc>4) {
        if (sscanf(argv[4],"%d", &loggingOn) != 1 || loggingOn<0 || loggingOn>1) {
            printf("error: The given logging flag (%s) is not boolean\n", argv[4]);
            exit(EXIT_FAILURE);
        }
    }
    if (argc>5) {
        if (strlen(argv[5]) != 1) {
            printf("error: The given CSV separator char (%s) is not valid\n", argv[5]);
            exit(EXIT_FAILURE);
        }
        csv_separator = argv[5][0];
    }
    if (argc>6) {
        printf("warning: Ignoring %d additional arguments: %s ...\n", argc-6, argv[6]);
        printHelp(argv[0]);
    }

    // get absolute path to FMU, NULL if not found
    fmuPath = getFmuPath(fmuFileName);
    if (!fmuPath) exit(EXIT_FAILURE);

    // unzip the FMU to the tmpPath directory
    tmpPath = getTmpPath();
    if (!unzip(fmuPath, tmpPath)) exit(EXIT_FAILURE);

    // parse tmpPath\modelDescription.xml
    xmlPath = calloc(sizeof(char), strlen(tmpPath) + strlen(XML_FILE) + 1);
    sprintf(xmlPath, "%s%s", tmpPath, XML_FILE);
    fmu.modelDescription = parse(xmlPath);
    free(xmlPath);
    if (!fmu.modelDescription) exit(EXIT_FAILURE);

    // load the FMU dll
    dllPath = calloc(sizeof(char), strlen(tmpPath) + strlen(DLL_DIR)
                     + strlen( getModelIdentifier(fmu.modelDescription)) +  strlen(".dll") + 1);
    sprintf(dllPath,"%s%s%s.dll", tmpPath, DLL_DIR, getModelIdentifier(fmu.modelDescription));
    if (!loadDll(dllPath, &fmu)) exit(EXIT_FAILURE);
    free(dllPath);
    free(fmuPath);
    free(tmpPath);

    // run the simulation
    printf("FMU Simulator: run '%s' from t=0..%g with step size h=%g, loggingOn=%d, csv separator='%c'\n",
           fmuFileName, tEnd, h, loggingOn, csv_separator);
    simulate(&fmu, tEnd, h, loggingOn, csv_separator);
    printf("CSV file '%s' written", RESULT_FILE);

    // release FMU
    FreeLibrary(fmu.dllHandle);
    freeElement(fmu.modelDescription);
    return EXIT_SUCCESS;
}