/*
 * Wrapper for the FMI function fmi2GetContinuousStates.
 * parameter flowParams is dummy and is only used to run the equations in sequence.
 * Returns states.
 */
void fmi2GetContinuousStates_OMC(void* in_fmi2me, int numberOfContinuousStates, double flowParams, double* states)
{
  FMI2ModelExchange* FMI2ME = (FMI2ModelExchange*)in_fmi2me;
  fmi2_status_t status = fmi2_import_get_continuous_states(FMI2ME->FMIImportInstance, (fmi2_real_t*)states, numberOfContinuousStates);
  if (status != fmi1_status_ok && status != fmi1_status_warning) {
    ModelicaFormatError("fmi2GetContinuousStates failed with status : %s\n", fmi2_status_to_string(status));
  }
}
/*
 * Wrapper for the FMI function fmi2GetEventIndicators.
 * parameter flowStates is dummy and is only used to run the equations in sequence.
 * Returns events.
 */
void fmi2GetEventIndicators_OMC(void* in_fmi2me, int numberOfEventIndicators, double flowStates, double* events)
{
  FMI2ModelExchange* FMI2ME = (FMI2ModelExchange*)in_fmi2me;
  fmi2_status_t status = fmi2_import_get_event_indicators(FMI2ME->FMIImportInstance, (fmi2_real_t*)events, numberOfEventIndicators);
  if (status != fmi1_status_ok && status != fmi1_status_warning) {
    ModelicaFormatError("fmi2GetEventIndicators failed with status : %s\n", fmi2_status_to_string(status));
  }
}
/*
 * Wrapper for the FMI function fmi2ExitInitializationMode.
 */
void fmi2ExitInitializationModel_OMC(void* in_fmi2me)
{
  FMI2ModelExchange* FMI2ME = (FMI2ModelExchange*)in_fmi2me;
  fmi2_status_t status = fmi2_import_exit_initialization_mode(FMI2ME->FMIImportInstance);
  FMI2ME->FMISolvingMode = fmi2_event_mode;
  if (status != fmi1_status_ok && status != fmi1_status_warning) {
    ModelicaFormatError("fmi2ExitInitializationMode failed with status : %s\n", fmi2_status_to_string(status));
  }
}
/* Logger function used by the FMU internally */
static void fmi2logger(fmi2_component_environment_t env, fmi2_string_t instanceName, fmi2_status_t status, fmi2_string_t category, fmi2_string_t message, ...)
{
    int len;
	char msg[BUFFER];
	va_list argp;	
	va_start(argp, message);
	len = jm_vsnprintf(msg, BUFFER, message, argp);
	printf("fmiStatus = %s;  %s (%s): %s\n", fmi2_status_to_string(status), instanceName, category, msg);
}
void  fmi2_log_forwarding_v(fmi2_component_environment_t c, fmi2_string_t instanceName, fmi2_status_t status, fmi2_string_t category, fmi2_string_t message, va_list args) {
    char buf[50000], *curp;
	const char* statusStr;
	fmi2_import_t* fmu = (fmi2_import_t*)c;
	jm_callbacks* cb;
	jm_log_level_enu_t logLevel;

	if(fmu) {
		 cb = fmu->callbacks;
	}
	else 
		cb = jm_get_default_callbacks();
	logLevel = cb->log_level;
	switch(status) {
		case fmi2_status_discard:
		case fmi2_status_pending:
		case fmi2_status_ok:
			logLevel = jm_log_level_info;
			break;
		case fmi2_status_warning:
			logLevel = jm_log_level_warning;
			break;
		case fmi2_status_error:
			logLevel = jm_log_level_error;
			break;
		case fmi2_status_fatal:
		default:
			logLevel = jm_log_level_fatal;
	}

    if(logLevel > cb->log_level) return;

	curp = buf;
    *curp = 0;

	if(category) {
        sprintf(curp, "[%s]", category);
        curp += strlen(category)+2;
    }
	statusStr = fmi2_status_to_string(status);
    sprintf(curp, "[FMU status:%s] ", statusStr);
        curp += strlen(statusStr) + strlen("[FMU status:] ");
	vsprintf(curp, message, args);

	if(fmu) {
		fmi2_import_expand_variable_references(fmu, buf, cb->errMessageBuffer,JM_MAX_ERROR_MESSAGE_SIZE);
	}
	else {
		strncpy(cb->errMessageBuffer, buf, JM_MAX_ERROR_MESSAGE_SIZE);
		cb->errMessageBuffer[JM_MAX_ERROR_MESSAGE_SIZE - 1] = '\0';
	}
	if(cb->logger) {
		cb->logger(cb, instanceName, logLevel, cb->errMessageBuffer);
	}

}
/*
 * Wrapper for the FMI function fmi2SetTime.
 * Returns status.
 */
void fmi2SetTime_OMC(void* in_fmi2me, double time)
{
  FMI2ModelExchange* FMI2ME = (FMI2ModelExchange*)in_fmi2me;
  if (FMI2ME->FMISolvingMode == fmi2_instantiated_mode || FMI2ME->FMISolvingMode == fmi2_event_mode || FMI2ME->FMISolvingMode == fmi2_continuousTime_mode) {
    fmi2_status_t status = fmi2_import_set_time(FMI2ME->FMIImportInstance, time);
    if (status != fmi1_status_ok && status != fmi1_status_warning) {
      ModelicaFormatError("fmi2SetTime failed with status : %s\n", fmi2_status_to_string(status));
    }
  }
}
/*
 * Wrapper for the FMI function fmi2CompletedIntegratorStep.
 */
int fmi2CompletedIntegratorStep_OMC(void* in_fmi2me, double flowStates)
{
  FMI2ModelExchange* FMI2ME = (FMI2ModelExchange*)in_fmi2me;
  if (FMI2ME->FMISolvingMode == fmi2_continuousTime_mode){
    fmi2_boolean_t callEventUpdate = fmi2_false;
    fmi2_boolean_t terminateSimulation = fmi2_false;
    fmi2_status_t status = fmi2_import_completed_integrator_step(FMI2ME->FMIImportInstance, fmi2_true, &callEventUpdate, &terminateSimulation);
    if (status != fmi1_status_ok && status != fmi1_status_warning) {
      ModelicaFormatError("fmi2CompletedIntegratorStep failed with status : %s\n", fmi2_status_to_string(status));
    }
    return callEventUpdate;
  }
  return fmi2_false;
}
Exemple #8
0
/*
 * Wrapper for the FMI function fmi2GetReal.
 * parameter flowStatesInput is dummy and is only used to run the equations in sequence.
 * Returns realValues.
 */
void fmi2GetReal_OMC(void* in_fmi2, int numberOfValueReferences, double* realValuesReferences, double flowStatesInput, double* realValues, int fmiType)
{
  if (fmiType == 1) {
    FMI2ModelExchange* FMI2ME = (FMI2ModelExchange*)in_fmi2;
    fmi2_value_reference_t* valuesReferences_int = real_to_fmi2_value_reference(numberOfValueReferences, realValuesReferences);
    fmi2_status_t status = fmi2_import_get_real(FMI2ME->FMIImportInstance, valuesReferences_int, numberOfValueReferences, (fmi2_real_t*)realValues);
    free(valuesReferences_int);
    if (status != fmi2_status_ok && status != fmi2_status_warning) {
      ModelicaFormatError("fmi2GetReal failed with status : %s\n", fmi2_status_to_string(status));
    }
  } else if (fmiType == 2) {

  }
}
/*
 * Wrapper for the FMI function fmi2NewDiscreteStates.
 * Returns valuesOfContinuousStatesChanged
 */
int fmi2EventUpdate_OMC(void* in_fmi2me)
{
  FMI2ModelExchange* FMI2ME = (FMI2ModelExchange*)in_fmi2me;
  fmi2_event_info_t *eventInfo = FMI2ME->FMIEventInfo;
  fmi2_status_t status = fmi2_import_enter_event_mode(FMI2ME->FMIImportInstance);
  if (status != fmi1_status_ok && status != fmi1_status_warning) {
    ModelicaFormatError("fmi2EnterEventMode failed with status : %s\n", fmi2_status_to_string(status));
  }
  FMI2ME->FMISolvingMode = fmi2_event_mode;

  eventInfo->newDiscreteStatesNeeded = fmi2_true;
  eventInfo->terminateSimulation = fmi2_false;
  status = fmi2_import_new_discrete_states(FMI2ME->FMIImportInstance, eventInfo);
  if (status != fmi1_status_ok && status != fmi1_status_warning) {
    ModelicaFormatError("fmi2NewDiscreteStates failed with status : %s\n", fmi2_status_to_string(status));
  }

  status = fmi2_import_enter_continuous_time_mode(FMI2ME->FMIImportInstance);
  if (status != fmi1_status_ok && status != fmi1_status_warning) {
    ModelicaFormatError("fmi2EnterContinuousTimeMode failed with status : %s\n", fmi2_status_to_string(status));
  }
  FMI2ME->FMISolvingMode = fmi2_continuousTime_mode;
  return eventInfo->valuesOfContinuousStatesChanged;
}
Exemple #10
0
/*
 * Wrapper for the FMI function fmi2SetString.
 * Returns status.
 */
void fmi2SetString_OMC(void* in_fmi2, int numberOfValueReferences, double* stringValuesReferences, char** stringValues, int fmiType)
{
  if (fmiType == 1) {
    FMI2ModelExchange* FMI2ME = (FMI2ModelExchange*)in_fmi2;
    if (FMI2ME->FMISolvingMode == fmi2_instantiated_mode || FMI2ME->FMISolvingMode == fmi2_initialization_mode || FMI2ME->FMISolvingMode == fmi2_event_mode) {
      fmi2_value_reference_t* valuesReferences_int = real_to_fmi2_value_reference(numberOfValueReferences, stringValuesReferences);
      fmi2_status_t status = fmi2_import_set_string(FMI2ME->FMIImportInstance, valuesReferences_int, numberOfValueReferences, (fmi2_string_t*)stringValues);
      free(valuesReferences_int);
      if (status != fmi2_status_ok && status != fmi2_status_warning) {
        ModelicaFormatError("fmi2SetString failed with status : %s\n", fmi2_status_to_string(status));
      }
    }
  } else if (fmiType == 2) {

  }
}
Exemple #11
0
/*
 * Wrapper for the FMI function fmi2GetBoolean.
 * parameter flowStatesInput is dummy and is only used to run the equations in sequence.
 * Returns booleanValues.
 */
void fmi2GetBoolean_OMC(void* in_fmi2, int numberOfValueReferences, double* booleanValuesReferences, double flowStatesInput, signed char* booleanValues, int fmiType)
{
  if (fmiType == 1) {
    FMI2ModelExchange* FMI2ME = (FMI2ModelExchange*)in_fmi2;
    fmi2_value_reference_t* valuesReferences_int = real_to_fmi2_value_reference(numberOfValueReferences, booleanValuesReferences);
    int* fmiBoolean = malloc(sizeof(int)*numberOfValueReferences);
    fmi2_status_t status = fmi2_import_get_boolean(FMI2ME->FMIImportInstance, valuesReferences_int, numberOfValueReferences, fmiBoolean);
    int_to_signedchar(fmiBoolean, booleanValues, numberOfValueReferences);
    free(fmiBoolean);
    free(valuesReferences_int);


    if (status != fmi2_status_ok && status != fmi2_status_warning) {
      ModelicaFormatError("fmi2GetBoolean failed with status : %s\n", fmi2_status_to_string(status));
    }
  } else if (fmiType == 2) {

  }
}
void  fmi2_default_callback_logger(fmi2_component_environment_t c, fmi2_string_t instanceName, fmi2_status_t status, fmi2_string_t category, fmi2_string_t message, ...) {
    va_list args;
    char buf[500], *curp;
    va_start (args, message);
    curp = buf;
    *curp = 0;
    if(instanceName) {
        sprintf(curp, "[%s]", instanceName);
        curp += strlen(instanceName)+2;
    }
    if(category) {
        sprintf(curp, "[%s]", category);
        curp += strlen(category)+2;
    }
    fprintf(stdout, "%s[status=%s]", buf, fmi2_status_to_string(status));
    vfprintf (stdout, message, args);
    fprintf(stdout, "\n");
    va_end (args);
}
Exemple #13
0
/*
 * Wrapper for the FMI function fmi2SetBoolean.
 * Returns status.
 */
void fmi2SetBoolean_OMC(void* in_fmi2, int numberOfValueReferences, double* booleanValuesReferences, signed char* booleanValues, int fmiType)
{
  if (fmiType == 1) {
    FMI2ModelExchange* FMI2ME = (FMI2ModelExchange*)in_fmi2;
    if (FMI2ME->FMISolvingMode == fmi2_instantiated_mode || FMI2ME->FMISolvingMode == fmi2_initialization_mode || FMI2ME->FMISolvingMode == fmi2_event_mode) {
      fmi2_value_reference_t* valuesReferences_int = real_to_fmi2_value_reference(numberOfValueReferences, booleanValuesReferences);
      int* fmiBoolean = malloc(sizeof(int)*numberOfValueReferences);
      fmi2_status_t status;
      signedchar_to_int(booleanValues, fmiBoolean, numberOfValueReferences);
      status = fmi2_import_set_boolean(FMI2ME->FMIImportInstance, valuesReferences_int, numberOfValueReferences, fmiBoolean);
      free(fmiBoolean);
      free(valuesReferences_int);
      if (status != fmi2_status_ok && status != fmi2_status_warning) {
        ModelicaFormatError("fmi2SetBoolean failed with status : %s\n", fmi2_status_to_string(status));
      }
    }
  } else if (fmiType == 2) {

  }
}
static void stepFinished(fmi2_component_environment_t env, fmi2_status_t status) {
	printf("stepFinished is called wiht fmiStatus = %s\n", fmi2_status_to_string(status));
}
int test_simulate_me(fmi2_import_t* fmu)
{	
	fmi2_status_t fmistatus;
	jm_status_enu_t jmstatus;
	fmi2_real_t tstart = 0.0;
	fmi2_real_t tcur;
	fmi2_real_t hcur;
	fmi2_real_t hdef = 0.1;
	fmi2_real_t tend = 2.0;
	size_t n_states;
	size_t n_event_indicators;
	fmi2_real_t* states;
	fmi2_real_t states_end_results[] = {0.362000, -3.962000};
	fmi2_real_t* states_der;
	fmi2_real_t* event_indicators;
	fmi2_real_t* event_indicators_prev;
	fmi2_boolean_t callEventUpdate;
	fmi2_boolean_t terminateSimulation = fmi2_false;
	fmi2_boolean_t toleranceControlled = fmi2_true;
	fmi2_real_t relativeTolerance = 0.001;
	fmi2_event_info_t eventInfo;
	size_t k;

	printf("Version returned from FMU:   %s\n", fmi2_import_get_version(fmu));
	printf("Platform type returned:      %s\n", fmi2_import_get_types_platform(fmu));

	n_states = fmi2_import_get_number_of_continuous_states(fmu);
	n_event_indicators = fmi2_import_get_number_of_event_indicators(fmu);

	if (sizeof(states_end_results)/sizeof(fmi2_real_t) != n_states) {
		printf("Number of states and results have different length n_states = %u n_results = %u\n", (unsigned)n_states, (unsigned)sizeof(states_end_results));
		do_exit(CTEST_RETURN_FAIL);
	}

	states = calloc(n_states, sizeof(double));
	states_der = calloc(n_states, sizeof(double));
	event_indicators = calloc(n_event_indicators, sizeof(double));
	event_indicators_prev = calloc(n_event_indicators, sizeof(double));

	jmstatus = fmi2_import_instantiate(fmu, "Test ME model instance",fmi2_model_exchange,0,0);
	if (jmstatus == jm_status_error) {
		printf("fmi2_import_instantiate failed\n");
		do_exit(CTEST_RETURN_FAIL);
	}

	fmistatus = fmi2_import_set_debug_logging(fmu, fmi2_false,0,0);
	printf("fmi2_import_set_debug_logging:  %s\n", fmi2_status_to_string(fmistatus));	
	fmi2_import_set_debug_logging(fmu, fmi2_true, 0, 0);

    fmistatus = fmi2_import_setup_experiment(fmu, toleranceControlled,
        relativeTolerance, tstart, fmi2_false, 0.0);

    fmistatus = fmi2_import_enter_initialization_mode(fmu);
    fmistatus = fmi2_import_exit_initialization_mode(fmu);

	tcur = tstart;
	hcur = hdef;
	callEventUpdate = fmi2_false;

	eventInfo.newDiscreteStatesNeeded           = fmi2_false;
	eventInfo.terminateSimulation               = fmi2_false;
	eventInfo.nominalsOfContinuousStatesChanged = fmi2_false;
	eventInfo.valuesOfContinuousStatesChanged   = fmi2_true;
	eventInfo.nextEventTimeDefined              = fmi2_false;
	eventInfo.nextEventTime                     = -0.0;

    /* fmiExitInitializationMode leaves FMU in event mode */
    do_event_iteration(fmu, &eventInfo);
    fmi2_import_enter_continuous_time_mode(fmu);

	fmistatus = fmi2_import_get_continuous_states(fmu, states, n_states);
	fmistatus = fmi2_import_get_event_indicators(fmu, event_indicators, n_event_indicators);

	while ((tcur < tend) && (!(eventInfo.terminateSimulation || terminateSimulation))) {
		size_t k;
        fmi2_real_t tlast;
		int zero_crossing_event = 0;

		fmistatus = fmi2_import_set_time(fmu, tcur);

        { /* Swap event_indicators and event_indicators_prev so that we can get new indicators */
            fmi2_real_t *temp = event_indicators;
            event_indicators = event_indicators_prev;
            event_indicators_prev = temp;
        }
		fmistatus = fmi2_import_get_event_indicators(fmu, event_indicators, n_event_indicators);

		/* Check if an event indicator has triggered */
		for (k = 0; k < n_event_indicators; k++) {
			if ((event_indicators[k] > 0) != (event_indicators_prev[k] > 0)) {
				zero_crossing_event = 1;
				break;
			}
		}

		/* Handle any events */
		if (callEventUpdate || zero_crossing_event ||
		  (eventInfo.nextEventTimeDefined && tcur == eventInfo.nextEventTime)) {
            fmistatus = fmi2_import_enter_event_mode(fmu);
            do_event_iteration(fmu, &eventInfo);
            fmistatus = fmi2_import_enter_continuous_time_mode(fmu);

			fmistatus = fmi2_import_get_continuous_states(fmu, states, n_states);
			fmistatus = fmi2_import_get_event_indicators(fmu, event_indicators, n_event_indicators);
		}

		/* Calculate next time step */
        tlast = tcur;
        tcur += hdef;
		if (eventInfo.nextEventTimeDefined && (tcur >= eventInfo.nextEventTime)) {
            tcur = eventInfo.nextEventTime;
		}
        hcur = tcur - tlast;
		if(tcur > tend - hcur/1e16) {
			tcur = tend;				
			hcur = tcur - tlast;
		}

		/* Integrate a step */
		fmistatus = fmi2_import_get_derivatives(fmu, states_der, n_states);
		for (k = 0; k < n_states; k++) {
			states[k] = states[k] + hcur*states_der[k];	
			if (k == 0) printf("Ball height state[%u] = %f\n", (unsigned)k, states[k]);
		}

		/* Set states */
		fmistatus = fmi2_import_set_continuous_states(fmu, states, n_states);
		/* Step is complete */
		fmistatus = fmi2_import_completed_integrator_step(fmu, fmi2_true, &callEventUpdate,
                                                          &terminateSimulation);
	}	

	/* Validate result */
	for (k = 0; k < n_states; k++) {
		fmi2_real_t res = states[k] - states_end_results[k];
		res = res > 0 ? res: -res; /* Take abs */
		if (res > 1e-10) {
			printf("Simulation results is wrong  states[%u] %f != %f, |res| = %f\n", (unsigned)k, states[k], states_end_results[k], res);
			do_exit(CTEST_RETURN_FAIL);
		}
	}
	

	fmistatus = fmi2_import_terminate(fmu);

	fmi2_import_free_instance(fmu);

	free(states);
	free(states_der);
	free(event_indicators);
	free(event_indicators_prev);

	return 0;
}