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<string> declaredTypes;
\r
46 vector<int> valueReferences;
\r
48 vector<int> variabilities;
\r
49 vector<int> causalities;
\r
51 vector<string> declaredTypeNames;
\r
52 vector<string> typeDescriptions;
\r
53 vector<string> quantities;
\r
54 vector<string> units;
\r
56 vector<int> subscription;
\r
62 struct FMUControlStruct {
\r
63 double step; // simulation step length
\r
64 fmiReal currentTime; // current simulation time
\r
66 fmiComponent c; // instance of the fmu
\r
67 ScalarVariable** vars; // model variables
\r
69 fmiEventInfo eventInfo; // updated by calls to initialize and eventUpdate
\r
70 const char* guid; // global unique id of the fmu
\r
71 fmiCallbackFunctions callbacks; // called by the model during simulation
\r
72 fmiStatus fmiFlag; // return code of the fmu functions
\r
74 map<string,int> indexes; // indexes for variable names in vars-table
\r
75 map<string,int>::iterator it;
\r
77 int nx; // number of state variables
\r
78 double *x; // continuous states
\r
79 double *xdot; // the crresponding derivatives in same order
\r
80 int nz; // number of state event indicators
\r
81 double *z; // state event indicators
\r
82 double *prez; // previous values of state event indicators
\r
84 bool initialized; // has the fmu been initialized
\r
86 vector<fmiValueReference> subscription; // result subscriptions
\r
87 vector<string> allVariables; // all variables in an initialized model
\r
88 vector<fmiValueReference> fmiValueReferences; // all value references
\r
90 string lastErrorMessage;
\r
97 //map<string,FMUControlStruct> fmus; // indexes for variable names in vars-table
\r
99 int throwException(JNIEnv *env, string message) {
\r
101 newExcCls = env->FindClass("java/lang/Exception");
\r
102 if (newExcCls == NULL) {
\r
103 /* Unable to find the exception class, give up. */
\r
106 env->ThrowNew(newExcCls, message.c_str());
\r
111 bool exists(string id) {
\r
112 map<string,FMUControlStruct>::iterator it = fmus.find(id);
\r
113 if(it != fmus.end()) {
\r
123 JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_loadFMUFile_1
\r
124 (JNIEnv *env, jobject obj, jstring path, jstring tempDir) {
\r
126 HMODULE module = NULL;
\r
128 FMIL_Variable *vars;
\r
129 FMIL_DeclaredType *types;
\r
130 int variableCount = 0;
\r
133 const char *fmuPath = env->GetStringUTFChars(path, 0);
\r
134 const char *fmuTempDir = env->GetStringUTFChars(tempDir, 0);
\r
136 fmi1.currentTime = 0;
\r
137 fmi1.timeStep = 0.1;
\r
138 fmi1.fmu = FMI1_CS_LOAD(fmuPath, fmuTempDir);
\r
140 return throwException(env, "No FMU loaded");
\r
142 vars = FMI1_CS_GET_VARIABLES(fmi1.fmu, &variableCount);
\r
143 for(int i=0;i<variableCount;i++) {
\r
144 fmi1.variables.push_back(string(vars[i].name));
\r
145 if(vars[i].description)
\r
146 fmi1.descriptions.push_back(string(vars[i].description));
\r
148 fmi1.descriptions.push_back(string(""));
\r
149 if(vars[i].declaredType)
\r
150 fmi1.declaredTypes.push_back(string(vars[i].declaredType));
\r
152 fmi1.declaredTypes.push_back(string(""));
\r
153 fmi1.types.push_back(vars[i].type);
\r
154 fmi1.causalities.push_back(vars[i].causality);
\r
155 fmi1.variabilities.push_back(vars[i].variability);
\r
156 fmi1.valueReferences.push_back(vars[i].vr);
\r
159 types = FMI1_CS_GET_DECLARED_TYPES(fmi1.fmu, &typeCount);
\r
160 for(int i=0;i<typeCount;i++) {
\r
161 fmi1.declaredTypeNames.push_back(string(types[i].name));
\r
162 if(types[i].description)
\r
163 fmi1.typeDescriptions.push_back(string(types[i].description));
\r
165 fmi1.typeDescriptions.push_back(string(""));
\r
166 if(types[i].quantity)
\r
167 fmi1.quantities.push_back(string(types[i].quantity));
\r
169 fmi1.quantities.push_back(string(""));
\r
171 fmi1.units.push_back(string(types[i].unit));
\r
173 fmi1.units.push_back(string(""));
\r
177 fmus.push_back(fmi1);
\r
179 env->ReleaseStringUTFChars(path, fmuPath);
\r
180 env->ReleaseStringUTFChars(tempDir, fmuTempDir);
\r
182 return fmus.size() - 1;
\r
186 JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_setStepLength_1
\r
187 (JNIEnv *env, jobject obj, jint id, jdouble stepLength) {
\r
188 fmus[id].timeStep = stepLength;
\r
192 JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_subscribe_1
\r
193 (JNIEnv *env, jobject obj, jint id, jintArray vrs) {
\r
196 jint* elements = env -> GetIntArrayElements(vrs, &isCopy);
\r
197 jsize n = env -> GetArrayLength(vrs);
\r
200 for (i = 0; i < n; i++) {
\r
201 fmus[id].subscription.push_back(elements[i]);
\r
204 if (isCopy == JNI_TRUE) {
\r
205 env -> ReleaseIntArrayElements(vrs, elements, 0);
\r
212 bool referenceExists(FMUControlStruct fmuStruct, string variable) {
\r
213 map<string,int>::iterator it = fmuStruct.indexes.find(variable);
\r
214 if(it != fmuStruct.indexes.end()) {
\r
221 // Remember to check if reference exists
\r
222 fmiValueReference getReference(FMUControlStruct fmuStruct, string variable) {
\r
223 return fmuStruct.fmiValueReferences[fmuStruct.indexes[variable]];
\r
226 // Get string representation of a scalar variable type
\r
227 string getTypeString(ScalarVariable* sv) {
\r
228 switch (sv->typeSpec->type){
\r
231 case elm_Enumeration:
\r
232 return "Enumeration";
\r
242 JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_setRealValue_1
\r
243 (JNIEnv *env, jobject obj, jint id, jint vr, jdouble value) {
\r
245 FMI1_CS_SET_REAL(fmus[id].fmu, vr, value);
\r
250 JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_setIntegerValue_1
\r
251 (JNIEnv *env, jobject obj, jstring id, jstring parameter, jint value) {
\r
253 const char *fmuId = env->GetStringUTFChars(id, 0);
\r
254 if(exists(fmuId)) {
\r
255 FMUControlStruct& fmuStruct = fmus[fmuId];
\r
256 const char *name = env->GetStringUTFChars(parameter, 0);
\r
257 string nameString = name;
\r
258 string modelId = fmuId;
\r
259 if(!referenceExists(fmuStruct, name)) {
\r
260 string errorMessage = "setIntegerValue: Model (id " + modelId + ") does not contain variable: " + nameString;
\r
261 env->ReleaseStringUTFChars(parameter, name);
\r
262 env->ReleaseStringUTFChars(id, fmuId);
\r
263 return throwException(env, errorMessage);
\r
265 // Check variable type
\r
266 ScalarVariable* sv = fmuStruct.vars[fmuStruct.indexes[name]];
\r
267 switch (sv->typeSpec->type){
\r
271 string errorMessage = "setIntegerValue: " + nameString + " is not of type Integer. (type: + " + getTypeString(sv) + ")";
\r
272 env->ReleaseStringUTFChars(parameter, name);
\r
273 env->ReleaseStringUTFChars(id, fmuId);
\r
274 return throwException(env, errorMessage);
\r
279 fmiValueReference vr = getReference(fmuStruct, name);
\r
280 const int intValue = (int) value;
\r
281 fmuStruct.fmu.setInteger(fmuStruct.c, &vr, 1, &intValue);
\r
282 env->ReleaseStringUTFChars(parameter, name);
\r
283 env->ReleaseStringUTFChars(id, fmuId);
\r
287 string message = fmuId;
\r
288 env->ReleaseStringUTFChars(id, fmuId);
\r
289 return throwException(env, "setIntegerValue: Model id " + message + " not found");
\r
295 JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_setBooleanValue_1
\r
296 (JNIEnv *env, jobject obj, jstring id, jstring parameter, jboolean value) {
\r
298 const char *fmuId = env->GetStringUTFChars(id, 0);
\r
299 if(exists(fmuId)) {
\r
300 FMUControlStruct& fmuStruct = fmus[fmuId];
\r
301 const char *name = env->GetStringUTFChars(parameter, 0);
\r
302 string nameString = name;
\r
303 string modelId = fmuId;
\r
304 if(!referenceExists(fmuStruct, name)) {
\r
305 string errorMessage = "setBooleanValue: Model (id " + modelId + ") does not contain variable: " + nameString;
\r
306 env->ReleaseStringUTFChars(parameter, name);
\r
307 env->ReleaseStringUTFChars(id, fmuId);
\r
308 return throwException(env, errorMessage);
\r
310 // Check variable type
\r
311 ScalarVariable* sv = fmuStruct.vars[fmuStruct.indexes[name]];
\r
312 switch (sv->typeSpec->type){
\r
316 string errorMessage = "setBooleanValue: " + nameString + " is not of type Boolean. (type: + " + getTypeString(sv) + ")";
\r
317 env->ReleaseStringUTFChars(parameter, name);
\r
318 env->ReleaseStringUTFChars(id, fmuId);
\r
319 return throwException(env, errorMessage);
\r
324 fmiValueReference vr = getReference(fmuStruct, name);
\r
325 fmiBoolean result = 1;
\r
328 fmuStruct.fmu.setBoolean(fmuStruct.c, &vr, 1, &result);
\r
329 env->ReleaseStringUTFChars(parameter, name);
\r
330 env->ReleaseStringUTFChars(id, fmuId);
\r
334 string message = fmuId;
\r
335 env->ReleaseStringUTFChars(id, fmuId);
\r
336 return throwException(env, "setBooleanValue: Model id " + message + " not found");
\r
341 JNIEXPORT jboolean JNICALL Java_org_simantics_fmil_FMIL_isInitialized_1
\r
342 (JNIEnv *env, jobject obj, jstring id) {
\r
344 const char *fmuId = env->GetStringUTFChars(id, 0);
\r
345 if(exists(fmuId)) {
\r
346 FMUControlStruct& fmuStruct = fmus[fmuId];
\r
347 env->ReleaseStringUTFChars(id, fmuId);
\r
348 return fmuStruct.initialized;
\r
350 env->ReleaseStringUTFChars(id, fmuId);
\r
358 JNIEXPORT jdouble JNICALL Java_org_simantics_fmil_FMIL_getTime_1
\r
359 (JNIEnv *env, jobject obj, jint id) {
\r
360 return fmus[id].currentTime;
\r
363 double getRealValue(FMUControlStruct fmuStruct, int index) {
\r
364 ScalarVariable *sv = fmuStruct.vars[index];
\r
365 fmiValueReference vr = fmuStruct.fmiValueReferences[index];
\r
367 fmiInteger integer;
\r
368 fmiBoolean fmibool;
\r
370 switch (sv->typeSpec->type){
\r
372 fmuStruct.fmu.getReal(fmuStruct.c, &vr, 1, &real);
\r
375 case elm_Enumeration:
\r
376 fmuStruct.fmu.getInteger(fmuStruct.c, &vr, 1, &integer);
\r
377 real = (double)integer;
\r
380 fmuStruct.fmu.getBoolean(fmuStruct.c, &vr, 1, &fmibool);
\r
381 if(fmibool == fmiTrue)
\r
390 JNIEXPORT jdoubleArray JNICALL Java_org_simantics_fmil_FMIL_getSubscribedResults_1
\r
391 (JNIEnv *env, jobject obj, jint id, jdoubleArray result) {
\r
394 jdouble* resultElements = env -> GetDoubleArrayElements(result, &isCopy);
\r
395 jsize n = env -> GetArrayLength(result);
\r
398 vrs = &(fmus[id].subscription[0]);
\r
399 FMI1_CS_GET_REALS(fmus[id].fmu, vrs, resultElements, n);
\r
401 if (isCopy == JNI_TRUE) {
\r
402 env -> ReleaseDoubleArrayElements(result, resultElements, 0);
\r
409 JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_instantiateSimulation_1
\r
410 (JNIEnv *env, jobject obj, jint id) {
\r
412 int asd = FMI1_CS_INSTANTIATE(fmus[id].fmu);
\r
414 return throwException(env, "No FMU loaded");
\r
420 JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_initializeSimulation_1
\r
421 (JNIEnv *env, jobject obj, jint id) {
\r
423 int asd = FMI1_CS_INITIALIZE(fmus[id].fmu);
\r
425 return throwException(env, "No FMU loaded");
\r
431 JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_setTime_1
\r
432 (JNIEnv *env, jobject obj, jstring id, jdouble time) {
\r
436 JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariables_1
\r
437 (JNIEnv *env, jobject obj, jint id) {
\r
439 jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].variables.size(),
\r
440 env->FindClass("java/lang/String"),
\r
441 env->NewStringUTF(""));
\r
443 for(int i=0;i<fmus[id].variables.size();i++) {
\r
444 env->SetObjectArrayElement(ret,i,env->NewStringUTF(fmus[id].variables[i].c_str()));
\r
451 JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariableDescriptions_1
\r
452 (JNIEnv *env, jobject obj, jint id) {
\r
454 jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].descriptions.size(),
\r
455 env->FindClass("java/lang/String"),
\r
456 env->NewStringUTF(""));
\r
458 for(int i=0;i<fmus[id].descriptions.size();i++) {
\r
459 env->SetObjectArrayElement(ret,i,env->NewStringUTF(fmus[id].descriptions[i].c_str()));
\r
466 JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariableDeclaredTypes_1
\r
467 (JNIEnv *env, jobject obj, jint id) {
\r
469 jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].declaredTypes.size(),
\r
470 env->FindClass("java/lang/String"),
\r
471 env->NewStringUTF(""));
\r
473 for(int i=0;i<fmus[id].declaredTypes.size();i++) {
\r
474 env->SetObjectArrayElement(ret,i,env->NewStringUTF(fmus[id].declaredTypes[i].c_str()));
\r
481 JNIEXPORT jintArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariableReferences_1
\r
482 (JNIEnv *env, jobject obj, jint id, jintArray result) {
\r
485 jint* resultElements = env -> GetIntArrayElements(result, &isCopy);
\r
486 jsize n = env -> GetArrayLength(result);
\r
489 for (i = 0; i < n; i++) {
\r
490 resultElements[i] = fmus[id].valueReferences[i];
\r
493 if (isCopy == JNI_TRUE) {
\r
494 env -> ReleaseIntArrayElements(result, resultElements, 0);
\r
501 JNIEXPORT jintArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariableTypes_1
\r
502 (JNIEnv *env, jobject obj, jint id, jintArray result) {
\r
505 jint* resultElements = env -> GetIntArrayElements(result, &isCopy);
\r
506 jsize n = env -> GetArrayLength(result);
\r
509 for (i = 0; i < n; i++) {
\r
510 resultElements[i] = fmus[id].types[i];
\r
513 if (isCopy == JNI_TRUE) {
\r
514 env -> ReleaseIntArrayElements(result, resultElements, 0);
\r
521 JNIEXPORT jintArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariableVariabilities_1
\r
522 (JNIEnv *env, jobject obj, jint id, jintArray result) {
\r
525 jint* resultElements = env -> GetIntArrayElements(result, &isCopy);
\r
526 jsize n = env -> GetArrayLength(result);
\r
529 for (i = 0; i < n; i++) {
\r
530 resultElements[i] = fmus[id].variabilities[i];
\r
533 if (isCopy == JNI_TRUE) {
\r
534 env -> ReleaseIntArrayElements(result, resultElements, 0);
\r
541 JNIEXPORT jintArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariableCausalities_1
\r
542 (JNIEnv *env, jobject obj, jint id, jintArray result) {
\r
545 jint* resultElements = env -> GetIntArrayElements(result, &isCopy);
\r
546 jsize n = env -> GetArrayLength(result);
\r
549 for (i = 0; i < n; i++) {
\r
550 resultElements[i] = fmus[id].causalities[i];
\r
553 if (isCopy == JNI_TRUE) {
\r
554 env -> ReleaseIntArrayElements(result, resultElements, 0);
\r
561 JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_getAllDeclaredTypes_1
\r
562 (JNIEnv *env, jobject obj, jint id) {
\r
564 jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].declaredTypeNames.size(),
\r
565 env->FindClass("java/lang/String"),
\r
566 env->NewStringUTF(""));
\r
568 for(int i=0;i<fmus[id].declaredTypeNames.size();i++) {
\r
569 env->SetObjectArrayElement(ret,i,env->NewStringUTF(fmus[id].declaredTypeNames[i].c_str()));
\r
576 JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_getAllDeclaredTypeDescriptions_1
\r
577 (JNIEnv *env, jobject obj, jint id) {
\r
579 jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].typeDescriptions.size(),
\r
580 env->FindClass("java/lang/String"),
\r
581 env->NewStringUTF(""));
\r
583 for(int i=0;i<fmus[id].typeDescriptions.size();i++) {
\r
584 env->SetObjectArrayElement(ret,i,env->NewStringUTF(fmus[id].typeDescriptions[i].c_str()));
\r
591 JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_getAllDeclaredTypeQuantities_1
\r
592 (JNIEnv *env, jobject obj, jint id) {
\r
594 jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].quantities.size(),
\r
595 env->FindClass("java/lang/String"),
\r
596 env->NewStringUTF(""));
\r
598 for(int i=0;i<fmus[id].quantities.size();i++) {
\r
599 env->SetObjectArrayElement(ret,i,env->NewStringUTF(fmus[id].quantities[i].c_str()));
\r
606 JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_getAllDeclaredTypeUnits_1
\r
607 (JNIEnv *env, jobject obj, jint id) {
\r
609 jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].units.size(),
\r
610 env->FindClass("java/lang/String"),
\r
611 env->NewStringUTF(""));
\r
613 for(int i=0;i<fmus[id].units.size();i++) {
\r
614 env->SetObjectArrayElement(ret,i,env->NewStringUTF(fmus[id].units[i].c_str()));
\r
622 JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_filterVariables_1
\r
623 (JNIEnv *env, jobject obj, jstring id, jstring regexp) {
\r
624 const char *rx = env->GetStringUTFChars(regexp, 0);
\r
625 jobjectArray result = filterVariables(env, obj, id, rx);
\r
626 env->ReleaseStringUTFChars(regexp, rx);
\r
631 JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_simulateStep_1
\r
632 (JNIEnv *env, jobject obj, jint id) {
\r
634 int asd = FMI1_CS_STEP(fmus[id].fmu, fmus[id].currentTime, fmus[id].timeStep);
\r
636 return throwException(env, "No FMU loaded");
\r
638 fmus[id].currentTime += fmus[id].timeStep;
\r
643 const char *fmuId = env->GetStringUTFChars(id, 0);
\r
644 if(exists(fmuId)) {
\r
645 FMUControlStruct& fmuStruct = fmus[fmuId];
\r
646 env->ReleaseStringUTFChars(id, fmuId);
\r
648 if(&fmuStruct.fmu == NULL || fmuStruct.fmu.modelDescription == NULL || &fmuStruct.vars == NULL) {
\r
649 return throwException(env, "Simulate step failed - fmu not loaded");
\r
652 if(fmuStruct.x == NULL) {
\r
653 return throwException(env, "Simulate step failed - fmu not instantiated");
\r
656 if(fmuStruct.initialized == false) {
\r
657 fmiBoolean toleranceControlled = fmiFalse;
\r
658 fmuStruct.fmiFlag = fmuStruct.fmu.initialize(fmuStruct.c, toleranceControlled, fmuStruct.currentTime, &(fmuStruct.eventInfo));
\r
659 if (fmuStruct.fmiFlag > fmiWarning) return throwException(env, "could not initialize model");
\r
660 fmuStruct.initialized = true;
\r
663 FMU& fmu = fmuStruct.fmu;
\r
664 int debug = 0; // DEBUG ON = 1, OFF = 0
\r
667 double dt, tPre, tEnd = fmuStruct.currentTime + fmuStruct.step;
\r
669 fmiBoolean timeEvent, stateEvent, stepEvent;
\r
670 fmiStatus fmiFlag; // return code of the fmu functions
\r
671 fmiValueReference vr;
\r
675 /* Simulate the duration of one step. The simulation may be done in
\r
676 * multiple parts if events occur
\r
678 while (fmuStruct.currentTime < tEnd) {
\r
679 // get current state and derivatives
\r
680 fmiFlag = fmu.getContinuousStates(fmuStruct.c, fmuStruct.x, fmuStruct.nx);
\r
681 if (fmiFlag > fmiWarning)
\r
682 return throwException(env, "could not retrieve states");
\r
684 fmiFlag = fmu.getDerivatives(fmuStruct.c, fmuStruct.xdot, fmuStruct.nx);
\r
685 if (fmiFlag > fmiWarning)
\r
686 return throwException(env, "could not retrieve derivatives");
\r
689 tPre = fmuStruct.currentTime;
\r
690 fmuStruct.currentTime = min(fmuStruct.currentTime+fmuStruct.step, tEnd);
\r
691 timeEvent = fmuStruct.eventInfo.upcomingTimeEvent && fmuStruct.eventInfo.nextEventTime < fmuStruct.currentTime;
\r
693 if (timeEvent) fmuStruct.currentTime = fmuStruct.eventInfo.nextEventTime;
\r
694 dt = fmuStruct.currentTime - tPre;
\r
695 fmiFlag = fmu.setTime(fmuStruct.c, fmuStruct.currentTime);
\r
696 if (fmiFlag > fmiWarning) throwException(env, "could not set time");
\r
698 if(referenceExists(fmuStruct, "time")) {
\r
699 vr = getReference(fmuStruct, "time");
\r
701 fmu.setReal(fmuStruct.c, &vr, 1, &(fmuStruct.currentTime));
\r
706 printf("Actual time: %lf\n", fmuStruct.currentTime);
\r
708 if (fmiFlag > fmiWarning)
\r
709 return throwException(env, "could not set time");
\r
711 // perform one step
\r
712 for (i=0; i<fmuStruct.nx; i++)
\r
713 fmuStruct.x[i] += dt*fmuStruct.xdot[i]; // forward Euler method
\r
715 fmiFlag = fmu.setContinuousStates(fmuStruct.c, fmuStruct.x, fmuStruct.nx);
\r
716 if (fmiFlag > fmiWarning)
\r
717 return throwException(env, "could not set states");
\r
719 // Check for step event, e.g. dynamic state selection
\r
720 fmiFlag = fmu.completedIntegratorStep(fmuStruct.c, &stepEvent);
\r
721 if (fmiFlag > fmiWarning) return throwException(env, "could not complete intgrator step");
\r
723 /* for (i=0; i<fmuStruct.nz; i++) fmuStruct.prez[i] = fmuStruct.z[i];
\r
724 fmiFlag = fmu.getEventIndicators(fmuStruct.c, fmuStruct.z, fmuStruct.nz);
\r
725 if (fmiFlag > fmiWarning) return throwException(env, "could not retrieve event indicators");
\r
726 stateEvent = FALSE;
\r
727 for (i=0; i<fmuStruct.nz; i++)
\r
728 stateEvent = stateEvent || (fmuStruct.prez[i] * fmuStruct.z[i] < 0);
\r
731 stepEvent = fmiTrue;
\r
733 if (timeEvent || stateEvent || stepEvent) {
\r
735 // event iteration in one step, ignoring intermediate results
\r
736 fmiFlag = fmu.eventUpdate(fmuStruct.c, fmiFalse, &(fmuStruct.eventInfo));
\r
737 if (fmiFlag > fmiWarning) return throwException(env, "could not perform event update");
\r
748 string message = fmuId;
\r
749 env->ReleaseStringUTFChars(id, fmuId);
\r
750 return throwException(env, "simulateStep: Model id " + message + " not found");
\r
755 JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_unloadFMU_1
\r
756 (JNIEnv *env, jobject obj, jint id) {
\r
758 int asd = FMI1_CS_UNLOAD(fmus[id].fmu);
\r
763 JNIEXPORT jstring JNICALL Java_org_simantics_fmil_FMIL_getLastErrorMessage_1
\r
764 (JNIEnv *env, jobject obj, jstring id) {
\r
765 return env->NewStringUTF("No errors");
\r
768 JNIEXPORT jdouble JNICALL Java_org_simantics_fmil_FMIL_getRealValue_1
\r
769 (JNIEnv *env, jobject obj, jint id, jint vr) {
\r
770 return FMI1_CS_GET_REAL(fmus[id].fmu, vr);
\r
773 JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_getIntegerValue_1
\r
774 (JNIEnv *env, jobject obj, jstring id, jstring variable) {
\r
776 const char *fmuId = env->GetStringUTFChars(id, 0);
\r
777 if(exists(fmuId)) {
\r
778 FMUControlStruct fmuStruct = fmus[fmuId];
\r
779 env->ReleaseStringUTFChars(id, fmuId);
\r
780 const char *name = env->GetStringUTFChars(variable, 0);
\r
782 if(referenceExists(fmuStruct, name)) {
\r
783 fmiValueReference vr = getReference(fmuStruct, name);
\r
785 fmuStruct.fmu.getInteger(fmuStruct.c, &vr, 1, &result);
\r
786 env->ReleaseStringUTFChars(variable, name);
\r
790 string nameString = name;
\r
791 string message = "Variable " + nameString + " not found";
\r
792 env->ReleaseStringUTFChars(variable, name);
\r
793 return throwException(env, message);
\r
797 string message = fmuId;
\r
798 env->ReleaseStringUTFChars(id, fmuId);
\r
799 return throwException(env, "unloadFMU: Model id " + message + " not found");
\r
806 JNIEXPORT jboolean JNICALL Java_org_simantics_fmil_FMIL_getBooleanValue_1
\r
807 (JNIEnv *env, jobject obj, jstring id, jstring variable) {
\r
809 const char *fmuId = env->GetStringUTFChars(id, 0);
\r
810 if(exists(fmuId)) {
\r
811 FMUControlStruct fmuStruct = fmus[fmuId];
\r
812 env->ReleaseStringUTFChars(id, fmuId);
\r
813 const char *name = env->GetStringUTFChars(variable, 0);
\r
815 if(referenceExists(fmuStruct, name)) {
\r
816 fmiValueReference vr = getReference(fmuStruct, name);
\r
818 fmuStruct.fmu.getBoolean(fmuStruct.c, &vr, 1, &result);
\r
819 env->ReleaseStringUTFChars(variable, name);
\r
823 string nameString = name;
\r
824 string message = "Variable " + nameString + " not found";
\r
825 env->ReleaseStringUTFChars(variable, name);
\r
826 return throwException(env, message);
\r
830 string message = fmuId;
\r
831 env->ReleaseStringUTFChars(id, fmuId);
\r
832 return throwException(env, "unloadFMU: Model id " + message + " not found");
\r
838 JNIEXPORT jstring JNICALL Java_org_simantics_fmil_FMIL_getStringValue_1
\r
839 (JNIEnv *env, jobject obj, jstring id, jstring variable) {
\r
841 const char *fmuId = env->GetStringUTFChars(id, 0);
\r
842 if(exists(fmuId)) {
\r
843 FMUControlStruct fmuStruct = fmus[fmuId];
\r
844 env->ReleaseStringUTFChars(id, fmuId);
\r
845 const char *name = env->GetStringUTFChars(variable, 0);
\r
847 if(referenceExists(fmuStruct, name)) {
\r
848 fmiValueReference vr = getReference(fmuStruct, name);
\r
850 fmuStruct.fmu.getString(fmuStruct.c, &vr, 1, &result);
\r
851 env->ReleaseStringUTFChars(variable, name);
\r
852 return env->NewStringUTF(result);
\r
855 string nameString = name;
\r
856 string message = "Variable " + nameString + " not found";
\r
857 env->ReleaseStringUTFChars(variable, name);
\r
858 return 0; //throwException(env, message);
\r
862 string message = fmuId;
\r
863 env->ReleaseStringUTFChars(id, fmuId);
\r
864 return 0; //throwException(env, "unloadFMU: Model id " + message + " not found");
\r