Skip to content
This repository has been archived by the owner on May 18, 2019. It is now read-only.

Commit

Permalink
Fix FMU import related simulation deviations
Browse files Browse the repository at this point in the history
Fixes the problem described in trac4455
(https://trac.openmodelica.org/OpenModelica/ticket/4455)
by enforcing that FMU inputs are set directly after
fmi2SetTime is called.
  • Loading branch information
bernhard-thiele authored and OpenModelica-Hudson committed Jul 12, 2017
1 parent acc20cc commit 591485e
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 5 deletions.
24 changes: 19 additions & 5 deletions Compiler/Template/CodegenFMU.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -1832,18 +1832,22 @@ case FMIIMPORT(fmiInfo=INFO(__),fmiExperimentAnnotation=EXPERIMENTANNOTATION(__)
let stringDependentParametersVRs = dumpVariables(fmiModelVariablesList, "string", "parameter", true, 1, "2.0")
let stringDependentParametersNames = dumpVariables(fmiModelVariablesList, "string", "parameter", true, 2, "2.0")
/* Get input Real varibales and their value references */
let nRealInputVariables = listLength(filterModelVariables(fmiModelVariablesList, "real", "input"))
let realInputVariablesVRs = dumpVariables(fmiModelVariablesList, "real", "input", false, 1, "2.0")
let realInputVariablesNames = dumpVariables(fmiModelVariablesList, "real", "input", false, 2, "2.0")
let realInputVariablesReturnNames = dumpVariables(fmiModelVariablesList, "real", "input", false, 3, "2.0")
/* Get input Integer varibales and their value references */
let nIntegerInputVariables = listLength(filterModelVariables(fmiModelVariablesList, "integer", "input"))
let integerInputVariablesVRs = dumpVariables(fmiModelVariablesList, "integer", "input", false, 1, "2.0")
let integerInputVariablesNames = dumpVariables(fmiModelVariablesList, "integer", "input", false, 2, "2.0")
let integerInputVariablesReturnNames = dumpVariables(fmiModelVariablesList, "integer", "input", false, 3, "2.0")
/* Get input Boolean varibales and their value references */
let nBooleanInputVariables = listLength(filterModelVariables(fmiModelVariablesList, "boolean", "input"))
let booleanInputVariablesVRs = dumpVariables(fmiModelVariablesList, "boolean", "input", false, 1, "2.0")
let booleanInputVariablesNames = dumpVariables(fmiModelVariablesList, "boolean", "input", false, 2, "2.0")
let booleanInputVariablesReturnNames = dumpVariables(fmiModelVariablesList, "boolean", "input", false, 3, "2.0")
/* Get input String varibales and their value references */
let nStringInputVariables = listLength(filterModelVariables(fmiModelVariablesList, "string", "input"))
let stringInputVariablesVRs = dumpVariables(fmiModelVariablesList, "string", "input", false, 1, "2.0")
let stringStartVariablesNames = dumpVariables(fmiModelVariablesList, "string", "input", false, 2, "2.0")
let stringInputVariablesReturnNames = dumpVariables(fmiModelVariablesList, "string", "input", false, 3, "2.0")
Expand Down Expand Up @@ -1881,9 +1885,13 @@ case FMIIMPORT(fmiInfo=INFO(__),fmiExperimentAnnotation=EXPERIMENTANNOTATION(__)
parameter Real flowParamsStart(fixed=false);
parameter Real flowInitInputs(fixed=false);
Real flowStatesInputs;
<%if not stringEq(realInputVariablesVRs, "") then "Real realInputVariables["+nRealInputVariables+"];"%>
<%if not stringEq(realInputVariablesVRs, "") then "Real "+realInputVariablesReturnNames+";"%>
<%if not stringEq(integerInputVariablesVRs, "") then "Integer integerInputVariables["+nIntegerInputVariables+"];"%>
<%if not stringEq(integerInputVariablesVRs, "") then "Integer "+integerInputVariablesReturnNames+";"%>
<%if not stringEq(booleanInputVariablesVRs, "") then "Boolean booleanInputVariables["+nBooleanInputVariables+"];"%>
<%if not stringEq(booleanInputVariablesVRs, "") then "Boolean "+booleanInputVariablesReturnNames+";"%>
<%if not stringEq(stringInputVariablesVRs, "") then "String stringInputVariables["+nStringInputVariables+"];"%>
<%if not stringEq(stringInputVariablesVRs, "") then "String "+stringInputVariablesReturnNames+";"%>
Boolean callEventUpdate;
Boolean newStatesAvailable(fixed = true);
Expand All @@ -1910,12 +1918,18 @@ case FMIIMPORT(fmiInfo=INFO(__),fmiExperimentAnnotation=EXPERIMENTANNOTATION(__)
<%if not stringEq(integerDependentParametersVRs, "") then "{"+integerDependentParametersNames+"} = fmi2Functions.fmi2GetInteger(fmi2me, {"+integerDependentParametersVRs+"}, flowInitialized);"%>
<%if not stringEq(booleanDependentParametersVRs, "") then "{"+booleanDependentParametersNames+"} = fmi2Functions.fmi2GetBoolean(fmi2me, {"+booleanDependentParametersVRs+"}, flowInitialized);"%>
<%if not stringEq(stringDependentParametersVRs, "") then "{"+stringDependentParametersNames+"} = fmi2Functions.fmi2GetString(fmi2me, {"+stringDependentParametersVRs+"}, flowInitialized);"%>
algorithm
flowTime := fmi2Functions.fmi2SetTime(fmi2me, time, flowInitialized);
/* algorithm section ensures that inputs to fmi (if any) are set directly after the new time is set */
<%if not stringEq(realInputVariablesVRs, "") then "realInputVariables := fmi2Functions.fmi2SetReal(fmi2me, {"+realInputVariablesVRs+"}, {"+realInputVariablesNames+"});"%>
<%if not stringEq(integerInputVariablesVRs, "") then "integerInputVariables := fmi2Functions.fmi2SetInteger(fmi2me, {"+integerInputVariablesVRs+"}, {"+integerInputVariablesNames+"});"%>
<%if not stringEq(booleanInputVariablesVRs, "") then "booleanInputVariables := fmi2Functions.fmi2SetBoolean(fmi2me, {"+booleanInputVariablesVRs+"}, {"+booleanInputVariablesNames+"});"%>
<%if not stringEq(stringInputVariablesVRs, "") then "stringInputVariables := fmi2Functions.fmi2SetString(fmi2me, {"+stringInputVariablesVRs+"}, {"+stringStartVariablesNames+"});"%>
equation
flowTime = fmi2Functions.fmi2SetTime(fmi2me, time, flowInitialized);
<%if not stringEq(realInputVariablesVRs, "") then "{"+realInputVariablesReturnNames+"} = fmi2Functions.fmi2SetReal(fmi2me, {"+realInputVariablesVRs+"}, {"+realInputVariablesNames+"});"%>
<%if not stringEq(integerInputVariablesVRs, "") then "{"+integerInputVariablesReturnNames+"} = fmi2Functions.fmi2SetInteger(fmi2me, {"+integerInputVariablesVRs+"}, {"+integerInputVariablesNames+"});"%>
<%if not stringEq(booleanInputVariablesVRs, "") then "{"+booleanInputVariablesReturnNames+"} = fmi2Functions.fmi2SetBoolean(fmi2me, {"+booleanInputVariablesVRs+"}, {"+booleanInputVariablesNames+"});"%>
<%if not stringEq(stringInputVariablesVRs, "") then "{"+stringInputVariablesReturnNames+"} = fmi2Functions.fmi2SetString(fmi2me, {"+stringInputVariablesVRs+"}, {"+stringStartVariablesNames+"});"%>
<%if not stringEq(realInputVariablesVRs, "") then "{"+realInputVariablesReturnNames+"} = realInputVariables;"%>
<%if not stringEq(integerInputVariablesVRs, "") then "{"+integerInputVariablesReturnNames+"} = integerInputVariables;"%>
<%if not stringEq(booleanInputVariablesVRs, "") then "{"+booleanInputVariablesReturnNames+"} = booleanInputVariables;"%>
<%if not stringEq(stringInputVariablesVRs, "") then "{"+stringInputVariablesReturnNames+"} = stringInputVariables;"%>
flowStatesInputs = fmi2Functions.fmi2SetContinuousStates(fmi2me, fmi_x, flowParamsStart + flowTime);
der(fmi_x) = fmi2Functions.fmi2GetDerivatives(fmi2me, numberOfContinuousStates, flowStatesInputs);
fmi_z = fmi2Functions.fmi2GetEventIndicators(fmi2me, numberOfEventIndicators, flowStatesInputs);
Expand Down
7 changes: 7 additions & 0 deletions Compiler/Template/SimCodeBackendTV.mo
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,13 @@ package FMI
input String inBaseType;
output String outEnumerationType;
end getEnumerationTypeFromTypes;

function filterModelVariables
input list<ModelVariables> inModelVariables;
input String tipe;
input String variableCausality;
output list<ModelVariables> outModelVariables;
end filterModelVariables;
end FMI;

end SimCodeBackendTV;
36 changes: 36 additions & 0 deletions Compiler/Util/FMI.mo
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ encapsulated package FMI
package: FMI
description: This file contains FMI's import specific function, which are implemented in C."

protected import List;

public uniontype Info
record INFO
String fmiVersion;
Expand Down Expand Up @@ -327,5 +329,39 @@ algorithm
end match;
end getEnumerationTypeFromTypes;

public function filterModelVariables
input list<ModelVariables> inModelVariables;
input String tipe;
input String variableCausality;
output list<ModelVariables> outModelVariables;
algorithm
outModelVariables := List.filter2OnTrue(inModelVariables, filterModelVariable, tipe, variableCausality);
end filterModelVariables;

protected function filterModelVariable
input ModelVariables modelVar;
input String tipe;
input String variableCausality;
output Boolean result;
algorithm
result := match modelVar
local
String causality;
case REALVARIABLE(causality=causality)
guard tipe == "real" and causality == variableCausality
then true;
case INTEGERVARIABLE(causality=causality)
guard tipe == "integer" and causality == variableCausality
then true;
case BOOLEANVARIABLE(causality=causality)
guard tipe == "boolean" and causality == variableCausality
then true;
case STRINGVARIABLE(causality=causality)
guard tipe == "string" and causality == variableCausality
then true;
else then false;
end match;
end filterModelVariable;

annotation(__OpenModelica_Interface="util");
end FMI;

0 comments on commit 591485e

Please sign in to comment.