]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
JNI interface and native libraries for FMU simulation. (refs #3398)
authorlempinen <lempinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Thu, 19 Apr 2012 10:57:26 +0000 (10:57 +0000)
committerlempinen <lempinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Thu, 19 Apr 2012 10:57:26 +0000 (10:57 +0000)
* Loads FMUs
* Simulates steps
* Changes parameter values
* Reads simulation results (subscribe to results)
* JNI interface for java handling

git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@24727 ac1ea38d-2e2b-0410-8846-a27921b304fc

org.simantics.modelica/META-INF/MANIFEST.MF
org.simantics.modelica/src/org/simantics/modelica/fmi/FMUControlJNI.java [new file with mode: 0644]
org.simantics.modelica/src/org/simantics/modelica/fmi/FMUJNIException.java [new file with mode: 0644]
org.simantics.modelica/src/org_simantics_modelica_fmi_FMUControlJNI.h [new file with mode: 0644]

index 80e82f4e0fc4d3c8dbcbf0779b1a75462e9a0d38..ab9e04e45c84c3851215afae7b0685272ac4f359 100644 (file)
@@ -10,7 +10,8 @@ Require-Bundle: gnu.trove2;bundle-version="2.0.4",
  org.simantics.history;bundle-version="1.0.0",
  org.simantics.databoard;bundle-version="0.6.3"
 Export-Package: org.simantics.modelica,
- org.simantics.modelica.data
+ org.simantics.modelica.data,
+ org.simantics.modelica.fmi
 Bundle-Activator: org.simantics.modelica.Activator
 Bundle-ActivationPolicy: lazy
 Bundle-Vendor: VTT Technical Research Centre of Finland
diff --git a/org.simantics.modelica/src/org/simantics/modelica/fmi/FMUControlJNI.java b/org.simantics.modelica/src/org/simantics/modelica/fmi/FMUControlJNI.java
new file mode 100644 (file)
index 0000000..620ae49
--- /dev/null
@@ -0,0 +1,327 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.modelica.fmi;\r
+\r
+import java.io.File;\r
+\r
+import org.eclipse.core.runtime.FileLocator;\r
+import org.eclipse.core.runtime.Platform;\r
+import org.osgi.framework.Bundle;\r
+import org.simantics.modelica.ModelicaManager;\r
+import org.simantics.modelica.ModelicaManager.OSType;\r
+\r
+\r
+/**\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class FMUControlJNI {\r
+\r
+       private static int              ERROR                           = 0;\r
+       private static int              OK                                      = 1;\r
+       private static String   UNSATISFIED_LINK        = "Method not found. DLL might not be loaded properly.";\r
+\r
+       /**\r
+        * Load native libraries required for the FMU simulation to work.\r
+        * \r
+        * @throws FMUJNIException\r
+        */\r
+       public void loadLibraries() throws FMUJNIException {\r
+               File[] libraries = new File[3];\r
+\r
+               OSType os = ModelicaManager.calculateOS();\r
+               if(os.equals(OSType.WINDOWS)) {\r
+                       Bundle bundle = Platform.getBundle("org.simantics.openmodelica.win32");\r
+                       if (bundle != null) {\r
+                               try{\r
+                                       String root = FileLocator.getBundleFile(bundle).getAbsolutePath();\r
+                                       libraries[0] = new File(root, "libraries/zlibwapi.dll");\r
+                                       libraries[1] = new File(root, "libraries/miniunz.dll");\r
+                                       libraries[2] = new File(root, "libraries/FMUSimulator.dll");\r
+                               }\r
+                               catch (Exception e) {\r
+                                       e.printStackTrace();\r
+                               }\r
+                       }\r
+               }\r
+\r
+               for(File library : libraries) {\r
+                       if(!library.isFile()) {\r
+                               throw new FMUJNIException(library.getAbsolutePath() + " not found");\r
+                       } else if(library != null) {\r
+                               try {\r
+                                       System.load(library.getAbsolutePath());\r
+                               } catch (Throwable t) {\r
+                                       throw new FMUJNIException(t.getMessage());\r
+                               }\r
+                       } \r
+               }\r
+       }\r
+\r
+       /**\r
+        * Load fmu from a given file path. Releases the (possible) previously\r
+        * loaded fmu.\r
+        * \r
+        * @param path absolute file path for fmu file\r
+        * @throws FMUJNIException\r
+        */\r
+       public void loadFMUFile(String path) throws FMUJNIException {\r
+               try {\r
+\r
+                       int ret = loadFMUFile_(path);\r
+                       if(ret == ERROR)\r
+                               throw new FMUJNIException(getLastErrorMessage());\r
+\r
+               } catch (UnsatisfiedLinkError err) {\r
+                       throw new FMUJNIException(UNSATISFIED_LINK);\r
+               }\r
+       }\r
+\r
+       private native int loadFMUFile_(String path);\r
+\r
+       /**\r
+        * Set a step length for simulation\r
+        * \r
+        * @param step Step length for simulation\r
+        * @throws FMUJNIException\r
+        */\r
+       public void setStepLength(double step) throws FMUJNIException {\r
+               try {\r
+\r
+                       int ret = setStepLength_(step);\r
+                       if(ret == ERROR)\r
+                               throw new FMUJNIException(getLastErrorMessage());\r
+\r
+               } catch (UnsatisfiedLinkError err) {\r
+                       throw new FMUJNIException(UNSATISFIED_LINK);\r
+               }\r
+       }\r
+\r
+       private native int setStepLength_(double step);\r
+\r
+       /**\r
+        * Initializes a simulation. \r
+        * <p>\r
+        * Make sure that an FMU is loaded first.\r
+        * @throws FMUJNIException\r
+        */\r
+       public void initializeSimulation() throws FMUJNIException {\r
+               try {\r
+\r
+                       int ret = initializeSimulation_(); \r
+                       if(ret == ERROR)\r
+                               throw new FMUJNIException(getLastErrorMessage());\r
+\r
+               } catch (UnsatisfiedLinkError err) {\r
+                       throw new FMUJNIException(UNSATISFIED_LINK);\r
+               }\r
+       }\r
+\r
+       private native int initializeSimulation_();\r
+\r
+       /**\r
+        * Subscribe a set of variables from a loaded simulation.\r
+        * <p>\r
+        * Make sure that an FMU is loaded first.\r
+        * @param variables Array of variables\r
+        * @throws FMUJNIException\r
+        */\r
+       public void subscribe(String[] variables) throws FMUJNIException {\r
+               try {\r
+\r
+                       int ret = subscribe_(variables, variables.length); \r
+                       if(ret == ERROR)\r
+                               throw new FMUJNIException(getLastErrorMessage());\r
+\r
+               } catch (UnsatisfiedLinkError err) {\r
+                       throw new FMUJNIException(UNSATISFIED_LINK);\r
+               }\r
+       }\r
+\r
+       private native int subscribe_(String[] variables, int size);\r
+\r
+\r
+       /**\r
+        * Set a new (Real, double) value for a variable. If the variable is a \r
+        * parameter, the change is effective immediately.\r
+        *  \r
+        * @param name Variable\r
+        * @param value New (Real, double) value\r
+        * @throws FMUJNIException\r
+        */\r
+       public void setRealValue(String name, double value) throws FMUJNIException {\r
+               try {\r
+\r
+                       int ret = setRealValue_(name, value); \r
+                       if(ret == ERROR)\r
+                               throw new FMUJNIException(getLastErrorMessage());\r
+\r
+               } catch (UnsatisfiedLinkError err) {\r
+                       throw new FMUJNIException(UNSATISFIED_LINK);\r
+               }\r
+       }\r
+\r
+       private native int setRealValue_(String name, double value);\r
+\r
+       /**\r
+        * Set a new (integer) value for a variable. If the variable is a \r
+        * parameter, the change is effective immediately.\r
+        *  \r
+        * @param name Variable\r
+        * @param value New (integer) value\r
+        * @throws FMUJNIException\r
+        */\r
+       public void setIntegerValue(String name, int value) throws FMUJNIException {\r
+               try {\r
+\r
+                       int ret = setIntegerValue_(name, value); \r
+                       if(ret == ERROR)\r
+                               throw new FMUJNIException(getLastErrorMessage());\r
+\r
+               } catch (UnsatisfiedLinkError err) {\r
+                       throw new FMUJNIException(UNSATISFIED_LINK);\r
+               }\r
+       }\r
+       private native int setIntegerValue_(String name, int value);\r
+\r
+       /**\r
+        * Set a new (boolean) value for a variable. If the variable is a \r
+        * parameter, the change is effective immediately.\r
+        *  \r
+        * @param name Variable\r
+        * @param value New (boolean) value\r
+        * @throws FMUJNIException\r
+        */\r
+       public void setBooleanValue(String name, boolean value) throws FMUJNIException {\r
+               try {\r
+\r
+                       int ret = setBooleanValue_(name, value); \r
+                       if(ret == ERROR)\r
+                               throw new FMUJNIException(getLastErrorMessage());\r
+\r
+               } catch (UnsatisfiedLinkError err) {\r
+                       throw new FMUJNIException(UNSATISFIED_LINK);\r
+               }\r
+       }\r
+       private native int setBooleanValue_(String name, boolean value);\r
+\r
+\r
+       /**\r
+        * Simulate one step forward. The step length can be set with\r
+        * setStepLength()\r
+        * \r
+        * @throws FMUJNIException\r
+        */\r
+       public void simulateStep() throws FMUJNIException {\r
+               try {\r
+\r
+                       int ret = simulateStep_(); \r
+                       if(ret == ERROR)\r
+                               throw new FMUJNIException(getLastErrorMessage());\r
+\r
+               } catch (UnsatisfiedLinkError err) {\r
+                       throw new FMUJNIException(UNSATISFIED_LINK);\r
+               }\r
+       }\r
+       private native int simulateStep_();\r
+\r
+       /**\r
+        * Get an array containing the current values for subscribed variables. The\r
+        * values are in the same order as in the subscription.\r
+        * \r
+        * @param results An array the size of subscribed results\r
+        * @return\r
+        */\r
+       public double[] getSubscribedResults(double[] results) throws FMUJNIException {\r
+               try {\r
+\r
+                       return getSubscribedResults_(results);\r
+\r
+               } catch (UnsatisfiedLinkError err) {\r
+                       throw new FMUJNIException(UNSATISFIED_LINK);\r
+               }\r
+       }\r
+       \r
+       private native double[] getSubscribedResults_(double[] results);\r
+\r
+       /**\r
+        * Unload FMU and the dll:s that it requires.\r
+        * <p>\r
+        * To be called after all FMU simulations are ended. \r
+        * If the fmu is loaded again / changed, call to loadFMUFile is sufficient. loadFMUFile \r
+        * releases the previous fmu.dll  \r
+        * \r
+        * @throws FMUJNIException\r
+        */\r
+       public void unloadFMU() throws FMUJNIException {\r
+               try {\r
+\r
+                       int ret = unloadFMU_(); \r
+                       if(ret == ERROR)\r
+                               throw new FMUJNIException(getLastErrorMessage());\r
+\r
+               } catch (UnsatisfiedLinkError err) {\r
+                       throw new FMUJNIException(UNSATISFIED_LINK);\r
+               }\r
+       }\r
+       private native int unloadFMU_();\r
+\r
+       /**\r
+        * Get the current simulation time\r
+        * @return current simulation time\r
+        */\r
+       public double getTime() throws FMUJNIException {\r
+               try {\r
+\r
+                       return getTime_();\r
+\r
+               } catch (UnsatisfiedLinkError err) {\r
+                       throw new FMUJNIException(UNSATISFIED_LINK);\r
+               }\r
+       }\r
+               \r
+       private native double getTime_();\r
+\r
+       /**\r
+        * Get all variables in a loaded model\r
+        * @return all variables in a loaded model\r
+        */\r
+       public String[] getAllVariables() throws FMUJNIException {\r
+               try {\r
+\r
+                       return getAllVariables_();\r
+\r
+               } catch (UnsatisfiedLinkError err) {\r
+                       throw new FMUJNIException(UNSATISFIED_LINK);\r
+               }\r
+       }\r
+       \r
+       private native String[] getAllVariables_();\r
+\r
+       /**\r
+        * Get the last error message\r
+        * @return Last error message\r
+        */\r
+       public String getLastErrorMessage() throws FMUJNIException {\r
+               try {\r
+\r
+                       return getLastErrorMessage_();\r
+\r
+               } catch (UnsatisfiedLinkError err) {\r
+                       throw new FMUJNIException(UNSATISFIED_LINK);\r
+               }\r
+       }\r
+               \r
+       private native String getLastErrorMessage_();\r
+\r
+}\r
diff --git a/org.simantics.modelica/src/org/simantics/modelica/fmi/FMUJNIException.java b/org.simantics.modelica/src/org/simantics/modelica/fmi/FMUJNIException.java
new file mode 100644 (file)
index 0000000..6308f73
--- /dev/null
@@ -0,0 +1,25 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.modelica.fmi;\r
+\r
+/**\r
+ * Exception thrown when native fmu calls fail\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class FMUJNIException extends Exception {\r
+       private static final long serialVersionUID = -7164064752664568008L;\r
+\r
+       public FMUJNIException(String message) {\r
+               super(message);\r
+       }\r
+}\r
diff --git a/org.simantics.modelica/src/org_simantics_modelica_fmi_FMUControlJNI.h b/org.simantics.modelica/src/org_simantics_modelica_fmi_FMUControlJNI.h
new file mode 100644 (file)
index 0000000..526042d
--- /dev/null
@@ -0,0 +1,117 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */\r
+#include <jni.h>\r
+/* Header for class org_simantics_modelica_fmi_FMUControlJNI */\r
+\r
+#ifndef _Included_org_simantics_modelica_fmi_FMUControlJNI\r
+#define _Included_org_simantics_modelica_fmi_FMUControlJNI\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+/*\r
+ * Class:     org_simantics_modelica_fmi_FMUControlJNI\r
+ * Method:    loadFMUFile_\r
+ * Signature: (Ljava/lang/String;)I\r
+ */\r
+JNIEXPORT jint JNICALL Java_org_simantics_modelica_fmi_FMUControlJNI_loadFMUFile_1\r
+  (JNIEnv *, jobject, jstring);\r
+\r
+/*\r
+ * Class:     org_simantics_modelica_fmi_FMUControlJNI\r
+ * Method:    setStepLength_\r
+ * Signature: (D)I\r
+ */\r
+JNIEXPORT jint JNICALL Java_org_simantics_modelica_fmi_FMUControlJNI_setStepLength_1\r
+  (JNIEnv *, jobject, jdouble);\r
+\r
+/*\r
+ * Class:     org_simantics_modelica_fmi_FMUControlJNI\r
+ * Method:    initializeSimulation_\r
+ * Signature: ()I\r
+ */\r
+JNIEXPORT jint JNICALL Java_org_simantics_modelica_fmi_FMUControlJNI_initializeSimulation_1\r
+  (JNIEnv *, jobject);\r
+\r
+/*\r
+ * Class:     org_simantics_modelica_fmi_FMUControlJNI\r
+ * Method:    subscribe_\r
+ * Signature: ([Ljava/lang/String;I)I\r
+ */\r
+JNIEXPORT jint JNICALL Java_org_simantics_modelica_fmi_FMUControlJNI_subscribe_1\r
+  (JNIEnv *, jobject, jobjectArray, jint);\r
+\r
+/*\r
+ * Class:     org_simantics_modelica_fmi_FMUControlJNI\r
+ * Method:    setRealValue_\r
+ * Signature: (Ljava/lang/String;D)I\r
+ */\r
+JNIEXPORT jint JNICALL Java_org_simantics_modelica_fmi_FMUControlJNI_setRealValue_1\r
+  (JNIEnv *, jobject, jstring, jdouble);\r
+\r
+/*\r
+ * Class:     org_simantics_modelica_fmi_FMUControlJNI\r
+ * Method:    setIntegerValue_\r
+ * Signature: (Ljava/lang/String;I)I\r
+ */\r
+JNIEXPORT jint JNICALL Java_org_simantics_modelica_fmi_FMUControlJNI_setIntegerValue_1\r
+  (JNIEnv *, jobject, jstring, jint);\r
+\r
+/*\r
+ * Class:     org_simantics_modelica_fmi_FMUControlJNI\r
+ * Method:    setBooleanValue_\r
+ * Signature: (Ljava/lang/String;Z)I\r
+ */\r
+JNIEXPORT jint JNICALL Java_org_simantics_modelica_fmi_FMUControlJNI_setBooleanValue_1\r
+  (JNIEnv *, jobject, jstring, jboolean);\r
+\r
+/*\r
+ * Class:     org_simantics_modelica_fmi_FMUControlJNI\r
+ * Method:    simulateStep_\r
+ * Signature: ()I\r
+ */\r
+JNIEXPORT jint JNICALL Java_org_simantics_modelica_fmi_FMUControlJNI_simulateStep_1\r
+  (JNIEnv *, jobject);\r
+\r
+/*\r
+ * Class:     org_simantics_modelica_fmi_FMUControlJNI\r
+ * Method:    getSubscribedResults_\r
+ * Signature: ([D)[D\r
+ */\r
+JNIEXPORT jdoubleArray JNICALL Java_org_simantics_modelica_fmi_FMUControlJNI_getSubscribedResults_1\r
+  (JNIEnv *, jobject, jdoubleArray);\r
+\r
+/*\r
+ * Class:     org_simantics_modelica_fmi_FMUControlJNI\r
+ * Method:    unloadFMU_\r
+ * Signature: ()I\r
+ */\r
+JNIEXPORT jint JNICALL Java_org_simantics_modelica_fmi_FMUControlJNI_unloadFMU_1\r
+  (JNIEnv *, jobject);\r
+\r
+/*\r
+ * Class:     org_simantics_modelica_fmi_FMUControlJNI\r
+ * Method:    getTime_\r
+ * Signature: ()D\r
+ */\r
+JNIEXPORT jdouble JNICALL Java_org_simantics_modelica_fmi_FMUControlJNI_getTime_1\r
+  (JNIEnv *, jobject);\r
+\r
+/*\r
+ * Class:     org_simantics_modelica_fmi_FMUControlJNI\r
+ * Method:    getAllVariables_\r
+ * Signature: ()[Ljava/lang/String;\r
+ */\r
+JNIEXPORT jobjectArray JNICALL Java_org_simantics_modelica_fmi_FMUControlJNI_getAllVariables_1\r
+  (JNIEnv *, jobject);\r
+\r
+/*\r
+ * Class:     org_simantics_modelica_fmi_FMUControlJNI\r
+ * Method:    getLastErrorMessage_\r
+ * Signature: ()Ljava/lang/String;\r
+ */\r
+JNIEXPORT jstring JNICALL Java_org_simantics_modelica_fmi_FMUControlJNI_getLastErrorMessage_1\r
+  (JNIEnv *, jobject);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+#endif\r