From: lempinen Date: Fri, 18 Jan 2013 08:22:44 +0000 (+0000) Subject: Separated fmu instantiation from initialization. Initial values can be changed after... X-Git-Tag: simantics-1.10.1~67 X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=617d3cfecbcb21e71d44d154cb65854d7e6bd41b;p=simantics%2Fsysdyn.git Separated fmu instantiation from initialization. Initial values can be changed after instantiation and before initialization with normal setRealValue, setBooleanValue, etc. If initialization has not been run after instantiation, and user tries to simulate steps, initialiation is run. (fixes #3909) git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@26644 ac1ea38d-2e2b-0410-8846-a27921b304fc --- diff --git a/org.simantics.fmu.me.win32/libraries/FMUSimulator.dll b/org.simantics.fmu.me.win32/libraries/FMUSimulator.dll index 52c78ab7..52dcd12b 100644 Binary files a/org.simantics.fmu.me.win32/libraries/FMUSimulator.dll and b/org.simantics.fmu.me.win32/libraries/FMUSimulator.dll differ diff --git a/org.simantics.fmu.me.win32/libraries/miniunz.dll b/org.simantics.fmu.me.win32/libraries/miniunz.dll index f3e7ccfa..56a5b2f5 100644 Binary files a/org.simantics.fmu.me.win32/libraries/miniunz.dll and b/org.simantics.fmu.me.win32/libraries/miniunz.dll differ diff --git a/org.simantics.fmu.me.win32/libraries/zlibwapi.dll b/org.simantics.fmu.me.win32/libraries/zlibwapi.dll index 6efda05e..767b655a 100644 Binary files a/org.simantics.fmu.me.win32/libraries/zlibwapi.dll and b/org.simantics.fmu.me.win32/libraries/zlibwapi.dll differ diff --git a/org.simantics.fmu/FMUSolution/FMUSimulator/include/org_simantics_fmu_FMUControlJNI.h b/org.simantics.fmu/FMUSolution/FMUSimulator/include/org_simantics_fmu_FMUControlJNI.h index 9f2697b4..20599879 100644 --- a/org.simantics.fmu/FMUSolution/FMUSimulator/include/org_simantics_fmu_FMUControlJNI.h +++ b/org.simantics.fmu/FMUSolution/FMUSimulator/include/org_simantics_fmu_FMUControlJNI.h @@ -23,6 +23,14 @@ JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_loadFMUFile_1 JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_setStepLength_1 (JNIEnv *, jobject, jstring, jdouble); +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: instantiateSimulation_ + * Signature: (Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_instantiateSimulation_1 + (JNIEnv *, jobject, jstring); + /* * Class: org_simantics_fmu_FMUControlJNI * Method: initializeSimulation_ @@ -95,6 +103,14 @@ JNIEXPORT jdoubleArray JNICALL Java_org_simantics_fmu_FMUControlJNI_getSubscribe JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_unloadFMU_1 (JNIEnv *, jobject, jstring); +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: isInitialized_ + * Signature: (Ljava/lang/String;)Z + */ +JNIEXPORT jboolean JNICALL Java_org_simantics_fmu_FMUControlJNI_isInitialized_1 + (JNIEnv *, jobject, jstring); + /* * Class: org_simantics_fmu_FMUControlJNI * Method: getTime_ diff --git a/org.simantics.fmu/FMUSolution/FMUSimulator/src/fmu_control.cpp b/org.simantics.fmu/FMUSolution/FMUSimulator/src/fmu_control.cpp index f1384510..43a1be98 100644 --- a/org.simantics.fmu/FMUSolution/FMUSimulator/src/fmu_control.cpp +++ b/org.simantics.fmu/FMUSolution/FMUSimulator/src/fmu_control.cpp @@ -56,6 +56,8 @@ struct FMUControlStruct { int nz; // number of state event indicators double *z; // state event indicators double *prez; // previous values of state event indicators + + bool initialized; // has the fmu been initialized vector subscription; // result subscriptions vector allVariables; // all variables in an initialized model @@ -385,6 +387,22 @@ JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_setBooleanValue_1 } } +JNIEXPORT jboolean JNICALL Java_org_simantics_fmu_FMUControlJNI_isInitialized_1 + (JNIEnv *env, jobject obj, jstring id) { + const char *fmuId = env->GetStringUTFChars(id, 0); + if(exists(fmuId)) { + FMUControlStruct& fmuStruct = fmus[fmuId]; + env->ReleaseStringUTFChars(id, fmuId); + return fmuStruct.initialized; + } else { + string message = fmuId; + env->ReleaseStringUTFChars(id, fmuId); + throwException(env, "getTime: Model id " + message + " not found"); + return false; + } +} + + JNIEXPORT jdouble JNICALL Java_org_simantics_fmu_FMUControlJNI_getTime_1 (JNIEnv *env, jobject obj, jstring id) { const char *fmuId = env->GetStringUTFChars(id, 0); @@ -462,7 +480,7 @@ JNIEXPORT jdoubleArray JNICALL Java_org_simantics_fmu_FMUControlJNI_getSubscribe return result; } -JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_initializeSimulation_1 +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_instantiateSimulation_1 (JNIEnv *env, jobject obj, jstring id) { const char *fmuId = env->GetStringUTFChars(id, 0); @@ -480,8 +498,6 @@ JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_initializeSimulation if(fmu.modelDescription == NULL) return throwException(env, "No FMU loaded"); - fmiBoolean toleranceControlled = fmiFalse; - fmuStruct.currentTime = 0; // start time // instantiate the fmu @@ -507,11 +523,9 @@ JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_initializeSimulation //if (!x || !xdot) return error("out of memory"); if (!fmuStruct.x || !fmuStruct.xdot || fmuStruct.nz>0 && (!fmuStruct.z || !fmuStruct.prez)) return throwException(env, "out of memory"); - // set the start time and initialize + // set the start time fmuStruct.fmiFlag = fmu.setTime(fmuStruct.c, fmuStruct.currentTime); if (fmuStruct.fmiFlag > fmiWarning) return throwException(env, "could not set time"); - fmuStruct.fmiFlag = fmu.initialize(fmuStruct.c, toleranceControlled, fmuStruct.currentTime, &(fmuStruct.eventInfo)); - if (fmuStruct.fmiFlag > fmiWarning) return throwException(env, "could not initialize model"); // Clear all variables -vector fmuStruct.allVariables.clear(); @@ -524,6 +538,42 @@ JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_initializeSimulation fmuStruct.indexes.insert ( pair(s,k) ); } + // Set initialized flag to 0 + fmuStruct.initialized = false; + + fflush(stdout); + return 1; + + } else { + string message = fmuId; + env->ReleaseStringUTFChars(id, fmuId); + return throwException(env, "instantiateSimulation: Model id " + message + " not found"); + } +} + +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_initializeSimulation_1 + (JNIEnv *env, jobject obj, jstring id) { + + const char *fmuId = env->GetStringUTFChars(id, 0); + if(exists(fmuId)) { + FMUControlStruct& fmuStruct = fmus[fmuId]; + env->ReleaseStringUTFChars(id, fmuId); + + FMU& fmu = fmuStruct.fmu; + + if(fmu.modelDescription == NULL) + return throwException(env, "No FMU loaded"); + + if(fmuStruct.initialized == true) + return throwException(env, "FMU already initialized. Instantiate it first."); + + fmiBoolean toleranceControlled = fmiFalse; + + fmuStruct.fmiFlag = fmu.initialize(fmuStruct.c, toleranceControlled, fmuStruct.currentTime, &(fmuStruct.eventInfo)); + if (fmuStruct.fmiFlag > fmiWarning) return throwException(env, "could not initialize model"); + + fmuStruct.initialized = true; + fflush(stdout); return 1; @@ -617,7 +667,14 @@ JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_simulateStep_1 } if(fmuStruct.x == NULL) { - return throwException(env, "Simulate step failed - fmu not initialized"); + return throwException(env, "Simulate step failed - fmu not instantiated"); + } + + if(fmuStruct.initialized == false) { + fmiBoolean toleranceControlled = fmiFalse; + fmuStruct.fmiFlag = fmuStruct.fmu.initialize(fmuStruct.c, toleranceControlled, fmuStruct.currentTime, &(fmuStruct.eventInfo)); + if (fmuStruct.fmiFlag > fmiWarning) return throwException(env, "could not initialize model"); + fmuStruct.initialized = true; } FMU& fmu = fmuStruct.fmu; diff --git a/org.simantics.fmu/src/org/simantics/fmu/FMUControlJNI.java b/org.simantics.fmu/src/org/simantics/fmu/FMUControlJNI.java index f49c2627..716a864b 100644 --- a/org.simantics.fmu/src/org/simantics/fmu/FMUControlJNI.java +++ b/org.simantics.fmu/src/org/simantics/fmu/FMUControlJNI.java @@ -200,11 +200,37 @@ public class FMUControlJNI { private native int setStepLength_(String id, double step); /** - * Initializes a simulation. + * Instantiates a simulation. *

* Make sure that an FMU is loaded first. * @throws FMUJNIException */ + public void instantiateSimulation() throws FMUJNIException { + synchronized(syncObject) { + + try { + + int ret = instantiateSimulation_(getModelID()); + if(ret == ERROR) + throw new FMUJNIException(getLastErrorMessage()); + + } catch (UnsatisfiedLinkError err) { + throw new FMUJNIException(UNSATISFIED_LINK); + } catch (Exception e) { + throw new FMUJNIException(e.getMessage()); + } + } + } + + private native int instantiateSimulation_(String id); + + + /** + * Initializes a simulation. + *

+ * Make sure that simulation is instantiated first! + * @throws FMUJNIException + */ public void initializeSimulation() throws FMUJNIException { synchronized(syncObject) { @@ -426,6 +452,24 @@ public class FMUControlJNI { } } private native int unloadFMU_(String id); + + /** + * Checks if fmu has been initialized + * @return current simulation time + */ + public boolean isInitialized() throws FMUJNIException { + synchronized(syncObject) { + try { + return isInitialized_(getModelID()); + } catch (UnsatisfiedLinkError err) { + throw new FMUJNIException(UNSATISFIED_LINK); + } catch (Exception e) { + throw new FMUJNIException(e.getMessage()); + } + } + } + + private native boolean isInitialized_(String id); /** * Get the current simulation time diff --git a/org.simantics.fmu/src/org_simantics_fmu_FMUControlJNI.h b/org.simantics.fmu/src/org_simantics_fmu_FMUControlJNI.h index 9f2697b4..20599879 100644 --- a/org.simantics.fmu/src/org_simantics_fmu_FMUControlJNI.h +++ b/org.simantics.fmu/src/org_simantics_fmu_FMUControlJNI.h @@ -23,6 +23,14 @@ JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_loadFMUFile_1 JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_setStepLength_1 (JNIEnv *, jobject, jstring, jdouble); +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: instantiateSimulation_ + * Signature: (Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_instantiateSimulation_1 + (JNIEnv *, jobject, jstring); + /* * Class: org_simantics_fmu_FMUControlJNI * Method: initializeSimulation_ @@ -95,6 +103,14 @@ JNIEXPORT jdoubleArray JNICALL Java_org_simantics_fmu_FMUControlJNI_getSubscribe JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_unloadFMU_1 (JNIEnv *, jobject, jstring); +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: isInitialized_ + * Signature: (Ljava/lang/String;)Z + */ +JNIEXPORT jboolean JNICALL Java_org_simantics_fmu_FMUControlJNI_isInitialized_1 + (JNIEnv *, jobject, jstring); + /* * Class: org_simantics_fmu_FMUControlJNI * Method: getTime_ diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SaveResultJob.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SaveResultJob.java index 6269318e..859bbc7a 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SaveResultJob.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SaveResultJob.java @@ -19,7 +19,6 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; -import org.simantics.Simantics; import org.simantics.db.Resource; import org.simantics.db.Session; import org.simantics.db.WriteGraph; @@ -55,7 +54,7 @@ public class SaveResultJob extends Job { int resultItemsNumber = sysdynResult.numberOfVariables(); monitor.beginTask("Save result", resultItemsNumber * 2); try { - File file = Simantics.getSession().syncRequest(new WriteResultRequest() { + File file = session.syncRequest(new WriteResultRequest() { @Override public File perform(WriteGraph graph) throws DatabaseException { diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynGameExperiment.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynGameExperiment.java index ed136642..77332a9e 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynGameExperiment.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynGameExperiment.java @@ -22,6 +22,7 @@ import org.eclipse.core.runtime.jobs.Job; import org.simantics.db.AsyncReadGraph; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; +import org.simantics.db.Session; import org.simantics.db.exception.DatabaseException; import org.simantics.db.procedure.AsyncListener; import org.simantics.db.request.Read; @@ -187,25 +188,7 @@ public class SysdynGameExperiment extends SysdynExperiment { try { control.loadFMUFile(simulationLocation.executableFile.getAbsolutePath()); // unzip and load fmu control.setStepLength(stepLength); // FIXME: fixed step lenghth - control.initializeSimulation(); // initialize simulation - if(inits.get("variableFilter") == null || inits.get("variableFilter").equals(".*")) - subscription = control.getAllVariables(); - else - subscription = control.filterVariables(inits.get("variableFilter")); - control.subscribe(subscription); // subscribe all variables - - // Initialize results - results.clear(); - - double[] initialValues = new double[subscription.length]; - initialValues = control.getSubscribedResults(initialValues); - for(int k = 0; k < subscription.length; k++) { - results.put(subscription[k], new ArrayList()); - results.get(subscription[k]).add(initialValues[k]); - } - - getCurrentResult().setResult(new GameResult(this.results, this.subscription)); - resultsChanged(); + instantiate(); } catch (FMUJNIException e) { System.err.println("SysdynGameExperiment initialization failed:\n\t" + e.getMessage()); @@ -260,6 +243,13 @@ public class SysdynGameExperiment extends SysdynExperiment { try { + + // initialize if not initialized + if(!control.isInitialized()) { + control.initializeSimulation(); + getInitialResultValues(); + } + control.setStepLength(stepLength); // Set step length each time in case there has been changes double time = control.getTime(); @@ -343,38 +333,58 @@ public class SysdynGameExperiment extends SysdynExperiment { return; if(time >-0.001 && time < 0.001) { - initialize(); + instantiate(); } else { System.out.println("rewindTo"); } } - private synchronized void initialize() { + @Override + public void refresh(Session session) { + try { + control.initializeSimulation(); + getInitialResultValues(); + + } catch (FMUJNIException e) { + System.err.println("SysdynGameExperiment instantiate failed: " + e.getMessage()); + } + } + + private synchronized void instantiate() { try { HashMap inits = getExperimentParameters(null); control.setStepLength(stepLength); // FIXME: fixed step lenghth - control.initializeSimulation(); // initialize simulation + control.instantiateSimulation(); // instantiate simulation if(inits.get("variableFilter") == null || inits.get("variableFilter").equals(".*")) subscription = control.getAllVariables(); else subscription = control.filterVariables(inits.get("variableFilter")); control.subscribe(subscription); // subscribe all variables + getInitialResultValues(); + + } catch (FMUJNIException e) { + System.err.println("SysdynGameExperiment instantiate failed: " + e.getMessage()); + } + } + + private synchronized void getInitialResultValues() { + try { // Initialize results results.clear(); - + double[] initialValues = new double[subscription.length]; initialValues = control.getSubscribedResults(initialValues); for(int k = 0; k < subscription.length; k++) { results.put(subscription[k], new ArrayList()); results.get(subscription[k]).add(initialValues[k]); } - + getCurrentResult().setResult(new GameResult(this.results, this.subscription)); - resultsChanged(); + resultsChanged(); } catch (FMUJNIException e) { - System.err.println("SysdynGameExperiment rewind failed: " + e.getMessage()); + System.err.println("SysdynGameExperiment getInitialResultValues failed: " + e.getMessage()); } } }