From fd93080dbb3f4cae715e3fea9788bcb5049fc059 Mon Sep 17 00:00:00 2001 From: lempinen Date: Thu, 19 Apr 2012 10:57:26 +0000 Subject: [PATCH] JNI interface and native libraries for FMU simulation. (refs #3398) * 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 | 3 +- .../simantics/modelica/fmi/FMUControlJNI.java | 327 ++++++++++++++++++ .../modelica/fmi/FMUJNIException.java | 25 ++ ...org_simantics_modelica_fmi_FMUControlJNI.h | 117 +++++++ 4 files changed, 471 insertions(+), 1 deletion(-) create mode 100644 org.simantics.modelica/src/org/simantics/modelica/fmi/FMUControlJNI.java create mode 100644 org.simantics.modelica/src/org/simantics/modelica/fmi/FMUJNIException.java create mode 100644 org.simantics.modelica/src/org_simantics_modelica_fmi_FMUControlJNI.h diff --git a/org.simantics.modelica/META-INF/MANIFEST.MF b/org.simantics.modelica/META-INF/MANIFEST.MF index 80e82f4e..ab9e04e4 100644 --- a/org.simantics.modelica/META-INF/MANIFEST.MF +++ b/org.simantics.modelica/META-INF/MANIFEST.MF @@ -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 index 00000000..620ae495 --- /dev/null +++ b/org.simantics.modelica/src/org/simantics/modelica/fmi/FMUControlJNI.java @@ -0,0 +1,327 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.modelica.fmi; + +import java.io.File; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Platform; +import org.osgi.framework.Bundle; +import org.simantics.modelica.ModelicaManager; +import org.simantics.modelica.ModelicaManager.OSType; + + +/** + * + * @author Teemu Lempinen + * + */ +public class FMUControlJNI { + + private static int ERROR = 0; + private static int OK = 1; + private static String UNSATISFIED_LINK = "Method not found. DLL might not be loaded properly."; + + /** + * Load native libraries required for the FMU simulation to work. + * + * @throws FMUJNIException + */ + public void loadLibraries() throws FMUJNIException { + File[] libraries = new File[3]; + + OSType os = ModelicaManager.calculateOS(); + if(os.equals(OSType.WINDOWS)) { + Bundle bundle = Platform.getBundle("org.simantics.openmodelica.win32"); + if (bundle != null) { + try{ + String root = FileLocator.getBundleFile(bundle).getAbsolutePath(); + libraries[0] = new File(root, "libraries/zlibwapi.dll"); + libraries[1] = new File(root, "libraries/miniunz.dll"); + libraries[2] = new File(root, "libraries/FMUSimulator.dll"); + } + catch (Exception e) { + e.printStackTrace(); + } + } + } + + for(File library : libraries) { + if(!library.isFile()) { + throw new FMUJNIException(library.getAbsolutePath() + " not found"); + } else if(library != null) { + try { + System.load(library.getAbsolutePath()); + } catch (Throwable t) { + throw new FMUJNIException(t.getMessage()); + } + } + } + } + + /** + * Load fmu from a given file path. Releases the (possible) previously + * loaded fmu. + * + * @param path absolute file path for fmu file + * @throws FMUJNIException + */ + public void loadFMUFile(String path) throws FMUJNIException { + try { + + int ret = loadFMUFile_(path); + if(ret == ERROR) + throw new FMUJNIException(getLastErrorMessage()); + + } catch (UnsatisfiedLinkError err) { + throw new FMUJNIException(UNSATISFIED_LINK); + } + } + + private native int loadFMUFile_(String path); + + /** + * Set a step length for simulation + * + * @param step Step length for simulation + * @throws FMUJNIException + */ + public void setStepLength(double step) throws FMUJNIException { + try { + + int ret = setStepLength_(step); + if(ret == ERROR) + throw new FMUJNIException(getLastErrorMessage()); + + } catch (UnsatisfiedLinkError err) { + throw new FMUJNIException(UNSATISFIED_LINK); + } + } + + private native int setStepLength_(double step); + + /** + * Initializes a simulation. + *

+ * Make sure that an FMU is loaded first. + * @throws FMUJNIException + */ + public void initializeSimulation() throws FMUJNIException { + try { + + int ret = initializeSimulation_(); + if(ret == ERROR) + throw new FMUJNIException(getLastErrorMessage()); + + } catch (UnsatisfiedLinkError err) { + throw new FMUJNIException(UNSATISFIED_LINK); + } + } + + private native int initializeSimulation_(); + + /** + * Subscribe a set of variables from a loaded simulation. + *

+ * Make sure that an FMU is loaded first. + * @param variables Array of variables + * @throws FMUJNIException + */ + public void subscribe(String[] variables) throws FMUJNIException { + try { + + int ret = subscribe_(variables, variables.length); + if(ret == ERROR) + throw new FMUJNIException(getLastErrorMessage()); + + } catch (UnsatisfiedLinkError err) { + throw new FMUJNIException(UNSATISFIED_LINK); + } + } + + private native int subscribe_(String[] variables, int size); + + + /** + * Set a new (Real, double) value for a variable. If the variable is a + * parameter, the change is effective immediately. + * + * @param name Variable + * @param value New (Real, double) value + * @throws FMUJNIException + */ + public void setRealValue(String name, double value) throws FMUJNIException { + try { + + int ret = setRealValue_(name, value); + if(ret == ERROR) + throw new FMUJNIException(getLastErrorMessage()); + + } catch (UnsatisfiedLinkError err) { + throw new FMUJNIException(UNSATISFIED_LINK); + } + } + + private native int setRealValue_(String name, double value); + + /** + * 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 FMUJNIException + */ + public void setIntegerValue(String name, int value) throws FMUJNIException { + try { + + int ret = setIntegerValue_(name, value); + if(ret == ERROR) + throw new FMUJNIException(getLastErrorMessage()); + + } catch (UnsatisfiedLinkError err) { + throw new FMUJNIException(UNSATISFIED_LINK); + } + } + private native int setIntegerValue_(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 FMUJNIException + */ + public void setBooleanValue(String name, boolean value) throws FMUJNIException { + try { + + int ret = setBooleanValue_(name, value); + if(ret == ERROR) + throw new FMUJNIException(getLastErrorMessage()); + + } catch (UnsatisfiedLinkError err) { + throw new FMUJNIException(UNSATISFIED_LINK); + } + } + private native int setBooleanValue_(String name, boolean value); + + + /** + * Simulate one step forward. The step length can be set with + * setStepLength() + * + * @throws FMUJNIException + */ + public void simulateStep() throws FMUJNIException { + try { + + int ret = simulateStep_(); + if(ret == ERROR) + throw new FMUJNIException(getLastErrorMessage()); + + } catch (UnsatisfiedLinkError err) { + throw new FMUJNIException(UNSATISFIED_LINK); + } + } + private native int simulateStep_(); + + /** + * Get an array containing the current values for subscribed variables. The + * values are in the same order as in the subscription. + * + * @param results An array the size of subscribed results + * @return + */ + public double[] getSubscribedResults(double[] results) throws FMUJNIException { + try { + + return getSubscribedResults_(results); + + } catch (UnsatisfiedLinkError err) { + throw new FMUJNIException(UNSATISFIED_LINK); + } + } + + private native double[] getSubscribedResults_(double[] results); + + /** + * Unload FMU and the dll:s that it requires. + *

+ * To be called after all FMU simulations are ended. + * If the fmu is loaded again / changed, call to loadFMUFile is sufficient. loadFMUFile + * releases the previous fmu.dll + * + * @throws FMUJNIException + */ + public void unloadFMU() throws FMUJNIException { + try { + + int ret = unloadFMU_(); + if(ret == ERROR) + throw new FMUJNIException(getLastErrorMessage()); + + } catch (UnsatisfiedLinkError err) { + throw new FMUJNIException(UNSATISFIED_LINK); + } + } + private native int unloadFMU_(); + + /** + * Get the current simulation time + * @return current simulation time + */ + public double getTime() throws FMUJNIException { + try { + + return getTime_(); + + } catch (UnsatisfiedLinkError err) { + throw new FMUJNIException(UNSATISFIED_LINK); + } + } + + private native double getTime_(); + + /** + * Get all variables in a loaded model + * @return all variables in a loaded model + */ + public String[] getAllVariables() throws FMUJNIException { + try { + + return getAllVariables_(); + + } catch (UnsatisfiedLinkError err) { + throw new FMUJNIException(UNSATISFIED_LINK); + } + } + + private native String[] getAllVariables_(); + + /** + * Get the last error message + * @return Last error message + */ + public String getLastErrorMessage() throws FMUJNIException { + try { + + return getLastErrorMessage_(); + + } catch (UnsatisfiedLinkError err) { + throw new FMUJNIException(UNSATISFIED_LINK); + } + } + + private native String getLastErrorMessage_(); + +} 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 index 00000000..6308f73a --- /dev/null +++ b/org.simantics.modelica/src/org/simantics/modelica/fmi/FMUJNIException.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.modelica.fmi; + +/** + * Exception thrown when native fmu calls fail + * @author Teemu Lempinen + * + */ +public class FMUJNIException extends Exception { + private static final long serialVersionUID = -7164064752664568008L; + + public FMUJNIException(String message) { + super(message); + } +} 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 index 00000000..526042da --- /dev/null +++ b/org.simantics.modelica/src/org_simantics_modelica_fmi_FMUControlJNI.h @@ -0,0 +1,117 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class org_simantics_modelica_fmi_FMUControlJNI */ + +#ifndef _Included_org_simantics_modelica_fmi_FMUControlJNI +#define _Included_org_simantics_modelica_fmi_FMUControlJNI +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: org_simantics_modelica_fmi_FMUControlJNI + * Method: loadFMUFile_ + * Signature: (Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_org_simantics_modelica_fmi_FMUControlJNI_loadFMUFile_1 + (JNIEnv *, jobject, jstring); + +/* + * Class: org_simantics_modelica_fmi_FMUControlJNI + * Method: setStepLength_ + * Signature: (D)I + */ +JNIEXPORT jint JNICALL Java_org_simantics_modelica_fmi_FMUControlJNI_setStepLength_1 + (JNIEnv *, jobject, jdouble); + +/* + * Class: org_simantics_modelica_fmi_FMUControlJNI + * Method: initializeSimulation_ + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_org_simantics_modelica_fmi_FMUControlJNI_initializeSimulation_1 + (JNIEnv *, jobject); + +/* + * Class: org_simantics_modelica_fmi_FMUControlJNI + * Method: subscribe_ + * Signature: ([Ljava/lang/String;I)I + */ +JNIEXPORT jint JNICALL Java_org_simantics_modelica_fmi_FMUControlJNI_subscribe_1 + (JNIEnv *, jobject, jobjectArray, jint); + +/* + * Class: org_simantics_modelica_fmi_FMUControlJNI + * Method: setRealValue_ + * Signature: (Ljava/lang/String;D)I + */ +JNIEXPORT jint JNICALL Java_org_simantics_modelica_fmi_FMUControlJNI_setRealValue_1 + (JNIEnv *, jobject, jstring, jdouble); + +/* + * Class: org_simantics_modelica_fmi_FMUControlJNI + * Method: setIntegerValue_ + * Signature: (Ljava/lang/String;I)I + */ +JNIEXPORT jint JNICALL Java_org_simantics_modelica_fmi_FMUControlJNI_setIntegerValue_1 + (JNIEnv *, jobject, jstring, jint); + +/* + * Class: org_simantics_modelica_fmi_FMUControlJNI + * Method: setBooleanValue_ + * Signature: (Ljava/lang/String;Z)I + */ +JNIEXPORT jint JNICALL Java_org_simantics_modelica_fmi_FMUControlJNI_setBooleanValue_1 + (JNIEnv *, jobject, jstring, jboolean); + +/* + * Class: org_simantics_modelica_fmi_FMUControlJNI + * Method: simulateStep_ + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_org_simantics_modelica_fmi_FMUControlJNI_simulateStep_1 + (JNIEnv *, jobject); + +/* + * Class: org_simantics_modelica_fmi_FMUControlJNI + * Method: getSubscribedResults_ + * Signature: ([D)[D + */ +JNIEXPORT jdoubleArray JNICALL Java_org_simantics_modelica_fmi_FMUControlJNI_getSubscribedResults_1 + (JNIEnv *, jobject, jdoubleArray); + +/* + * Class: org_simantics_modelica_fmi_FMUControlJNI + * Method: unloadFMU_ + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_org_simantics_modelica_fmi_FMUControlJNI_unloadFMU_1 + (JNIEnv *, jobject); + +/* + * Class: org_simantics_modelica_fmi_FMUControlJNI + * Method: getTime_ + * Signature: ()D + */ +JNIEXPORT jdouble JNICALL Java_org_simantics_modelica_fmi_FMUControlJNI_getTime_1 + (JNIEnv *, jobject); + +/* + * Class: org_simantics_modelica_fmi_FMUControlJNI + * Method: getAllVariables_ + * Signature: ()[Ljava/lang/String; + */ +JNIEXPORT jobjectArray JNICALL Java_org_simantics_modelica_fmi_FMUControlJNI_getAllVariables_1 + (JNIEnv *, jobject); + +/* + * Class: org_simantics_modelica_fmi_FMUControlJNI + * Method: getLastErrorMessage_ + * Signature: ()Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_simantics_modelica_fmi_FMUControlJNI_getLastErrorMessage_1 + (JNIEnv *, jobject); + +#ifdef __cplusplus +} +#endif +#endif -- 2.47.1