X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.fmil.core%2Fsrc%2Forg%2Fsimantics%2Ffmil%2Fcore%2FFMIL.java;h=4b1eeaca132386d9e1071b4e6bac3569d25d8325;hb=f6f05cb36bc0b849af8090efac1d549779e2076f;hp=3a7c031dc2522a60d8d1ff2e2028947a0e16cb8b;hpb=b74cf2632ea8a42163add129b4fe8ec36a4f39d1;p=simantics%2Ffmil.git diff --git a/org.simantics.fmil.core/src/org/simantics/fmil/core/FMIL.java b/org.simantics.fmil.core/src/org/simantics/fmil/core/FMIL.java index 3a7c031..4b1eeac 100644 --- a/org.simantics.fmil.core/src/org/simantics/fmil/core/FMIL.java +++ b/org.simantics.fmil.core/src/org/simantics/fmil/core/FMIL.java @@ -6,8 +6,10 @@ import java.io.RandomAccessFile; 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; @@ -30,11 +32,14 @@ public class FMIL { 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; @@ -61,7 +66,7 @@ public class FMIL { simulatorFMIUrl = FileLocator.find(b, new Path("libraries/FMUSimulator.dll"), null); } else if(env.os == OSType.LINUX) { sharedFMILIBUrl = FileLocator.find(b, new Path("libraries/libfmilib_shared.so"), null); - simulatorFMIUrl = FileLocator.find(b, new Path("libraries/FMUSimulator.so"), null); + simulatorFMIUrl = FileLocator.find(b, new Path("libraries/libFMUSimulator.so"), null); } libraries[0] = new File(FileLocator.toFileURL(sharedFMILIBUrl).getPath()); @@ -129,15 +134,16 @@ public class FMIL { } 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() { @@ -181,6 +187,11 @@ public class 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) { @@ -191,23 +202,25 @@ public class FMIL { 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(); - if(!tmpPath.endsWith("\\")) - tmpPath = tmpPath + "\\"; + String tmpPath = tempDir.toString(); + if(!tmpPath.endsWith("\\") && !tmpPath.endsWith("/")) + tmpPath = tmpPath + "/"; id = loadFMUFile_(path, tmpPath); getAllVariables(); @@ -221,12 +234,13 @@ public class FMIL { } catch (UnsatisfiedLinkError err) { throw new FMILException(UNSATISFIED_LINK, err); } catch (Exception e) { + LOGGER.error(e.getMessage()); throw new FMILException(e.getMessage()); } } } - private native int loadFMUFile_(String path, String toDir); + private native int loadFMUFile_(String path, String toDir) throws FMILException; /** * Set a step length for simulation @@ -334,23 +348,31 @@ public class FMIL { 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) { @@ -358,21 +380,77 @@ public class FMIL { } 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) { @@ -380,82 +458,50 @@ public class FMIL { } 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 @@ -468,10 +514,11 @@ public class FMIL { 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) { @@ -494,10 +541,11 @@ public class FMIL { 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) { @@ -858,19 +906,60 @@ public class FMIL { // 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) { @@ -878,71 +967,75 @@ public class FMIL { } } } + + 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;