1 /* -------------------------------------------------------------------------
\r
3 * Simulation controls for fmus
\r
5 * Free libraries and tools used to implement this simulator:
\r
6 * - header files from the FMU specification
\r
7 * - eXpat 2.0.1 XML parser, see http://expat.sourceforge.net
\r
8 * - 7z.exe 4.57 zip and unzip tool, see http://www.7-zip.org <---------- Replace with zlib
\r
9 * Author: Teemu Lempinen
\r
10 * Copyright 2012 Semantum Oy
\r
11 * -------------------------------------------------------------------------
\r
23 #include <org_simantics_fmil_FMILJNI.h>
\r
27 #include "sim_support.h"
\r
30 #include "fmi1_cs.h"
\r
32 #define PRINT(fmt,args) { FILE *fp = fopen("R:\\Simantics\\Sysdyn\\log.txt", "ab"); fprintf(fp, fmt, args); fclose(fp); }
\r
35 #define GetCurrentDir _getcwd
\r
37 using namespace std;
\r
43 vector<string> variables;
\r
44 vector<string> descriptions;
\r
45 vector<int> valueReferences;
\r
47 vector<int> variabilities;
\r
48 vector<int> causalities;
\r
50 vector<int> subscription;
\r
56 struct FMUControlStruct {
\r
57 double step; // simulation step length
\r
58 fmiReal currentTime; // current simulation time
\r
60 fmiComponent c; // instance of the fmu
\r
61 ScalarVariable** vars; // model variables
\r
63 fmiEventInfo eventInfo; // updated by calls to initialize and eventUpdate
\r
64 const char* guid; // global unique id of the fmu
\r
65 fmiCallbackFunctions callbacks; // called by the model during simulation
\r
66 fmiStatus fmiFlag; // return code of the fmu functions
\r
68 map<string,int> indexes; // indexes for variable names in vars-table
\r
69 map<string,int>::iterator it;
\r
71 int nx; // number of state variables
\r
72 double *x; // continuous states
\r
73 double *xdot; // the crresponding derivatives in same order
\r
74 int nz; // number of state event indicators
\r
75 double *z; // state event indicators
\r
76 double *prez; // previous values of state event indicators
\r
78 bool initialized; // has the fmu been initialized
\r
80 vector<fmiValueReference> subscription; // result subscriptions
\r
81 vector<string> allVariables; // all variables in an initialized model
\r
82 vector<fmiValueReference> fmiValueReferences; // all value references
\r
84 string lastErrorMessage;
\r
91 //map<string,FMUControlStruct> fmus; // indexes for variable names in vars-table
\r
93 int throwException(JNIEnv *env, string message) {
\r
95 newExcCls = env->FindClass("java/lang/Exception");
\r
96 if (newExcCls == NULL) {
\r
97 /* Unable to find the exception class, give up. */
\r
100 env->ThrowNew(newExcCls, message.c_str());
\r
105 bool exists(string id) {
\r
106 map<string,FMUControlStruct>::iterator it = fmus.find(id);
\r
107 if(it != fmus.end()) {
\r
117 JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_loadFMUFile_1
\r
118 (JNIEnv *env, jobject obj, jstring path, jstring tempDir) {
\r
120 HMODULE module = NULL;
\r
122 FMIL_Variable *vars;
\r
123 int variableCount = 0;
\r
125 const char *fmuPath = env->GetStringUTFChars(path, 0);
\r
126 const char *fmuTempDir = env->GetStringUTFChars(tempDir, 0);
\r
128 fmi1.currentTime = 0;
\r
129 fmi1.timeStep = 0.1;
\r
130 fmi1.fmu = FMI1_CS_LOAD(fmuPath, fmuTempDir);
\r
132 return throwException(env, "No FMU loaded");
\r
134 vars = FMI1_CS_GET_VARIABLES(fmi1.fmu, &variableCount);
\r
135 for(int i=0;i<variableCount;i++) {
\r
136 fmi1.variables.push_back(string(vars[i].name));
\r
137 if(vars[i].description)
\r
138 fmi1.descriptions.push_back(string(vars[i].description));
\r
140 fmi1.descriptions.push_back(string(""));
\r
141 fmi1.types.push_back(vars[i].type);
\r
142 fmi1.causalities.push_back(vars[i].causality);
\r
143 fmi1.variabilities.push_back(vars[i].variability);
\r
144 fmi1.valueReferences.push_back(vars[i].vr);
\r
147 fmus.push_back(fmi1);
\r
149 env->ReleaseStringUTFChars(path, fmuPath);
\r
150 env->ReleaseStringUTFChars(tempDir, fmuTempDir);
\r
152 return fmus.size() - 1;
\r
156 JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_setStepLength_1
\r
157 (JNIEnv *env, jobject obj, jint id, jdouble stepLength) {
\r
158 fmus[id].timeStep = stepLength;
\r
162 JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_subscribe_1
\r
163 (JNIEnv *env, jobject obj, jint id, jintArray vrs) {
\r
166 jint* elements = env -> GetIntArrayElements(vrs, &isCopy);
\r
167 jsize n = env -> GetArrayLength(vrs);
\r
170 for (i = 0; i < n; i++) {
\r
171 fmus[id].subscription.push_back(elements[i]);
\r
174 if (isCopy == JNI_TRUE) {
\r
175 env -> ReleaseIntArrayElements(vrs, elements, 0);
\r
182 bool referenceExists(FMUControlStruct fmuStruct, string variable) {
\r
183 map<string,int>::iterator it = fmuStruct.indexes.find(variable);
\r
184 if(it != fmuStruct.indexes.end()) {
\r
191 // Remember to check if reference exists
\r
192 fmiValueReference getReference(FMUControlStruct fmuStruct, string variable) {
\r
193 return fmuStruct.fmiValueReferences[fmuStruct.indexes[variable]];
\r
196 // Get string representation of a scalar variable type
\r
197 string getTypeString(ScalarVariable* sv) {
\r
198 switch (sv->typeSpec->type){
\r
201 case elm_Enumeration:
\r
202 return "Enumeration";
\r
212 JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_setRealValue_1
\r
213 (JNIEnv *env, jobject obj, jint id, jint vr, jdouble value) {
\r
215 FMI1_CS_SET_REAL(fmus[id].fmu, vr, value);
\r
220 JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_setIntegerValue_1
\r
221 (JNIEnv *env, jobject obj, jstring id, jstring parameter, jint value) {
\r
223 const char *fmuId = env->GetStringUTFChars(id, 0);
\r
224 if(exists(fmuId)) {
\r
225 FMUControlStruct& fmuStruct = fmus[fmuId];
\r
226 const char *name = env->GetStringUTFChars(parameter, 0);
\r
227 string nameString = name;
\r
228 string modelId = fmuId;
\r
229 if(!referenceExists(fmuStruct, name)) {
\r
230 string errorMessage = "setIntegerValue: Model (id " + modelId + ") does not contain variable: " + nameString;
\r
231 env->ReleaseStringUTFChars(parameter, name);
\r
232 env->ReleaseStringUTFChars(id, fmuId);
\r
233 return throwException(env, errorMessage);
\r
235 // Check variable type
\r
236 ScalarVariable* sv = fmuStruct.vars[fmuStruct.indexes[name]];
\r
237 switch (sv->typeSpec->type){
\r
241 string errorMessage = "setIntegerValue: " + nameString + " is not of type Integer. (type: + " + getTypeString(sv) + ")";
\r
242 env->ReleaseStringUTFChars(parameter, name);
\r
243 env->ReleaseStringUTFChars(id, fmuId);
\r
244 return throwException(env, errorMessage);
\r
249 fmiValueReference vr = getReference(fmuStruct, name);
\r
250 const int intValue = (int) value;
\r
251 fmuStruct.fmu.setInteger(fmuStruct.c, &vr, 1, &intValue);
\r
252 env->ReleaseStringUTFChars(parameter, name);
\r
253 env->ReleaseStringUTFChars(id, fmuId);
\r
257 string message = fmuId;
\r
258 env->ReleaseStringUTFChars(id, fmuId);
\r
259 return throwException(env, "setIntegerValue: Model id " + message + " not found");
\r
265 JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_setBooleanValue_1
\r
266 (JNIEnv *env, jobject obj, jstring id, jstring parameter, jboolean value) {
\r
268 const char *fmuId = env->GetStringUTFChars(id, 0);
\r
269 if(exists(fmuId)) {
\r
270 FMUControlStruct& fmuStruct = fmus[fmuId];
\r
271 const char *name = env->GetStringUTFChars(parameter, 0);
\r
272 string nameString = name;
\r
273 string modelId = fmuId;
\r
274 if(!referenceExists(fmuStruct, name)) {
\r
275 string errorMessage = "setBooleanValue: Model (id " + modelId + ") does not contain variable: " + nameString;
\r
276 env->ReleaseStringUTFChars(parameter, name);
\r
277 env->ReleaseStringUTFChars(id, fmuId);
\r
278 return throwException(env, errorMessage);
\r
280 // Check variable type
\r
281 ScalarVariable* sv = fmuStruct.vars[fmuStruct.indexes[name]];
\r
282 switch (sv->typeSpec->type){
\r
286 string errorMessage = "setBooleanValue: " + nameString + " is not of type Boolean. (type: + " + getTypeString(sv) + ")";
\r
287 env->ReleaseStringUTFChars(parameter, name);
\r
288 env->ReleaseStringUTFChars(id, fmuId);
\r
289 return throwException(env, errorMessage);
\r
294 fmiValueReference vr = getReference(fmuStruct, name);
\r
295 fmiBoolean result = 1;
\r
298 fmuStruct.fmu.setBoolean(fmuStruct.c, &vr, 1, &result);
\r
299 env->ReleaseStringUTFChars(parameter, name);
\r
300 env->ReleaseStringUTFChars(id, fmuId);
\r
304 string message = fmuId;
\r
305 env->ReleaseStringUTFChars(id, fmuId);
\r
306 return throwException(env, "setBooleanValue: Model id " + message + " not found");
\r
311 JNIEXPORT jboolean JNICALL Java_org_simantics_fmil_FMIL_isInitialized_1
\r
312 (JNIEnv *env, jobject obj, jstring id) {
\r
314 const char *fmuId = env->GetStringUTFChars(id, 0);
\r
315 if(exists(fmuId)) {
\r
316 FMUControlStruct& fmuStruct = fmus[fmuId];
\r
317 env->ReleaseStringUTFChars(id, fmuId);
\r
318 return fmuStruct.initialized;
\r
320 env->ReleaseStringUTFChars(id, fmuId);
\r
328 JNIEXPORT jdouble JNICALL Java_org_simantics_fmil_FMIL_getTime_1
\r
329 (JNIEnv *env, jobject obj, jint id) {
\r
330 return fmus[id].currentTime;
\r
333 double getRealValue(FMUControlStruct fmuStruct, int index) {
\r
334 ScalarVariable *sv = fmuStruct.vars[index];
\r
335 fmiValueReference vr = fmuStruct.fmiValueReferences[index];
\r
337 fmiInteger integer;
\r
338 fmiBoolean fmibool;
\r
340 switch (sv->typeSpec->type){
\r
342 fmuStruct.fmu.getReal(fmuStruct.c, &vr, 1, &real);
\r
345 case elm_Enumeration:
\r
346 fmuStruct.fmu.getInteger(fmuStruct.c, &vr, 1, &integer);
\r
347 real = (double)integer;
\r
350 fmuStruct.fmu.getBoolean(fmuStruct.c, &vr, 1, &fmibool);
\r
351 if(fmibool == fmiTrue)
\r
360 JNIEXPORT jdoubleArray JNICALL Java_org_simantics_fmil_FMIL_getSubscribedResults_1
\r
361 (JNIEnv *env, jobject obj, jint id, jdoubleArray result) {
\r
364 jdouble* resultElements = env -> GetDoubleArrayElements(result, &isCopy);
\r
365 jsize n = env -> GetArrayLength(result);
\r
368 vrs = &(fmus[id].subscription[0]);
\r
369 FMI1_CS_GET_REALS(fmus[id].fmu, vrs, resultElements, n);
\r
371 if (isCopy == JNI_TRUE) {
\r
372 env -> ReleaseDoubleArrayElements(result, resultElements, 0);
\r
379 JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_instantiateSimulation_1
\r
380 (JNIEnv *env, jobject obj, jint id) {
\r
382 int asd = FMI1_CS_INSTANTIATE(fmus[id].fmu);
\r
384 return throwException(env, "No FMU loaded");
\r
390 JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_initializeSimulation_1
\r
391 (JNIEnv *env, jobject obj, jint id) {
\r
393 int asd = FMI1_CS_INITIALIZE(fmus[id].fmu);
\r
395 return throwException(env, "No FMU loaded");
\r
401 JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_setTime_1
\r
402 (JNIEnv *env, jobject obj, jstring id, jdouble time) {
\r
406 JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariables_1
\r
407 (JNIEnv *env, jobject obj, jint id) {
\r
409 jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].variables.size(),
\r
410 env->FindClass("java/lang/String"),
\r
411 env->NewStringUTF(""));
\r
413 for(int i=0;i<fmus[id].variables.size();i++) {
\r
414 env->SetObjectArrayElement(ret,i,env->NewStringUTF(fmus[id].variables[i].c_str()));
\r
421 JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariableDescriptions_1
\r
422 (JNIEnv *env, jobject obj, jint id) {
\r
424 jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].descriptions.size(),
\r
425 env->FindClass("java/lang/String"),
\r
426 env->NewStringUTF(""));
\r
428 for(int i=0;i<fmus[id].descriptions.size();i++) {
\r
429 env->SetObjectArrayElement(ret,i,env->NewStringUTF(fmus[id].descriptions[i].c_str()));
\r
436 JNIEXPORT jintArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariableReferences_1
\r
437 (JNIEnv *env, jobject obj, jint id, jintArray result) {
\r
440 jint* resultElements = env -> GetIntArrayElements(result, &isCopy);
\r
441 jsize n = env -> GetArrayLength(result);
\r
444 for (i = 0; i < n; i++) {
\r
445 resultElements[i] = fmus[id].valueReferences[i];
\r
448 if (isCopy == JNI_TRUE) {
\r
449 env -> ReleaseIntArrayElements(result, resultElements, 0);
\r
456 JNIEXPORT jintArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariableTypes_1
\r
457 (JNIEnv *env, jobject obj, jint id, jintArray result) {
\r
460 jint* resultElements = env -> GetIntArrayElements(result, &isCopy);
\r
461 jsize n = env -> GetArrayLength(result);
\r
464 for (i = 0; i < n; i++) {
\r
465 resultElements[i] = fmus[id].types[i];
\r
468 if (isCopy == JNI_TRUE) {
\r
469 env -> ReleaseIntArrayElements(result, resultElements, 0);
\r
476 JNIEXPORT jintArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariableVariabilities_1
\r
477 (JNIEnv *env, jobject obj, jint id, jintArray result) {
\r
480 jint* resultElements = env -> GetIntArrayElements(result, &isCopy);
\r
481 jsize n = env -> GetArrayLength(result);
\r
484 for (i = 0; i < n; i++) {
\r
485 resultElements[i] = fmus[id].variabilities[i];
\r
488 if (isCopy == JNI_TRUE) {
\r
489 env -> ReleaseIntArrayElements(result, resultElements, 0);
\r
496 JNIEXPORT jintArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariableCausalities_1
\r
497 (JNIEnv *env, jobject obj, jint id, jintArray result) {
\r
500 jint* resultElements = env -> GetIntArrayElements(result, &isCopy);
\r
501 jsize n = env -> GetArrayLength(result);
\r
504 for (i = 0; i < n; i++) {
\r
505 resultElements[i] = fmus[id].causalities[i];
\r
508 if (isCopy == JNI_TRUE) {
\r
509 env -> ReleaseIntArrayElements(result, resultElements, 0);
\r
517 JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_filterVariables_1
\r
518 (JNIEnv *env, jobject obj, jstring id, jstring regexp) {
\r
519 const char *rx = env->GetStringUTFChars(regexp, 0);
\r
520 jobjectArray result = filterVariables(env, obj, id, rx);
\r
521 env->ReleaseStringUTFChars(regexp, rx);
\r
526 JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_simulateStep_1
\r
527 (JNIEnv *env, jobject obj, jint id) {
\r
529 int asd = FMI1_CS_STEP(fmus[id].fmu, fmus[id].currentTime, fmus[id].timeStep);
\r
531 return throwException(env, "No FMU loaded");
\r
533 fmus[id].currentTime += fmus[id].timeStep;
\r
538 const char *fmuId = env->GetStringUTFChars(id, 0);
\r
539 if(exists(fmuId)) {
\r
540 FMUControlStruct& fmuStruct = fmus[fmuId];
\r
541 env->ReleaseStringUTFChars(id, fmuId);
\r
543 if(&fmuStruct.fmu == NULL || fmuStruct.fmu.modelDescription == NULL || &fmuStruct.vars == NULL) {
\r
544 return throwException(env, "Simulate step failed - fmu not loaded");
\r
547 if(fmuStruct.x == NULL) {
\r
548 return throwException(env, "Simulate step failed - fmu not instantiated");
\r
551 if(fmuStruct.initialized == false) {
\r
552 fmiBoolean toleranceControlled = fmiFalse;
\r
553 fmuStruct.fmiFlag = fmuStruct.fmu.initialize(fmuStruct.c, toleranceControlled, fmuStruct.currentTime, &(fmuStruct.eventInfo));
\r
554 if (fmuStruct.fmiFlag > fmiWarning) return throwException(env, "could not initialize model");
\r
555 fmuStruct.initialized = true;
\r
558 FMU& fmu = fmuStruct.fmu;
\r
559 int debug = 0; // DEBUG ON = 1, OFF = 0
\r
562 double dt, tPre, tEnd = fmuStruct.currentTime + fmuStruct.step;
\r
564 fmiBoolean timeEvent, stateEvent, stepEvent;
\r
565 fmiStatus fmiFlag; // return code of the fmu functions
\r
566 fmiValueReference vr;
\r
570 /* Simulate the duration of one step. The simulation may be done in
\r
571 * multiple parts if events occur
\r
573 while (fmuStruct.currentTime < tEnd) {
\r
574 // get current state and derivatives
\r
575 fmiFlag = fmu.getContinuousStates(fmuStruct.c, fmuStruct.x, fmuStruct.nx);
\r
576 if (fmiFlag > fmiWarning)
\r
577 return throwException(env, "could not retrieve states");
\r
579 fmiFlag = fmu.getDerivatives(fmuStruct.c, fmuStruct.xdot, fmuStruct.nx);
\r
580 if (fmiFlag > fmiWarning)
\r
581 return throwException(env, "could not retrieve derivatives");
\r
584 tPre = fmuStruct.currentTime;
\r
585 fmuStruct.currentTime = min(fmuStruct.currentTime+fmuStruct.step, tEnd);
\r
586 timeEvent = fmuStruct.eventInfo.upcomingTimeEvent && fmuStruct.eventInfo.nextEventTime < fmuStruct.currentTime;
\r
588 if (timeEvent) fmuStruct.currentTime = fmuStruct.eventInfo.nextEventTime;
\r
589 dt = fmuStruct.currentTime - tPre;
\r
590 fmiFlag = fmu.setTime(fmuStruct.c, fmuStruct.currentTime);
\r
591 if (fmiFlag > fmiWarning) throwException(env, "could not set time");
\r
593 if(referenceExists(fmuStruct, "time")) {
\r
594 vr = getReference(fmuStruct, "time");
\r
596 fmu.setReal(fmuStruct.c, &vr, 1, &(fmuStruct.currentTime));
\r
601 printf("Actual time: %lf\n", fmuStruct.currentTime);
\r
603 if (fmiFlag > fmiWarning)
\r
604 return throwException(env, "could not set time");
\r
606 // perform one step
\r
607 for (i=0; i<fmuStruct.nx; i++)
\r
608 fmuStruct.x[i] += dt*fmuStruct.xdot[i]; // forward Euler method
\r
610 fmiFlag = fmu.setContinuousStates(fmuStruct.c, fmuStruct.x, fmuStruct.nx);
\r
611 if (fmiFlag > fmiWarning)
\r
612 return throwException(env, "could not set states");
\r
614 // Check for step event, e.g. dynamic state selection
\r
615 fmiFlag = fmu.completedIntegratorStep(fmuStruct.c, &stepEvent);
\r
616 if (fmiFlag > fmiWarning) return throwException(env, "could not complete intgrator step");
\r
618 /* for (i=0; i<fmuStruct.nz; i++) fmuStruct.prez[i] = fmuStruct.z[i];
\r
619 fmiFlag = fmu.getEventIndicators(fmuStruct.c, fmuStruct.z, fmuStruct.nz);
\r
620 if (fmiFlag > fmiWarning) return throwException(env, "could not retrieve event indicators");
\r
621 stateEvent = FALSE;
\r
622 for (i=0; i<fmuStruct.nz; i++)
\r
623 stateEvent = stateEvent || (fmuStruct.prez[i] * fmuStruct.z[i] < 0);
\r
626 stepEvent = fmiTrue;
\r
628 if (timeEvent || stateEvent || stepEvent) {
\r
630 // event iteration in one step, ignoring intermediate results
\r
631 fmiFlag = fmu.eventUpdate(fmuStruct.c, fmiFalse, &(fmuStruct.eventInfo));
\r
632 if (fmiFlag > fmiWarning) return throwException(env, "could not perform event update");
\r
643 string message = fmuId;
\r
644 env->ReleaseStringUTFChars(id, fmuId);
\r
645 return throwException(env, "simulateStep: Model id " + message + " not found");
\r
650 JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_unloadFMU_1
\r
651 (JNIEnv *env, jobject obj, jint id) {
\r
653 int asd = FMI1_CS_UNLOAD(fmus[id].fmu);
\r
658 JNIEXPORT jstring JNICALL Java_org_simantics_fmil_FMIL_getLastErrorMessage_1
\r
659 (JNIEnv *env, jobject obj, jstring id) {
\r
660 return env->NewStringUTF("No errors");
\r
663 JNIEXPORT jdouble JNICALL Java_org_simantics_fmil_FMIL_getRealValue_1
\r
664 (JNIEnv *env, jobject obj, jint id, jint vr) {
\r
665 return FMI1_CS_GET_REAL(fmus[id].fmu, vr);
\r
668 JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_getIntegerValue_1
\r
669 (JNIEnv *env, jobject obj, jstring id, jstring variable) {
\r
671 const char *fmuId = env->GetStringUTFChars(id, 0);
\r
672 if(exists(fmuId)) {
\r
673 FMUControlStruct fmuStruct = fmus[fmuId];
\r
674 env->ReleaseStringUTFChars(id, fmuId);
\r
675 const char *name = env->GetStringUTFChars(variable, 0);
\r
677 if(referenceExists(fmuStruct, name)) {
\r
678 fmiValueReference vr = getReference(fmuStruct, name);
\r
680 fmuStruct.fmu.getInteger(fmuStruct.c, &vr, 1, &result);
\r
681 env->ReleaseStringUTFChars(variable, name);
\r
685 string nameString = name;
\r
686 string message = "Variable " + nameString + " not found";
\r
687 env->ReleaseStringUTFChars(variable, name);
\r
688 return throwException(env, message);
\r
692 string message = fmuId;
\r
693 env->ReleaseStringUTFChars(id, fmuId);
\r
694 return throwException(env, "unloadFMU: Model id " + message + " not found");
\r
701 JNIEXPORT jboolean JNICALL Java_org_simantics_fmil_FMIL_getBooleanValue_1
\r
702 (JNIEnv *env, jobject obj, jstring id, jstring variable) {
\r
704 const char *fmuId = env->GetStringUTFChars(id, 0);
\r
705 if(exists(fmuId)) {
\r
706 FMUControlStruct fmuStruct = fmus[fmuId];
\r
707 env->ReleaseStringUTFChars(id, fmuId);
\r
708 const char *name = env->GetStringUTFChars(variable, 0);
\r
710 if(referenceExists(fmuStruct, name)) {
\r
711 fmiValueReference vr = getReference(fmuStruct, name);
\r
713 fmuStruct.fmu.getBoolean(fmuStruct.c, &vr, 1, &result);
\r
714 env->ReleaseStringUTFChars(variable, name);
\r
718 string nameString = name;
\r
719 string message = "Variable " + nameString + " not found";
\r
720 env->ReleaseStringUTFChars(variable, name);
\r
721 return throwException(env, message);
\r
725 string message = fmuId;
\r
726 env->ReleaseStringUTFChars(id, fmuId);
\r
727 return throwException(env, "unloadFMU: Model id " + message + " not found");
\r
733 JNIEXPORT jstring JNICALL Java_org_simantics_fmil_FMIL_getStringValue_1
\r
734 (JNIEnv *env, jobject obj, jstring id, jstring variable) {
\r
736 const char *fmuId = env->GetStringUTFChars(id, 0);
\r
737 if(exists(fmuId)) {
\r
738 FMUControlStruct fmuStruct = fmus[fmuId];
\r
739 env->ReleaseStringUTFChars(id, fmuId);
\r
740 const char *name = env->GetStringUTFChars(variable, 0);
\r
742 if(referenceExists(fmuStruct, name)) {
\r
743 fmiValueReference vr = getReference(fmuStruct, name);
\r
745 fmuStruct.fmu.getString(fmuStruct.c, &vr, 1, &result);
\r
746 env->ReleaseStringUTFChars(variable, name);
\r
747 return env->NewStringUTF(result);
\r
750 string nameString = name;
\r
751 string message = "Variable " + nameString + " not found";
\r
752 env->ReleaseStringUTFChars(variable, name);
\r
753 return 0; //throwException(env, message);
\r
757 string message = fmuId;
\r
758 env->ReleaseStringUTFChars(id, fmuId);
\r
759 return 0; //throwException(env, "unloadFMU: Model id " + message + " not found");
\r