Skip to content

Commit e7eb8f3

Browse files
committed
- Make FMI 1.0 co-simulation work.
git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@23858 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
1 parent eff1d76 commit e7eb8f3

File tree

2 files changed

+48
-53
lines changed

2 files changed

+48
-53
lines changed

Compiler/Template/CodegenFMU.tpl

Lines changed: 29 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2205,15 +2205,6 @@ case FMIIMPORT(fmiInfo=INFO(__),fmiExperimentAnnotation=EXPERIMENTANNOTATION(__)
22052205
external "C" outCallEventUpdate = fmi1CompletedIntegratorStep_OMC(fmi1me, inFlowStates) annotation(Library = {"OpenModelicaFMIRuntimeC", "fmilib"<%if stringEq(platform, "win32") then ", \"shlwapi\""%>});
22062206
end fmi1CompletedIntegratorStep;
22072207
end fmi1Functions;
2208-
2209-
package fmiStatus
2210-
constant Integer fmiOK=0;
2211-
constant Integer fmiWarning=1;
2212-
constant Integer fmiDiscard=2;
2213-
constant Integer fmiError=3;
2214-
constant Integer fmiFatal=4;
2215-
constant Integer fmiPending=5;
2216-
end fmiStatus;
22172208
end <%fmiInfo.fmiModelIdentifier%>_<%getFMIType(fmiInfo)%>_FMU;
22182209
>>
22192210
end importFMU1ModelExchange;
@@ -2522,15 +2513,6 @@ case FMIIMPORT(fmiInfo=INFO(__),fmiExperimentAnnotation=EXPERIMENTANNOTATION(__)
25222513
external "C" outCallEventUpdate = fmi2CompletedIntegratorStep_OMC(fmi2me, inFlowStates) annotation(Library = {"OpenModelicaFMIRuntimeC", "fmilib"<%if stringEq(platform, "win32") then ", \"shlwapi\""%>});
25232514
end fmi2CompletedIntegratorStep;
25242515
end fmi2Functions;
2525-
2526-
package fmiStatus
2527-
constant Integer fmiOK=0;
2528-
constant Integer fmiWarning=1;
2529-
constant Integer fmiDiscard=2;
2530-
constant Integer fmiError=3;
2531-
constant Integer fmiFatal=4;
2532-
constant Integer fmiPending=5;
2533-
end fmiStatus;
25342516
end <%fmiInfo.fmiModelIdentifier%>_<%getFMIType(fmiInfo)%>_FMU;
25352517
>>
25362518
end importFMU2ModelExchange;
@@ -2603,27 +2585,32 @@ case FMIIMPORT(fmiInfo=INFO(__),fmiExperimentAnnotation=EXPERIMENTANNOTATION(__)
26032585
constant Real timeout = 0.0;
26042586
constant Boolean visible = false;
26052587
constant Boolean interactive = false;
2606-
parameter Real StartTime = <%fmiExperimentAnnotation.fmiExperimentStartTime%> "start time used to initialize the slave" annotation (Dialog(tab="FMI", group="Step time"));
2607-
parameter Real StopTime = <%fmiExperimentAnnotation.fmiExperimentStopTime%> "stop time used to initialize the slave" annotation (Dialog(tab="FMI", group="Step time"));
2608-
parameter Real communicationStepSize = (StopTime-StartTime)/500 "step size used by fmiDoStep" annotation (Dialog(tab="FMI", group="Step time"));
2609-
constant Boolean stopTimeDefined = false;
2610-
FMI1CoSimulation fmi1cs = FMI1CoSimulation(logLevel, fmuWorkingDir, "<%fmiInfo.fmiModelIdentifier%>", debugLogging, fmuLocation, mimeType, timeout, visible, interactive, StartTime, stopTimeDefined, StopTime);
2588+
parameter Real startTime = <%fmiExperimentAnnotation.fmiExperimentStartTime%> "start time used to initialize the slave" annotation (Dialog(tab="FMI", group="Step time"));
2589+
parameter Real stopTime = <%fmiExperimentAnnotation.fmiExperimentStopTime%> "stop time used to initialize the slave" annotation (Dialog(tab="FMI", group="Step time"));
2590+
parameter Real numberOfSteps = 500 annotation (Dialog(tab="FMI", group="Step time"));
2591+
parameter Real communicationStepSize = (stopTime-startTime)/numberOfSteps "step size used by fmiDoStep" annotation (Dialog(tab="FMI", group="Step time"));
2592+
constant Boolean stopTimeDefined = true;
26112593
<%dumpFMIModelVariablesList(fmiModelVariablesList, fmiTypeDefinitionsList, generateInputConnectors, generateOutputConnectors)%>
2612-
Real flowControl;
2594+
protected
2595+
FMI1CoSimulation fmi1cs = FMI1CoSimulation(logLevel, fmuWorkingDir, "<%fmiInfo.fmiModelIdentifier%>", debugLogging, fmuLocation, mimeType, timeout, visible, interactive, startTime, stopTimeDefined, stopTime);
2596+
parameter Real flowInitialized(fixed=false);
2597+
Real flowStep;
26132598
<%if not stringEq(realInputVariablesVRs, "") then "Real "+realInputVariablesReturnNames+";"%>
2614-
<%if not stringEq(integerInputVariablesVRs, "") then "Real "+integerInputVariablesReturnNames+";"%>
2615-
<%if not stringEq(booleanInputVariablesVRs, "") then "Real "+booleanInputVariablesReturnNames+";"%>
2616-
<%if not stringEq(stringInputVariablesVRs, "") then "Real "+stringInputVariablesReturnNames+";"%>
2599+
<%if not stringEq(integerInputVariablesVRs, "") then "Integer "+integerInputVariablesReturnNames+";"%>
2600+
<%if not stringEq(booleanInputVariablesVRs, "") then "Boolean "+booleanInputVariablesReturnNames+";"%>
2601+
<%if not stringEq(stringInputVariablesVRs, "") then "String "+stringInputVariablesReturnNames+";"%>
2602+
initial equation
2603+
flowInitialized = fmi1Functions.fmi1InitializeSlave(fmi1cs, 1);
26172604
equation
2605+
<%if not boolAnd(stringEq(realOutputVariablesNames, ""), stringEq(realOutputVariablesVRs, "")) then "{"+realOutputVariablesNames+"} = fmi1Functions.fmi1GetReal(fmi1cs, {"+realOutputVariablesVRs+"}, flowInitialized);"%>
2606+
<%if not boolAnd(stringEq(integerOutputVariablesNames, ""), stringEq(integerOutputVariablesVRs, "")) then "{"+integerOutputVariablesNames+"} = fmi1Functions.fmi1GetInteger(fmi1cs, {"+integerOutputVariablesVRs+"}, flowInitialized);"%>
2607+
<%if not boolAnd(stringEq(booleanOutputVariablesNames, ""), stringEq(booleanOutputVariablesVRs, "")) then "{"+booleanOutputVariablesNames+"} = fmi1Functions.fmi1GetBoolean(fmi1cs, {"+booleanOutputVariablesVRs+"}, flowInitialized);"%>
2608+
<%if not boolAnd(stringEq(stringOutputVariablesNames, ""), stringEq(stringOutputVariablesVRs, "")) then "{"+stringOutputVariablesNames+"} = fmi1Functions.fmi1GetString(fmi1cs, {"+stringOutputVariablesVRs+"}, flowInitialized);"%>
26182609
<%if not stringEq(realInputVariablesVRs, "") then "{"+realInputVariablesReturnNames+"} = fmi1Functions.fmi1SetReal(fmi1cs, {"+realInputVariablesVRs+"}, {"+realInputVariablesNames+"});"%>
26192610
<%if not stringEq(integerInputVariablesVRs, "") then "{"+integerInputVariablesReturnNames+"} = fmi1Functions.fmi1SetInteger(fmi1cs, {"+integerInputVariablesVRs+"}, {"+integerInputVariablesNames+"});"%>
26202611
<%if not stringEq(booleanInputVariablesVRs, "") then "{"+booleanInputVariablesReturnNames+"} = fmi1Functions.fmi1SetBoolean(fmi1cs, {"+booleanInputVariablesVRs+"}, {"+booleanInputVariablesNames+"});"%>
26212612
<%if not stringEq(stringInputVariablesVRs, "") then "{"+stringInputVariablesReturnNames+"} = fmi1Functions.fmi1SetString(fmi1cs, {"+stringInputVariablesVRs+"}, {"+stringStartVariablesNames+"});"%>
2622-
flowControl = fmi1Functions.fmi1DoStep(fmi1cs, time, communicationStepSize, true);
2623-
<%if not boolAnd(stringEq(realOutputVariablesNames, ""), stringEq(realOutputVariablesVRs, "")) then "{"+realOutputVariablesNames+"} = fmi1Functions.fmi1GetReal(fmi1cs, {"+realOutputVariablesVRs+"}, flowControl);"%>
2624-
<%if not boolAnd(stringEq(integerOutputVariablesNames, ""), stringEq(integerOutputVariablesVRs, "")) then "{"+integerOutputVariablesNames+"} = fmi1Functions.fmi1GetInteger(fmi1cs, {"+integerOutputVariablesVRs+"}, flowControl);"%>
2625-
<%if not boolAnd(stringEq(booleanOutputVariablesNames, ""), stringEq(booleanOutputVariablesVRs, "")) then "{"+booleanOutputVariablesNames+"} = fmi1Functions.fmi1GetBoolean(fmi1cs, {"+booleanOutputVariablesVRs+"}, flowControl);"%>
2626-
<%if not boolAnd(stringEq(stringOutputVariablesNames, ""), stringEq(stringOutputVariablesVRs, "")) then "{"+stringOutputVariablesNames+"} = fmi1Functions.fmi1GetString(fmi1cs, {"+stringOutputVariablesVRs+"}, flowControl);"%>
2613+
flowStep = fmi1Functions.fmi1DoStep(fmi1cs, time, communicationStepSize, true, flowInitialized);
26272614
annotation(experiment(StartTime=<%fmiExperimentAnnotation.fmiExperimentStartTime%>, StopTime=<%fmiExperimentAnnotation.fmiExperimentStopTime%>, Tolerance=<%fmiExperimentAnnotation.fmiExperimentTolerance%>));
26282615
annotation (Icon(graphics={
26292616
Rectangle(
@@ -2671,13 +2658,21 @@ case FMIIMPORT(fmiInfo=INFO(__),fmiExperimentAnnotation=EXPERIMENTANNOTATION(__)
26712658
<%dumpFMITypeDefinitionsArrayMappingFunctions(fmiTypeDefinitionsList)%>
26722659

26732660
package fmi1Functions
2661+
function fmi1InitializeSlave
2662+
input FMI1CoSimulation fmi1cs;
2663+
input Real preInitialized;
2664+
output Real postInitialized=preInitialized;
2665+
external "C" fmi1InitializeSlave_OMC(fmi1cs) annotation(Library = {"OpenModelicaFMIRuntimeC", "fmilib"<%if stringEq(platform, "win32") then ", \"shlwapi\""%>});
2666+
end fmi1InitializeSlave;
2667+
26742668
function fmi1DoStep
26752669
input FMI1CoSimulation fmi1cs;
26762670
input Real currentCommunicationPoint;
26772671
input Real communicationStepSize;
26782672
input Boolean newStep;
2679-
output Real outFlowControl;
2680-
external "C" outFlowControl = fmi1DoStep_OMC(fmi1cs, currentCommunicationPoint, communicationStepSize, newStep) annotation(Library = {"OpenModelicaFMIRuntimeC", "fmilib"<%if stringEq(platform, "win32") then ", \"shlwapi\""%>});
2673+
input Real preInitialized;
2674+
output Real postInitialized=preInitialized;
2675+
external "C" fmi1DoStep_OMC(fmi1cs, currentCommunicationPoint, communicationStepSize, newStep) annotation(Library = {"OpenModelicaFMIRuntimeC", "fmilib"<%if stringEq(platform, "win32") then ", \"shlwapi\""%>});
26812676
end fmi1DoStep;
26822677

26832678
function fmi1GetReal
@@ -2744,15 +2739,6 @@ case FMIIMPORT(fmiInfo=INFO(__),fmiExperimentAnnotation=EXPERIMENTANNOTATION(__)
27442739
external "C" fmi1SetString_OMC(fmi1cs, size(stringValuesReferences, 1), stringValuesReferences, stringValues, out_Values, 2) annotation(Library = {"OpenModelicaFMIRuntimeC", "fmilib"<%if stringEq(platform, "win32") then ", \"shlwapi\""%>});
27452740
end fmi1SetString;
27462741
end fmi1Functions;
2747-
2748-
package fmiStatus
2749-
constant Integer fmiOK=0;
2750-
constant Integer fmiWarning=1;
2751-
constant Integer fmiDiscard=2;
2752-
constant Integer fmiError=3;
2753-
constant Integer fmiFatal=4;
2754-
constant Integer fmiPending=5;
2755-
end fmiStatus;
27562742
end <%fmiInfo.fmiModelIdentifier%>_<%getFMIType(fmiInfo)%>_FMU;
27572743
>>
27582744
end importFMU1CoSimulationStandAlone;

SimulationRuntime/c/fmi/FMI1CoSimulation.c

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ void* FMI1CoSimulationConstructor_OMC(int fmi_log_level, char* working_directory
5555
FMI1CS->FMIImportContext = fmi_import_allocate_context(&FMI1CS->JMCallbacks);
5656
/* FMI callback functions */
5757
FMI1CS->FMICallbackFunctions.logger = fmi1logger;
58+
FMI1CS->FMICallbackFunctions.stepFinished = NULL;
5859
FMI1CS->FMICallbackFunctions.allocateMemory = calloc;
5960
FMI1CS->FMICallbackFunctions.freeMemory = free;
6061
/* parse the xml file */
@@ -93,10 +94,6 @@ void* FMI1CoSimulationConstructor_OMC(int fmi_log_level, char* working_directory
9394
FMI1CS->FMITStart = tStart;
9495
FMI1CS->FMIStopTimeDefined = stopTimeDefined;
9596
FMI1CS->FMITStop = tStop;
96-
fmi1_status_t initializeSlaveStatus = fmi1_import_initialize_slave(FMI1CS->FMIImportInstance, FMI1CS->FMITStart, FMI1CS->FMIStopTimeDefined, FMI1CS->FMITStop);
97-
if (initializeSlaveStatus != fmi1_status_ok && initializeSlaveStatus != fmi1_status_warning) {
98-
ModelicaFormatError("fmiInitializeSlave failed with status : %s\n", fmi1_status_to_string(initializeSlaveStatus));
99-
}
10097
return FMI1CS;
10198
}
10299

@@ -114,18 +111,30 @@ void FMI1CoSimulationDestructor_OMC(void* in_fmi1cs)
114111
free(FMI1CS->FMIMimeType);
115112
}
116113

114+
/*
115+
* Wrapper for the FMI function fmiInitializeSlave.
116+
*/
117+
void fmi1InitializeSlave_OMC(void* in_fmi1cs)
118+
{
119+
FMI1CoSimulation* FMI1CS = (FMI1CoSimulation*)in_fmi1cs;
120+
fmi1_status_t initializeSlaveStatus = fmi1_import_initialize_slave(FMI1CS->FMIImportInstance, FMI1CS->FMITStart, FMI1CS->FMIStopTimeDefined, FMI1CS->FMITStop);
121+
if (initializeSlaveStatus != fmi1_status_ok && initializeSlaveStatus != fmi1_status_warning) {
122+
ModelicaFormatError("fmiInitializeSlave failed with status : %s\n", fmi1_status_to_string(initializeSlaveStatus));
123+
}
124+
}
125+
117126
/*
118127
* Wrapper for the FMI function fmiDoStep.
119-
* Return value is dummy and is only used to run the equations in sequence.
120128
*/
121-
double fmi1DoStep_OMC(void* in_fmi1cs, double currentCommunicationPoint, double communicationStepSize, int newStep)
129+
void fmi1DoStep_OMC(void* in_fmi1cs, double currentCommunicationPoint, double communicationStepSize, int newStep)
122130
{
123131
FMI1CoSimulation* FMI1CS = (FMI1CoSimulation*)in_fmi1cs;
124-
fmi1_status_t status = fmi1_import_do_step(FMI1CS->FMIImportInstance, currentCommunicationPoint, communicationStepSize, newStep);
125-
if (status != fmi1_status_ok && status != fmi1_status_warning) {
126-
ModelicaFormatError("fmiDoStep failed with status : %s\n", fmi1_status_to_string(status));
132+
if (currentCommunicationPoint < FMI1CS->FMITStop) {
133+
fmi1_status_t status = fmi1_import_do_step(FMI1CS->FMIImportInstance, currentCommunicationPoint, communicationStepSize, newStep);
134+
if (status != fmi1_status_ok && status != fmi1_status_warning && status != fmi1_status_discard && status != fmi1_status_pending) {
135+
ModelicaFormatError("fmiDoStep failed with status : %s\n", fmi1_status_to_string(status));
136+
}
127137
}
128-
return 0.0;
129138
}
130139

131140
#ifdef __cplusplus

0 commit comments

Comments
 (0)