X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.fmil.core%2Fnative%2FFMUSimulator%2Fsrc%2Ffmu_control.cpp;h=310e9066fa7bdb0137ed280ff2c2b5f47a56a6e3;hb=9dcc8cac323b2fc064007203ef76e57e152699db;hp=c5c99412d644fc8752d99d039043115d982a8e1a;hpb=e3ede17bbc55c6598bc5262015ff5ea8df3570e0;p=simantics%2Ffmil.git diff --git a/org.simantics.fmil.core/native/FMUSimulator/src/fmu_control.cpp b/org.simantics.fmil.core/native/FMUSimulator/src/fmu_control.cpp index c5c9941..310e906 100644 --- a/org.simantics.fmil.core/native/FMUSimulator/src/fmu_control.cpp +++ b/org.simantics.fmil.core/native/FMUSimulator/src/fmu_control.cpp @@ -1,869 +1,984 @@ -/* ------------------------------------------------------------------------- - * fmu_control.c - * Simulation controls for fmus - * - * Free libraries and tools used to implement this simulator: - * - header files from the FMU specification - * - eXpat 2.0.1 XML parser, see http://expat.sourceforge.net - * - 7z.exe 4.57 zip and unzip tool, see http://www.7-zip.org <---------- Replace with zlib - * Author: Teemu Lempinen - * Copyright 2012 Semantum Oy - * ------------------------------------------------------------------------- - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -extern "C" { - #include "fmi_me.h" - #include "sim_support.h" -} - -#include "fmi1_cs.h" - -#define PRINT(fmt,args) { FILE *fp = fopen("R:\\Simantics\\Sysdyn\\log.txt", "ab"); fprintf(fp, fmt, args); fclose(fp); } - -#include -#define GetCurrentDir _getcwd - -using namespace std; - -struct FMI1 { - - void *fmu; - - vector variables; - vector descriptions; - vector declaredTypes; - vector valueReferences; - vector types; - vector variabilities; - vector causalities; - - vector declaredTypeNames; - vector typeDescriptions; - vector quantities; - vector units; - - vector subscription; - double currentTime; - double timeStep; - -}; - -struct FMUControlStruct { - double step; // simulation step length - fmiReal currentTime; // current simulation time - - fmiComponent c; // instance of the fmu - ScalarVariable** vars; // model variables - - fmiEventInfo eventInfo; // updated by calls to initialize and eventUpdate - const char* guid; // global unique id of the fmu - fmiCallbackFunctions callbacks; // called by the model during simulation - fmiStatus fmiFlag; // return code of the fmu functions - - map indexes; // indexes for variable names in vars-table - map::iterator it; - - int nx; // number of state variables - double *x; // continuous states - double *xdot; // the crresponding derivatives in same order - 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 - vector fmiValueReferences; // all value references - - string lastErrorMessage; - - FMU fmu; -}; - -vector fmus; - -//map fmus; // indexes for variable names in vars-table - -int throwException(JNIEnv *env, string message) { - jclass newExcCls; - newExcCls = env->FindClass("java/lang/Exception"); - if (newExcCls == NULL) { - /* Unable to find the exception class, give up. */ - return 0; - } - env->ThrowNew(newExcCls, message.c_str()); - return 0; -} - -/* -bool exists(string id) { - map::iterator it = fmus.find(id); - if(it != fmus.end()) { - return true; - } else { - return false; - } -} -*/ - - - -JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_loadFMUFile_1 - (JNIEnv *env, jobject obj, jstring path, jstring tempDir) { - - HMODULE module = NULL; - FMI1 fmi1; - FMIL_Variable *vars; - FMIL_DeclaredType *types; - int variableCount = 0; - int typeCount = 0; - - const char *fmuPath = env->GetStringUTFChars(path, 0); - const char *fmuTempDir = env->GetStringUTFChars(tempDir, 0); - - fmi1.currentTime = 0; - fmi1.timeStep = 0.1; - fmi1.fmu = FMI1_CS_LOAD(fmuPath, fmuTempDir); - if(!fmi1.fmu) - return throwException(env, "No FMU loaded"); - - vars = FMI1_CS_GET_VARIABLES(fmi1.fmu, &variableCount); - for(int i=0;iReleaseStringUTFChars(path, fmuPath); - env->ReleaseStringUTFChars(tempDir, fmuTempDir); - - return fmus.size() - 1; - -} - -JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_setStepLength_1 - (JNIEnv *env, jobject obj, jint id, jdouble stepLength) { - fmus[id].timeStep = stepLength; - return 1; -} - -JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_subscribe_1 - (JNIEnv *env, jobject obj, jint id, jintArray vrs) { - - jboolean isCopy; - jint* elements = env -> GetIntArrayElements(vrs, &isCopy); - jsize n = env -> GetArrayLength(vrs); - - int i; - for (i = 0; i < n; i++) { - fmus[id].subscription.push_back(elements[i]); - } - - if (isCopy == JNI_TRUE) { - env -> ReleaseIntArrayElements(vrs, elements, 0); - } - - return 1; - -} - -bool referenceExists(FMUControlStruct fmuStruct, string variable) { - map::iterator it = fmuStruct.indexes.find(variable); - if(it != fmuStruct.indexes.end()) { - return true; - } else { - return false; - } -} - -// Remember to check if reference exists -fmiValueReference getReference(FMUControlStruct fmuStruct, string variable) { - return fmuStruct.fmiValueReferences[fmuStruct.indexes[variable]]; -} - -// Get string representation of a scalar variable type -string getTypeString(ScalarVariable* sv) { - switch (sv->typeSpec->type){ - case elm_Integer: - return "Integer"; - case elm_Enumeration: - return "Enumeration"; - case elm_Real: - return "Real"; - case elm_Boolean: - return "Boolean"; - default: - return "No type"; - } -} - -JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_setRealValue_1 - (JNIEnv *env, jobject obj, jint id, jint vr, jdouble value) { - - FMI1_CS_SET_REAL(fmus[id].fmu, vr, value); - return 1; - -} - -JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_setIntegerValue_1 - (JNIEnv *env, jobject obj, jstring id, jstring parameter, jint value) { - /* - const char *fmuId = env->GetStringUTFChars(id, 0); - if(exists(fmuId)) { - FMUControlStruct& fmuStruct = fmus[fmuId]; - const char *name = env->GetStringUTFChars(parameter, 0); - string nameString = name; - string modelId = fmuId; - if(!referenceExists(fmuStruct, name)) { - string errorMessage = "setIntegerValue: Model (id " + modelId + ") does not contain variable: " + nameString; - env->ReleaseStringUTFChars(parameter, name); - env->ReleaseStringUTFChars(id, fmuId); - return throwException(env, errorMessage); - } else { - // Check variable type - ScalarVariable* sv = fmuStruct.vars[fmuStruct.indexes[name]]; - switch (sv->typeSpec->type){ - case elm_Integer: - break; // ok - default: { - string errorMessage = "setIntegerValue: " + nameString + " is not of type Integer. (type: + " + getTypeString(sv) + ")"; - env->ReleaseStringUTFChars(parameter, name); - env->ReleaseStringUTFChars(id, fmuId); - return throwException(env, errorMessage); - } - } - - // Change value - fmiValueReference vr = getReference(fmuStruct, name); - const int intValue = (int) value; - fmuStruct.fmu.setInteger(fmuStruct.c, &vr, 1, &intValue); - env->ReleaseStringUTFChars(parameter, name); - env->ReleaseStringUTFChars(id, fmuId); - return 1; - } - } else { - string message = fmuId; - env->ReleaseStringUTFChars(id, fmuId); - return throwException(env, "setIntegerValue: Model id " + message + " not found"); - } - */ - return 1; -} - -JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_setBooleanValue_1 - (JNIEnv *env, jobject obj, jstring id, jstring parameter, jboolean value) { - /* - const char *fmuId = env->GetStringUTFChars(id, 0); - if(exists(fmuId)) { - FMUControlStruct& fmuStruct = fmus[fmuId]; - const char *name = env->GetStringUTFChars(parameter, 0); - string nameString = name; - string modelId = fmuId; - if(!referenceExists(fmuStruct, name)) { - string errorMessage = "setBooleanValue: Model (id " + modelId + ") does not contain variable: " + nameString; - env->ReleaseStringUTFChars(parameter, name); - env->ReleaseStringUTFChars(id, fmuId); - return throwException(env, errorMessage); - } else { - // Check variable type - ScalarVariable* sv = fmuStruct.vars[fmuStruct.indexes[name]]; - switch (sv->typeSpec->type){ - case elm_Boolean: - break; // ok - default: { - string errorMessage = "setBooleanValue: " + nameString + " is not of type Boolean. (type: + " + getTypeString(sv) + ")"; - env->ReleaseStringUTFChars(parameter, name); - env->ReleaseStringUTFChars(id, fmuId); - return throwException(env, errorMessage); - } - } - - // Change value - fmiValueReference vr = getReference(fmuStruct, name); - fmiBoolean result = 1; - if(value == 0) - result = 0; - fmuStruct.fmu.setBoolean(fmuStruct.c, &vr, 1, &result); - env->ReleaseStringUTFChars(parameter, name); - env->ReleaseStringUTFChars(id, fmuId); - return 1; - } - } else { - string message = fmuId; - env->ReleaseStringUTFChars(id, fmuId); - return throwException(env, "setBooleanValue: Model id " + message + " not found"); - }*/ - return 1; -} - -JNIEXPORT jboolean JNICALL Java_org_simantics_fmil_FMIL_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 { - env->ReleaseStringUTFChars(id, fmuId); - return false; - } - */ - return 1; -} - - -JNIEXPORT jdouble JNICALL Java_org_simantics_fmil_FMIL_getTime_1 - (JNIEnv *env, jobject obj, jint id) { - return fmus[id].currentTime; -} - -double getRealValue(FMUControlStruct fmuStruct, int index) { - ScalarVariable *sv = fmuStruct.vars[index]; - fmiValueReference vr = fmuStruct.fmiValueReferences[index]; - double real; - fmiInteger integer; - fmiBoolean fmibool; - - switch (sv->typeSpec->type){ - case elm_Real: - fmuStruct.fmu.getReal(fmuStruct.c, &vr, 1, &real); - break; - case elm_Integer: - case elm_Enumeration: - fmuStruct.fmu.getInteger(fmuStruct.c, &vr, 1, &integer); - real = (double)integer; - break; - case elm_Boolean: - fmuStruct.fmu.getBoolean(fmuStruct.c, &vr, 1, &fmibool); - if(fmibool == fmiTrue) - real = 1.0; - else - real = 0.0; - break; - } - return real; -} - -JNIEXPORT jdoubleArray JNICALL Java_org_simantics_fmil_FMIL_getSubscribedResults_1 - (JNIEnv *env, jobject obj, jint id, jdoubleArray result) { - - jboolean isCopy; - jdouble* resultElements = env -> GetDoubleArrayElements(result, &isCopy); - jsize n = env -> GetArrayLength(result); - int *vrs; - if(n > 0) { - vrs = &(fmus[id].subscription[0]); - FMI1_CS_GET_REALS(fmus[id].fmu, vrs, resultElements, n); - } - if (isCopy == JNI_TRUE) { - env -> ReleaseDoubleArrayElements(result, resultElements, 0); - } - - return result; - -} - -JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_instantiateSimulation_1 - (JNIEnv *env, jobject obj, jint id) { - - int asd = FMI1_CS_INSTANTIATE(fmus[id].fmu); - if(asd != 0) - return throwException(env, "No FMU loaded"); - - return 1; - -} - -JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_initializeSimulation_1 - (JNIEnv *env, jobject obj, jint id) { - - int asd = FMI1_CS_INITIALIZE(fmus[id].fmu); - if(asd != 0) - return throwException(env, "No FMU loaded"); - - return 1; - -} - -JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_setTime_1 - (JNIEnv *env, jobject obj, jstring id, jdouble time) { - return 1; -} - -JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariables_1 - (JNIEnv *env, jobject obj, jint id) { - - jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].variables.size(), - env->FindClass("java/lang/String"), - env->NewStringUTF("")); - - for(int i=0;iSetObjectArrayElement(ret,i,env->NewStringUTF(fmus[id].variables[i].c_str())); - } - - return ret; - -} - -JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariableDescriptions_1 - (JNIEnv *env, jobject obj, jint id) { - - jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].descriptions.size(), - env->FindClass("java/lang/String"), - env->NewStringUTF("")); - - for(int i=0;iSetObjectArrayElement(ret,i,env->NewStringUTF(fmus[id].descriptions[i].c_str())); - } - - return ret; - -} - -JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariableDeclaredTypes_1 - (JNIEnv *env, jobject obj, jint id) { - - jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].declaredTypes.size(), - env->FindClass("java/lang/String"), - env->NewStringUTF("")); - - for(int i=0;iSetObjectArrayElement(ret,i,env->NewStringUTF(fmus[id].declaredTypes[i].c_str())); - } - - return ret; - -} - -JNIEXPORT jintArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariableReferences_1 - (JNIEnv *env, jobject obj, jint id, jintArray result) { - - jboolean isCopy; - jint* resultElements = env -> GetIntArrayElements(result, &isCopy); - jsize n = env -> GetArrayLength(result); - - int i; - for (i = 0; i < n; i++) { - resultElements[i] = fmus[id].valueReferences[i]; - } - - if (isCopy == JNI_TRUE) { - env -> ReleaseIntArrayElements(result, resultElements, 0); - } - - return result; - -} - -JNIEXPORT jintArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariableTypes_1 - (JNIEnv *env, jobject obj, jint id, jintArray result) { - - jboolean isCopy; - jint* resultElements = env -> GetIntArrayElements(result, &isCopy); - jsize n = env -> GetArrayLength(result); - - int i; - for (i = 0; i < n; i++) { - resultElements[i] = fmus[id].types[i]; - } - - if (isCopy == JNI_TRUE) { - env -> ReleaseIntArrayElements(result, resultElements, 0); - } - - return result; - -} - -JNIEXPORT jintArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariableVariabilities_1 - (JNIEnv *env, jobject obj, jint id, jintArray result) { - - jboolean isCopy; - jint* resultElements = env -> GetIntArrayElements(result, &isCopy); - jsize n = env -> GetArrayLength(result); - - int i; - for (i = 0; i < n; i++) { - resultElements[i] = fmus[id].variabilities[i]; - } - - if (isCopy == JNI_TRUE) { - env -> ReleaseIntArrayElements(result, resultElements, 0); - } - - return result; - -} - -JNIEXPORT jintArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariableCausalities_1 - (JNIEnv *env, jobject obj, jint id, jintArray result) { - - jboolean isCopy; - jint* resultElements = env -> GetIntArrayElements(result, &isCopy); - jsize n = env -> GetArrayLength(result); - - int i; - for (i = 0; i < n; i++) { - resultElements[i] = fmus[id].causalities[i]; - } - - if (isCopy == JNI_TRUE) { - env -> ReleaseIntArrayElements(result, resultElements, 0); - } - - return result; - -} - -JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_getAllDeclaredTypes_1 - (JNIEnv *env, jobject obj, jint id) { - - jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].declaredTypeNames.size(), - env->FindClass("java/lang/String"), - env->NewStringUTF("")); - - for(int i=0;iSetObjectArrayElement(ret,i,env->NewStringUTF(fmus[id].declaredTypeNames[i].c_str())); - } - - return ret; - -} - -JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_getAllDeclaredTypeDescriptions_1 - (JNIEnv *env, jobject obj, jint id) { - - jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].typeDescriptions.size(), - env->FindClass("java/lang/String"), - env->NewStringUTF("")); - - for(int i=0;iSetObjectArrayElement(ret,i,env->NewStringUTF(fmus[id].typeDescriptions[i].c_str())); - } - - return ret; - -} - -JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_getAllDeclaredTypeQuantities_1 - (JNIEnv *env, jobject obj, jint id) { - - jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].quantities.size(), - env->FindClass("java/lang/String"), - env->NewStringUTF("")); - - for(int i=0;iSetObjectArrayElement(ret,i,env->NewStringUTF(fmus[id].quantities[i].c_str())); - } - - return ret; - -} - -JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_getAllDeclaredTypeUnits_1 - (JNIEnv *env, jobject obj, jint id) { - - jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].units.size(), - env->FindClass("java/lang/String"), - env->NewStringUTF("")); - - for(int i=0;iSetObjectArrayElement(ret,i,env->NewStringUTF(fmus[id].units[i].c_str())); - } - - return ret; - -} - -/* -JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_filterVariables_1 - (JNIEnv *env, jobject obj, jstring id, jstring regexp) { - const char *rx = env->GetStringUTFChars(regexp, 0); - jobjectArray result = filterVariables(env, obj, id, rx); - env->ReleaseStringUTFChars(regexp, rx); - return result; -} -*/ - -JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_simulateStep_1 - (JNIEnv *env, jobject obj, jint id) { - - int asd = FMI1_CS_STEP(fmus[id].fmu, fmus[id].currentTime, fmus[id].timeStep); - if(asd != 0) - return throwException(env, "No FMU loaded"); - - fmus[id].currentTime += fmus[id].timeStep; - - return 1; - - /* - const char *fmuId = env->GetStringUTFChars(id, 0); - if(exists(fmuId)) { - FMUControlStruct& fmuStruct = fmus[fmuId]; - env->ReleaseStringUTFChars(id, fmuId); - - if(&fmuStruct.fmu == NULL || fmuStruct.fmu.modelDescription == NULL || &fmuStruct.vars == NULL) { - return throwException(env, "Simulate step failed - fmu not loaded"); - } - - if(fmuStruct.x == NULL) { - 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; - int debug = 0; // DEBUG ON = 1, OFF = 0 - - int i; - double dt, tPre, tEnd = fmuStruct.currentTime + fmuStruct.step; - - fmiBoolean timeEvent, stateEvent, stepEvent; - fmiStatus fmiFlag; // return code of the fmu functions - fmiValueReference vr; - - - */ - /* Simulate the duration of one step. The simulation may be done in - * multiple parts if events occur - */ /* - while (fmuStruct.currentTime < tEnd) { - // get current state and derivatives - fmiFlag = fmu.getContinuousStates(fmuStruct.c, fmuStruct.x, fmuStruct.nx); - if (fmiFlag > fmiWarning) - return throwException(env, "could not retrieve states"); - - fmiFlag = fmu.getDerivatives(fmuStruct.c, fmuStruct.xdot, fmuStruct.nx); - if (fmiFlag > fmiWarning) - return throwException(env, "could not retrieve derivatives"); - - // advance time - tPre = fmuStruct.currentTime; - fmuStruct.currentTime = min(fmuStruct.currentTime+fmuStruct.step, tEnd); - timeEvent = fmuStruct.eventInfo.upcomingTimeEvent && fmuStruct.eventInfo.nextEventTime < fmuStruct.currentTime; - - if (timeEvent) fmuStruct.currentTime = fmuStruct.eventInfo.nextEventTime; - dt = fmuStruct.currentTime - tPre; - fmiFlag = fmu.setTime(fmuStruct.c, fmuStruct.currentTime); - if (fmiFlag > fmiWarning) throwException(env, "could not set time"); - - if(referenceExists(fmuStruct, "time")) { - vr = getReference(fmuStruct, "time"); - if(vr != NULL) { - fmu.setReal(fmuStruct.c, &vr, 1, &(fmuStruct.currentTime)); - } - } - - if(debug) - printf("Actual time: %lf\n", fmuStruct.currentTime); - - if (fmiFlag > fmiWarning) - return throwException(env, "could not set time"); - - // perform one step - for (i=0; i fmiWarning) - return throwException(env, "could not set states"); - - // Check for step event, e.g. dynamic state selection - fmiFlag = fmu.completedIntegratorStep(fmuStruct.c, &stepEvent); - if (fmiFlag > fmiWarning) return throwException(env, "could not complete intgrator step"); - */ -/* for (i=0; i fmiWarning) return throwException(env, "could not retrieve event indicators"); - stateEvent = FALSE; - for (i=0; i fmiWarning) return throwException(env, "could not perform event update"); - - } // if event - */ - -/* } - - fflush(stdout); - return 1; - - } else { - string message = fmuId; - env->ReleaseStringUTFChars(id, fmuId); - return throwException(env, "simulateStep: Model id " + message + " not found"); - }*/ - return 1; -} - -JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_unloadFMU_1 - (JNIEnv *env, jobject obj, jint id) { - - int asd = FMI1_CS_UNLOAD(fmus[id].fmu); - return asd; - -} - -JNIEXPORT jstring JNICALL Java_org_simantics_fmil_FMIL_getLastErrorMessage_1 - (JNIEnv *env, jobject obj, jstring id) { - return env->NewStringUTF("No errors"); -} - -JNIEXPORT jdouble JNICALL Java_org_simantics_fmil_FMIL_getRealValue_1 - (JNIEnv *env, jobject obj, jint id, jint vr) { - return FMI1_CS_GET_REAL(fmus[id].fmu, vr); -} - -JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_getIntegerValue_1 - (JNIEnv *env, jobject obj, jstring id, jstring variable) { - /* - const char *fmuId = env->GetStringUTFChars(id, 0); - if(exists(fmuId)) { - FMUControlStruct fmuStruct = fmus[fmuId]; - env->ReleaseStringUTFChars(id, fmuId); - const char *name = env->GetStringUTFChars(variable, 0); - - if(referenceExists(fmuStruct, name)) { - fmiValueReference vr = getReference(fmuStruct, name); - int result; - fmuStruct.fmu.getInteger(fmuStruct.c, &vr, 1, &result); - env->ReleaseStringUTFChars(variable, name); - return result; - - } else { - string nameString = name; - string message = "Variable " + nameString + " not found"; - env->ReleaseStringUTFChars(variable, name); - return throwException(env, message); - } - - } else { - string message = fmuId; - env->ReleaseStringUTFChars(id, fmuId); - return throwException(env, "unloadFMU: Model id " + message + " not found"); - } - */ - return 1; - -} - -JNIEXPORT jboolean JNICALL Java_org_simantics_fmil_FMIL_getBooleanValue_1 - (JNIEnv *env, jobject obj, jstring id, jstring variable) { - /* - const char *fmuId = env->GetStringUTFChars(id, 0); - if(exists(fmuId)) { - FMUControlStruct fmuStruct = fmus[fmuId]; - env->ReleaseStringUTFChars(id, fmuId); - const char *name = env->GetStringUTFChars(variable, 0); - - if(referenceExists(fmuStruct, name)) { - fmiValueReference vr = getReference(fmuStruct, name); - fmiBoolean result; - fmuStruct.fmu.getBoolean(fmuStruct.c, &vr, 1, &result); - env->ReleaseStringUTFChars(variable, name); - return result; - - } else { - string nameString = name; - string message = "Variable " + nameString + " not found"; - env->ReleaseStringUTFChars(variable, name); - return throwException(env, message); - } - - } else { - string message = fmuId; - env->ReleaseStringUTFChars(id, fmuId); - return throwException(env, "unloadFMU: Model id " + message + " not found"); - }*/ - return 1; - -} - -JNIEXPORT jstring JNICALL Java_org_simantics_fmil_FMIL_getStringValue_1 - (JNIEnv *env, jobject obj, jstring id, jstring variable) { - /* - const char *fmuId = env->GetStringUTFChars(id, 0); - if(exists(fmuId)) { - FMUControlStruct fmuStruct = fmus[fmuId]; - env->ReleaseStringUTFChars(id, fmuId); - const char *name = env->GetStringUTFChars(variable, 0); - - if(referenceExists(fmuStruct, name)) { - fmiValueReference vr = getReference(fmuStruct, name); - fmiString result; - fmuStruct.fmu.getString(fmuStruct.c, &vr, 1, &result); - env->ReleaseStringUTFChars(variable, name); - return env->NewStringUTF(result); - - } else { - string nameString = name; - string message = "Variable " + nameString + " not found"; - env->ReleaseStringUTFChars(variable, name); - return 0; //throwException(env, message); - } - - } else { - string message = fmuId; - env->ReleaseStringUTFChars(id, fmuId); - return 0; //throwException(env, "unloadFMU: Model id " + message + " not found"); - } - */ - return 0; - +/* ------------------------------------------------------------------------- + * fmu_control.c + * Simulation controls for fmus + * + * Free libraries and tools used to implement this simulator: + * - header files from the FMU specification + * - eXpat 2.0.1 XML parser, see http://expat.sourceforge.net + * - 7z.exe 4.57 zip and unzip tool, see http://www.7-zip.org <---------- Replace with zlib + * Author: Teemu Lempinen + * Copyright 2012 Semantum Oy + * ------------------------------------------------------------------------- + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +extern "C" { + #include "fmi_me.h" + #include "sim_support.h" +} + +#include "fmi1_cs.h" + +#define PRINT(fmt,args) { FILE *fp = fopen("R:\\Simantics\\Sysdyn\\log.txt", "ab"); fprintf(fp, fmt, args); fclose(fp); } + +#include +#define GetCurrentDir _getcwd + +using namespace std; + +struct FMI1 { + + void *fmu; + + vector variables; + vector descriptions; + vector declaredTypes; + vector valueReferences; + vector types; + vector variabilities; + vector causalities; + + vector declaredTypeNames; + vector typeDescriptions; + vector quantities; + vector units; + + vector subscription; + double currentTime; + double timeStep; + + int version; + +}; + +struct FMUControlStruct { + double step; // simulation step length + fmiReal currentTime; // current simulation time + + fmiComponent c; // instance of the fmu + ScalarVariable** vars; // model variables + + fmiEventInfo eventInfo; // updated by calls to initialize and eventUpdate + const char* guid; // global unique id of the fmu + fmiCallbackFunctions callbacks; // called by the model during simulation + fmiStatus fmiFlag; // return code of the fmu functions + + map indexes; // indexes for variable names in vars-table + map::iterator it; + + int nx; // number of state variables + double *x; // continuous states + double *xdot; // the crresponding derivatives in same order + 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 + vector fmiValueReferences; // all value references + + string lastErrorMessage; + + FMU fmu; +}; + +vector fmus; + +//map fmus; // indexes for variable names in vars-table + +int throwFMILException(JNIEnv *env, string message) { + jclass newExcCls; + newExcCls = env->FindClass("org/simantics/fmil/core/FMILException"); + if (newExcCls == NULL) { + newExcCls = env->FindClass("java/lang/Exception"); + } + if (newExcCls == NULL) { + /* Unable to find the exception class, give up. */ + return 1; + } + env->ThrowNew(newExcCls, message.c_str()); + return 1; +} + +int throwException(JNIEnv *env, string message) { + return throwFMILException(env, message); +} + +bool isEmpty(const char *c) { + if (c == NULL) { + return true; + } + if (c[0] == '\0') { + return true; + } + return false; +} + +/* +bool exists(string id) { + map::iterator it = fmus.find(id); + if(it != fmus.end()) { + return true; + } else { + return false; + } +} +*/ + + + +JNIEXPORT jint JNICALL Java_org_simantics_fmil_core_FMIL_loadFMUFile_1 + (JNIEnv *env, jobject obj, jstring path, jstring tempDir) { + + HMODULE module = NULL; + FMI1 fmi1; + FMIL_Variable *vars; + FMIL_DeclaredType *types; + + int returnValue; + + int variableCount = 0; + int typeCount = 0; + + int fmuVersion = 0; + const char *error = ""; + + const char *fmuPath = env->GetStringUTFChars(path, 0); + const char *fmuTempDir = env->GetStringUTFChars(tempDir, 0); + + fmi1.currentTime = 0; + fmi1.timeStep = 0.1; + returnValue = FMI_CS_LOAD(fmuPath, fmuTempDir, &fmi1.fmu, &fmuVersion, &error); + + if (returnValue != 0) { + string message = "Could not load FMU: "; + return throwFMILException(env, message += error); + } + if(!fmi1.fmu) { + string message = "No FMU loaded: "; + return throwFMILException(env, message += error); + } + + fmi1.version = fmuVersion; + if (fmi1.version == 1) { + vars = FMI1_CS_GET_VARIABLES(fmi1.fmu, &variableCount, &error); + } else if (fmi1.version == 2) { + vars = FMI2_CS_GET_VARIABLES(fmi1.fmu, &variableCount, &error); + } + if (!isEmpty(error)) { + string message = "Could not get variables "; + return throwFMILException(env, message += error); + } + + for(int i=0;iReleaseStringUTFChars(path, fmuPath); + env->ReleaseStringUTFChars(tempDir, fmuTempDir); + + return fmus.size() - 1; + +} + +JNIEXPORT jint JNICALL Java_org_simantics_fmil_core_FMIL_setStepLength_1 + (JNIEnv *env, jobject obj, jint id, jdouble stepLength) { + fmus[id].timeStep = stepLength; + return 0; +} + +JNIEXPORT jint JNICALL Java_org_simantics_fmil_core_FMIL_subscribe_1 + (JNIEnv *env, jobject obj, jint id, jintArray vrs) { + + jboolean isCopy; + jint* elements = env -> GetIntArrayElements(vrs, &isCopy); + jsize n = env -> GetArrayLength(vrs); + + int i; + for (i = 0; i < n; i++) { + fmus[id].subscription.push_back(elements[i]); + } + + if (isCopy == JNI_TRUE) { + env -> ReleaseIntArrayElements(vrs, elements, 0); + } + + return 0; + +} + +bool referenceExists(FMUControlStruct fmuStruct, string variable) { + map::iterator it = fmuStruct.indexes.find(variable); + if(it != fmuStruct.indexes.end()) { + return true; + } else { + return false; + } +} + +// Remember to check if reference exists +fmiValueReference getReference(FMUControlStruct fmuStruct, string variable) { + return fmuStruct.fmiValueReferences[fmuStruct.indexes[variable]]; +} + +// Get string representation of a scalar variable type +string getTypeString(ScalarVariable* sv) { + switch (sv->typeSpec->type){ + case elm_Integer: + return "Integer"; + case elm_Enumeration: + return "Enumeration"; + case elm_Real: + return "Real"; + case elm_Boolean: + return "Boolean"; + default: + return "No type"; + } +} + +JNIEXPORT jint JNICALL Java_org_simantics_fmil_core_FMIL_setRealValue_1 + (JNIEnv *env, jobject obj, jint id, jint vr, jdouble value) { + + const char *error = ""; + FMI1 fmi = fmus[id]; + if (fmi.version == 1) { + FMI1_CS_SET_REAL(fmi.fmu, vr, value, &error); + } else if (fmi.version == 2) { + FMI2_CS_SET_REAL(fmi.fmu, vr, value, &error); + } + if (!isEmpty(error)) { + string message = "Could not set real value "; + return throwFMILException(env, message += error); + } + return 0; +} + +JNIEXPORT jint JNICALL Java_org_simantics_fmil_core_FMIL_setIntegerValue_1 + (JNIEnv *env, jobject obj, jstring id, jstring parameter, jint value) { + /* + const char *fmuId = env->GetStringUTFChars(id, 0); + if(exists(fmuId)) { + FMUControlStruct& fmuStruct = fmus[fmuId]; + const char *name = env->GetStringUTFChars(parameter, 0); + string nameString = name; + string modelId = fmuId; + if(!referenceExists(fmuStruct, name)) { + string errorMessage = "setIntegerValue: Model (id " + modelId + ") does not contain variable: " + nameString; + env->ReleaseStringUTFChars(parameter, name); + env->ReleaseStringUTFChars(id, fmuId); + return throwException(env, errorMessage); + } else { + // Check variable type + ScalarVariable* sv = fmuStruct.vars[fmuStruct.indexes[name]]; + switch (sv->typeSpec->type){ + case elm_Integer: + break; // ok + default: { + string errorMessage = "setIntegerValue: " + nameString + " is not of type Integer. (type: + " + getTypeString(sv) + ")"; + env->ReleaseStringUTFChars(parameter, name); + env->ReleaseStringUTFChars(id, fmuId); + return throwException(env, errorMessage); + } + } + + // Change value + fmiValueReference vr = getReference(fmuStruct, name); + const int intValue = (int) value; + fmuStruct.fmu.setInteger(fmuStruct.c, &vr, 1, &intValue); + env->ReleaseStringUTFChars(parameter, name); + env->ReleaseStringUTFChars(id, fmuId); + return 1; + } + } else { + string message = fmuId; + env->ReleaseStringUTFChars(id, fmuId); + return throwException(env, "setIntegerValue: Model id " + message + " not found"); + } + */ + return 1; +} + +JNIEXPORT jint JNICALL Java_org_simantics_fmil_core_FMIL_setBooleanValue_1 + (JNIEnv *env, jobject obj, jstring id, jstring parameter, jboolean value) { + /* + const char *fmuId = env->GetStringUTFChars(id, 0); + if(exists(fmuId)) { + FMUControlStruct& fmuStruct = fmus[fmuId]; + const char *name = env->GetStringUTFChars(parameter, 0); + string nameString = name; + string modelId = fmuId; + if(!referenceExists(fmuStruct, name)) { + string errorMessage = "setBooleanValue: Model (id " + modelId + ") does not contain variable: " + nameString; + env->ReleaseStringUTFChars(parameter, name); + env->ReleaseStringUTFChars(id, fmuId); + return throwException(env, errorMessage); + } else { + // Check variable type + ScalarVariable* sv = fmuStruct.vars[fmuStruct.indexes[name]]; + switch (sv->typeSpec->type){ + case elm_Boolean: + break; // ok + default: { + string errorMessage = "setBooleanValue: " + nameString + " is not of type Boolean. (type: + " + getTypeString(sv) + ")"; + env->ReleaseStringUTFChars(parameter, name); + env->ReleaseStringUTFChars(id, fmuId); + return throwException(env, errorMessage); + } + } + + // Change value + fmiValueReference vr = getReference(fmuStruct, name); + fmiBoolean result = 1; + if(value == 0) + result = 0; + fmuStruct.fmu.setBoolean(fmuStruct.c, &vr, 1, &result); + env->ReleaseStringUTFChars(parameter, name); + env->ReleaseStringUTFChars(id, fmuId); + return 1; + } + } else { + string message = fmuId; + env->ReleaseStringUTFChars(id, fmuId); + return throwException(env, "setBooleanValue: Model id " + message + " not found"); + }*/ + return 1; +} + +JNIEXPORT jboolean JNICALL Java_org_simantics_fmil_core_FMIL_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 { + env->ReleaseStringUTFChars(id, fmuId); + return false; + } + */ + return 1; +} + + +JNIEXPORT jdouble JNICALL Java_org_simantics_fmil_core_FMIL_getTime_1 + (JNIEnv *env, jobject obj, jint id) { + return fmus[id].currentTime; +} + +double getRealValue(FMUControlStruct fmuStruct, int index) { + ScalarVariable *sv = fmuStruct.vars[index]; + fmiValueReference vr = fmuStruct.fmiValueReferences[index]; + double real; + fmiInteger integer; + fmiBoolean fmibool; + + switch (sv->typeSpec->type){ + case elm_Real: + fmuStruct.fmu.getReal(fmuStruct.c, &vr, 1, &real); + break; + case elm_Integer: + case elm_Enumeration: + fmuStruct.fmu.getInteger(fmuStruct.c, &vr, 1, &integer); + real = (double)integer; + break; + case elm_Boolean: + fmuStruct.fmu.getBoolean(fmuStruct.c, &vr, 1, &fmibool); + if(fmibool == fmiTrue) + real = 1.0; + else + real = 0.0; + break; + } + return real; +} + +JNIEXPORT jdoubleArray JNICALL Java_org_simantics_fmil_core_FMIL_getSubscribedResults_1 + (JNIEnv *env, jobject obj, jint id, jdoubleArray result) { + + jboolean isCopy; + jdouble* resultElements = env -> GetDoubleArrayElements(result, &isCopy); + jsize n = env -> GetArrayLength(result); + int *vrs; + const char *error = ""; + int returnValue = 0; + + FMI1 fmi = fmus[id]; + if(n > 0) { + vrs = &(fmus[id].subscription[0]); + if (fmi.version == 1) { + FMI1_CS_GET_REALS(fmi.fmu, vrs, resultElements, n, &error); + } else if (fmi.version == 2) { + FMI2_CS_GET_REALS(fmi.fmu, vrs, resultElements, n, &error); + } + } + if (isCopy == JNI_TRUE) { + env -> ReleaseDoubleArrayElements(result, resultElements, 0); + } + + return result; + +} + +JNIEXPORT jint JNICALL Java_org_simantics_fmil_core_FMIL_instantiateSimulation_1 + (JNIEnv *env, jobject obj, jint id) { + + int returnValue; + const char *error = ""; + + FMI1 fmi = fmus[id]; + if (fmi.version == 1) { + returnValue = FMI1_CS_INSTANTIATE(fmi.fmu, "", &error); + } else if (fmi.version == 2) { + returnValue = FMI2_CS_INSTANTIATE(fmi.fmu, "", &error); + } + if(returnValue != 0) { + string message = "No FMU loaded: "; + return throwFMILException(env, message += error); + } + return 0; +} + +JNIEXPORT jint JNICALL Java_org_simantics_fmil_core_FMIL_initializeSimulation_1 + (JNIEnv *env, jobject obj, jint id) { + + const char *error = ""; + int returnValue; + FMI1 fmi = fmus[id]; + if (fmi.version == 1) { + returnValue = FMI1_CS_INITIALIZE(fmi.fmu, &error); + } else if (fmi.version == 2) { + returnValue = FMI2_CS_INITIALIZE(fmi.fmu, &error); + } + if(returnValue != 0) { + string message = "Could not initialize simulation: "; + return throwFMILException(env, message += error); + } + + return 0; + +} + +JNIEXPORT jint JNICALL Java_org_simantics_fmil_core_FMIL_setTime_1 + (JNIEnv *env, jobject obj, jstring id, jdouble time) { + return 0; +} + +JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_core_FMIL_getAllVariables_1 + (JNIEnv *env, jobject obj, jint id) { + + jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].variables.size(), + env->FindClass("java/lang/String"), + env->NewStringUTF("")); + + for(int i=0;iSetObjectArrayElement(ret,i,env->NewStringUTF(fmus[id].variables[i].c_str())); + } + + return ret; + +} + +JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_core_FMIL_getAllVariableDescriptions_1 + (JNIEnv *env, jobject obj, jint id) { + + jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].descriptions.size(), + env->FindClass("java/lang/String"), + env->NewStringUTF("")); + + for(int i=0;iSetObjectArrayElement(ret,i,env->NewStringUTF(fmus[id].descriptions[i].c_str())); + } + + return ret; + +} + +JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_core_FMIL_getAllVariableDeclaredTypes_1 + (JNIEnv *env, jobject obj, jint id) { + + jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].declaredTypes.size(), + env->FindClass("java/lang/String"), + env->NewStringUTF("")); + + for(int i=0;iSetObjectArrayElement(ret,i,env->NewStringUTF(fmus[id].declaredTypes[i].c_str())); + } + + return ret; + +} + +JNIEXPORT jintArray JNICALL Java_org_simantics_fmil_core_FMIL_getAllVariableReferences_1 + (JNIEnv *env, jobject obj, jint id, jintArray result) { + + jboolean isCopy; + jint* resultElements = env -> GetIntArrayElements(result, &isCopy); + jsize n = env -> GetArrayLength(result); + + int i; + for (i = 0; i < n; i++) { + resultElements[i] = fmus[id].valueReferences[i]; + } + + if (isCopy == JNI_TRUE) { + env -> ReleaseIntArrayElements(result, resultElements, 0); + } + + return result; + +} + +JNIEXPORT jintArray JNICALL Java_org_simantics_fmil_core_FMIL_getAllVariableTypes_1 + (JNIEnv *env, jobject obj, jint id, jintArray result) { + + jboolean isCopy; + jint* resultElements = env -> GetIntArrayElements(result, &isCopy); + jsize n = env -> GetArrayLength(result); + + int i; + for (i = 0; i < n; i++) { + resultElements[i] = fmus[id].types[i]; + } + + if (isCopy == JNI_TRUE) { + env -> ReleaseIntArrayElements(result, resultElements, 0); + } + + return result; + +} + +JNIEXPORT jintArray JNICALL Java_org_simantics_fmil_core_FMIL_getAllVariableVariabilities_1 + (JNIEnv *env, jobject obj, jint id, jintArray result) { + + jboolean isCopy; + jint* resultElements = env -> GetIntArrayElements(result, &isCopy); + jsize n = env -> GetArrayLength(result); + + int i; + for (i = 0; i < n; i++) { + resultElements[i] = fmus[id].variabilities[i]; + } + + if (isCopy == JNI_TRUE) { + env -> ReleaseIntArrayElements(result, resultElements, 0); + } + + return result; + +} + +JNIEXPORT jintArray JNICALL Java_org_simantics_fmil_core_FMIL_getAllVariableCausalities_1 + (JNIEnv *env, jobject obj, jint id, jintArray result) { + + jboolean isCopy; + jint* resultElements = env -> GetIntArrayElements(result, &isCopy); + jsize n = env -> GetArrayLength(result); + + int i; + for (i = 0; i < n; i++) { + resultElements[i] = fmus[id].causalities[i]; + } + + if (isCopy == JNI_TRUE) { + env -> ReleaseIntArrayElements(result, resultElements, 0); + } + + return result; + +} + +JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_core_FMIL_getAllDeclaredTypes_1 + (JNIEnv *env, jobject obj, jint id) { + + jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].declaredTypeNames.size(), + env->FindClass("java/lang/String"), + env->NewStringUTF("")); + + for(int i=0;iSetObjectArrayElement(ret,i,env->NewStringUTF(fmus[id].declaredTypeNames[i].c_str())); + } + + return ret; + +} + +JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_core_FMIL_getAllDeclaredTypeDescriptions_1 + (JNIEnv *env, jobject obj, jint id) { + + jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].typeDescriptions.size(), + env->FindClass("java/lang/String"), + env->NewStringUTF("")); + + for(int i=0;iSetObjectArrayElement(ret,i,env->NewStringUTF(fmus[id].typeDescriptions[i].c_str())); + } + + return ret; + +} + +JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_core_FMIL_getAllDeclaredTypeQuantities_1 + (JNIEnv *env, jobject obj, jint id) { + + jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].quantities.size(), + env->FindClass("java/lang/String"), + env->NewStringUTF("")); + + for(int i=0;iSetObjectArrayElement(ret,i,env->NewStringUTF(fmus[id].quantities[i].c_str())); + } + + return ret; + +} + +JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_core_FMIL_getAllDeclaredTypeUnits_1 + (JNIEnv *env, jobject obj, jint id) { + + jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].units.size(), + env->FindClass("java/lang/String"), + env->NewStringUTF("")); + + for(int i=0;iSetObjectArrayElement(ret,i,env->NewStringUTF(fmus[id].units[i].c_str())); + } + + return ret; + +} + +/* +JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_core_FMIL_filterVariables_1 + (JNIEnv *env, jobject obj, jstring id, jstring regexp) { + const char *rx = env->GetStringUTFChars(regexp, 0); + jobjectArray result = filterVariables(env, obj, id, rx); + env->ReleaseStringUTFChars(regexp, rx); + return result; +} +*/ + +JNIEXPORT jint JNICALL Java_org_simantics_fmil_core_FMIL_simulateStep_1 + (JNIEnv *env, jobject obj, jint id) { + + int returnValue; + const char *error = ""; + + FMI1 fmi = fmus[id]; + if (fmi.version == 1) { + returnValue = FMI1_CS_STEP(fmi.fmu, fmi.currentTime, fmi.timeStep, &error); + } else if (fmi.version == 2) { + returnValue = FMI2_CS_STEP(fmi.fmu, fmi.currentTime, fmi.timeStep, &error); + } + if(returnValue != 0) { + string message = "Could not simulate step: "; + return throwException(env, message += error); + } + + fmi.currentTime += fmi.timeStep; + + return 0; + + /* + const char *fmuId = env->GetStringUTFChars(id, 0); + if(exists(fmuId)) { + FMUControlStruct& fmuStruct = fmus[fmuId]; + env->ReleaseStringUTFChars(id, fmuId); + + if(&fmuStruct.fmu == NULL || fmuStruct.fmu.modelDescription == NULL || &fmuStruct.vars == NULL) { + return throwException(env, "Simulate step failed - fmu not loaded"); + } + + if(fmuStruct.x == NULL) { + 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; + int debug = 0; // DEBUG ON = 1, OFF = 0 + + int i; + double dt, tPre, tEnd = fmuStruct.currentTime + fmuStruct.step; + + fmiBoolean timeEvent, stateEvent, stepEvent; + fmiStatus fmiFlag; // return code of the fmu functions + fmiValueReference vr; + + + */ + /* Simulate the duration of one step. The simulation may be done in + * multiple parts if events occur + */ /* + while (fmuStruct.currentTime < tEnd) { + // get current state and derivatives + fmiFlag = fmu.getContinuousStates(fmuStruct.c, fmuStruct.x, fmuStruct.nx); + if (fmiFlag > fmiWarning) + return throwException(env, "could not retrieve states"); + + fmiFlag = fmu.getDerivatives(fmuStruct.c, fmuStruct.xdot, fmuStruct.nx); + if (fmiFlag > fmiWarning) + return throwException(env, "could not retrieve derivatives"); + + // advance time + tPre = fmuStruct.currentTime; + fmuStruct.currentTime = min(fmuStruct.currentTime+fmuStruct.step, tEnd); + timeEvent = fmuStruct.eventInfo.upcomingTimeEvent && fmuStruct.eventInfo.nextEventTime < fmuStruct.currentTime; + + if (timeEvent) fmuStruct.currentTime = fmuStruct.eventInfo.nextEventTime; + dt = fmuStruct.currentTime - tPre; + fmiFlag = fmu.setTime(fmuStruct.c, fmuStruct.currentTime); + if (fmiFlag > fmiWarning) throwException(env, "could not set time"); + + if(referenceExists(fmuStruct, "time")) { + vr = getReference(fmuStruct, "time"); + if(vr != NULL) { + fmu.setReal(fmuStruct.c, &vr, 1, &(fmuStruct.currentTime)); + } + } + + if(debug) + printf("Actual time: %lf\n", fmuStruct.currentTime); + + if (fmiFlag > fmiWarning) + return throwException(env, "could not set time"); + + // perform one step + for (i=0; i fmiWarning) + return throwException(env, "could not set states"); + + // Check for step event, e.g. dynamic state selection + fmiFlag = fmu.completedIntegratorStep(fmuStruct.c, &stepEvent); + if (fmiFlag > fmiWarning) return throwException(env, "could not complete intgrator step"); + */ +/* for (i=0; i fmiWarning) return throwException(env, "could not retrieve event indicators"); + stateEvent = FALSE; + for (i=0; i fmiWarning) return throwException(env, "could not perform event update"); + + } // if event + */ + +/* } + + fflush(stdout); + return 1; + + } else { + string message = fmuId; + env->ReleaseStringUTFChars(id, fmuId); + return throwException(env, "simulateStep: Model id " + message + " not found"); + }*/ + return 1; +} + +JNIEXPORT jint JNICALL Java_org_simantics_fmil_core_FMIL_unloadFMU_1 + (JNIEnv *env, jobject obj, jint id) { + + int returnValue; + const char *error = ""; + + FMI1 fmi = fmus[id]; + if (fmi.version == 1) { + returnValue = FMI1_CS_UNLOAD(fmi.fmu, &error); + } else if (fmi.version == 2) { + returnValue = FMI2_CS_UNLOAD(fmi.fmu, &error); + } + if(returnValue != 0) { + string message = "Could not unload FMU: "; + return throwException(env, message += error); + } + return returnValue; +} + +JNIEXPORT jdouble JNICALL Java_org_simantics_fmil_core_FMIL_getRealValue_1 + (JNIEnv *env, jobject obj, jint id, jint vr) { + + double value; + const char *error = ""; + + FMI1 fmi = fmus[id]; + if (fmi.version == 1) { + value = FMI1_CS_GET_REAL(fmi.fmu, vr, &error); + } else if (fmi.version == 2) { + value = FMI2_CS_GET_REAL(fmi.fmu, vr, &error); + } + if (!isEmpty(error)) { + string message = "Could not get real value: "; + return throwFMILException(env, message += error); + } + return value; +} + +JNIEXPORT jint JNICALL Java_org_simantics_fmil_core_FMIL_getIntegerValue_1 + (JNIEnv *env, jobject obj, jstring id, jstring variable) { + /* + const char *fmuId = env->GetStringUTFChars(id, 0); + if(exists(fmuId)) { + FMUControlStruct fmuStruct = fmus[fmuId]; + env->ReleaseStringUTFChars(id, fmuId); + const char *name = env->GetStringUTFChars(variable, 0); + + if(referenceExists(fmuStruct, name)) { + fmiValueReference vr = getReference(fmuStruct, name); + int result; + fmuStruct.fmu.getInteger(fmuStruct.c, &vr, 1, &result); + env->ReleaseStringUTFChars(variable, name); + return result; + + } else { + string nameString = name; + string message = "Variable " + nameString + " not found"; + env->ReleaseStringUTFChars(variable, name); + return throwException(env, message); + } + + } else { + string message = fmuId; + env->ReleaseStringUTFChars(id, fmuId); + return throwException(env, "unloadFMU: Model id " + message + " not found"); + } + */ + return 1; + +} + +JNIEXPORT jboolean JNICALL Java_org_simantics_fmil_core_FMIL_getBooleanValue_1 + (JNIEnv *env, jobject obj, jstring id, jstring variable) { + /* + const char *fmuId = env->GetStringUTFChars(id, 0); + if(exists(fmuId)) { + FMUControlStruct fmuStruct = fmus[fmuId]; + env->ReleaseStringUTFChars(id, fmuId); + const char *name = env->GetStringUTFChars(variable, 0); + + if(referenceExists(fmuStruct, name)) { + fmiValueReference vr = getReference(fmuStruct, name); + fmiBoolean result; + fmuStruct.fmu.getBoolean(fmuStruct.c, &vr, 1, &result); + env->ReleaseStringUTFChars(variable, name); + return result; + + } else { + string nameString = name; + string message = "Variable " + nameString + " not found"; + env->ReleaseStringUTFChars(variable, name); + return throwException(env, message); + } + + } else { + string message = fmuId; + env->ReleaseStringUTFChars(id, fmuId); + return throwException(env, "unloadFMU: Model id " + message + " not found"); + }*/ + return 1; + +} + +JNIEXPORT jstring JNICALL Java_org_simantics_fmil_core_FMIL_getStringValue_1 + (JNIEnv *env, jobject obj, jstring id, jstring variable) { + /* + const char *fmuId = env->GetStringUTFChars(id, 0); + if(exists(fmuId)) { + FMUControlStruct fmuStruct = fmus[fmuId]; + env->ReleaseStringUTFChars(id, fmuId); + const char *name = env->GetStringUTFChars(variable, 0); + + if(referenceExists(fmuStruct, name)) { + fmiValueReference vr = getReference(fmuStruct, name); + fmiString result; + fmuStruct.fmu.getString(fmuStruct.c, &vr, 1, &result); + env->ReleaseStringUTFChars(variable, name); + return env->NewStringUTF(result); + + } else { + string nameString = name; + string message = "Variable " + nameString + " not found"; + env->ReleaseStringUTFChars(variable, name); + return 0; //throwException(env, message); + } + + } else { + string message = fmuId; + env->ReleaseStringUTFChars(id, fmuId); + return 0; //throwException(env, "unloadFMU: Model id " + message + " not found"); + } + */ + return 0; + } \ No newline at end of file