Esempio n. 1
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
}
Esempio n. 2
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
}