Skip to content

Commit

Permalink
- fixes for FMI 2.0
Browse files Browse the repository at this point in the history
   - corrected some case of initial, variability and causality 
   - fixed Boolean handling
   - added test cases for Boolen and Integer


git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@23831 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
Willi Braun committed Dec 17, 2014
1 parent 7461209 commit 2ac4703
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 29 deletions.
62 changes: 37 additions & 25 deletions Compiler/Template/CodegenFMU.tpl
Expand Up @@ -168,9 +168,9 @@ match simVar
case SIMVAR(__) then
let valueReference = '<%System.tmpTick()%>'
let description = if comment then 'description="<%Util.escapeModelicaStringToXmlString(comment)%>"'
let variability = getVariability2(varKind)
let variability = getVariability2(varKind, type_)
let caus = getCausality2(causality, varKind, isValueChangeable)
let initial = getInitialType(varKind, initialValue, causality)
let initial = getInitialType(varKind, initialValue, causality, isValueChangeable)
<<
name="<%System.stringReplace(crefStrNoUnderscore(name),"$", "_D_")%>"
valueReference="<%valueReference%>"
Expand All @@ -181,15 +181,18 @@ match simVar
>>
end ScalarVariableAttribute2;

template getVariability2(VarKind varKind)
template getVariability2(VarKind varKind, DAE.Type type_)
"Returns the variability Attribute of ScalarVariable."
::=
match varKind
case DISCRETE(__) then "discrete"
case PARAM(__) then "fixed"
/*case PARAM(__) then "tunable"*/ /*TODO! Don't know how tunable variables are represented in OpenModelica.*/
case CONST(__) then "constant"
else "continuous"
else
match type_
case T_REAL(__) then "continuous"
else "discrete"
end getVariability2;

template getCausality2(Causality c, VarKind varKind, Boolean isValueChangeable)
Expand All @@ -211,30 +214,31 @@ match varKind
else "local"
end getCausality2Helper;

template getInitialType(VarKind varKind, Option<DAE.Exp> initialValue, Causality c)
template getInitialType(VarKind varKind, Option<DAE.Exp> initialValue, Causality c, Boolean isValueChangeable)
"Returns the Initial Attribute of ScalarVariable."
::=
match c
case INPUT(__) then "approx"
else
match varKind
case STATE_DER(__) then "calculated"
else
match initialValue
case SOME(exp) then "exact"
else "calculated"
match initialValue
case SOME(exp) then
match varKind
case STATE_DER(__) then "calculated"
case PARAM(__) then if isValueChangeable then "exact" else "calculated"
else "approx"
else "calculated"
end getInitialType;

template ScalarVariableType2(list<SimVar> stateVars, DAE.Type type_, String unit, String displayUnit, Option<DAE.Exp> initialValue, VarKind varKind, Integer index)
template ScalarVariableType2(list<SimVar> stateVars, DAE.Type type_, String unit, String displayUnit, Option<DAE.Exp> initialValue, VarKind varKind, Integer index, Boolean isValueChangeable)
"Generates code for ScalarVariable Type file for FMU 2.0 target."
::=
match type_
case T_INTEGER(__) then '<Integer<%ScalarVariableTypeCommonAttribute2(initialValue)%>/>'
case T_INTEGER(__) then '<Integer<%ScalarVariableTypeCommonAttribute2(initialValue, varKind, isValueChangeable)%>/>'
/* Don't generate the units for now since it is wrong. If you generate a unit attribute here then we must add the UnitDefinitions tag section also. */
case T_REAL(__) then '<Real<%RealVariableTypeCommonAttribute2(stateVars, initialValue, varKind, index)%>/>'
case T_BOOL(__) then '<Boolean<%ScalarVariableTypeCommonAttribute2(initialValue)%>/>'
case T_STRING(__) then '<String<%StringVariableTypeCommonAttribute2(initialValue)%>/>'
case T_ENUMERATION(__) then '<Enumeration declaredType="<%Absyn.pathString2NoLeadingDot(path, ".")%>"<%ScalarVariableTypeCommonAttribute2(initialValue)%>/>'
case T_REAL(__) then '<Real<%RealVariableTypeCommonAttribute2(stateVars, initialValue, varKind, isValueChangeable, index)%>/>'
case T_BOOL(__) then '<Boolean<%ScalarVariableTypeCommonAttribute2(initialValue, varKind, isValueChangeable)%>/>'
case T_STRING(__) then '<String<%StringVariableTypeCommonAttribute2(initialValue, varKind, isValueChangeable)%>/>'
case T_ENUMERATION(__) then '<Enumeration declaredType="<%Absyn.pathString2NoLeadingDot(path, ".")%>"<%ScalarVariableTypeCommonAttribute2(initialValue, varKind, isValueChangeable)%>/>'
else 'UNKOWN_TYPE'
end ScalarVariableType2;

Expand All @@ -249,28 +253,36 @@ match exp
else ''
end StartString2;

template ScalarVariableTypeCommonAttribute2(Option<DAE.Exp> initialValue)
template ScalarVariableTypeCommonAttribute2(Option<DAE.Exp> initialValue, VarKind varKind, Boolean isValueChangeable)
"Generates code for ScalarVariable Type file for FMU 2.0 target."
::=
match initialValue
case SOME(exp) then '<%StartString2(exp)%>'
case SOME(exp) then
match varKind
case PARAM(__) then if isValueChangeable then '<%StartString2(exp)%>' else ''
else '<%StartString2(exp)%>'
end ScalarVariableTypeCommonAttribute2;

template RealVariableTypeCommonAttribute2(list<SimVar> stateVars, Option<DAE.Exp> initialValue, VarKind varKind, Integer index)
template RealVariableTypeCommonAttribute2(list<SimVar> stateVars, Option<DAE.Exp> initialValue, VarKind varKind, Boolean isValueChangeable, Integer index)
"Generates code for ScalarVariable Type file for FMU 2.0 target."
::=
match varKind
case STATE_DER(__) then ' derivative="<%getStateSimVarIndexFromIndex(stateVars, index)%>"'
else
match initialValue
case SOME(exp) then '<%StartString2(exp)%>'
match initialValue
case SOME(exp) then
match varKind
case PARAM(__) then if isValueChangeable then '<%StartString2(exp)%>' else ''
else '<%StartString2(exp)%>'
end RealVariableTypeCommonAttribute2;

template StringVariableTypeCommonAttribute2(Option<DAE.Exp> initialValue)
template StringVariableTypeCommonAttribute2(Option<DAE.Exp> initialValue, VarKind varKind, Boolean isValueChangeable)
"Generates code for ScalarVariable Type file for FMU 2.0 target."
::=
match initialValue
case SOME(exp) then ' start=<%initVal(exp)%>'
case SOME(exp) then
match varKind
case PARAM(__) then if isValueChangeable then ' start=<%initVal(exp)%>' else ''
end StringVariableTypeCommonAttribute2;

// Code for generating modelDescription.xml file for FMI 1.0 ModelExchange.
Expand Down Expand Up @@ -496,7 +508,7 @@ case SIMVAR(__) then
<!-- Index of variable = "<%getVariableIndex(simVar)%>" -->
<ScalarVariable
<%ScalarVariableAttribute2(simVar)%>>
<%ScalarVariableType2(stateVars, type_,unit,displayUnit,initialValue,varKind,index)%>
<%ScalarVariableType2(stateVars, type_,unit,displayUnit,initialValue,varKind,index,isValueChangeable)%>
</ScalarVariable>
>>
else
Expand Down
42 changes: 38 additions & 4 deletions SimulationRuntime/c/fmi/FMI2Common.c
Expand Up @@ -62,6 +62,31 @@ fmi2_value_reference_t* real_to_fmi2_value_reference(int numberOfValueReferences
return valuesReferences_int;
}

/*
* OpenModelica uses signed char for boolean and according to FMI specifications boolean are ints.
* So to this function converts signed char into int
*/
int signedchar_to_int(signed char* modelicaBoolean, int* fmiBoolean, int size)
{
int i;
for (i = 0; i < size; i++) {
fmiBoolean[i] = (int) modelicaBoolean[i];
}
return 0;
}
/*
* OpenModelica uses signed char for boolean and according to FMI specifications boolean are ints.
* So to this function converts int into signed char
*/
int int_to_signedchar(int* fmiBoolean, signed char* modelicaBoolean, int size)
{
int i;
for (i = 0; i < size; i++) {
modelicaBoolean[i] = (signed char) fmiBoolean[i];
}
return 0;
}

/*
* Wrapper for the FMI function fmi2GetReal.
* parameter flowStatesInput is dummy and is only used to run the equations in sequence.
Expand Down Expand Up @@ -145,13 +170,19 @@ void fmi2SetInteger_OMC(void* in_fmi2, int numberOfValueReferences, double* inte
* 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, int* booleanValues, int fmiType)
void fmi2GetBoolean_OMC(void* in_fmi2, int numberOfValueReferences, double* booleanValuesReferences, double flowStatesInput, signed char* booleanValues, int fmiType)
{
if (fmiType == 1) {
int i;
FMI2ModelExchange* FMI2ME = (FMI2ModelExchange*)in_fmi2;
fmi2_value_reference_t* valuesReferences_int = real_to_fmi2_value_reference(numberOfValueReferences, booleanValuesReferences);
fmi2_status_t status = fmi2_import_get_boolean(FMI2ME->FMIImportInstance, valuesReferences_int, numberOfValueReferences, (fmi2_boolean_t*)booleanValues);
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));
}
Expand All @@ -164,12 +195,15 @@ void fmi2GetBoolean_OMC(void* in_fmi2, int numberOfValueReferences, double* bool
* Wrapper for the FMI function fmi2SetBoolean.
* Returns status.
*/
void fmi2SetBoolean_OMC(void* in_fmi2, int numberOfValueReferences, double* booleanValuesReferences, int* booleanValues, int fmiType)
void fmi2SetBoolean_OMC(void* in_fmi2, int numberOfValueReferences, double* booleanValuesReferences, 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);
fmi2_status_t status = fmi2_import_set_boolean(FMI2ME->FMIImportInstance, valuesReferences_int, numberOfValueReferences, (fmi2_boolean_t*)booleanValues);
int* fmiBoolean = malloc(sizeof(int)*numberOfValueReferences);
signedchar_to_int(booleanValues, fmiBoolean, numberOfValueReferences);
fmi2_status_t 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));
Expand Down

0 comments on commit 2ac4703

Please sign in to comment.