import java.net.URL;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
+import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
private static final Logger LOGGER = LoggerFactory.getLogger(FMIL.class);
+ private static final boolean DEBUG = false;
+
/**
* Static variables
*/
private static int OK = 0;
private static int ERROR = 1;
+ private static int PENDING = 2;
private static String UNSATISFIED_LINK = "Method not found. DLL might not be loaded properly.";
public static final String TEMP_FMU_DIRECTORY_NAME = "fmil";
public static String TEMP_FMU_COMMON_DIRECTORY;
}
public boolean subscribe(String name) throws FMILException {
- // Safety check
- int vr = variableMap.get(name);
- if(vr == 0) return false;
- if(!subscriptionSet.add(name)) return false;
- subscribedNames.add(name);
- System.err.println("subscribed : " + name + " => " + subscribedNames.size());
- subscription.add(vr);
- subscribe(new int[] { vr });
- return true;
+ synchronized(syncObject) {
+ // Safety check
+ int vr = variableMap.get(name);
+ if(vr == 0) return false;
+ if(!subscriptionSet.add(name)) return false;
+ subscribedNames.add(name);
+ subscription.add(vr);
+ subscribe(new int[] { vr });
+ return true;
+ }
}
public FMIL() {
private boolean fmuLoaded = false;
public void loadFMUFile(String path) throws FMILException {
+ if (!Files.exists(Paths.get(path)))
+ throw new FMILException("File " + path + " does not exist");
+ if (!Files.isRegularFile(Paths.get(path)))
+ throw new FMILException("Path " + path + " is not a file");
+
synchronized(syncObject) {
if(fmuN % 2 == 0) {
fmuN = 0;
}
- File tempDir = new File(fmuDir);
- if(tempDir.isDirectory()) {
+ java.nio.file.Path tempDir = Paths.get(fmuDir);
+ if(Files.exists(tempDir) && Files.isDirectory(tempDir)) {
try {
- FileUtils.deleteAll(tempDir);
+ FileUtils.emptyDirectory(tempDir);
} catch (IOException e) {
- throw new FMILException("Could not create temp folder for fmu");
+ throw new FMILException("Could not delete existing files from temp folder for fmu " + path, e);
}
- tempDir.mkdir();
} else {
- tempDir.mkdir();
+ try {
+ Files.createDirectory(tempDir);
+ } catch (IOException e) {
+ throw new FMILException("Could not create temp folder for fmu " + path, e);
+ }
}
-
try {
- String tmpPath = tempDir.getAbsolutePath();
+ String tmpPath = tempDir.toString();
if(!tmpPath.endsWith("\\") && !tmpPath.endsWith("/"))
tmpPath = tmpPath + "/";
id = loadFMUFile_(path, tmpPath);
}
}
- private native int loadFMUFile_(String path, String toDir);
+ private native int loadFMUFile_(String path, String toDir) throws FMILException;
/**
* Set a step length for simulation
private native int subscribe_(int id, int[] variables);
/**
- * Set a new (Real, double) value for a variable. If the variable is a
+ * Set value of a real variable. If the variable is a
* parameter, the change is effective immediately.
*
- * @param name Variable
- * @param value New (Real, double) value
+ * @param name Variable name
+ * @param value New value
* @throws FMILException
*/
public void setRealValue(String name, double value) throws FMILException {
-
- synchronized(syncObject) {
+ setRealValue(variableMap.get(name), value);
+ }
+ /**
+ * Set value of a real variable. If the variable is a
+ * parameter, the change is effective immediately.
+ *
+ * @param name Variable id
+ * @param value New value
+ * @throws FMILException
+ */
+ public void setRealValue(int variableReference, double value) throws FMILException {
+ synchronized(syncObject) {
try {
-
- int ret = setRealValue_(getModelIDNew(), variableMap.get(name), value);
+ int ret = setRealValue_(getModelIDNew(), variableReference, value);
if(ret != OK)
LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
-
} catch (FMILException e) {
throw e;
} catch (UnsatisfiedLinkError err) {
} catch (Exception e) {
throw new FMILException(e.getMessage());
}
-
}
-
}
- public void setRealValue(int variableReference, double value) throws FMILException {
-
- synchronized(syncObject) {
+ private native int setRealValue_(int id, int variableReference, double value) throws FMILException;
- try {
+
+ /**
+ * Set value of an integer variable. If the variable is a
+ * parameter, the change is effective immediately.
+ *
+ * @param name Variable name
+ * @param value New value
+ * @throws FMILException
+ */
+ public void setIntegerValue(String name, int value) throws FMILException {
+ setIntegerValue(variableMap.get(name), value);
+ }
- int ret = setRealValue_(getModelIDNew(), variableReference, value);
+ /**
+ * Set value of an integer variable. If the variable is a
+ * parameter, the change is effective immediately.
+ *
+ * @param name Variable id
+ * @param value New value
+ * @throws FMILException
+ */
+ public void setIntegerValue(int variableReference, int value) throws FMILException {
+ synchronized(syncObject) {
+ try {
+ int ret = setIntegerValue_(getModelIDNew(), variableReference, value);
if(ret != OK)
LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
+ } catch (FMILException e) {
+ throw e;
+ } catch (UnsatisfiedLinkError err) {
+ throw new FMILException(UNSATISFIED_LINK);
+ } catch (Exception e) {
+ throw new FMILException(e.getMessage());
+ }
+ }
+ }
+ private native int setIntegerValue_(int id, int variableReference, int value) throws FMILException;
+
+
+ /**
+ * Set value of a boolean variable. If the variable is a
+ * parameter, the change is effective immediately.
+ *
+ * @param name Variable name
+ * @param value New value
+ * @throws FMILException
+ */
+ public void setBooleanValue(String name, boolean value) throws FMILException {
+ setBooleanValue(variableMap.get(name), value);
+ }
+
+ /**
+ * Set value of a boolean variable. If the variable is a
+ * parameter, the change is effective immediately.
+ *
+ * @param name Variable id
+ * @param value New value
+ * @throws FMILException
+ */
+ public void setBooleanValue(int variableReference, boolean value) throws FMILException {
+ synchronized(syncObject) {
+ try {
+ int ret = setBooleanValue_(getModelIDNew(), variableReference, value);
+ if(ret != OK)
+ LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
} catch (FMILException e) {
throw e;
} catch (UnsatisfiedLinkError err) {
} catch (Exception e) {
throw new FMILException(e.getMessage());
}
-
}
-
}
- private native int setRealValue_(int id, int variableReference, double value) throws FMILException;
+ private native int setBooleanValue_(int id, int variableReference, boolean value) throws FMILException;
-// /**
-// * Set a new (integer) value for a variable. If the variable is a
-// * parameter, the change is effective immediately.
-// *
-// * @param name Variable
-// * @param value New (integer) value
-// * @throws FMILException
-// */
-// public void setIntegerValue(String name, int value) throws FMILException {
-// synchronized(syncObject) {
-//
-// try {
-//
-// int ret = setIntegerValue_(getModelID(), name, value);
-// if(ret == ERROR)
-// throw new FMILException(getLastErrorMessage());
-//
-// } catch (UnsatisfiedLinkError err) {
-// throw new FMILException(UNSATISFIED_LINK);
-// } catch (Exception e) {
-// throw new FMILException(e.getMessage());
-// }
-// }
-// }
-// private native int setIntegerValue_(String id, String name, int value);
-//
-// /**
-// * Set a new (boolean) value for a variable. If the variable is a
-// * parameter, the change is effective immediately.
-// *
-// * @param name Variable
-// * @param value New (boolean) value
-// * @throws FMILException
-// */
-// public void setBooleanValue(String name, boolean value) throws FMILException {
-// synchronized(syncObject) {
-//
-// try {
-//
-// int ret = setBooleanValue_(getModelID(), name, value);
-// if(ret == ERROR)
-// throw new FMILException(getLastErrorMessage());
-//
-// } catch (UnsatisfiedLinkError err) {
-// throw new FMILException(UNSATISFIED_LINK);
-// } catch (Exception e) {
-// throw new FMILException(e.getMessage());
-// }
-// }
-// }
-// private native int setBooleanValue_(String id, String name, boolean value);
-//
-// public void setTime(double time) throws FMILException {
-// synchronized(syncObject) {
-//
-// try {
-//
-// int ret = setTime_(getModelID(), time);
-// if(ret == ERROR)
-// throw new FMILException(getLastErrorMessage());
-//
-// } catch (UnsatisfiedLinkError err) {
-// throw new FMILException(UNSATISFIED_LINK);
-// } catch (Exception e) {
-// throw new FMILException(e.getMessage());
-// }
-// }
-// }
-// private native int setTime_(String id, double time);
+
+ /**
+ * Set value of a string variable. If the variable is a
+ * parameter, the change is effective immediately.
+ *
+ * @param name Variable name
+ * @param value New value
+ * @throws FMILException
+ */
+ public void setStringValue(String name, String value) throws FMILException {
+ setStringValue(variableMap.get(name), value);
+ }
+
+ /**
+ * Set value of a string variable. If the variable is a
+ * parameter, the change is effective immediately.
+ *
+ * @param name Variable id
+ * @param value New value
+ * @throws FMILException
+ */
+ public void setStringValue(int variableReference, String value) throws FMILException {
+ synchronized(syncObject) {
+ try {
+ int ret = setStringValue_(getModelIDNew(), variableReference, value);
+ if(ret != OK)
+ LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
+ } catch (FMILException e) {
+ throw e;
+ } catch (UnsatisfiedLinkError err) {
+ throw new FMILException(UNSATISFIED_LINK);
+ } catch (Exception e) {
+ throw new FMILException(e.getMessage());
+ }
+ }
+ }
+
+ private native int setStringValue_(int id, int variableReference, String value) throws FMILException;
+
/**
* Simulate one step forward. The step length can be set with
try {
- int ret = simulateStep_(getModelIDNew());
- if(ret != OK)
+ int ret = simulateStep_(getModelIDNew()); //0 is ok, 1 is error, 2 is pending
+ if(ret == PENDING)
+ LOGGER.warn("Pending status return from FMU. This is not implemented in our Simulator yet!");
+ else if(ret != OK)
LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
-
} catch (FMILException e) {
throw e;
} catch (UnsatisfiedLinkError err) {
synchronized(syncObject) {
try {
-
+
double[] results = new double[subscription.size()];
- return getSubscribedResults_(getModelIDNew(), results);
-
+ Arrays.fill(results, Double.NaN);
+
+ return getSubscribedResults_(getModelIDNew(), results);
} catch (UnsatisfiedLinkError err) {
throw new FMILException(UNSATISFIED_LINK);
} catch (Exception e) {
// private native String getLastErrorMessage_(String id);
/**
- * Get a real (double) value for variable
+ * Get a value (double) for real variable
* @param name Name of the variable
* @return value
* @throws FMILException
*/
public double getRealValue(String name) throws FMILException {
+ double result = getRealValue(variableMap.get(name));
+ if (DEBUG) System.err.println("getRealValue " + name + " = " + result);
+ return result;
+ }
+
+ /**
+ * Get a value (double) for real variable
+ * @param variableReference Numeric id of the variable
+ * @return value
+ * @throws FMILException
+ */
+ public double getRealValue(int variableReference) throws FMILException {
synchronized(syncObject) {
+ try {
+ return getRealValue_(getModelIDNew(), variableReference);
+ } catch (UnsatisfiedLinkError err) {
+ throw new FMILException(UNSATISFIED_LINK);
+ } catch (Exception e) {
+ throw new FMILException(e.getMessage());
+ }
+ }
+ }
+
+ private native double getRealValue_(int id, int variableReference) throws FMILException;
+
+ /**
+ * Get value of integer variable
+ * @param name Name of the variable
+ * @return value
+ * @throws FMILException
+ */
+ public int getIntegerValue(String name) throws FMILException {
+ int result = getIntegerValue(variableMap.get(name));
+ if (DEBUG) System.err.println("getIntegerValue " + name + " = " + result);
+ return result;
+ }
+
+ /**
+ * Get a real (double) value for variable
+ * @param variableReference Numeric id of the variable
+ * @return value
+ * @throws FMILException
+ */
+ public int getIntegerValue(int variableReference) throws FMILException {
+ synchronized(syncObject) {
try {
- // TODO: printtaa id ja name, jotta saadaan virheessä kiinni
- double result = getRealValue_(getModelIDNew(), variableMap.get(name));
- System.err.println("getRealValue " + name + " = " + result);
- return result;
+ return getIntegerValue_(getModelIDNew(), variableReference);
} catch (UnsatisfiedLinkError err) {
throw new FMILException(UNSATISFIED_LINK);
} catch (Exception e) {
}
}
}
+
+ private native int getIntegerValue_(int id, int variableReference) throws FMILException;
+
+
+ /**
+ * Get value of boolean variable
+ * @param name Name of the variable
+ * @return value
+ * @throws FMILException
+ */
+ public boolean getBooleanValue(String name) throws FMILException {
+ boolean result = getBooleanValue(variableMap.get(name));
+ if (DEBUG) System.err.println("getBooleanValue " + name + " = " + result);
+ return result;
+ }
- private native double getRealValue_(int id, int variableReference);
+ /**
+ * Get value of boolean variable
+ * @param variableReference Numeric id of the variable
+ * @return value
+ * @throws FMILException
+ */
+ public boolean getBooleanValue(int variableReference) throws FMILException {
+ synchronized(syncObject) {
+ try {
+ return getBooleanValue_(getModelIDNew(), variableReference);
+ } catch (UnsatisfiedLinkError err) {
+ throw new FMILException(UNSATISFIED_LINK);
+ } catch (Exception e) {
+ throw new FMILException(e.getMessage());
+ }
+ }
+ }
+
+ private native boolean getBooleanValue_(int id, int variableReference) throws FMILException;
+
+
+ /**
+ * Get value of string variable
+ * @param name Name of the variable
+ * @return value
+ * @throws FMILException
+ */
+ public String getStringValue(String name) throws FMILException {
+ String result = getStringValue(variableMap.get(name));
+ if (DEBUG) System.err.println("getIntegerValue " + name + " = " + result);
+ return result;
+ }
-// /**
-// * Get a string value for variable
-// * @param name Name of the variable
-// * @return value
-// * @throws FMILException
-// */
-// public String getStringValue(String name) throws FMILException {
-// synchronized(syncObject) {
-//
-// try {
-// return getStringValue_(getModelID(), name);
-// } catch (UnsatisfiedLinkError err) {
-// throw new FMILException(UNSATISFIED_LINK);
-// } catch (Exception e) {
-// throw new FMILException(e.getMessage());
-// }
-// }
-// }
-//
-// private native String getStringValue_(String id, String name);
-//
-// /**
-// * Get an integer value for variable
-// * @param name Name of the variable
-// * @return value
-// * @throws FMILException
-// */
-// public int getIntegerValue(String name) throws FMILException {
-// synchronized(syncObject) {
-//
-// try {
-// return getIntegerValue_(getModelID(), name);
-// } catch (UnsatisfiedLinkError err) {
-// throw new FMILException(UNSATISFIED_LINK);
-// } catch (Exception e) {
-// throw new FMILException(e.getMessage());
-// }
-// }
-// }
-//
-// private native int getIntegerValue_(String id, String name);
-//
-// /**
-// * Get a real (double) value for variable
-// * @param name Name of the variable
-// * @return value
-// * @throws FMILException
-// */
-// public boolean getBooleanValue(String name) throws FMILException {
-// synchronized(syncObject) {
-//
-// try {
-// return getBooleanValue_(getModelID(), name);
-// } catch (UnsatisfiedLinkError err) {
-// throw new FMILException(UNSATISFIED_LINK);
-// } catch (Exception e) {
-// throw new FMILException(e.getMessage());
-// }
-// }
-// }
-//
-// private native boolean getBooleanValue_(String id, String name);
+ /**
+ * Get value of string variable
+ * @param variableReference Numeric id of the variable
+ * @return value
+ * @throws FMILException
+ */
+ public String getStringValue(int variableReference) throws FMILException {
+ synchronized(syncObject) {
+ try {
+ return getStringValue_(getModelIDNew(), variableReference);
+ } catch (UnsatisfiedLinkError err) {
+ throw new FMILException(UNSATISFIED_LINK);
+ } catch (Exception e) {
+ throw new FMILException(e.getMessage());
+ }
+ }
+ }
+
+ private native String getStringValue_(int id, int variableReference) throws FMILException;
+
private FileChannel channel;
private FileLock lock;