Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delay exitInitializationMode() until first call to doStep() #420

Merged
merged 3 commits into from
Apr 29, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 82 additions & 24 deletions src/sfun_fmurun.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,23 +211,39 @@ static FMIVariableType variableType(SimStruct *S, Parameter parameter, int index
}

static DTypeId simulinkVariableType(SimStruct *S, Parameter parameter, size_t index) {

const mxArray *param = ssGetSFcnParam(S, parameter);
const real_T realValue = ((real_T *)mxGetData(param))[index];
const int intValue = (int)realValue;
FMIVariableType type = (FMIVariableType)intValue;
const FMIVariableType type = (FMIVariableType)intValue;

switch (type) {
case FMIFloat32Type: return SS_SINGLE;
case FMIFloat64Type: return SS_DOUBLE;
case FMIInt8Type: return SS_INT8;
case FMIUInt8Type: return SS_UINT8;
case FMIInt16Type: return SS_INT16;
case FMIUInt16Type: return SS_UINT16;
case FMIInt32Type: return SS_INT32;
case FMIUInt32Type: return SS_UINT32;
case FMIInt64Type: return SS_INT32;
case FMIUInt64Type: return SS_UINT32;
case FMIBooleanType: return SS_BOOLEAN;
default: return -1; // error
case FMIFloat32Type:
case FMIDiscreteFloat32Type:
return SS_SINGLE;
case FMIFloat64Type:
case FMIDiscreteFloat64Type:
return SS_DOUBLE;
case FMIInt8Type:
return SS_INT8;
case FMIUInt8Type:
return SS_UINT8;
case FMIInt16Type:
return SS_INT16;
case FMIUInt16Type:
return SS_UINT16;
case FMIInt32Type:
return SS_INT32;
case FMIUInt32Type:
return SS_UINT32;
case FMIInt64Type:
return SS_INT32;
case FMIUInt64Type:
return SS_UINT32;
case FMIBooleanType:
return SS_BOOLEAN;
default:
return -1; // error
}
}

Expand All @@ -245,6 +261,22 @@ static int ny(SimStruct *S) {
return (int)mxGetNumberOfElements(ssGetSFcnParam(S, outputPortWidthsParam));
}

static bool initialized(SimStruct* S) {

void** p = ssGetPWork(S);

FMIInstance* instance = (FMIInstance*)p[0];

switch (instance->state) {
case FMI2EventModeState:
case FMI2ContinuousTimeModeState:
case FMI2StepCompleteState:
return true;
default:
return false;
}
}

static void logCall(SimStruct *S, const char* message) {

FILE *logfile = NULL;
Expand Down Expand Up @@ -839,6 +871,8 @@ static void update(SimStruct *S, bool inputEvent) {
nextEventTime = instance->fmi2Functions->eventInfo.nextEventTime;
} else {
// TODO
upcomingTimeEvent = false;
nextEventTime = 0;
}

// Work around for the event handling in Dymola FMUs:
Expand Down Expand Up @@ -1057,7 +1091,6 @@ static void initialize(SimStruct *S) {
CHECK_ERROR(setParameters(S, false, false));
CHECK_STATUS(FMI2SetupExperiment(instance, toleranceDefined, relativeTolerance(S), time, stopTime > time, stopTime));
CHECK_STATUS(FMI2EnterInitializationMode(instance));
CHECK_STATUS(FMI2ExitInitializationMode(instance));

} else {

Expand All @@ -1070,12 +1103,17 @@ static void initialize(SimStruct *S) {
CHECK_ERROR(setParameters(S, false, false));

CHECK_STATUS(FMI3EnterInitializationMode(instance, toleranceDefined, relativeTolerance(S), time, stopTime > time, stopTime));
CHECK_STATUS(FMI3ExitInitializationMode(instance));

}

if (isME(S)) {

if (isFMI2(S)) {
CHECK_STATUS(FMI2ExitInitializationMode(instance));
} else {
CHECK_STATUS(FMI3ExitInitializationMode(instance));
}

// initialize the continuous states
real_T *x = ssGetContStates(S);

Expand Down Expand Up @@ -1222,7 +1260,6 @@ static void mdlEnable(SimStruct *S) {
if (!isFMI1(S)) {
strcat(fmuResourceLocation, "/resources");
}


// instantiate the FMU
if (isFMI1(S)) {
Expand Down Expand Up @@ -1737,16 +1774,25 @@ static void mdlOutputs(SimStruct *S, int_T tid) {
const time_T h = time - instance->time;

if (h > 0) {

if (!initialized(S)) {
if (isFMI2(S)) {
CHECK_STATUS(FMI2ExitInitializationMode(instance));
} else if (isFMI3(S)) {
CHECK_STATUS(FMI3ExitInitializationMode(instance));
}
}

if (isFMI1(S)) {
CHECK_STATUS(FMI1DoStep(instance, instance->time, h, fmi1True));
} else if (isFMI2(S)) {
CHECK_STATUS(FMI2DoStep(instance, instance->time, h, fmi2False));
CHECK_STATUS(FMI2DoStep(instance, instance->time, h, fmi2True));
} else {
fmi3Boolean eventEncountered;
fmi3Boolean terminateSimulation;
fmi3Boolean earlyReturn;
fmi3Float64 lastSuccessfulTime;
CHECK_STATUS(FMI3DoStep(instance, instance->time, h, fmi2False, &eventEncountered, &terminateSimulation, &earlyReturn, &lastSuccessfulTime));
CHECK_STATUS(FMI3DoStep(instance, instance->time, h, fmi3True, &eventEncountered, &terminateSimulation, &earlyReturn, &lastSuccessfulTime));
// TODO: handle terminateSimulation == true
}
}
Expand All @@ -1760,6 +1806,10 @@ static void mdlOutputs(SimStruct *S, int_T tid) {
#if defined(MDL_UPDATE)
static void mdlUpdate(SimStruct *S, int_T tid) {

void** p = ssGetPWork(S);

FMIInstance* instance = (FMIInstance*)p[0];

logDebug(S, "mdlUpdate(tid=%d, time=%.16g, majorTimeStep=%d)", tid, ssGetT(S), ssIsMajorTimeStep(S));

bool inputEvent;
Expand Down Expand Up @@ -1875,21 +1925,29 @@ static void mdlTerminate(SimStruct *S) {
if (isFMI1(S)) {

if (isME(S)) {
CHECK_STATUS(FMI1Terminate(instance));
if (initialized(S)) {
CHECK_STATUS(FMI1Terminate(instance));
}
FMI1FreeModelInstance(instance);
} else {
CHECK_STATUS(FMI1TerminateSlave(instance));
if (initialized(S)) {
CHECK_STATUS(FMI1TerminateSlave(instance));
}
FMI1FreeSlaveInstance(instance);
}

} else if (isFMI2(S)) {

CHECK_STATUS(FMI2Terminate(instance));

if (initialized(S)) {
CHECK_STATUS(FMI2Terminate(instance));
}
FMI2FreeInstance(instance);

} else {

CHECK_STATUS(FMI3Terminate(instance));

if (initialized(S)) {
CHECK_STATUS(FMI3Terminate(instance));
}
FMI3FreeInstance(instance);

}
Expand Down