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

Handle FMI 3.0 Enumerations in FMU import #417

Merged
merged 2 commits into from
Apr 29, 2023
Merged
Show file tree
Hide file tree
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
13 changes: 7 additions & 6 deletions Java/src/main/java/fmikit/ui/FMUBlockDialog.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.tree.*;
import java.awt.*;
Expand Down Expand Up @@ -833,7 +834,7 @@ public String getSFunctionParameters() {
String startValue = startValues.get(variable.name);

if ("structuralParameter".equals(variable.causality)) {
structuralParameterTypes.add(Util.typeEnumForVariable(variable));
structuralParameterTypes.add(Util.typeEnumForVariable(variable, modelDescription.fmiVersion));
structuralParameterVRs.add(variable.valueReference);
structuralParameterValues.add(startValue);
} else if ("String".equals(variable.type)) {
Expand All @@ -842,7 +843,7 @@ public String getSFunctionParameters() {
stringStartValues.add("'" + startValue + "'");
} else {
scalarStartSizes.add(variableSize);
scalarStartTypes.add(Util.typeEnumForVariable(variable));
scalarStartTypes.add(Util.typeEnumForVariable(variable, modelDescription.fmiVersion));
scalarStartVRs.add(variable.valueReference);
scalarStartValues.add(startValue);
}
Expand All @@ -869,7 +870,7 @@ public String getSFunctionParameters() {

inputPortWidths.add(inputPortWidth);

inputPortTypes.add(Util.typeEnumForVariable(firstVariable));
inputPortTypes.add(Util.typeEnumForVariable(firstVariable, modelDescription.fmiVersion));

for (ScalarVariable variable : inputPort) {
inputPortVariableVRs.add(variable.valueReference);
Expand All @@ -895,7 +896,7 @@ public String getSFunctionParameters() {

outportWidths.add(portWidth);

outportPortTypes.add(Util.typeEnumForVariable(firstVariable));
outportPortTypes.add(Util.typeEnumForVariable(firstVariable, modelDescription.fmiVersion));

for (ScalarVariable variable : outputPort) {
outputPortVariableVRs.add(variable.valueReference);
Expand Down Expand Up @@ -1005,7 +1006,7 @@ public String getSFunctionParameters() {
params.add(isTunable ? "1" : "0");

// variable type
params.add(Integer.toString(Util.typeEnumForVariable(variable)));
params.add(Integer.toString(Util.typeEnumForVariable(variable, modelDescription.fmiVersion)));

// value reference
params.add(variable.valueReference);
Expand Down Expand Up @@ -1772,7 +1773,7 @@ public void setStartValue(String variableName, String startValue) {
panel7.setLayout(new GridLayoutManager(1, 1, new Insets(0, 0, 0, 0), -1, -1));
panel7.setOpaque(false);
panel4.add(panel7, new GridConstraints(1, 2, 9, 1, GridConstraints.ANCHOR_EAST, GridConstraints.FILL_VERTICAL, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, new Dimension(280, 280), new Dimension(280, 280), new Dimension(280, 280), 0, false));
panel7.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), null));
panel7.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), null, TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, null, null));
lblModelImage = new JLabel();
lblModelImage.setEnabled(false);
lblModelImage.setText("no image available");
Expand Down
19 changes: 14 additions & 5 deletions Java/src/main/java/fmikit/ui/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.io.File;
Expand Down Expand Up @@ -55,9 +56,11 @@ public static void setTreeExpandedState(JTree tree, boolean expanded) {
}

public static void setNodeExpandedState(JTree tree, DefaultMutableTreeNode node, boolean expanded) {
ArrayList<DefaultMutableTreeNode> list = Collections.list(node.children());
for (DefaultMutableTreeNode treeNode : list) {
setNodeExpandedState(tree, treeNode, expanded);
ArrayList list = Collections.list(node.children());
for (Object treeNode : list) {
if (treeNode instanceof DefaultMutableTreeNode) {
setNodeExpandedState(tree, (DefaultMutableTreeNode) treeNode, expanded);
}
}
if (!expanded && node.isRoot()) {
return;
Expand Down Expand Up @@ -173,7 +176,7 @@ public static void delete(File f) throws IOException {
throw new FileNotFoundException("Failed to delete file: " + f);
}

public static int typeEnumForVariable(ScalarVariable variable) {
public static int typeEnumForVariable(final ScalarVariable variable, final String fmiVersion) {

final String type = variable.type;
final boolean discrete = "tunable".equals(variable.variability) || "discrete".equals(variable.variability);
Expand All @@ -190,7 +193,7 @@ public static int typeEnumForVariable(ScalarVariable variable) {
return 6;
} else if ("UInt16".equals(type)) {
return 7;
} else if ("Int32".equals(type) || "Integer".equals(type) || "Enumeration".equals(type)) {
} else if ("Int32".equals(type) || "Integer".equals(type)) {
return 8;
} else if ("UInt32".equals(type)) {
return 9;
Expand All @@ -206,6 +209,12 @@ public static int typeEnumForVariable(ScalarVariable variable) {
return 14;
} else if ("Clock".equals(type)) {
return 15;
} else if ("Enumeration".equals(type)) {
if ("1.0".equals(fmiVersion) || "2.0".equals(fmiVersion)) {
return 8;
} else {
return 10;
}
}

throw new RuntimeException("Unknown variable type: " + type);
Expand Down
4 changes: 2 additions & 2 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ jobs:
- job: maci64
displayName: 'macOS'
pool:
vmImage: 'macos-10.15'
vmImage: 'macos-11'

steps:

Expand Down Expand Up @@ -89,7 +89,7 @@ jobs:
- win32
- win64
pool:
vmImage: 'ubuntu-18.04'
vmImage: 'ubuntu-20.04'

steps:

Expand Down
48 changes: 47 additions & 1 deletion src/sfun_fmurun.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,8 @@ static DTypeId simulinkVariableType(SimStruct *S, Parameter parameter, size_t in
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 Down Expand Up @@ -570,6 +572,24 @@ static void setInput(SimStruct *S, bool direct, bool discrete, bool *inputEvent)
case FMIUInt32Type:
CHECK_STATUS(FMI3SetUInt32(instance, &vr, 1, (const uint32_T *)y, nValues));
break;
case FMIInt64Type: {
fmi3Int64* values = (fmi3Int64*)calloc(nValues, sizeof(fmi3Int64));
for (int j = 0; j < nValues; j++) {
values[j] = ((const int32_T*)y)[j];
}
CHECK_STATUS(FMI3SetInt64(instance, &vr, 1, values, nValues));
free(values);
break;
}
case FMIUInt64Type: {
fmi3UInt64* values = (fmi3UInt64*)calloc(nValues, sizeof(fmi3UInt64));
for (int j = 0; j < nValues; j++) {
values[j] = ((const uint32_T*)y)[j];
}
CHECK_STATUS(FMI3SetUInt64(instance, &vr, 1, values, nValues));
free(values);
break;
}
case FMIBooleanType: {
fmi3Boolean *values = (fmi3Boolean *)calloc(nValues, sizeof(fmi3Boolean));
for (int j = 0; j < nValues; j++) {
Expand Down Expand Up @@ -688,6 +708,24 @@ static void getOutput(SimStruct *S) {
case FMIUInt32Type:
CHECK_STATUS(FMI3GetUInt32(instance, &vr, 1, (uint32_T *)y, nValues));
break;
case FMIInt64Type: {
fmi3Int64* values = (fmi3Int64*)calloc(nValues, sizeof(fmi3Int64));
CHECK_STATUS(FMI3GetInt64(instance, &vr, 1, values, nValues));
for (int j = 0; j < nValues; j++) {
((int32_T*)y)[j] = values[j];
}
free(values);
break;
}
case FMIUInt64Type: {
fmi3UInt64* values = (fmi3UInt64*)calloc(nValues, sizeof(fmi3UInt64));
CHECK_STATUS(FMI3GetUInt64(instance, &vr, 1, values, nValues));
for (int j = 0; j < nValues; j++) {
((uint32_T*)y)[j] = values[j];
}
free(values);
break;
}
case FMIBooleanType: {
fmi3Boolean *values = (fmi3Boolean *)calloc(nValues, sizeof(fmi3Boolean));
CHECK_STATUS(FMI3GetBoolean(instance, &vr, 1, values, nValues));
Expand Down Expand Up @@ -1496,7 +1534,11 @@ static void mdlInitializeSizes(SimStruct *S) {
for (int i = 0; i < nu(S); i++) {
ssSetInputPortWidth(S, i, inputPortWidth(S, i));
ssSetInputPortRequiredContiguous(S, i, 1); // direct input signal access
DTypeId type = simulinkVariableType(S, inputPortTypesParam, i);
const DTypeId type = simulinkVariableType(S, inputPortTypesParam, i);
if (type < 0) {
setErrorStatus(S, "Unexpected type id for input port %d.", i);
return;
}
ssSetInputPortDataType(S, i, type);
bool dirFeed = inputPortDirectFeedThrough(S, i);
ssSetInputPortDirectFeedThrough(S, i, dirFeed); // direct feed through
Expand All @@ -1515,6 +1557,10 @@ static void mdlInitializeSizes(SimStruct *S) {
for (int i = 0; i < ny(S); i++) {
ssSetOutputPortWidth(S, i, outputPortWidth(S, i));
DTypeId type = simulinkVariableType(S, outputPortTypesParam, i);
if (type < 0) {
setErrorStatus(S, "Unexpected type id for output port %d.", i);
return;
}
ssSetOutputPortDataType(S, i, type);
}

Expand Down