]> gerrit.simantics Code Review - simantics/fmil.git/blob - org.simantics.fmil.core/native/FMUSimulator/src/fmu_control.cpp
Mavenized FMIL projects.
[simantics/fmil.git] / org.simantics.fmil.core / native / FMUSimulator / src / fmu_control.cpp
1 /* ------------------------------------------------------------------------- \r
2  * fmu_control.c\r
3  * Simulation controls for fmus\r
4  *\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
12  */\r
13 \r
14 #include <stdlib.h>\r
15 #include <stdio.h>\r
16 #include <string.h>\r
17 #include <map>\r
18 #include <string>\r
19 #include <vector>\r
20 #include <iostream>\r
21 #include <regex>\r
22 \r
23 #include <org_simantics_fmil_FMILJNI.h>\r
24 \r
25 extern "C" {\r
26         #include "fmi_me.h"\r
27         #include "sim_support.h"\r
28 }\r
29 \r
30 #include "fmi1_cs.h"\r
31 \r
32 #define PRINT(fmt,args) { FILE *fp = fopen("R:\\Simantics\\Sysdyn\\log.txt", "ab"); fprintf(fp, fmt, args); fclose(fp); }\r
33 \r
34 #include <direct.h>\r
35 #define GetCurrentDir _getcwd\r
36 \r
37 using namespace std;\r
38 \r
39 struct FMI1 {\r
40 \r
41         void *fmu;\r
42 \r
43         vector<string> variables;\r
44         vector<string> descriptions;\r
45         vector<string> declaredTypes;\r
46         vector<int> valueReferences;\r
47         vector<int> types;\r
48         vector<int> variabilities;\r
49         vector<int> causalities;\r
50 \r
51         vector<string> declaredTypeNames;\r
52         vector<string> typeDescriptions;\r
53         vector<string> quantities;\r
54         vector<string> units;\r
55 \r
56         vector<int> subscription;\r
57         double currentTime;\r
58         double timeStep;\r
59 \r
60 };\r
61 \r
62 struct FMUControlStruct {\r
63         double step;                                    // simulation step length\r
64         fmiReal currentTime;                    // current simulation time\r
65 \r
66         fmiComponent c;                                 // instance of the fmu \r
67         ScalarVariable** vars;                  // model variables\r
68 \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
73 \r
74         map<string,int> indexes;                // indexes for variable names in vars-table\r
75         map<string,int>::iterator it;\r
76 \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
83         \r
84         bool initialized;                               // has the fmu been initialized\r
85 \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
89 \r
90         string lastErrorMessage;\r
91 \r
92         FMU fmu;\r
93 };\r
94 \r
95 vector<FMI1> fmus;\r
96 \r
97 //map<string,FMUControlStruct> fmus;            // indexes for variable names in vars-table\r
98 \r
99 int throwException(JNIEnv *env, string message) {\r
100         jclass newExcCls;\r
101     newExcCls = env->FindClass("java/lang/Exception");\r
102     if (newExcCls == NULL) {\r
103         /* Unable to find the exception class, give up. */\r
104         return 0;\r
105     }\r
106         env->ThrowNew(newExcCls, message.c_str());\r
107         return 0;\r
108 }\r
109 \r
110 /*\r
111 bool exists(string id) {\r
112         map<string,FMUControlStruct>::iterator it = fmus.find(id);\r
113         if(it != fmus.end()) {\r
114                 return true;\r
115         } else {\r
116                 return false;\r
117         }\r
118 }\r
119 */\r
120 \r
121 \r
122 \r
123 JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_loadFMUFile_1 \r
124         (JNIEnv *env, jobject obj, jstring path, jstring tempDir) {\r
125 \r
126         HMODULE module = NULL;\r
127         FMI1 fmi1;\r
128         FMIL_Variable *vars;\r
129         FMIL_DeclaredType *types;\r
130         int variableCount = 0;\r
131         int typeCount = 0;\r
132 \r
133     const char *fmuPath = env->GetStringUTFChars(path, 0);\r
134         const char *fmuTempDir = env->GetStringUTFChars(tempDir, 0);\r
135 \r
136         fmi1.currentTime = 0;\r
137         fmi1.timeStep = 0.1;\r
138         fmi1.fmu = FMI1_CS_LOAD(fmuPath, fmuTempDir);\r
139         if(!fmi1.fmu)\r
140           return throwException(env, "No FMU loaded");\r
141 \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
147            else\r
148                         fmi1.descriptions.push_back(string(""));\r
149            if(vars[i].declaredType)\r
150                         fmi1.declaredTypes.push_back(string(vars[i].declaredType));\r
151            else\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
157    }\r
158 \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
164            else\r
165                         fmi1.typeDescriptions.push_back(string(""));\r
166            if(types[i].quantity)\r
167                         fmi1.quantities.push_back(string(types[i].quantity));\r
168            else\r
169                         fmi1.quantities.push_back(string(""));\r
170            if(types[i].unit)\r
171                         fmi1.units.push_back(string(types[i].unit));\r
172            else\r
173                         fmi1.units.push_back(string(""));\r
174    }\r
175 \r
176 \r
177    fmus.push_back(fmi1);\r
178 \r
179         env->ReleaseStringUTFChars(path, fmuPath);\r
180         env->ReleaseStringUTFChars(tempDir, fmuTempDir);\r
181 \r
182         return fmus.size() - 1;\r
183 \r
184 }\r
185 \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
189         return 1;\r
190 }\r
191 \r
192 JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_subscribe_1\r
193   (JNIEnv *env, jobject obj, jint id, jintArray vrs) {\r
194 \r
195         jboolean isCopy;\r
196         jint* elements = env -> GetIntArrayElements(vrs, &isCopy);\r
197         jsize n = env -> GetArrayLength(vrs);\r
198 \r
199         int i;\r
200         for (i = 0; i < n; i++) {\r
201                 fmus[id].subscription.push_back(elements[i]);\r
202         } \r
203           \r
204         if (isCopy == JNI_TRUE) {\r
205                 env -> ReleaseIntArrayElements(vrs, elements, 0);\r
206         }\r
207 \r
208         return 1;\r
209 \r
210 }\r
211 \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
215                 return true;\r
216         } else {\r
217                 return false;\r
218         }\r
219 }\r
220 \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
224 }\r
225 \r
226 // Get string representation of a scalar variable type\r
227 string getTypeString(ScalarVariable* sv) {\r
228         switch (sv->typeSpec->type){\r
229                 case elm_Integer:\r
230                         return "Integer";\r
231                 case elm_Enumeration:\r
232                         return "Enumeration";\r
233                 case elm_Real:\r
234                         return "Real";\r
235                 case elm_Boolean:\r
236                         return "Boolean";\r
237                 default:\r
238                         return "No type";\r
239         }\r
240 }\r
241 \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
244 \r
245           FMI1_CS_SET_REAL(fmus[id].fmu, vr, value);\r
246           return 1;\r
247 \r
248 }\r
249 \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
252           /*\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
264                 } else {\r
265                         // Check variable type\r
266                         ScalarVariable* sv = fmuStruct.vars[fmuStruct.indexes[name]];\r
267                         switch (sv->typeSpec->type){\r
268                                 case elm_Integer:\r
269                                         break; // ok\r
270                                 default: {\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
275                                 }\r
276                         }\r
277 \r
278                         // Change value\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
284                         return 1;\r
285                 }\r
286         }  else {\r
287                 string message = fmuId;\r
288                 env->ReleaseStringUTFChars(id, fmuId);\r
289                 return throwException(env, "setIntegerValue: Model id " + message + " not found");\r
290         }\r
291         */\r
292           return 1;\r
293 }\r
294 \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
297           /*\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
309                 } else {\r
310                         // Check variable type\r
311                         ScalarVariable* sv = fmuStruct.vars[fmuStruct.indexes[name]];\r
312                         switch (sv->typeSpec->type){\r
313                                 case elm_Boolean:\r
314                                         break; // ok\r
315                                 default: {\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
320                                 }\r
321                         }\r
322 \r
323                         // Change value\r
324                         fmiValueReference vr = getReference(fmuStruct, name);\r
325                         fmiBoolean result = 1;\r
326                         if(value == 0)\r
327                                 result = 0;\r
328                         fmuStruct.fmu.setBoolean(fmuStruct.c, &vr, 1, &result);\r
329                         env->ReleaseStringUTFChars(parameter, name);\r
330                         env->ReleaseStringUTFChars(id, fmuId);\r
331                         return 1;\r
332                 }\r
333         }  else {\r
334                 string message = fmuId;\r
335                 env->ReleaseStringUTFChars(id, fmuId);\r
336                 return throwException(env, "setBooleanValue: Model id " + message + " not found");\r
337         }*/\r
338           return 1;\r
339 }\r
340 \r
341 JNIEXPORT jboolean JNICALL Java_org_simantics_fmil_FMIL_isInitialized_1\r
342   (JNIEnv *env, jobject obj, jstring id) {\r
343           /*\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
349         } else {\r
350                 env->ReleaseStringUTFChars(id, fmuId);\r
351                 return false;\r
352         }\r
353         */\r
354           return 1;\r
355 }\r
356 \r
357 \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
361 }\r
362 \r
363 double getRealValue(FMUControlStruct fmuStruct, int index) {\r
364         ScalarVariable *sv = fmuStruct.vars[index];\r
365         fmiValueReference vr = fmuStruct.fmiValueReferences[index];\r
366         double real;\r
367         fmiInteger integer;\r
368         fmiBoolean fmibool;\r
369 \r
370         switch (sv->typeSpec->type){\r
371         case elm_Real:\r
372                         fmuStruct.fmu.getReal(fmuStruct.c, &vr, 1, &real);\r
373             break;\r
374         case elm_Integer:\r
375         case elm_Enumeration:\r
376             fmuStruct.fmu.getInteger(fmuStruct.c, &vr, 1, &integer);\r
377                         real = (double)integer;\r
378             break;\r
379         case elm_Boolean:\r
380             fmuStruct.fmu.getBoolean(fmuStruct.c, &vr, 1, &fmibool);\r
381                         if(fmibool == fmiTrue)\r
382                                 real = 1.0;\r
383                         else\r
384                                 real = 0.0;\r
385             break;\r
386         }\r
387         return real;\r
388 }\r
389 \r
390 JNIEXPORT jdoubleArray JNICALL Java_org_simantics_fmil_FMIL_getSubscribedResults_1\r
391   (JNIEnv *env, jobject obj, jint id, jdoubleArray result) {\r
392 \r
393         jboolean isCopy;\r
394         jdouble* resultElements = env -> GetDoubleArrayElements(result, &isCopy);\r
395         jsize n = env -> GetArrayLength(result);\r
396         int *vrs;\r
397         if(n > 0) {\r
398                 vrs = &(fmus[id].subscription[0]);\r
399                 FMI1_CS_GET_REALS(fmus[id].fmu, vrs, resultElements, n);\r
400         }\r
401         if (isCopy == JNI_TRUE) {\r
402                 env -> ReleaseDoubleArrayElements(result, resultElements, 0);\r
403         }\r
404 \r
405         return result;\r
406         \r
407 }\r
408 \r
409 JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_instantiateSimulation_1\r
410   (JNIEnv *env, jobject obj, jint id) {\r
411 \r
412           int asd = FMI1_CS_INSTANTIATE(fmus[id].fmu);\r
413           if(asd != 0)\r
414                 return throwException(env, "No FMU loaded");\r
415 \r
416           return 1;\r
417 \r
418 }\r
419 \r
420 JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_initializeSimulation_1\r
421   (JNIEnv *env, jobject obj, jint id) {\r
422 \r
423           int asd = FMI1_CS_INITIALIZE(fmus[id].fmu);\r
424           if(asd != 0)\r
425                 return throwException(env, "No FMU loaded");\r
426 \r
427           return 1;\r
428 \r
429 }\r
430 \r
431 JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_setTime_1\r
432   (JNIEnv *env, jobject obj, jstring id, jdouble time) {\r
433           return 1;\r
434 }\r
435 \r
436 JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariables_1\r
437   (JNIEnv *env, jobject obj, jint id) {\r
438 \r
439         jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].variables.size(),  \r
440                         env->FindClass("java/lang/String"),  \r
441                         env->NewStringUTF(""));  \r
442    \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
445         }  \r
446 \r
447         return ret;  \r
448 \r
449 }\r
450 \r
451 JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariableDescriptions_1\r
452   (JNIEnv *env, jobject obj, jint id) {\r
453 \r
454         jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].descriptions.size(),  \r
455                         env->FindClass("java/lang/String"),  \r
456                         env->NewStringUTF(""));  \r
457    \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
460         }  \r
461 \r
462         return ret;  \r
463 \r
464 }\r
465 \r
466 JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariableDeclaredTypes_1\r
467   (JNIEnv *env, jobject obj, jint id) {\r
468 \r
469         jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].declaredTypes.size(),  \r
470                         env->FindClass("java/lang/String"),  \r
471                         env->NewStringUTF(""));\r
472    \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
475         }  \r
476 \r
477         return ret;  \r
478 \r
479 }\r
480 \r
481 JNIEXPORT jintArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariableReferences_1\r
482   (JNIEnv *env, jobject obj, jint id, jintArray result) {\r
483 \r
484         jboolean isCopy;\r
485         jint* resultElements = env -> GetIntArrayElements(result, &isCopy);\r
486         jsize n = env -> GetArrayLength(result);\r
487 \r
488         int i;\r
489         for (i = 0; i < n; i++) {\r
490                 resultElements[i] = fmus[id].valueReferences[i];\r
491         } \r
492           \r
493         if (isCopy == JNI_TRUE) {\r
494                 env -> ReleaseIntArrayElements(result, resultElements, 0);\r
495         }\r
496 \r
497         return result;\r
498 \r
499 }\r
500 \r
501 JNIEXPORT jintArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariableTypes_1\r
502   (JNIEnv *env, jobject obj, jint id, jintArray result) {\r
503 \r
504         jboolean isCopy;\r
505         jint* resultElements = env -> GetIntArrayElements(result, &isCopy);\r
506         jsize n = env -> GetArrayLength(result);\r
507 \r
508         int i;\r
509         for (i = 0; i < n; i++) {\r
510                 resultElements[i] = fmus[id].types[i];\r
511         } \r
512           \r
513         if (isCopy == JNI_TRUE) {\r
514                 env -> ReleaseIntArrayElements(result, resultElements, 0);\r
515         }\r
516 \r
517         return result;\r
518 \r
519 }\r
520 \r
521 JNIEXPORT jintArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariableVariabilities_1\r
522   (JNIEnv *env, jobject obj, jint id, jintArray result) {\r
523 \r
524         jboolean isCopy;\r
525         jint* resultElements = env -> GetIntArrayElements(result, &isCopy);\r
526         jsize n = env -> GetArrayLength(result);\r
527 \r
528         int i;\r
529         for (i = 0; i < n; i++) {\r
530                 resultElements[i] = fmus[id].variabilities[i];\r
531         } \r
532           \r
533         if (isCopy == JNI_TRUE) {\r
534                 env -> ReleaseIntArrayElements(result, resultElements, 0);\r
535         }\r
536 \r
537         return result;\r
538 \r
539 }\r
540 \r
541 JNIEXPORT jintArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariableCausalities_1\r
542   (JNIEnv *env, jobject obj, jint id, jintArray result) {\r
543 \r
544         jboolean isCopy;\r
545         jint* resultElements = env -> GetIntArrayElements(result, &isCopy);\r
546         jsize n = env -> GetArrayLength(result);\r
547 \r
548         int i;\r
549         for (i = 0; i < n; i++) {\r
550                 resultElements[i] = fmus[id].causalities[i];\r
551         } \r
552           \r
553         if (isCopy == JNI_TRUE) {\r
554                 env -> ReleaseIntArrayElements(result, resultElements, 0);\r
555         }\r
556 \r
557         return result;\r
558 \r
559 }\r
560 \r
561 JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_getAllDeclaredTypes_1\r
562   (JNIEnv *env, jobject obj, jint id) {\r
563 \r
564         jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].declaredTypeNames.size(),  \r
565                         env->FindClass("java/lang/String"),  \r
566                         env->NewStringUTF(""));\r
567    \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
570         }  \r
571 \r
572         return ret;  \r
573 \r
574 }\r
575 \r
576 JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_getAllDeclaredTypeDescriptions_1\r
577   (JNIEnv *env, jobject obj, jint id) {\r
578 \r
579         jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].typeDescriptions.size(),  \r
580                         env->FindClass("java/lang/String"),  \r
581                         env->NewStringUTF(""));\r
582    \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
585         }  \r
586 \r
587         return ret;  \r
588 \r
589 }\r
590 \r
591 JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_getAllDeclaredTypeQuantities_1\r
592   (JNIEnv *env, jobject obj, jint id) {\r
593 \r
594         jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].quantities.size(),  \r
595                         env->FindClass("java/lang/String"),  \r
596                         env->NewStringUTF(""));\r
597    \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
600         }  \r
601 \r
602         return ret;  \r
603 \r
604 }\r
605 \r
606 JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_getAllDeclaredTypeUnits_1\r
607   (JNIEnv *env, jobject obj, jint id) {\r
608 \r
609         jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].units.size(),  \r
610                         env->FindClass("java/lang/String"),  \r
611                         env->NewStringUTF(""));\r
612    \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
615         }  \r
616 \r
617         return ret;  \r
618 \r
619 }\r
620 \r
621 /*\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
627          return result;\r
628 }\r
629 */\r
630 \r
631 JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_simulateStep_1\r
632   (JNIEnv *env, jobject obj, jint id) {\r
633 \r
634           int asd = FMI1_CS_STEP(fmus[id].fmu, fmus[id].currentTime, fmus[id].timeStep);\r
635           if(asd != 0)\r
636                 return throwException(env, "No FMU loaded");\r
637 \r
638           fmus[id].currentTime += fmus[id].timeStep;\r
639 \r
640           return 1;\r
641 \r
642           /*\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
647 \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
650                 }\r
651 \r
652                 if(fmuStruct.x == NULL) {\r
653                         return throwException(env, "Simulate step failed - fmu not instantiated");\r
654                 }\r
655 \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
661                 }\r
662 \r
663                 FMU& fmu = fmuStruct.fmu;\r
664                 int debug = 0; // DEBUG ON = 1, OFF = 0\r
665 \r
666                 int i;\r
667                 double dt, tPre, tEnd = fmuStruct.currentTime + fmuStruct.step;\r
668 \r
669                 fmiBoolean timeEvent, stateEvent, stepEvent;\r
670                 fmiStatus fmiFlag;                      // return code of the fmu functions\r
671                 fmiValueReference vr;\r
672 \r
673 \r
674                 */\r
675                 /* Simulate the duration of one step. The simulation may be done in \r
676                  * multiple parts if events occur\r
677                  */ /*\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
683 \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
687 \r
688                          // advance time\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
692                 \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
697 \r
698                         if(referenceExists(fmuStruct, "time")) {\r
699                                 vr = getReference(fmuStruct, "time");\r
700                                 if(vr != NULL) {\r
701                                         fmu.setReal(fmuStruct.c, &vr, 1, &(fmuStruct.currentTime));\r
702                                 }\r
703                         }\r
704 \r
705                         if(debug)\r
706                                 printf("Actual time: %lf\n", fmuStruct.currentTime);\r
707 \r
708                         if (fmiFlag > fmiWarning) \r
709                                 return throwException(env, "could not set time");\r
710 \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
714 \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
718 \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
722                         */\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
729      \r
730 \r
731                         stepEvent = fmiTrue;\r
732                         // handle events\r
733                         if (timeEvent || stateEvent || stepEvent) {\r
734         \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
738       \r
739                         } // if event\r
740                         */\r
741         \r
742 /*              }\r
743 \r
744                 fflush(stdout);\r
745                 return 1;\r
746 \r
747         } else {\r
748                 string message = fmuId;\r
749                 env->ReleaseStringUTFChars(id, fmuId);\r
750                 return throwException(env, "simulateStep: Model id " + message + " not found");\r
751         }*/\r
752         return 1;\r
753 }\r
754 \r
755 JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_unloadFMU_1\r
756   (JNIEnv *env, jobject obj, jint id) {\r
757 \r
758           int asd = FMI1_CS_UNLOAD(fmus[id].fmu);\r
759           return asd;\r
760 \r
761 }\r
762 \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
766 }\r
767 \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
771 }\r
772 \r
773 JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_getIntegerValue_1\r
774   (JNIEnv *env, jobject obj, jstring id, jstring variable) {\r
775           /*\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
781 \r
782                 if(referenceExists(fmuStruct, name)) {\r
783                         fmiValueReference vr = getReference(fmuStruct, name);\r
784                         int result;\r
785                         fmuStruct.fmu.getInteger(fmuStruct.c, &vr, 1, &result);\r
786                         env->ReleaseStringUTFChars(variable, name);\r
787                         return result;\r
788 \r
789                 } else {\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
794                 }\r
795 \r
796         } else {\r
797                 string message = fmuId;\r
798                 env->ReleaseStringUTFChars(id, fmuId);\r
799                 return throwException(env, "unloadFMU: Model id " + message + " not found");\r
800         }\r
801         */\r
802           return 1;\r
803 \r
804 }\r
805 \r
806 JNIEXPORT jboolean JNICALL Java_org_simantics_fmil_FMIL_getBooleanValue_1\r
807   (JNIEnv *env, jobject obj, jstring id, jstring variable) {\r
808           /*\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
814 \r
815                 if(referenceExists(fmuStruct, name)) {\r
816                         fmiValueReference vr = getReference(fmuStruct, name);\r
817                         fmiBoolean result;\r
818                         fmuStruct.fmu.getBoolean(fmuStruct.c, &vr, 1, &result);\r
819                         env->ReleaseStringUTFChars(variable, name);\r
820                         return result;\r
821 \r
822                 } else {\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
827                 }\r
828 \r
829         } else {\r
830                 string message = fmuId;\r
831                 env->ReleaseStringUTFChars(id, fmuId);\r
832                 return throwException(env, "unloadFMU: Model id " + message + " not found");\r
833         }*/\r
834           return 1;\r
835 \r
836 }\r
837 \r
838 JNIEXPORT jstring JNICALL Java_org_simantics_fmil_FMIL_getStringValue_1\r
839   (JNIEnv *env, jobject obj, jstring id, jstring variable) {\r
840           /*\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
846 \r
847                 if(referenceExists(fmuStruct, name)) {\r
848                         fmiValueReference vr = getReference(fmuStruct, name);\r
849                         fmiString result;\r
850                         fmuStruct.fmu.getString(fmuStruct.c, &vr, 1, &result);\r
851                         env->ReleaseStringUTFChars(variable, name);\r
852                         return env->NewStringUTF(result);\r
853 \r
854                 } else {\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
859                 }\r
860 \r
861         } else {\r
862                 string message = fmuId;\r
863                 env->ReleaseStringUTFChars(id, fmuId);\r
864                 return 0; //throwException(env, "unloadFMU: Model id " + message + " not found");\r
865         }\r
866         */\r
867           return 0;\r
868 \r
869 }