Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Require-Bundle: org.eclipse.core.runtime;bundle-version="3.7.0",
org.simantics.utils;bundle-version="1.1.0",
- org.simantics;bundle-version="1.0.0"
+ org.simantics;bundle-version="1.0.0",
+ org.slf4j.api
Export-Package: org.simantics.fmil.core
--- /dev/null
+# How to build FMUSimulator and FMILibrary
+
+CMake GUI for generating Visual Studio project files from FMILibrary sources
+
+Remember to manually delete CMakeCache and CMakeFiles from FMILibrary/build/expatex/-folder
\ No newline at end of file
--- /dev/null
+Debug
+x64
+x86
+Release
\ No newline at end of file
--- /dev/null
+Debug
+x64
+x86
+Release
\ No newline at end of file
-/*\r
- Copyright (C) 2012 Modelon AB\r
-\r
- This program is free software: you can redistribute it and/or modify\r
- it under the terms of the BSD style license.\r
-\r
- This program is distributed in the hope that it will be useful,\r
- but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- FMILIB_License.txt file for more details.\r
-\r
- You should have received a copy of the FMILIB_License.txt file\r
- along with this program. If not, contact Modelon AB <http://www.modelon.com>.\r
-*/\r
-\r
-#include <assert.h>\r
-#include <string.h>\r
-#include <stdio.h>\r
-#include <FMI/fmi_util.h>\r
-#include <FMI/fmi_zip_unzip.h>\r
-\r
-char* fmi_construct_dll_dir_name(jm_callbacks* callbacks, const char* fmu_unzipped_path) {\r
- char* dir_path;\r
- size_t len;\r
-\r
- assert( fmu_unzipped_path && callbacks);\r
-\r
- len = \r
- strlen(fmu_unzipped_path) + strlen(FMI_FILE_SEP)\r
- + strlen(FMI_BINARIES) + strlen(FMI_FILE_SEP) \r
- + strlen(FMI_PLATFORM) + strlen(FMI_FILE_SEP) + 1;\r
-\r
- dir_path = (char*)callbacks->malloc(len);\r
- if (dir_path == NULL) {\r
- jm_log_fatal(callbacks, "FMIUT", "Failed to allocate memory.");\r
- return NULL;\r
- }\r
-\r
- sprintf(dir_path, "%s%s%s%s%s%s", fmu_unzipped_path, FMI_FILE_SEP, FMI_BINARIES, FMI_FILE_SEP, FMI_PLATFORM, FMI_FILE_SEP);/*safe */\r
-\r
- return dir_path;\r
-}\r
-\r
-char* fmi_construct_dll_file_name(jm_callbacks* callbacks, const char* dll_dir_name, const char* model_identifier) {\r
- char* fname;\r
- size_t len;\r
- assert(callbacks && model_identifier);\r
- len = \r
- strlen(dll_dir_name) +\r
- strlen(model_identifier) \r
- + strlen(FMI_DLL_EXT) + 1;\r
- fname = (char*)callbacks->malloc(len);\r
- if (fname == NULL) {\r
- jm_log_fatal(callbacks, "FMIUT", "Failed to allocate memory.");\r
- return NULL;\r
- }\r
- sprintf(fname, "%s%s%s", dll_dir_name, model_identifier, FMI_DLL_EXT);/*safe */\r
-\r
- return fname;\r
-}\r
-\r
-\r
-////\r
-\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <stdarg.h>\r
-#include <string.h>\r
-#include <errno.h>\r
-\r
-#include <fmilib.h>\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-typedef struct {\r
- char *name;\r
- char *description;\r
- char *declaredType;\r
- long vr;\r
- // 0 = real\r
- // 1 = integer\r
- // 2 = boolean\r
- // 3 = string\r
- // 4 = enumeration\r
- int type;\r
- // 0 = constant\r
- // 1 = parameter\r
- // 2 = discrete\r
- // 3 = continuous\r
- // 4 = unknown\r
- int variability;\r
- // 0 = input\r
- // 1 = output\r
- // 2 = internal\r
- // 3 = none\r
- // 4 = unknown\r
- int causality;\r
-} FMIL_Variable;\r
-\r
-typedef struct {\r
- char *name;\r
- char *description;\r
- char *quantity;\r
- char *unit;\r
-} FMIL_DeclaredType;\r
-\r
-__declspec(dllexport) void* FMI1_CS_LOAD(const char *zipFilePath, const char *unzipFolder);\r
-__declspec(dllexport) int FMI1_CS_UNLOAD(void* fmu);\r
-__declspec(dllexport) FMIL_Variable *FMI1_CS_GET_VARIABLES(void* fmu, int *count);\r
-__declspec(dllexport) FMIL_DeclaredType *FMI1_CS_GET_DECLARED_TYPES(void* fmu, int *count);\r
-__declspec(dllexport) int FMI1_CS_INSTANTIATE(void* fmu);\r
-__declspec(dllexport) int FMI1_CS_INITIALIZE(void* fmu);\r
-__declspec(dllexport) int FMI1_CS_STEP(void* fmu, double masterTime, double stepSize);\r
-__declspec(dllexport) int FMI1_CS_SET_REAL(void* fmu, int vr, double value);\r
-__declspec(dllexport) double FMI1_CS_GET_REAL(void* fmu, int vr);\r
-__declspec(dllexport) int FMI1_CS_GET_REALS(void* fmu, int *vrs, double *values, int count);\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-#define BUFFER 4096\r
-\r
-/* Logger function used by the C-API */\r
-void importlogger(jm_callbacks* c, jm_string module, jm_log_level_enu_t log_level, jm_string message)\r
-{\r
- printf("module = %s, log level = %d: %s\n", module, log_level, message);\r
-}\r
-\r
-/* Logger function used by the FMU internally */\r
-void fmilogger(fmi1_component_t c, fmi1_string_t instanceName, fmi1_status_t status, fmi1_string_t category, fmi1_string_t message, ...)\r
-{\r
- char msg[BUFFER];\r
- int len;\r
- va_list argp; \r
- va_start(argp, message);\r
- /*len=jm_vsnprintf(msg, BUFFER, message, argp);\r
- printf("fmiStatus = %d; %s (%s): %s\n", status, instanceName, category, msg);\r
- if(len > BUFFER) {\r
- printf("Warning: message was trancated");\r
- }*/\r
-}\r
-\r
-void *FMI1_CS_LOAD(char *zipFilePath, char *unzipFolder) {\r
-\r
- fmi1_callback_functions_t callBackFunctions;\r
- fmi_import_context_t* context;\r
- fmi1_fmu_kind_enu_t standard = fmi1_fmu_kind_enu_cs_standalone; \r
- fmi_version_enu_t version;\r
- jm_status_enu_t status;\r
- fmi1_import_t *fmu;\r
- jm_callbacks* callbacks;\r
-\r
- callbacks = (jm_callbacks *)calloc(1, sizeof(jm_callbacks));\r
-\r
- callbacks->malloc = malloc;\r
- callbacks->calloc = calloc;\r
- callbacks->realloc = realloc;\r
- callbacks->free = free;\r
- callbacks->logger = importlogger;\r
- callbacks->log_level = jm_log_level_debug;\r
- callbacks->context = 0;\r
-\r
- callBackFunctions.logger = fmilogger;\r
- callBackFunctions.allocateMemory = calloc;\r
- callBackFunctions.freeMemory = free;\r
-\r
- context = fmi_import_allocate_context(callbacks);\r
-\r
- version = fmi_import_get_fmi_version(context, zipFilePath, unzipFolder);\r
-\r
- fmu = fmi1_import_parse_xml(context, unzipFolder);\r
-\r
- status = fmi1_import_create_dllfmu(fmu, callBackFunctions, 0);\r
-\r
- fmi_import_free_context(context);\r
-\r
- return fmu;\r
-\r
-}\r
-\r
-int FMI1_CS_UNLOAD(void *fmu_) {\r
-\r
- fmi1_import_t *fmu = (fmi1_import_t *)fmu_;\r
-\r
- fmi1_import_destroy_dllfmu(fmu);\r
-\r
- fmi1_import_free(fmu);\r
-\r
- return 1;\r
-\r
-}\r
-\r
-/*\r
- if(!vt) {\r
- printf("No type definition\n");\r
- return;\r
- }\r
-\r
- quan = fmi1_import_get_type_quantity(vt);\r
-\r
- printf("Type %s\n description: %s\n", fmi1_import_get_type_name(vt), fmi1_import_get_type_description(vt));\r
-\r
- printf("Base type: %s\n", fmi1_base_type_to_string(fmi1_import_get_base_type(vt)));\r
-\r
- if(quan) {\r
- printf("Quantity: %s\n", quan);\r
- }\r
- switch(fmi1_import_get_base_type(vt)) {\r
- case fmi1_base_type_real: {\r
- fmi1_import_real_typedef_t* rt = fmi1_import_get_type_as_real(vt);\r
- fmi1_real_t min = fmi1_import_get_real_type_min(rt);\r
- fmi1_real_t max = fmi1_import_get_real_type_max(rt);\r
- fmi1_real_t nom = fmi1_import_get_real_type_nominal(rt);\r
- fmi1_import_unit_t* u = fmi1_import_get_real_type_unit(rt);\r
- fmi1_import_display_unit_t* du = fmi1_import_get_type_display_unit(rt);\r
-\r
- printf("Min %g, max %g, nominal %g\n", min, max, nom);\r
-\r
- if(u) {\r
- printf("Unit: %s\n", fmi1_import_get_unit_name(u));\r
- }\r
- if(du) {\r
- printf("Display unit: %s, gain: %g, offset: %g, is relative: %s",\r
- fmi1_import_get_display_unit_name(du),\r
- fmi1_import_get_display_unit_gain(du),\r
- fmi1_import_get_display_unit_offset(du),\r
- fmi1_import_get_real_type_is_relative_quantity(rt)?"yes":"no"\r
- );\r
- }\r
-\r
- break;\r
- }\r
- case fmi1_base_type_int:{\r
- fmi1_import_integer_typedef_t* it = fmi1_import_get_type_as_int(vt);\r
- int min = fmi1_import_get_integer_type_min(it);\r
- int max = fmi1_import_get_integer_type_max(it);\r
- printf("Min %d, max %d\n", min, max);\r
- break;\r
- }\r
- case fmi1_base_type_bool:{\r
- break;\r
- }\r
- case fmi1_base_type_str:{\r
- break;\r
- }\r
- case fmi1_base_type_enum:{\r
- fmi1_import_enumeration_typedef_t* et = fmi1_import_get_type_as_enum(vt);\r
- int min = fmi1_import_get_enum_type_min(et);\r
- int max = fmi1_import_get_enum_type_max(et);\r
- printf("Min %d, max %d\n", min, max);\r
- {\r
- size_t ni;\r
- unsigned i;\r
- ni = fmi1_import_get_enum_type_size(et);\r
- i = (unsigned)(ni);\r
- assert( i == ni);\r
- printf("There are %u items \n",(unsigned)ni);\r
- for(i = 0; i < ni; i++) {\r
- printf("[%u] %s (%s) \n", (unsigned)i+1, fmi1_import_get_enum_type_item_name(et, i), fmi1_import_get_enum_type_item_description(et, i));\r
- }\r
- }\r
- break;\r
- }\r
- default:\r
- printf("Error in fmiGetBaseType()\n");\r
- }\r
-*/\r
-\r
-\r
-FMIL_Variable *FMI1_CS_GET_VARIABLES(void *fmu, int *count) {\r
-\r
- int i;\r
- FMIL_Variable *result;\r
- fmi1_import_variable_list_t* vl = fmi1_import_get_variable_list((fmi1_import_t *)fmu);\r
- fmi1_import_variable_typedef_t* type;\r
-\r
- count[0] = fmi1_import_get_variable_list_size(vl);\r
-\r
- result = (FMIL_Variable *)malloc(count[0]*sizeof(FMIL_Variable));\r
-\r
- for(i = 0; i < count[0]; i++) {\r
-\r
- fmi1_import_variable_t* var = fmi1_import_get_variable(vl, i);\r
- if(!var) {\r
-\r
- printf("Something wrong with variable %d \n",i);\r
- return 0;\r
-\r
- } else {\r
-\r
- result[i].name = fmi1_import_get_variable_name(var);\r
- result[i].description = fmi1_import_get_variable_description(var);\r
-\r
- switch (fmi1_import_get_variability(var)) {\r
- case fmi1_variability_enu_constant:\r
- result[i].variability = 0;\r
- break;\r
- case fmi1_variability_enu_parameter:\r
- result[i].variability = 1;\r
- break;\r
- case fmi1_variability_enu_discrete:\r
- result[i].variability = 2;\r
- break;\r
- case fmi1_variability_enu_continuous:\r
- result[i].variability = 3;\r
- break;\r
- case fmi1_variability_enu_unknown:\r
- result[i].variability = 4;\r
- break;\r
- }\r
-\r
- switch (fmi1_import_get_causality(var)) {\r
- case fmi1_causality_enu_input:\r
- result[i].causality = 0;\r
- break;\r
- case fmi1_causality_enu_output:\r
- result[i].causality = 1;\r
- break;\r
- case fmi1_causality_enu_internal:\r
- result[i].causality = 2;\r
- break;\r
- case fmi1_causality_enu_none:\r
- result[i].causality = 3;\r
- break;\r
- case fmi1_causality_enu_unknown:\r
- result[i].causality = 4;\r
- break;\r
- }\r
-\r
- switch (fmi1_import_get_variable_base_type(var)) {\r
- case fmi1_base_type_real:\r
- result[i].type = 0;\r
- break;\r
- case fmi1_base_type_int:\r
- result[i].type = 1;\r
- break;\r
- case fmi1_base_type_bool:\r
- result[i].type = 2;\r
- break;\r
- case fmi1_base_type_str:\r
- result[i].type = 3;\r
- break;\r
- case fmi1_base_type_enum:\r
- result[i].type = 4;\r
- break;\r
- }\r
- \r
- result[i].vr = fmi1_import_get_variable_vr(var);\r
-\r
- type = fmi1_import_get_variable_declared_type(var);\r
- if(type) {\r
- result[i].declaredType = fmi1_import_get_type_name(type);\r
- } else {\r
- result[i].declaredType = 0;\r
- }\r
-\r
- }\r
-\r
- }\r
-\r
- fmi1_import_free_variable_list(vl);\r
-\r
- return result;\r
-\r
-}\r
-\r
-FMIL_DeclaredType *FMI1_CS_GET_DECLARED_TYPES(void *fmu, int *count) {\r
-\r
- FMIL_DeclaredType *result;\r
- fmi1_import_type_definitions_t* td = fmi1_import_get_type_definitions((fmi1_import_t *)fmu);\r
- fmi1_import_variable_typedef_t* type;\r
- unsigned i, ntd = (unsigned)fmi1_import_get_type_definition_number(td);\r
-\r
- count[0] = ntd;\r
-\r
- result = (FMIL_DeclaredType *)malloc(count[0]*sizeof(FMIL_DeclaredType));\r
-\r
- for(i = 0; i < ntd; i++) {\r
- type = fmi1_import_get_typedef(td, i);\r
- result[i].name = fmi1_import_get_type_name(type);\r
- result[i].description = fmi1_import_get_type_description(type);\r
- result[i].quantity = fmi1_import_get_type_quantity(type);\r
- result[i].unit = 0;\r
-\r
- switch(fmi1_import_get_base_type(type)) {\r
- case fmi1_base_type_real: {\r
- fmi1_import_real_typedef_t* rt = fmi1_import_get_type_as_real(type);\r
- fmi1_import_unit_t* u = fmi1_import_get_real_type_unit(rt);\r
- if(u) result[i].unit = fmi1_import_get_unit_name(u);\r
- }\r
- }\r
-\r
- }\r
-\r
- return result;\r
-\r
-}\r
-\r
-#define INSTANCE_NAME "kekkeli"\r
-\r
-int FMI1_CS_INSTANTIATE(void *fmu) {\r
-\r
- fmi1_string_t fmuLocation;\r
- fmi1_string_t mimeType;\r
- fmi1_real_t timeout;\r
- fmi1_boolean_t visible;\r
- fmi1_boolean_t interactive;\r
- fmi1_boolean_t loggingOn;\r
-\r
- fmuLocation = "";\r
- mimeType = "";\r
- timeout = 0;\r
- visible = fmi1_false;\r
- interactive = fmi1_false;\r
- loggingOn = fmi1_true;\r
-\r
- if (fmi1_import_instantiate_slave(fmu, INSTANCE_NAME, NULL, NULL, timeout, fmi1_false, fmi1_false) == NULL) { \r
- printf("fmi1_capi_instantiate_slave: Failed\n");\r
- return 0;\r
- } else {\r
- printf("fmi1_capi_instantiate_slave: Success\n");\r
- }\r
- return 0;\r
-\r
-}\r
-\r
-int FMI1_CS_INITIALIZE(void *fmu) {\r
-\r
- fmi1_status_t status;\r
- fmi1_real_t tStart;\r
- fmi1_real_t tStop;\r
- fmi1_boolean_t StopTimeDefined;\r
-\r
- tStart = 0;\r
- tStop = 10;\r
- StopTimeDefined = fmi1_false;\r
-\r
- status = fmi1_import_initialize_slave((fmi1_import_t *)fmu, tStart, StopTimeDefined, tStop);\r
- if (status == fmi1_status_error || status == fmi1_status_fatal) {\r
- printf("fmi1_capi_initialize_slave: Failed\n");\r
- return 0;\r
- } else {\r
- printf("fmi1_capi_initialize_slave: Success\n");\r
- }\r
- return 0;\r
-\r
-}\r
-\r
-int FMI1_CS_STEP(void *fmu, double masterTime, double stepSize) {\r
-\r
- fmi1_status_t status;\r
-\r
- status = fmi1_import_do_step((fmi1_import_t *)fmu, (fmi1_real_t)masterTime, (fmi1_real_t)stepSize, fmi1_true);\r
- if (status == fmi1_status_error || status == fmi1_status_fatal) {\r
- return 1;\r
- } else {\r
- return 0;\r
- }\r
-}\r
-\r
-int FMI1_CS_SET_REAL(void *fmu, long valueId, double value) {\r
-\r
- fmi1_value_reference_t vr = valueId;\r
- fmi1_import_set_real((fmi1_import_t *)fmu, &vr, 1, &value);\r
-\r
- return 0;\r
-\r
-}\r
-\r
-double FMI1_CS_GET_REAL(void *fmu, int valueReference) {\r
-\r
- fmi1_value_reference_t vr = valueReference;\r
- fmi1_real_t value;\r
- fmi1_import_get_real((fmi1_import_t *)fmu, &vr, 1, &value);\r
- return value;\r
-\r
-}\r
-\r
-int FMI1_CS_GET_REALS(void *fmu, int *valueReferences, double *result, int count) {\r
-\r
- fmi1_value_reference_t *vrs = valueReferences;\r
- fmi1_real_t value;\r
- fmi1_import_get_real((fmi1_import_t *)fmu, vrs, count, result);\r
- return 1;\r
-\r
-}\r
+/*
+ Copyright (C) 2012 Modelon AB
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the BSD style license.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ FMILIB_License.txt file for more details.
+
+ You should have received a copy of the FMILIB_License.txt file
+ along with this program. If not, contact Modelon AB <http://www.modelon.com>.
+*/
+
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+#include <FMI/fmi_util.h>
+#include <FMI/fmi_zip_unzip.h>
+
+char* fmi_construct_dll_dir_name(jm_callbacks* callbacks, const char* fmu_unzipped_path) {
+ char* dir_path;
+ size_t len;
+
+ assert( fmu_unzipped_path && callbacks);
+
+ len =
+ strlen(fmu_unzipped_path) + strlen(FMI_FILE_SEP)
+ + strlen(FMI_BINARIES) + strlen(FMI_FILE_SEP)
+ + strlen(FMI_PLATFORM) + strlen(FMI_FILE_SEP) + 1;
+
+ dir_path = (char*)callbacks->malloc(len);
+ if (dir_path == NULL) {
+ jm_log_fatal(callbacks, "FMIUT", "Failed to allocate memory.");
+ return NULL;
+ }
+
+ sprintf(dir_path, "%s%s%s%s%s%s", fmu_unzipped_path, FMI_FILE_SEP, FMI_BINARIES, FMI_FILE_SEP, FMI_PLATFORM, FMI_FILE_SEP);/*safe */
+
+ return dir_path;
+}
+
+char* fmi_construct_dll_file_name(jm_callbacks* callbacks, const char* dll_dir_name, const char* model_identifier) {
+ char* fname;
+ size_t len;
+ assert(callbacks && model_identifier);
+ len =
+ strlen(dll_dir_name) +
+ strlen(model_identifier)
+ + strlen(FMI_DLL_EXT) + 1;
+ fname = (char*)callbacks->malloc(len);
+ if (fname == NULL) {
+ jm_log_fatal(callbacks, "FMIUT", "Failed to allocate memory.");
+ return NULL;
+ }
+ sprintf(fname, "%s%s%s", dll_dir_name, model_identifier, FMI_DLL_EXT);/*safe */
+
+ return fname;
+}
+
+////
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+
+#include <fmilib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ char *name;
+ char *description;
+ char *declaredType;
+ long vr;
+ // 0 = real
+ // 1 = integer
+ // 2 = boolean
+ // 3 = string
+ // 4 = enumeration
+ int type;
+ // 0 = constant
+ // 1 = parameter
+ // 2 = discrete
+ // 3 = continuous
+ // 4 = unknown
+ int variability;
+ // 0 = input
+ // 1 = output
+ // 2 = internal
+ // 3 = none
+ // 4 = unknown
+ int causality;
+} FMIL_Variable;
+
+typedef struct {
+ char *name;
+ char *description;
+ char *quantity;
+ char *unit;
+} FMIL_DeclaredType;
+
+__declspec(dllexport) int FMI_CS_LOAD(const char *zipFilePath, const char *unzipFolder, void **fmuPointer, int *fmuVersion, const char **error);
+
+__declspec(dllexport) int FMI1_CS_UNLOAD(void* fmu, const char **error);
+__declspec(dllexport) FMIL_Variable *FMI1_CS_GET_VARIABLES(void* fmu, int *count, const char **error);
+__declspec(dllexport) FMIL_DeclaredType *FMI1_CS_GET_DECLARED_TYPES(void* fmu, int *count, const char **error);
+__declspec(dllexport) int FMI1_CS_INSTANTIATE(void* fmu, const char *instanceName, const char **error);
+__declspec(dllexport) int FMI1_CS_INITIALIZE(void* fmu, const char **error);
+__declspec(dllexport) int FMI1_CS_STEP(void* fmu, double masterTime, double stepSize, const char **error);
+__declspec(dllexport) int FMI1_CS_SET_REAL(void* fmu, int vr, double value, const char **error);
+__declspec(dllexport) double FMI1_CS_GET_REAL(void* fmu, int vr, const char **error);
+__declspec(dllexport) int FMI1_CS_GET_REALS(void* fmu, int *vrs, double *values, int count, const char **error);
+
+__declspec(dllexport) int FMI2_CS_UNLOAD(void* fmu, const char **error);
+__declspec(dllexport) FMIL_Variable *FMI2_CS_GET_VARIABLES(void* fmu, int *count, const char **error);
+__declspec(dllexport) FMIL_DeclaredType *FMI2_CS_GET_DECLARED_TYPES(void* fmu, int *count, const char **error);
+__declspec(dllexport) int FMI2_CS_INSTANTIATE(void* fmu, const char *instanceName, const char **error);
+__declspec(dllexport) int FMI2_CS_INITIALIZE(void* fmu, const char **error);
+__declspec(dllexport) int FMI2_CS_STEP(void* fmu, double masterTime, double stepSize, const char **error);
+__declspec(dllexport) int FMI2_CS_SET_REAL(void* fmu, int vr, double value, const char **error);
+__declspec(dllexport) double FMI2_CS_GET_REAL(void* fmu, int vr, const char **error);
+__declspec(dllexport) int FMI2_CS_GET_REALS(void* fmu, int *vrs, double *values, int count, const char **error);
+
+#ifdef __cplusplus
+}
+#endif
+
+#define BUFFER 4096
+
+/* Logger function used by the C-API */
+void importlogger(jm_callbacks* c, jm_string module, jm_log_level_enu_t log_level, jm_string message)
+{
+ printf("module = %s, log level = %d: %s\n", module, log_level, message);
+}
+
+/* Logger function used by the FMU internally */
+void fmilogger(fmi1_component_t c, fmi1_string_t instanceName, fmi1_status_t status, fmi1_string_t category, fmi1_string_t message, ...)
+{
+ char msg[BUFFER];
+ int len;
+ va_list argp;
+ va_start(argp, message);
+ /*len=jm_vsnprintf(msg, BUFFER, message, argp);
+ printf("fmiStatus = %d; %s (%s): %s\n", status, instanceName, category, msg);
+ if(len > BUFFER) {
+ printf("Warning: message was trancated");
+ }*/
+}
+
+int FMI_CS_LOAD(char *zipFilePath, char *unzipFolder, void **fmuPointer, int *fmuVersion, const char **error) {
+
+ fmi1_callback_functions_t callBackFunctions;
+ fmi2_callback_functions_t callBackFunctions2;
+ fmi_import_context_t* context;
+ fmi_version_enu_t version;
+ jm_status_enu_t status;
+ fmi1_import_t *fmu;
+ fmi2_import_t *fmu2;
+ jm_callbacks* callbacks;
+
+ callbacks = (jm_callbacks *)calloc(1, sizeof(jm_callbacks));
+
+ callbacks->malloc = malloc;
+ callbacks->calloc = calloc;
+ callbacks->realloc = realloc;
+ callbacks->free = free;
+ callbacks->logger = importlogger;
+ callbacks->log_level = jm_log_level_debug;
+ callbacks->context = 0;
+
+ context = fmi_import_allocate_context(callbacks);
+
+ version = fmi_import_get_fmi_version(context, zipFilePath, unzipFolder);
+
+ if (version == fmi_version_1_enu ) {
+ fmu = fmi1_import_parse_xml(context, unzipFolder);
+ if (fmi1_import_get_fmu_kind(fmu) != fmi1_fmu_kind_enu_cs_standalone && fmi1_import_get_fmu_kind(fmu) != fmi1_fmu_kind_enu_cs_tool) {
+ *error = "Provided FMU is version 1 but wrong type me (Model Exchange) when it should be cs (Co-Simulation)";
+ return 2; // wrong type, should be co-simulation
+ }
+
+ callBackFunctions.logger = fmilogger;
+ callBackFunctions.allocateMemory = calloc;
+ callBackFunctions.freeMemory = free;
+
+ status = fmi1_import_create_dllfmu(fmu, callBackFunctions, 0);
+ if (status == jm_status_error) {
+ *error = fmi1_import_get_last_error(fmu);
+ return 3;
+ }
+
+ *fmuPointer = fmu;
+ *fmuVersion = 1;
+ } else if (version == fmi_version_2_0_enu) {
+ fmu2 = fmi2_import_parse_xml(context, unzipFolder, 0);
+
+ if (fmi2_import_get_fmu_kind(fmu2) != fmi1_fmu_kind_enu_cs_standalone && fmi2_import_get_fmu_kind(fmu2) != fmi1_fmu_kind_enu_cs_tool) {
+ *error = "Provided FMU is version 2.0 but wrong type me (Model Exchange) when it should be cs (Co-Simulation)";
+ return 2; // wrong type, should be co-simulation
+ }
+
+ callBackFunctions2.logger = fmi2_log_forwarding;
+ callBackFunctions2.allocateMemory = calloc;
+ callBackFunctions2.freeMemory = free;
+ callBackFunctions2.componentEnvironment = fmu2;
+
+ status = fmi2_import_create_dllfmu(fmu2, fmi2_fmu_kind_cs, &callBackFunctions2);
+ if (status == jm_status_error) {
+ *error = fmi2_import_get_last_error(fmu2);
+ return 3;
+ }
+
+ *fmuPointer = fmu2;
+ *fmuVersion = 2;
+ }
+
+ fmi_import_free_context(context);
+
+ return 0; // success
+}
+
+int FMI1_CS_UNLOAD(void *fmu_, const char **error) {
+ fmi1_import_t *fmu = (fmi1_import_t *)fmu_;
+ fmi1_import_destroy_dllfmu(fmu);
+ fmi1_import_free(fmu);
+ return 0;
+}
+
+int FMI2_CS_UNLOAD(void *fmu_, const char **error) {
+ fmi2_import_t *fmu = (fmi2_import_t *)fmu_;
+ fmi2_import_destroy_dllfmu(fmu);
+ fmi2_import_free(fmu);
+ return 0;
+}
+
+/*
+ if(!vt) {
+ printf("No type definition\n");
+ return;
+ }
+
+ quan = fmi1_import_get_type_quantity(vt);
+
+ printf("Type %s\n description: %s\n", fmi1_import_get_type_name(vt), fmi1_import_get_type_description(vt));
+
+ printf("Base type: %s\n", fmi1_base_type_to_string(fmi1_import_get_base_type(vt)));
+
+ if(quan) {
+ printf("Quantity: %s\n", quan);
+ }
+ switch(fmi1_import_get_base_type(vt)) {
+ case fmi1_base_type_real: {
+ fmi1_import_real_typedef_t* rt = fmi1_import_get_type_as_real(vt);
+ fmi1_real_t min = fmi1_import_get_real_type_min(rt);
+ fmi1_real_t max = fmi1_import_get_real_type_max(rt);
+ fmi1_real_t nom = fmi1_import_get_real_type_nominal(rt);
+ fmi1_import_unit_t* u = fmi1_import_get_real_type_unit(rt);
+ fmi1_import_display_unit_t* du = fmi1_import_get_type_display_unit(rt);
+
+ printf("Min %g, max %g, nominal %g\n", min, max, nom);
+
+ if(u) {
+ printf("Unit: %s\n", fmi1_import_get_unit_name(u));
+ }
+ if(du) {
+ printf("Display unit: %s, gain: %g, offset: %g, is relative: %s",
+ fmi1_import_get_display_unit_name(du),
+ fmi1_import_get_display_unit_gain(du),
+ fmi1_import_get_display_unit_offset(du),
+ fmi1_import_get_real_type_is_relative_quantity(rt)?"yes":"no"
+ );
+ }
+
+ break;
+ }
+ case fmi1_base_type_int:{
+ fmi1_import_integer_typedef_t* it = fmi1_import_get_type_as_int(vt);
+ int min = fmi1_import_get_integer_type_min(it);
+ int max = fmi1_import_get_integer_type_max(it);
+ printf("Min %d, max %d\n", min, max);
+ break;
+ }
+ case fmi1_base_type_bool:{
+ break;
+ }
+ case fmi1_base_type_str:{
+ break;
+ }
+ case fmi1_base_type_enum:{
+ fmi1_import_enumeration_typedef_t* et = fmi1_import_get_type_as_enum(vt);
+ int min = fmi1_import_get_enum_type_min(et);
+ int max = fmi1_import_get_enum_type_max(et);
+ printf("Min %d, max %d\n", min, max);
+ {
+ size_t ni;
+ unsigned i;
+ ni = fmi1_import_get_enum_type_size(et);
+ i = (unsigned)(ni);
+ assert( i == ni);
+ printf("There are %u items \n",(unsigned)ni);
+ for(i = 0; i < ni; i++) {
+ printf("[%u] %s (%s) \n", (unsigned)i+1, fmi1_import_get_enum_type_item_name(et, i), fmi1_import_get_enum_type_item_description(et, i));
+ }
+ }
+ break;
+ }
+ default:
+ printf("Error in fmiGetBaseType()\n");
+ }
+*/
+
+
+FMIL_Variable *FMI1_CS_GET_VARIABLES(void *fmu, int *count, const char **error) {
+
+ int i;
+ FMIL_Variable *result;
+ fmi1_import_variable_list_t* vl = fmi1_import_get_variable_list((fmi1_import_t *)fmu);
+ fmi1_import_variable_typedef_t* type;
+
+ count[0] = fmi1_import_get_variable_list_size(vl);
+
+ result = (FMIL_Variable *)malloc(count[0]*sizeof(FMIL_Variable));
+
+ for(i = 0; i < count[0]; i++) {
+
+ fmi1_import_variable_t* var = fmi1_import_get_variable(vl, i);
+ if(!var) {
+
+ printf("Something wrong with variable %d \n",i);
+ return 0;
+
+ } else {
+
+ result[i].name = fmi1_import_get_variable_name(var);
+ result[i].description = fmi1_import_get_variable_description(var);
+
+ switch (fmi1_import_get_variability(var)) {
+ case fmi1_variability_enu_constant:
+ result[i].variability = 0;
+ break;
+ case fmi1_variability_enu_parameter:
+ result[i].variability = 1;
+ break;
+ case fmi1_variability_enu_discrete:
+ result[i].variability = 2;
+ break;
+ case fmi1_variability_enu_continuous:
+ result[i].variability = 3;
+ break;
+ case fmi1_variability_enu_unknown:
+ result[i].variability = 4;
+ break;
+ }
+
+ switch (fmi1_import_get_causality(var)) {
+ case fmi1_causality_enu_input:
+ result[i].causality = 0;
+ break;
+ case fmi1_causality_enu_output:
+ result[i].causality = 1;
+ break;
+ case fmi1_causality_enu_internal:
+ result[i].causality = 2;
+ break;
+ case fmi1_causality_enu_none:
+ result[i].causality = 3;
+ break;
+ case fmi1_causality_enu_unknown:
+ result[i].causality = 4;
+ break;
+ }
+
+ switch (fmi1_import_get_variable_base_type(var)) {
+ case fmi1_base_type_real:
+ result[i].type = 0;
+ break;
+ case fmi1_base_type_int:
+ result[i].type = 1;
+ break;
+ case fmi1_base_type_bool:
+ result[i].type = 2;
+ break;
+ case fmi1_base_type_str:
+ result[i].type = 3;
+ break;
+ case fmi1_base_type_enum:
+ result[i].type = 4;
+ break;
+ }
+
+ result[i].vr = fmi1_import_get_variable_vr(var);
+
+ type = fmi1_import_get_variable_declared_type(var);
+ if(type) {
+ result[i].declaredType = fmi1_import_get_type_name(type);
+ } else {
+ result[i].declaredType = 0;
+ }
+
+ }
+
+ }
+
+ fmi1_import_free_variable_list(vl);
+
+ return result;
+
+}
+
+FMIL_Variable *FMI2_CS_GET_VARIABLES(void *fmu, int *count, const char **error) {
+
+ int i;
+ FMIL_Variable *result;
+ fmi2_import_variable_list_t* vl = fmi2_import_get_variable_list((fmi2_import_t *)fmu, 0);
+ fmi2_import_variable_typedef_t* type;
+
+ count[0] = fmi2_import_get_variable_list_size(vl);
+
+ result = (FMIL_Variable *)malloc(count[0]*sizeof(FMIL_Variable));
+
+ for(i = 0; i < count[0]; i++) {
+
+ fmi2_import_variable_t* var = fmi2_import_get_variable(vl, i);
+ if(!var) {
+
+ printf("Something wrong with variable %d \n",i);
+ return 0;
+
+ } else {
+
+ result[i].name = fmi2_import_get_variable_name(var);
+ result[i].description = fmi2_import_get_variable_description(var);
+
+ switch (fmi2_import_get_variability(var)) {
+ case fmi2_variability_enu_constant:
+ result[i].variability = 0;
+ break;
+ case fmi2_variability_enu_fixed:
+ case fmi2_variability_enu_tunable:
+ result[i].variability = 1;
+ break;
+ case fmi2_variability_enu_discrete:
+ result[i].variability = 2;
+ break;
+ case fmi2_variability_enu_continuous:
+ result[i].variability = 3;
+ break;
+ case fmi2_variability_enu_unknown:
+ result[i].variability = 4;
+ break;
+ }
+
+ switch (fmi2_import_get_causality(var)) {
+ case fmi2_causality_enu_input:
+ result[i].causality = 0;
+ break;
+ case fmi2_causality_enu_output:
+ result[i].causality = 1;
+ break;
+ case fmi2_causality_enu_local:
+ result[i].causality = 2;
+ break;
+ case fmi2_causality_enu_independent:
+ result[i].causality = 3;
+ break;
+ case fmi2_causality_enu_unknown:
+ result[i].causality = 4;
+ break;
+ }
+
+ switch (fmi2_import_get_variable_base_type(var)) {
+ case fmi2_base_type_real:
+ result[i].type = 0;
+ break;
+ case fmi2_base_type_int:
+ result[i].type = 1;
+ break;
+ case fmi2_base_type_bool:
+ result[i].type = 2;
+ break;
+ case fmi2_base_type_str:
+ result[i].type = 3;
+ break;
+ case fmi2_base_type_enum:
+ result[i].type = 4;
+ break;
+ }
+
+ result[i].vr = fmi2_import_get_variable_vr(var);
+
+ type = fmi2_import_get_variable_declared_type(var);
+ if(type) {
+ result[i].declaredType = fmi2_import_get_type_name(type);
+ } else {
+ result[i].declaredType = 0;
+ }
+
+ }
+
+ }
+
+ fmi2_import_free_variable_list(vl);
+
+ return result;
+
+}
+
+FMIL_DeclaredType *FMI1_CS_GET_DECLARED_TYPES(void *fmu, int *count, const char **error) {
+
+ FMIL_DeclaredType *result;
+ fmi1_import_type_definitions_t* td = fmi1_import_get_type_definitions((fmi1_import_t *)fmu);
+ fmi1_import_variable_typedef_t* type;
+ unsigned i, ntd = (unsigned)fmi1_import_get_type_definition_number(td);
+
+ count[0] = ntd;
+
+ result = (FMIL_DeclaredType *)malloc(count[0]*sizeof(FMIL_DeclaredType));
+
+ for(i = 0; i < ntd; i++) {
+ type = fmi1_import_get_typedef(td, i);
+ result[i].name = fmi1_import_get_type_name(type);
+ result[i].description = fmi1_import_get_type_description(type);
+ result[i].quantity = fmi1_import_get_type_quantity(type);
+ result[i].unit = 0;
+
+ switch(fmi1_import_get_base_type(type)) {
+ case fmi1_base_type_real: {
+ fmi1_import_real_typedef_t* rt = fmi1_import_get_type_as_real(type);
+ fmi1_import_unit_t* u = fmi1_import_get_real_type_unit(rt);
+ if(u) result[i].unit = fmi1_import_get_unit_name(u);
+ }
+ }
+
+ }
+
+ return result;
+
+}
+
+FMIL_DeclaredType *FMI2_CS_GET_DECLARED_TYPES(void *fmu, int *count, const char **error) {
+
+ FMIL_DeclaredType *result;
+ fmi2_import_type_definitions_t* td = fmi2_import_get_type_definitions((fmi2_import_t *)fmu);
+ fmi2_import_variable_typedef_t* type;
+ unsigned i, ntd = (unsigned)fmi2_import_get_type_definition_number(td);
+
+ count[0] = ntd;
+
+ result = (FMIL_DeclaredType *)malloc(count[0]*sizeof(FMIL_DeclaredType));
+
+ for(i = 0; i < ntd; i++) {
+ type = fmi2_import_get_typedef(td, i);
+ result[i].name = fmi2_import_get_type_name(type);
+ result[i].description = fmi2_import_get_type_description(type);
+ result[i].quantity = fmi2_import_get_type_quantity(type);
+ result[i].unit = 0;
+
+ switch(fmi2_import_get_base_type(type)) {
+ case fmi2_base_type_real: {
+ fmi2_import_real_typedef_t* rt = fmi2_import_get_type_as_real(type);
+ fmi2_import_unit_t* u = fmi2_import_get_real_type_unit(rt);
+ if(u) result[i].unit = fmi2_import_get_unit_name(u);
+ }
+ }
+
+ }
+
+ return result;
+
+}
+
+int FMI1_CS_INSTANTIATE(void *fmu, const char *instanceName, const char **error) {
+
+ fmi1_string_t fmuLocation;
+ fmi1_string_t mimeType;
+ fmi1_real_t timeout;
+ fmi1_boolean_t visible;
+ fmi1_boolean_t interactive;
+ fmi1_boolean_t loggingOn;
+
+ jm_status_enu_t jmstatus;
+
+ fmuLocation = "";
+ mimeType = "";
+ timeout = 0;
+ visible = fmi1_false;
+ interactive = fmi1_false;
+ loggingOn = fmi1_true;
+
+ jmstatus = fmi1_import_instantiate_slave((fmi1_import_t*)fmu, instanceName, NULL, NULL, timeout, fmi1_false, fmi1_false);
+ if (jmstatus == jm_status_error) {
+ *error = fmi1_import_get_last_error((fmi1_import_t*)fmu);
+ return 1;
+ }
+ return 0;
+}
+
+int FMI2_CS_INSTANTIATE(void *fmu, const char *instanceName, const char **error) {
+
+ fmi2_string_t fmuLocation;
+ fmi2_string_t mimeType;
+ fmi2_real_t timeout;
+ fmi2_boolean_t visible;
+ fmi2_boolean_t interactive;
+ fmi2_boolean_t loggingOn;
+ jm_status_enu_t jmstatus;
+
+ fmuLocation = "";
+ mimeType = "";
+ timeout = 0;
+ visible = fmi2_false;
+ jmstatus = fmi2_import_instantiate((fmi2_import_t*)fmu, instanceName, fmi2_cosimulation, NULL, visible);
+ if (jmstatus == jm_status_error) {
+ *error = fmi2_import_get_last_error((fmi2_import_t*)fmu);
+ return 1;
+ }
+ return 0;
+}
+
+int FMI1_CS_INITIALIZE(void *fmu, const char **error) {
+
+ fmi1_status_t status;
+ fmi1_real_t tStart;
+ fmi1_real_t tStop;
+ fmi1_boolean_t StopTimeDefined;
+
+ tStart = 0;
+ tStop = 10;
+ StopTimeDefined = fmi1_false;
+
+ status = fmi1_import_initialize_slave((fmi1_import_t *)fmu, tStart, StopTimeDefined, tStop);
+ if (status == fmi1_status_error || status == fmi1_status_fatal) {
+ printf("fmi1_capi_initialize_slave: Failed\n");
+ return 0;
+ } else {
+ printf("fmi1_capi_initialize_slave: Success\n");
+ }
+ return 0;
+
+}
+
+int FMI2_CS_INITIALIZE(void *fmu, const char **error) {
+
+ fmi2_real_t tStart;
+ fmi2_real_t tStop;
+ fmi2_boolean_t StopTimeDefined;
+ fmi2_real_t relativeTol = 1e-4;
+
+ fmi2_status_t fmistatus;
+
+ tStart = 0;
+ tStop = 10;
+ StopTimeDefined = fmi1_false;
+
+ fmistatus = fmi2_import_setup_experiment((fmi2_import_t*)fmu, fmi2_true, relativeTol, tStart, StopTimeDefined, tStop);
+ if(fmistatus != fmi2_status_ok) {
+ *error = ("fmi2_import_setup_experiment failed\n");
+ return 1;
+ }
+
+ fmistatus = fmi2_import_enter_initialization_mode((fmi2_import_t*)fmu);
+ if(fmistatus != fmi2_status_ok) {
+ *error = ("fmi2_import_enter_initialization_mode failed\n");
+ return 1;
+ }
+
+ fmistatus = fmi2_import_exit_initialization_mode((fmi2_import_t*)fmu);
+ if(fmistatus != fmi2_status_ok) {
+ *error = ("fmi2_import_exit_initialization_mode failed\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+int FMI1_CS_STEP(void *fmu, double masterTime, double stepSize, const char **error) {
+
+ fmi1_status_t status;
+
+ status = fmi1_import_do_step((fmi1_import_t *)fmu, (fmi1_real_t)masterTime, (fmi1_real_t)stepSize, fmi1_true);
+ if (status == fmi1_status_error || status == fmi1_status_fatal) {
+ *error = "Error happened during stepping!";
+ return 1;
+ }
+ return 0;
+}
+
+int FMI2_CS_STEP(void *fmu, double masterTime, double stepSize, const char **error) {
+
+ fmi2_status_t status;
+
+ status = fmi2_import_do_step((fmi2_import_t *)fmu, (fmi2_real_t)masterTime, (fmi2_real_t)stepSize, fmi2_true);
+ if (status == fmi2_status_error || status == fmi2_status_fatal) {
+ *error = "Error happened during stepping!";
+ return 1;
+ }
+ return 0;
+}
+
+int FMI1_CS_SET_REAL(void *fmu, long valueId, double value, const char **error) {
+
+ fmi1_status_t status;
+
+ fmi1_value_reference_t vr = valueId;
+ status = fmi1_import_set_real((fmi1_import_t *)fmu, &vr, 1, &value);
+ if (status == fmi1_status_error || status == fmi1_status_fatal) {
+ *error = "Error happened during setting real value!";
+ return 1;
+ }
+ return 0;
+}
+
+int FMI2_CS_SET_REAL(void *fmu, long valueId, double value, const char **error) {
+
+ fmi2_status_t status;
+
+ fmi2_value_reference_t vr = valueId;
+ status = fmi2_import_set_real((fmi2_import_t *)fmu, &vr, 1, &value);
+ if (status == fmi2_status_error || status == fmi2_status_fatal) {
+ *error = "Error happened during setting real value!";
+ return 1;
+ }
+ return 0;
+}
+
+double FMI1_CS_GET_REAL(void *fmu, int valueReference, const char **error) {
+
+ fmi1_value_reference_t vr = valueReference;
+ fmi1_real_t value;
+
+ fmi1_status_t status;
+
+ status = fmi1_import_get_real((fmi1_import_t *)fmu, &vr, 1, &value);
+ if (status == fmi1_status_error || status == fmi1_status_fatal) {
+ *error = "Error happened during getting real value!";
+ }
+ return value;
+}
+
+double FMI2_CS_GET_REAL(void *fmu, int valueReference, const char **error) {
+
+ fmi2_value_reference_t vr = valueReference;
+ fmi2_real_t value;
+
+ fmi2_status_t status;
+
+ status = fmi2_import_get_real((fmi2_import_t *)fmu, &vr, 1, &value);
+ if (status == fmi2_status_error || status == fmi2_status_fatal) {
+ *error = "Error happened during setting real value!";
+ }
+ return value;
+}
+
+int FMI1_CS_GET_REALS(void *fmu, int *valueReferences, double *result, int count, const char **error) {
+
+ fmi1_value_reference_t *vrs = valueReferences;
+ fmi1_real_t value;
+
+ fmi1_status_t status;
+
+ status = fmi1_import_get_real((fmi1_import_t *)fmu, vrs, count, result);
+ if (status == fmi1_status_error || status == fmi1_status_fatal) {
+ *error = "Error happened during getting reals value!";
+ }
+ return 0;
+}
+
+int FMI2_CS_GET_REALS(void *fmu, int *valueReferences, double *result, int count, const char **error) {
+
+ fmi2_value_reference_t *vrs = valueReferences;
+ fmi2_real_t value;
+
+ fmi2_status_t status;
+
+ status = fmi2_import_get_real((fmi2_import_t *)fmu, vrs, count, result);
+ if (status == fmi2_status_error || status == fmi2_status_fatal) {
+ *error = "Error happened during getting reals value!";
+ }
+ return 0;
+
+}
-#ifndef __FMI1_CS_H__\r
-#define __FMI1_CS_H__\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-typedef struct {\r
- char *name;\r
- char *description;\r
- char *declaredType;\r
- long vr;\r
- // 0 = real\r
- // 1 = integer\r
- // 2 = boolean\r
- // 3 = string\r
- // 4 = enumeration\r
- int type;\r
- // 0 = constant\r
- // 1 = parameter\r
- // 2 = discrete\r
- // 3 = continuous\r
- // 4 = unknown\r
- int variability;\r
- // 0 = input\r
- // 1 = output\r
- // 2 = internal\r
- // 3 = none\r
- // 4 = unknown\r
- int causality;\r
-} FMIL_Variable;\r
-\r
-typedef struct {\r
- char *name;\r
- char *description;\r
- char *quantity;\r
- char *unit;\r
-} FMIL_DeclaredType;\r
-\r
-__declspec(dllexport) void* FMI1_CS_LOAD(const char *zipFilePath, const char *unzipFolder);\r
-__declspec(dllexport) int FMI1_CS_UNLOAD(void* fmu);\r
-__declspec(dllexport) FMIL_Variable *FMI1_CS_GET_VARIABLES(void* fmu, int *count);\r
-__declspec(dllexport) FMIL_DeclaredType *FMI1_CS_GET_DECLARED_TYPES(void* fmu, int *count);\r
-__declspec(dllexport) int FMI1_CS_INSTANTIATE(void* fmu);\r
-__declspec(dllexport) int FMI1_CS_INITIALIZE(void* fmu);\r
-__declspec(dllexport) int FMI1_CS_STEP(void* fmu, double masterTime, double stepSize);\r
-__declspec(dllexport) double FMI1_CS_SET_REAL(void* fmu, int vr, double value);\r
-__declspec(dllexport) int FMI1_CS_GET_REALS(void* fmu, int *vrs, double *values, int count);\r
-__declspec(dllexport) double FMI1_CS_GET_REAL(void* fmu, int vr);\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
+#ifndef __FMI1_CS_H__
+#define __FMI1_CS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ char *name;
+ char *description;
+ char *declaredType;
+ long vr;
+ // 0 = real
+ // 1 = integer
+ // 2 = boolean
+ // 3 = string
+ // 4 = enumeration
+ int type;
+ // 0 = constant
+ // 1 = parameter
+ // 2 = discrete
+ // 3 = continuous
+ // 4 = unknown
+ int variability;
+ // 0 = input
+ // 1 = output
+ // 2 = internal
+ // 3 = none
+ // 4 = unknown
+ int causality;
+} FMIL_Variable;
+
+typedef struct {
+ char *name;
+ char *description;
+ char *quantity;
+ char *unit;
+} FMIL_DeclaredType;
+
+__declspec(dllexport) int FMI_CS_LOAD(const char *zipFilePath, const char *unzipFolder, void **fmuPointer, int *fmuVersion, const char **error);
+
+__declspec(dllexport) int FMI1_CS_UNLOAD(void* fmu, const char **error);
+__declspec(dllexport) FMIL_Variable *FMI1_CS_GET_VARIABLES(void* fmu, int *count, const char **error);
+__declspec(dllexport) FMIL_DeclaredType *FMI1_CS_GET_DECLARED_TYPES(void* fmu, int *count, const char **error);
+__declspec(dllexport) int FMI1_CS_INSTANTIATE(void* fmu, const char *instanceName, const char **error);
+__declspec(dllexport) int FMI1_CS_INITIALIZE(void* fmu, const char **error);
+__declspec(dllexport) int FMI1_CS_STEP(void* fmu, double masterTime, double stepSize, const char **error);
+__declspec(dllexport) int FMI1_CS_SET_REAL(void* fmu, int vr, double value, const char **error);
+__declspec(dllexport) double FMI1_CS_GET_REAL(void* fmu, int vr, const char **error);
+__declspec(dllexport) int FMI1_CS_GET_REALS(void* fmu, int *vrs, double *values, int count, const char **error);
+
+__declspec(dllexport) int FMI2_CS_UNLOAD(void* fmu, const char **error);
+__declspec(dllexport) FMIL_Variable *FMI2_CS_GET_VARIABLES(void* fmu, int *count, const char **error);
+__declspec(dllexport) FMIL_DeclaredType *FMI2_CS_GET_DECLARED_TYPES(void* fmu, int *count, const char **error);
+__declspec(dllexport) int FMI2_CS_INSTANTIATE(void* fmu, const char *instanceName, const char **error);
+__declspec(dllexport) int FMI2_CS_INITIALIZE(void* fmu, const char **error);
+__declspec(dllexport) int FMI2_CS_STEP(void* fmu, double masterTime, double stepSize, const char **error);
+__declspec(dllexport) int FMI2_CS_SET_REAL(void* fmu, int vr, double value, const char **error);
+__declspec(dllexport) double FMI2_CS_GET_REAL(void* fmu, int vr, const char **error);
+__declspec(dllexport) int FMI2_CS_GET_REALS(void* fmu, int *vrs, double *values, int count, const char **error);
+
+#ifdef __cplusplus
+}
+#endif
+
#endif
\ No newline at end of file
-/* DO NOT EDIT THIS FILE - it is machine generated */\r
-#include <jni.h>\r
-/* Header for class org_simantics_fmu_FMUControlJNI */\r
-\r
-#ifndef _Included_org_simantics_fmu_FMUControlJNI\r
-#define _Included_org_simantics_fmu_FMUControlJNI\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_loadFMUFile_1\r
- (JNIEnv *, jobject, jstring, jstring);\r
-\r
-/*\r
- * Class: org_simantics_fmu_FMUControlJNI\r
- * Method: setStepLength_\r
- * Signature: (Ljava/lang/String;D)I\r
- */\r
-JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_setStepLength_1\r
- (JNIEnv *, jobject, jint, jdouble);\r
-\r
-/*\r
- * Class: org_simantics_fmu_FMUControlJNI\r
- * Method: instantiateSimulation_\r
- * Signature: (Ljava/lang/String;)I\r
- */\r
-JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_instantiateSimulation_1\r
- (JNIEnv *, jobject, jint);\r
-\r
-/*\r
- * Class: org_simantics_fmu_FMUControlJNI\r
- * Method: initializeSimulation_\r
- * Signature: (Ljava/lang/String;)I\r
- */\r
-JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_initializeSimulation_1\r
- (JNIEnv *, jobject, jint);\r
-\r
-/*\r
- * Class: org_simantics_fmu_FMUControlJNI\r
- * Method: subscribe_\r
- * Signature: (Ljava/lang/String;[Ljava/lang/String;I)I\r
- */\r
-JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_subscribe_1\r
- (JNIEnv *, jobject, jint, jintArray);\r
-\r
-/*\r
- * Class: org_simantics_fmu_FMUControlJNI\r
- * Method: setRealValue_\r
- * Signature: (Ljava/lang/String;Ljava/lang/String;D)I\r
- */\r
-JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_setRealValue_1\r
- (JNIEnv *, jobject, jint, jint, jdouble);\r
-\r
-/*\r
- * Class: org_simantics_fmu_FMUControlJNI\r
- * Method: setIntegerValue_\r
- * Signature: (Ljava/lang/String;Ljava/lang/String;I)I\r
- */\r
-JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_setIntegerValue_1\r
- (JNIEnv *, jobject, jstring, jstring, jint);\r
-\r
-/*\r
- * Class: org_simantics_fmu_FMUControlJNI\r
- * Method: setBooleanValue_\r
- * Signature: (Ljava/lang/String;Ljava/lang/String;Z)I\r
- */\r
-JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_setBooleanValue_1\r
- (JNIEnv *, jobject, jstring, jstring, jboolean);\r
-\r
-/*\r
- * Class: org_simantics_fmu_FMUControlJNI\r
- * Method: setTime_\r
- * Signature: (Ljava/lang/String;D)I\r
- */\r
-JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_setTime_1\r
- (JNIEnv *, jobject, jstring, jdouble);\r
-\r
-/*\r
- * Class: org_simantics_fmu_FMUControlJNI\r
- * Method: simulateStep_\r
- * Signature: (Ljava/lang/String;)I\r
- */\r
-JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_simulateStep_1\r
- (JNIEnv *, jobject, jint);\r
-\r
-/*\r
- * Class: org_simantics_fmu_FMUControlJNI\r
- * Method: getSubscribedResults_\r
- * Signature: (Ljava/lang/String;[D)[D\r
- */\r
-JNIEXPORT jdoubleArray JNICALL Java_org_simantics_fmil_FMIL_getSubscribedResults_1\r
- (JNIEnv *, jobject, jint, jdoubleArray);\r
-\r
-/*\r
- * Class: org_simantics_fmu_FMUControlJNI\r
- * Method: unloadFMU_\r
- * Signature: (Ljava/lang/String;)I\r
- */\r
-JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_unloadFMU_1\r
- (JNIEnv *, jobject, jint);\r
-\r
-/*\r
- * Class: org_simantics_fmu_FMUControlJNI\r
- * Method: isInitialized_\r
- * Signature: (Ljava/lang/String;)Z\r
- */\r
-JNIEXPORT jboolean JNICALL Java_org_simantics_fmil_FMIL_isInitialized_1\r
- (JNIEnv *, jobject, jstring);\r
-\r
-/*\r
- * Class: org_simantics_fmu_FMUControlJNI\r
- * Method: getTime_\r
- * Signature: (Ljava/lang/String;)D\r
- */\r
-JNIEXPORT jdouble JNICALL Java_org_simantics_fmil_FMIL_getTime_1\r
- (JNIEnv *, jobject, jint);\r
-\r
-/*\r
- * Class: org_simantics_fmu_FMUControlJNI\r
- * Method: getAllVariables_\r
- * Signature: (Ljava/lang/String;)[Ljava/lang/String;\r
- */\r
-JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariables_1\r
- (JNIEnv *, jobject, jint);\r
-\r
-JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariableDescriptions_1\r
- (JNIEnv *, jobject, jint);\r
-\r
-JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariableDeclaredTypes_1\r
- (JNIEnv *, jobject, jint);\r
-\r
-JNIEXPORT jintArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariableReferences_1\r
- (JNIEnv *, jobject, jint, jintArray);\r
-\r
-JNIEXPORT jintArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariableTypes_1\r
- (JNIEnv *, jobject, jint, jintArray);\r
-\r
-JNIEXPORT jintArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariableVariabilities_1\r
- (JNIEnv *, jobject, jint, jintArray);\r
-\r
-JNIEXPORT jintArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariableCausalities_1\r
- (JNIEnv *, jobject, jint, jintArray);\r
-\r
-JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_getAllDeclaredTypes_1\r
- (JNIEnv *, jobject, jint);\r
-\r
-JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_getAllDeclaredTypeDescriptions_1\r
- (JNIEnv *, jobject, jint);\r
-\r
-JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_getAllDeclaredTypeQuantities_1\r
- (JNIEnv *, jobject, jint);\r
-\r
-JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_getAllDeclaredTypeUnits_1\r
- (JNIEnv *, jobject, jint);\r
-\r
-/*\r
- * Class: org_simantics_fmu_FMUControlJNI\r
- * Method: filterVariables_\r
- * Signature: (Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;\r
- */\r
-JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_filterVariables_1\r
- (JNIEnv *, jobject, jstring, jstring);\r
-\r
-/*\r
- * Class: org_simantics_fmu_FMUControlJNI\r
- * Method: getLastErrorMessage_\r
- * Signature: (Ljava/lang/String;)Ljava/lang/String;\r
- */\r
-JNIEXPORT jstring JNICALL Java_org_simantics_fmil_FMIL_getLastErrorMessage_1\r
- (JNIEnv *, jobject, jstring);\r
-\r
-/*\r
- * Class: org_simantics_fmu_FMUControlJNI\r
- * Method: getRealValue_\r
- * Signature: (Ljava/lang/String;Ljava/lang/String;)D\r
- */\r
-JNIEXPORT jdouble JNICALL Java_org_simantics_fmil_FMIL_getRealValue_1\r
- (JNIEnv *, jobject, jint, jint);\r
-\r
-/*\r
- * Class: org_simantics_fmu_FMUControlJNI\r
- * Method: getStringValue_\r
- * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;\r
- */\r
-JNIEXPORT jstring JNICALL Java_org_simantics_fmil_FMIL_getStringValue_1\r
- (JNIEnv *, jobject, jstring, jstring);\r
-\r
-/*\r
- * Class: org_simantics_fmu_FMUControlJNI\r
- * Method: getIntegerValue_\r
- * Signature: (Ljava/lang/String;Ljava/lang/String;)I\r
- */\r
-JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_getIntegerValue_1\r
- (JNIEnv *, jobject, jstring, jstring);\r
-\r
-/*\r
- * Class: org_simantics_fmu_FMUControlJNI\r
- * Method: getBooleanValue_\r
- * Signature: (Ljava/lang/String;Ljava/lang/String;)Z\r
- */\r
-JNIEXPORT jboolean JNICALL Java_org_simantics_fmil_FMIL_getBooleanValue_1\r
- (JNIEnv *, jobject, jstring, jstring);\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-#endif\r
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class org_simantics_fmu_FMUControlJNI */
+
+#ifndef _Included_org_simantics_fmu_FMUControlJNI
+#define _Included_org_simantics_fmu_FMUControlJNI
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+JNIEXPORT jint JNICALL Java_org_simantics_fmil_core_FMIL_loadFMUFile_1
+ (JNIEnv *, jobject, jstring, jstring);
+
+/*
+ * Class: org_simantics_fmu_FMUControlJNI
+ * Method: setStepLength_
+ * Signature: (Ljava/lang/String;D)I
+ */
+JNIEXPORT jint JNICALL Java_org_simantics_fmil_core_FMIL_setStepLength_1
+ (JNIEnv *, jobject, jint, jdouble);
+
+/*
+ * Class: org_simantics_fmu_FMUControlJNI
+ * Method: instantiateSimulation_
+ * Signature: (Ljava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL Java_org_simantics_fmil_core_FMIL_instantiateSimulation_1
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: org_simantics_fmu_FMUControlJNI
+ * Method: initializeSimulation_
+ * Signature: (Ljava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL Java_org_simantics_fmil_core_FMIL_initializeSimulation_1
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: org_simantics_fmu_FMUControlJNI
+ * Method: subscribe_
+ * Signature: (Ljava/lang/String;[Ljava/lang/String;I)I
+ */
+JNIEXPORT jint JNICALL Java_org_simantics_fmil_core_FMIL_subscribe_1
+ (JNIEnv *, jobject, jint, jintArray);
+
+/*
+ * Class: org_simantics_fmu_FMUControlJNI
+ * Method: setRealValue_
+ * Signature: (Ljava/lang/String;Ljava/lang/String;D)I
+ */
+JNIEXPORT jint JNICALL Java_org_simantics_fmil_core_FMIL_setRealValue_1
+ (JNIEnv *, jobject, jint, jint, jdouble);
+
+/*
+ * Class: org_simantics_fmu_FMUControlJNI
+ * Method: setIntegerValue_
+ * Signature: (Ljava/lang/String;Ljava/lang/String;I)I
+ */
+JNIEXPORT jint JNICALL Java_org_simantics_fmil_core_FMIL_setIntegerValue_1
+ (JNIEnv *, jobject, jstring, jstring, jint);
+
+/*
+ * Class: org_simantics_fmu_FMUControlJNI
+ * Method: setBooleanValue_
+ * Signature: (Ljava/lang/String;Ljava/lang/String;Z)I
+ */
+JNIEXPORT jint JNICALL Java_org_simantics_fmil_core_FMIL_setBooleanValue_1
+ (JNIEnv *, jobject, jstring, jstring, jboolean);
+
+/*
+ * Class: org_simantics_fmu_FMUControlJNI
+ * Method: setTime_
+ * Signature: (Ljava/lang/String;D)I
+ */
+JNIEXPORT jint JNICALL Java_org_simantics_fmil_core_FMIL_setTime_1
+ (JNIEnv *, jobject, jstring, jdouble);
+
+/*
+ * Class: org_simantics_fmu_FMUControlJNI
+ * Method: simulateStep_
+ * Signature: (Ljava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL Java_org_simantics_fmil_core_FMIL_simulateStep_1
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: org_simantics_fmu_FMUControlJNI
+ * Method: getSubscribedResults_
+ * Signature: (Ljava/lang/String;[D)[D
+ */
+JNIEXPORT jdoubleArray JNICALL Java_org_simantics_fmil_core_FMIL_getSubscribedResults_1
+ (JNIEnv *, jobject, jint, jdoubleArray);
+
+/*
+ * Class: org_simantics_fmu_FMUControlJNI
+ * Method: unloadFMU_
+ * Signature: (Ljava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL Java_org_simantics_fmil_core_FMIL_unloadFMU_1
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: org_simantics_fmu_FMUControlJNI
+ * Method: isInitialized_
+ * Signature: (Ljava/lang/String;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_simantics_fmil_core_FMIL_isInitialized_1
+ (JNIEnv *, jobject, jstring);
+
+/*
+ * Class: org_simantics_fmu_FMUControlJNI
+ * Method: getTime_
+ * Signature: (Ljava/lang/String;)D
+ */
+JNIEXPORT jdouble JNICALL Java_org_simantics_fmil_core_FMIL_getTime_1
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: org_simantics_fmu_FMUControlJNI
+ * Method: getAllVariables_
+ * Signature: (Ljava/lang/String;)[Ljava/lang/String;
+ */
+JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_core_FMIL_getAllVariables_1
+ (JNIEnv *, jobject, jint);
+
+JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_core_FMIL_getAllVariableDescriptions_1
+ (JNIEnv *, jobject, jint);
+
+JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_core_FMIL_getAllVariableDeclaredTypes_1
+ (JNIEnv *, jobject, jint);
+
+JNIEXPORT jintArray JNICALL Java_org_simantics_fmil_core_FMIL_getAllVariableReferences_1
+ (JNIEnv *, jobject, jint, jintArray);
+
+JNIEXPORT jintArray JNICALL Java_org_simantics_fmil_core_FMIL_getAllVariableTypes_1
+ (JNIEnv *, jobject, jint, jintArray);
+
+JNIEXPORT jintArray JNICALL Java_org_simantics_fmil_core_FMIL_getAllVariableVariabilities_1
+ (JNIEnv *, jobject, jint, jintArray);
+
+JNIEXPORT jintArray JNICALL Java_org_simantics_fmil_core_FMIL_getAllVariableCausalities_1
+ (JNIEnv *, jobject, jint, jintArray);
+
+JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_core_FMIL_getAllDeclaredTypes_1
+ (JNIEnv *, jobject, jint);
+
+JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_core_FMIL_getAllDeclaredTypeDescriptions_1
+ (JNIEnv *, jobject, jint);
+
+JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_core_FMIL_getAllDeclaredTypeQuantities_1
+ (JNIEnv *, jobject, jint);
+
+JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_core_FMIL_getAllDeclaredTypeUnits_1
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: org_simantics_fmu_FMUControlJNI
+ * Method: filterVariables_
+ * Signature: (Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;
+ */
+JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_core_FMIL_filterVariables_1
+ (JNIEnv *, jobject, jstring, jstring);
+
+/*
+ * Class: org_simantics_fmu_FMUControlJNI
+ * Method: getRealValue_
+ * Signature: (Ljava/lang/String;Ljava/lang/String;)D
+ */
+JNIEXPORT jdouble JNICALL Java_org_simantics_fmil_core_FMIL_getRealValue_1
+ (JNIEnv *, jobject, jint, jint);
+
+/*
+ * Class: org_simantics_fmu_FMUControlJNI
+ * Method: getStringValue_
+ * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_org_simantics_fmil_core_FMIL_getStringValue_1
+ (JNIEnv *, jobject, jstring, jstring);
+
+/*
+ * Class: org_simantics_fmu_FMUControlJNI
+ * Method: getIntegerValue_
+ * Signature: (Ljava/lang/String;Ljava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL Java_org_simantics_fmil_core_FMIL_getIntegerValue_1
+ (JNIEnv *, jobject, jstring, jstring);
+
+/*
+ * Class: org_simantics_fmu_FMUControlJNI
+ * Method: getBooleanValue_
+ * Signature: (Ljava/lang/String;Ljava/lang/String;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_simantics_fmil_core_FMIL_getBooleanValue_1
+ (JNIEnv *, jobject, jstring, jstring);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
-/* ------------------------------------------------------------------------- \r
- * fmu_control.c\r
- * Simulation controls for fmus\r
- *\r
- * Free libraries and tools used to implement this simulator:\r
- * - header files from the FMU specification\r
- * - eXpat 2.0.1 XML parser, see http://expat.sourceforge.net\r
- * - 7z.exe 4.57 zip and unzip tool, see http://www.7-zip.org <---------- Replace with zlib\r
- * Author: Teemu Lempinen\r
- * Copyright 2012 Semantum Oy\r
- * -------------------------------------------------------------------------\r
- */\r
-\r
-#include <stdlib.h>\r
-#include <stdio.h>\r
-#include <string.h>\r
-#include <map>\r
-#include <string>\r
-#include <vector>\r
-#include <iostream>\r
-#include <regex>\r
-\r
-#include <org_simantics_fmil_FMILJNI.h>\r
-\r
-extern "C" {\r
- #include "fmi_me.h"\r
- #include "sim_support.h"\r
-}\r
-\r
-#include "fmi1_cs.h"\r
-\r
-#define PRINT(fmt,args) { FILE *fp = fopen("R:\\Simantics\\Sysdyn\\log.txt", "ab"); fprintf(fp, fmt, args); fclose(fp); }\r
-\r
-#include <direct.h>\r
-#define GetCurrentDir _getcwd\r
-\r
-using namespace std;\r
-\r
-struct FMI1 {\r
-\r
- void *fmu;\r
-\r
- vector<string> variables;\r
- vector<string> descriptions;\r
- vector<string> declaredTypes;\r
- vector<int> valueReferences;\r
- vector<int> types;\r
- vector<int> variabilities;\r
- vector<int> causalities;\r
-\r
- vector<string> declaredTypeNames;\r
- vector<string> typeDescriptions;\r
- vector<string> quantities;\r
- vector<string> units;\r
-\r
- vector<int> subscription;\r
- double currentTime;\r
- double timeStep;\r
-\r
-};\r
-\r
-struct FMUControlStruct {\r
- double step; // simulation step length\r
- fmiReal currentTime; // current simulation time\r
-\r
- fmiComponent c; // instance of the fmu \r
- ScalarVariable** vars; // model variables\r
-\r
- fmiEventInfo eventInfo; // updated by calls to initialize and eventUpdate\r
- const char* guid; // global unique id of the fmu\r
- fmiCallbackFunctions callbacks; // called by the model during simulation\r
- fmiStatus fmiFlag; // return code of the fmu functions\r
-\r
- map<string,int> indexes; // indexes for variable names in vars-table\r
- map<string,int>::iterator it;\r
-\r
- int nx; // number of state variables\r
- double *x; // continuous states\r
- double *xdot; // the crresponding derivatives in same order\r
- int nz; // number of state event indicators\r
- double *z; // state event indicators\r
- double *prez; // previous values of state event indicators\r
- \r
- bool initialized; // has the fmu been initialized\r
-\r
- vector<fmiValueReference> subscription; // result subscriptions\r
- vector<string> allVariables; // all variables in an initialized model\r
- vector<fmiValueReference> fmiValueReferences; // all value references\r
-\r
- string lastErrorMessage;\r
-\r
- FMU fmu;\r
-};\r
-\r
-vector<FMI1> fmus;\r
-\r
-//map<string,FMUControlStruct> fmus; // indexes for variable names in vars-table\r
-\r
-int throwException(JNIEnv *env, string message) {\r
- jclass newExcCls;\r
- newExcCls = env->FindClass("java/lang/Exception");\r
- if (newExcCls == NULL) {\r
- /* Unable to find the exception class, give up. */\r
- return 0;\r
- }\r
- env->ThrowNew(newExcCls, message.c_str());\r
- return 0;\r
-}\r
-\r
-/*\r
-bool exists(string id) {\r
- map<string,FMUControlStruct>::iterator it = fmus.find(id);\r
- if(it != fmus.end()) {\r
- return true;\r
- } else {\r
- return false;\r
- }\r
-}\r
-*/\r
-\r
-\r
-\r
-JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_loadFMUFile_1 \r
- (JNIEnv *env, jobject obj, jstring path, jstring tempDir) {\r
-\r
- HMODULE module = NULL;\r
- FMI1 fmi1;\r
- FMIL_Variable *vars;\r
- FMIL_DeclaredType *types;\r
- int variableCount = 0;\r
- int typeCount = 0;\r
-\r
- const char *fmuPath = env->GetStringUTFChars(path, 0);\r
- const char *fmuTempDir = env->GetStringUTFChars(tempDir, 0);\r
-\r
- fmi1.currentTime = 0;\r
- fmi1.timeStep = 0.1;\r
- fmi1.fmu = FMI1_CS_LOAD(fmuPath, fmuTempDir);\r
- if(!fmi1.fmu)\r
- return throwException(env, "No FMU loaded");\r
-\r
- vars = FMI1_CS_GET_VARIABLES(fmi1.fmu, &variableCount);\r
- for(int i=0;i<variableCount;i++) {\r
- fmi1.variables.push_back(string(vars[i].name));\r
- if(vars[i].description)\r
- fmi1.descriptions.push_back(string(vars[i].description));\r
- else\r
- fmi1.descriptions.push_back(string(""));\r
- if(vars[i].declaredType)\r
- fmi1.declaredTypes.push_back(string(vars[i].declaredType));\r
- else\r
- fmi1.declaredTypes.push_back(string(""));\r
- fmi1.types.push_back(vars[i].type);\r
- fmi1.causalities.push_back(vars[i].causality);\r
- fmi1.variabilities.push_back(vars[i].variability);\r
- fmi1.valueReferences.push_back(vars[i].vr);\r
- }\r
-\r
- types = FMI1_CS_GET_DECLARED_TYPES(fmi1.fmu, &typeCount);\r
- for(int i=0;i<typeCount;i++) {\r
- fmi1.declaredTypeNames.push_back(string(types[i].name));\r
- if(types[i].description)\r
- fmi1.typeDescriptions.push_back(string(types[i].description));\r
- else\r
- fmi1.typeDescriptions.push_back(string(""));\r
- if(types[i].quantity)\r
- fmi1.quantities.push_back(string(types[i].quantity));\r
- else\r
- fmi1.quantities.push_back(string(""));\r
- if(types[i].unit)\r
- fmi1.units.push_back(string(types[i].unit));\r
- else\r
- fmi1.units.push_back(string(""));\r
- }\r
-\r
-\r
- fmus.push_back(fmi1);\r
-\r
- env->ReleaseStringUTFChars(path, fmuPath);\r
- env->ReleaseStringUTFChars(tempDir, fmuTempDir);\r
-\r
- return fmus.size() - 1;\r
-\r
-}\r
-\r
-JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_setStepLength_1 \r
- (JNIEnv *env, jobject obj, jint id, jdouble stepLength) {\r
- fmus[id].timeStep = stepLength;\r
- return 1;\r
-}\r
-\r
-JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_subscribe_1\r
- (JNIEnv *env, jobject obj, jint id, jintArray vrs) {\r
-\r
- jboolean isCopy;\r
- jint* elements = env -> GetIntArrayElements(vrs, &isCopy);\r
- jsize n = env -> GetArrayLength(vrs);\r
-\r
- int i;\r
- for (i = 0; i < n; i++) {\r
- fmus[id].subscription.push_back(elements[i]);\r
- } \r
- \r
- if (isCopy == JNI_TRUE) {\r
- env -> ReleaseIntArrayElements(vrs, elements, 0);\r
- }\r
-\r
- return 1;\r
-\r
-}\r
-\r
-bool referenceExists(FMUControlStruct fmuStruct, string variable) {\r
- map<string,int>::iterator it = fmuStruct.indexes.find(variable);\r
- if(it != fmuStruct.indexes.end()) {\r
- return true;\r
- } else {\r
- return false;\r
- }\r
-}\r
-\r
-// Remember to check if reference exists\r
-fmiValueReference getReference(FMUControlStruct fmuStruct, string variable) {\r
- return fmuStruct.fmiValueReferences[fmuStruct.indexes[variable]];\r
-}\r
-\r
-// Get string representation of a scalar variable type\r
-string getTypeString(ScalarVariable* sv) {\r
- switch (sv->typeSpec->type){\r
- case elm_Integer:\r
- return "Integer";\r
- case elm_Enumeration:\r
- return "Enumeration";\r
- case elm_Real:\r
- return "Real";\r
- case elm_Boolean:\r
- return "Boolean";\r
- default:\r
- return "No type";\r
- }\r
-}\r
-\r
-JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_setRealValue_1\r
- (JNIEnv *env, jobject obj, jint id, jint vr, jdouble value) {\r
-\r
- FMI1_CS_SET_REAL(fmus[id].fmu, vr, value);\r
- return 1;\r
-\r
-}\r
-\r
-JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_setIntegerValue_1\r
- (JNIEnv *env, jobject obj, jstring id, jstring parameter, jint value) {\r
- /*\r
- const char *fmuId = env->GetStringUTFChars(id, 0);\r
- if(exists(fmuId)) {\r
- FMUControlStruct& fmuStruct = fmus[fmuId];\r
- const char *name = env->GetStringUTFChars(parameter, 0);\r
- string nameString = name;\r
- string modelId = fmuId;\r
- if(!referenceExists(fmuStruct, name)) {\r
- string errorMessage = "setIntegerValue: Model (id " + modelId + ") does not contain variable: " + nameString;\r
- env->ReleaseStringUTFChars(parameter, name);\r
- env->ReleaseStringUTFChars(id, fmuId);\r
- return throwException(env, errorMessage);\r
- } else {\r
- // Check variable type\r
- ScalarVariable* sv = fmuStruct.vars[fmuStruct.indexes[name]];\r
- switch (sv->typeSpec->type){\r
- case elm_Integer:\r
- break; // ok\r
- default: {\r
- string errorMessage = "setIntegerValue: " + nameString + " is not of type Integer. (type: + " + getTypeString(sv) + ")";\r
- env->ReleaseStringUTFChars(parameter, name);\r
- env->ReleaseStringUTFChars(id, fmuId);\r
- return throwException(env, errorMessage);\r
- }\r
- }\r
-\r
- // Change value\r
- fmiValueReference vr = getReference(fmuStruct, name);\r
- const int intValue = (int) value;\r
- fmuStruct.fmu.setInteger(fmuStruct.c, &vr, 1, &intValue);\r
- env->ReleaseStringUTFChars(parameter, name);\r
- env->ReleaseStringUTFChars(id, fmuId);\r
- return 1;\r
- }\r
- } else {\r
- string message = fmuId;\r
- env->ReleaseStringUTFChars(id, fmuId);\r
- return throwException(env, "setIntegerValue: Model id " + message + " not found");\r
- }\r
- */\r
- return 1;\r
-}\r
-\r
-JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_setBooleanValue_1\r
- (JNIEnv *env, jobject obj, jstring id, jstring parameter, jboolean value) {\r
- /*\r
- const char *fmuId = env->GetStringUTFChars(id, 0);\r
- if(exists(fmuId)) {\r
- FMUControlStruct& fmuStruct = fmus[fmuId];\r
- const char *name = env->GetStringUTFChars(parameter, 0);\r
- string nameString = name;\r
- string modelId = fmuId;\r
- if(!referenceExists(fmuStruct, name)) {\r
- string errorMessage = "setBooleanValue: Model (id " + modelId + ") does not contain variable: " + nameString;\r
- env->ReleaseStringUTFChars(parameter, name);\r
- env->ReleaseStringUTFChars(id, fmuId);\r
- return throwException(env, errorMessage);\r
- } else {\r
- // Check variable type\r
- ScalarVariable* sv = fmuStruct.vars[fmuStruct.indexes[name]];\r
- switch (sv->typeSpec->type){\r
- case elm_Boolean:\r
- break; // ok\r
- default: {\r
- string errorMessage = "setBooleanValue: " + nameString + " is not of type Boolean. (type: + " + getTypeString(sv) + ")";\r
- env->ReleaseStringUTFChars(parameter, name);\r
- env->ReleaseStringUTFChars(id, fmuId);\r
- return throwException(env, errorMessage);\r
- }\r
- }\r
-\r
- // Change value\r
- fmiValueReference vr = getReference(fmuStruct, name);\r
- fmiBoolean result = 1;\r
- if(value == 0)\r
- result = 0;\r
- fmuStruct.fmu.setBoolean(fmuStruct.c, &vr, 1, &result);\r
- env->ReleaseStringUTFChars(parameter, name);\r
- env->ReleaseStringUTFChars(id, fmuId);\r
- return 1;\r
- }\r
- } else {\r
- string message = fmuId;\r
- env->ReleaseStringUTFChars(id, fmuId);\r
- return throwException(env, "setBooleanValue: Model id " + message + " not found");\r
- }*/\r
- return 1;\r
-}\r
-\r
-JNIEXPORT jboolean JNICALL Java_org_simantics_fmil_FMIL_isInitialized_1\r
- (JNIEnv *env, jobject obj, jstring id) {\r
- /*\r
- const char *fmuId = env->GetStringUTFChars(id, 0);\r
- if(exists(fmuId)) {\r
- FMUControlStruct& fmuStruct = fmus[fmuId];\r
- env->ReleaseStringUTFChars(id, fmuId);\r
- return fmuStruct.initialized;\r
- } else {\r
- env->ReleaseStringUTFChars(id, fmuId);\r
- return false;\r
- }\r
- */\r
- return 1;\r
-}\r
-\r
-\r
-JNIEXPORT jdouble JNICALL Java_org_simantics_fmil_FMIL_getTime_1\r
- (JNIEnv *env, jobject obj, jint id) {\r
- return fmus[id].currentTime;\r
-}\r
-\r
-double getRealValue(FMUControlStruct fmuStruct, int index) {\r
- ScalarVariable *sv = fmuStruct.vars[index];\r
- fmiValueReference vr = fmuStruct.fmiValueReferences[index];\r
- double real;\r
- fmiInteger integer;\r
- fmiBoolean fmibool;\r
-\r
- switch (sv->typeSpec->type){\r
- case elm_Real:\r
- fmuStruct.fmu.getReal(fmuStruct.c, &vr, 1, &real);\r
- break;\r
- case elm_Integer:\r
- case elm_Enumeration:\r
- fmuStruct.fmu.getInteger(fmuStruct.c, &vr, 1, &integer);\r
- real = (double)integer;\r
- break;\r
- case elm_Boolean:\r
- fmuStruct.fmu.getBoolean(fmuStruct.c, &vr, 1, &fmibool);\r
- if(fmibool == fmiTrue)\r
- real = 1.0;\r
- else\r
- real = 0.0;\r
- break;\r
- }\r
- return real;\r
-}\r
-\r
-JNIEXPORT jdoubleArray JNICALL Java_org_simantics_fmil_FMIL_getSubscribedResults_1\r
- (JNIEnv *env, jobject obj, jint id, jdoubleArray result) {\r
-\r
- jboolean isCopy;\r
- jdouble* resultElements = env -> GetDoubleArrayElements(result, &isCopy);\r
- jsize n = env -> GetArrayLength(result);\r
- int *vrs;\r
- if(n > 0) {\r
- vrs = &(fmus[id].subscription[0]);\r
- FMI1_CS_GET_REALS(fmus[id].fmu, vrs, resultElements, n);\r
- }\r
- if (isCopy == JNI_TRUE) {\r
- env -> ReleaseDoubleArrayElements(result, resultElements, 0);\r
- }\r
-\r
- return result;\r
- \r
-}\r
-\r
-JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_instantiateSimulation_1\r
- (JNIEnv *env, jobject obj, jint id) {\r
-\r
- int asd = FMI1_CS_INSTANTIATE(fmus[id].fmu);\r
- if(asd != 0)\r
- return throwException(env, "No FMU loaded");\r
-\r
- return 1;\r
-\r
-}\r
-\r
-JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_initializeSimulation_1\r
- (JNIEnv *env, jobject obj, jint id) {\r
-\r
- int asd = FMI1_CS_INITIALIZE(fmus[id].fmu);\r
- if(asd != 0)\r
- return throwException(env, "No FMU loaded");\r
-\r
- return 1;\r
-\r
-}\r
-\r
-JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_setTime_1\r
- (JNIEnv *env, jobject obj, jstring id, jdouble time) {\r
- return 1;\r
-}\r
-\r
-JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariables_1\r
- (JNIEnv *env, jobject obj, jint id) {\r
-\r
- jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].variables.size(), \r
- env->FindClass("java/lang/String"), \r
- env->NewStringUTF("")); \r
- \r
- for(int i=0;i<fmus[id].variables.size();i++) { \r
- env->SetObjectArrayElement(ret,i,env->NewStringUTF(fmus[id].variables[i].c_str())); \r
- } \r
-\r
- return ret; \r
-\r
-}\r
-\r
-JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariableDescriptions_1\r
- (JNIEnv *env, jobject obj, jint id) {\r
-\r
- jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].descriptions.size(), \r
- env->FindClass("java/lang/String"), \r
- env->NewStringUTF("")); \r
- \r
- for(int i=0;i<fmus[id].descriptions.size();i++) { \r
- env->SetObjectArrayElement(ret,i,env->NewStringUTF(fmus[id].descriptions[i].c_str())); \r
- } \r
-\r
- return ret; \r
-\r
-}\r
-\r
-JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariableDeclaredTypes_1\r
- (JNIEnv *env, jobject obj, jint id) {\r
-\r
- jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].declaredTypes.size(), \r
- env->FindClass("java/lang/String"), \r
- env->NewStringUTF(""));\r
- \r
- for(int i=0;i<fmus[id].declaredTypes.size();i++) { \r
- env->SetObjectArrayElement(ret,i,env->NewStringUTF(fmus[id].declaredTypes[i].c_str())); \r
- } \r
-\r
- return ret; \r
-\r
-}\r
-\r
-JNIEXPORT jintArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariableReferences_1\r
- (JNIEnv *env, jobject obj, jint id, jintArray result) {\r
-\r
- jboolean isCopy;\r
- jint* resultElements = env -> GetIntArrayElements(result, &isCopy);\r
- jsize n = env -> GetArrayLength(result);\r
-\r
- int i;\r
- for (i = 0; i < n; i++) {\r
- resultElements[i] = fmus[id].valueReferences[i];\r
- } \r
- \r
- if (isCopy == JNI_TRUE) {\r
- env -> ReleaseIntArrayElements(result, resultElements, 0);\r
- }\r
-\r
- return result;\r
-\r
-}\r
-\r
-JNIEXPORT jintArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariableTypes_1\r
- (JNIEnv *env, jobject obj, jint id, jintArray result) {\r
-\r
- jboolean isCopy;\r
- jint* resultElements = env -> GetIntArrayElements(result, &isCopy);\r
- jsize n = env -> GetArrayLength(result);\r
-\r
- int i;\r
- for (i = 0; i < n; i++) {\r
- resultElements[i] = fmus[id].types[i];\r
- } \r
- \r
- if (isCopy == JNI_TRUE) {\r
- env -> ReleaseIntArrayElements(result, resultElements, 0);\r
- }\r
-\r
- return result;\r
-\r
-}\r
-\r
-JNIEXPORT jintArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariableVariabilities_1\r
- (JNIEnv *env, jobject obj, jint id, jintArray result) {\r
-\r
- jboolean isCopy;\r
- jint* resultElements = env -> GetIntArrayElements(result, &isCopy);\r
- jsize n = env -> GetArrayLength(result);\r
-\r
- int i;\r
- for (i = 0; i < n; i++) {\r
- resultElements[i] = fmus[id].variabilities[i];\r
- } \r
- \r
- if (isCopy == JNI_TRUE) {\r
- env -> ReleaseIntArrayElements(result, resultElements, 0);\r
- }\r
-\r
- return result;\r
-\r
-}\r
-\r
-JNIEXPORT jintArray JNICALL Java_org_simantics_fmil_FMIL_getAllVariableCausalities_1\r
- (JNIEnv *env, jobject obj, jint id, jintArray result) {\r
-\r
- jboolean isCopy;\r
- jint* resultElements = env -> GetIntArrayElements(result, &isCopy);\r
- jsize n = env -> GetArrayLength(result);\r
-\r
- int i;\r
- for (i = 0; i < n; i++) {\r
- resultElements[i] = fmus[id].causalities[i];\r
- } \r
- \r
- if (isCopy == JNI_TRUE) {\r
- env -> ReleaseIntArrayElements(result, resultElements, 0);\r
- }\r
-\r
- return result;\r
-\r
-}\r
-\r
-JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_getAllDeclaredTypes_1\r
- (JNIEnv *env, jobject obj, jint id) {\r
-\r
- jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].declaredTypeNames.size(), \r
- env->FindClass("java/lang/String"), \r
- env->NewStringUTF(""));\r
- \r
- for(int i=0;i<fmus[id].declaredTypeNames.size();i++) { \r
- env->SetObjectArrayElement(ret,i,env->NewStringUTF(fmus[id].declaredTypeNames[i].c_str())); \r
- } \r
-\r
- return ret; \r
-\r
-}\r
-\r
-JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_getAllDeclaredTypeDescriptions_1\r
- (JNIEnv *env, jobject obj, jint id) {\r
-\r
- jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].typeDescriptions.size(), \r
- env->FindClass("java/lang/String"), \r
- env->NewStringUTF(""));\r
- \r
- for(int i=0;i<fmus[id].typeDescriptions.size();i++) { \r
- env->SetObjectArrayElement(ret,i,env->NewStringUTF(fmus[id].typeDescriptions[i].c_str())); \r
- } \r
-\r
- return ret; \r
-\r
-}\r
-\r
-JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_getAllDeclaredTypeQuantities_1\r
- (JNIEnv *env, jobject obj, jint id) {\r
-\r
- jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].quantities.size(), \r
- env->FindClass("java/lang/String"), \r
- env->NewStringUTF(""));\r
- \r
- for(int i=0;i<fmus[id].quantities.size();i++) { \r
- env->SetObjectArrayElement(ret,i,env->NewStringUTF(fmus[id].quantities[i].c_str())); \r
- } \r
-\r
- return ret; \r
-\r
-}\r
-\r
-JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_getAllDeclaredTypeUnits_1\r
- (JNIEnv *env, jobject obj, jint id) {\r
-\r
- jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].units.size(), \r
- env->FindClass("java/lang/String"), \r
- env->NewStringUTF(""));\r
- \r
- for(int i=0;i<fmus[id].units.size();i++) { \r
- env->SetObjectArrayElement(ret,i,env->NewStringUTF(fmus[id].units[i].c_str())); \r
- } \r
-\r
- return ret; \r
-\r
-}\r
-\r
-/*\r
-JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_FMIL_filterVariables_1\r
- (JNIEnv *env, jobject obj, jstring id, jstring regexp) {\r
- const char *rx = env->GetStringUTFChars(regexp, 0);\r
- jobjectArray result = filterVariables(env, obj, id, rx);\r
- env->ReleaseStringUTFChars(regexp, rx);\r
- return result;\r
-}\r
-*/\r
-\r
-JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_simulateStep_1\r
- (JNIEnv *env, jobject obj, jint id) {\r
-\r
- int asd = FMI1_CS_STEP(fmus[id].fmu, fmus[id].currentTime, fmus[id].timeStep);\r
- if(asd != 0)\r
- return throwException(env, "No FMU loaded");\r
-\r
- fmus[id].currentTime += fmus[id].timeStep;\r
-\r
- return 1;\r
-\r
- /*\r
- const char *fmuId = env->GetStringUTFChars(id, 0);\r
- if(exists(fmuId)) {\r
- FMUControlStruct& fmuStruct = fmus[fmuId];\r
- env->ReleaseStringUTFChars(id, fmuId);\r
-\r
- if(&fmuStruct.fmu == NULL || fmuStruct.fmu.modelDescription == NULL || &fmuStruct.vars == NULL) {\r
- return throwException(env, "Simulate step failed - fmu not loaded");\r
- }\r
-\r
- if(fmuStruct.x == NULL) {\r
- return throwException(env, "Simulate step failed - fmu not instantiated");\r
- }\r
-\r
- if(fmuStruct.initialized == false) {\r
- fmiBoolean toleranceControlled = fmiFalse;\r
- fmuStruct.fmiFlag = fmuStruct.fmu.initialize(fmuStruct.c, toleranceControlled, fmuStruct.currentTime, &(fmuStruct.eventInfo));\r
- if (fmuStruct.fmiFlag > fmiWarning) return throwException(env, "could not initialize model");\r
- fmuStruct.initialized = true;\r
- }\r
-\r
- FMU& fmu = fmuStruct.fmu;\r
- int debug = 0; // DEBUG ON = 1, OFF = 0\r
-\r
- int i;\r
- double dt, tPre, tEnd = fmuStruct.currentTime + fmuStruct.step;\r
-\r
- fmiBoolean timeEvent, stateEvent, stepEvent;\r
- fmiStatus fmiFlag; // return code of the fmu functions\r
- fmiValueReference vr;\r
-\r
-\r
- */\r
- /* Simulate the duration of one step. The simulation may be done in \r
- * multiple parts if events occur\r
- */ /*\r
- while (fmuStruct.currentTime < tEnd) {\r
- // get current state and derivatives\r
- fmiFlag = fmu.getContinuousStates(fmuStruct.c, fmuStruct.x, fmuStruct.nx);\r
- if (fmiFlag > fmiWarning) \r
- return throwException(env, "could not retrieve states");\r
-\r
- fmiFlag = fmu.getDerivatives(fmuStruct.c, fmuStruct.xdot, fmuStruct.nx);\r
- if (fmiFlag > fmiWarning) \r
- return throwException(env, "could not retrieve derivatives");\r
-\r
- // advance time\r
- tPre = fmuStruct.currentTime;\r
- fmuStruct.currentTime = min(fmuStruct.currentTime+fmuStruct.step, tEnd);\r
- timeEvent = fmuStruct.eventInfo.upcomingTimeEvent && fmuStruct.eventInfo.nextEventTime < fmuStruct.currentTime; \r
- \r
- if (timeEvent) fmuStruct.currentTime = fmuStruct.eventInfo.nextEventTime;\r
- dt = fmuStruct.currentTime - tPre; \r
- fmiFlag = fmu.setTime(fmuStruct.c, fmuStruct.currentTime);\r
- if (fmiFlag > fmiWarning) throwException(env, "could not set time");\r
-\r
- if(referenceExists(fmuStruct, "time")) {\r
- vr = getReference(fmuStruct, "time");\r
- if(vr != NULL) {\r
- fmu.setReal(fmuStruct.c, &vr, 1, &(fmuStruct.currentTime));\r
- }\r
- }\r
-\r
- if(debug)\r
- printf("Actual time: %lf\n", fmuStruct.currentTime);\r
-\r
- if (fmiFlag > fmiWarning) \r
- return throwException(env, "could not set time");\r
-\r
- // perform one step\r
- for (i=0; i<fmuStruct.nx; i++) \r
- fmuStruct.x[i] += dt*fmuStruct.xdot[i]; // forward Euler method\r
-\r
- fmiFlag = fmu.setContinuousStates(fmuStruct.c, fmuStruct.x, fmuStruct.nx);\r
- if (fmiFlag > fmiWarning) \r
- return throwException(env, "could not set states");\r
-\r
- // Check for step event, e.g. dynamic state selection\r
- fmiFlag = fmu.completedIntegratorStep(fmuStruct.c, &stepEvent);\r
- if (fmiFlag > fmiWarning) return throwException(env, "could not complete intgrator step");\r
- */\r
-/* for (i=0; i<fmuStruct.nz; i++) fmuStruct.prez[i] = fmuStruct.z[i]; \r
- fmiFlag = fmu.getEventIndicators(fmuStruct.c, fmuStruct.z, fmuStruct.nz);\r
- if (fmiFlag > fmiWarning) return throwException(env, "could not retrieve event indicators");\r
- stateEvent = FALSE;\r
- for (i=0; i<fmuStruct.nz; i++) \r
- stateEvent = stateEvent || (fmuStruct.prez[i] * fmuStruct.z[i] < 0); \r
- \r
-\r
- stepEvent = fmiTrue;\r
- // handle events\r
- if (timeEvent || stateEvent || stepEvent) {\r
- \r
- // event iteration in one step, ignoring intermediate results\r
- fmiFlag = fmu.eventUpdate(fmuStruct.c, fmiFalse, &(fmuStruct.eventInfo));\r
- if (fmiFlag > fmiWarning) return throwException(env, "could not perform event update");\r
- \r
- } // if event\r
- */\r
- \r
-/* }\r
-\r
- fflush(stdout);\r
- return 1;\r
-\r
- } else {\r
- string message = fmuId;\r
- env->ReleaseStringUTFChars(id, fmuId);\r
- return throwException(env, "simulateStep: Model id " + message + " not found");\r
- }*/\r
- return 1;\r
-}\r
-\r
-JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_unloadFMU_1\r
- (JNIEnv *env, jobject obj, jint id) {\r
-\r
- int asd = FMI1_CS_UNLOAD(fmus[id].fmu);\r
- return asd;\r
-\r
-}\r
-\r
-JNIEXPORT jstring JNICALL Java_org_simantics_fmil_FMIL_getLastErrorMessage_1\r
- (JNIEnv *env, jobject obj, jstring id) {\r
- return env->NewStringUTF("No errors");\r
-}\r
-\r
-JNIEXPORT jdouble JNICALL Java_org_simantics_fmil_FMIL_getRealValue_1\r
- (JNIEnv *env, jobject obj, jint id, jint vr) {\r
- return FMI1_CS_GET_REAL(fmus[id].fmu, vr);\r
-}\r
-\r
-JNIEXPORT jint JNICALL Java_org_simantics_fmil_FMIL_getIntegerValue_1\r
- (JNIEnv *env, jobject obj, jstring id, jstring variable) {\r
- /*\r
- const char *fmuId = env->GetStringUTFChars(id, 0);\r
- if(exists(fmuId)) {\r
- FMUControlStruct fmuStruct = fmus[fmuId];\r
- env->ReleaseStringUTFChars(id, fmuId);\r
- const char *name = env->GetStringUTFChars(variable, 0);\r
-\r
- if(referenceExists(fmuStruct, name)) {\r
- fmiValueReference vr = getReference(fmuStruct, name);\r
- int result;\r
- fmuStruct.fmu.getInteger(fmuStruct.c, &vr, 1, &result);\r
- env->ReleaseStringUTFChars(variable, name);\r
- return result;\r
-\r
- } else {\r
- string nameString = name;\r
- string message = "Variable " + nameString + " not found";\r
- env->ReleaseStringUTFChars(variable, name);\r
- return throwException(env, message);\r
- }\r
-\r
- } else {\r
- string message = fmuId;\r
- env->ReleaseStringUTFChars(id, fmuId);\r
- return throwException(env, "unloadFMU: Model id " + message + " not found");\r
- }\r
- */\r
- return 1;\r
-\r
-}\r
-\r
-JNIEXPORT jboolean JNICALL Java_org_simantics_fmil_FMIL_getBooleanValue_1\r
- (JNIEnv *env, jobject obj, jstring id, jstring variable) {\r
- /*\r
- const char *fmuId = env->GetStringUTFChars(id, 0);\r
- if(exists(fmuId)) {\r
- FMUControlStruct fmuStruct = fmus[fmuId];\r
- env->ReleaseStringUTFChars(id, fmuId);\r
- const char *name = env->GetStringUTFChars(variable, 0);\r
-\r
- if(referenceExists(fmuStruct, name)) {\r
- fmiValueReference vr = getReference(fmuStruct, name);\r
- fmiBoolean result;\r
- fmuStruct.fmu.getBoolean(fmuStruct.c, &vr, 1, &result);\r
- env->ReleaseStringUTFChars(variable, name);\r
- return result;\r
-\r
- } else {\r
- string nameString = name;\r
- string message = "Variable " + nameString + " not found";\r
- env->ReleaseStringUTFChars(variable, name);\r
- return throwException(env, message);\r
- }\r
-\r
- } else {\r
- string message = fmuId;\r
- env->ReleaseStringUTFChars(id, fmuId);\r
- return throwException(env, "unloadFMU: Model id " + message + " not found");\r
- }*/\r
- return 1;\r
-\r
-}\r
-\r
-JNIEXPORT jstring JNICALL Java_org_simantics_fmil_FMIL_getStringValue_1\r
- (JNIEnv *env, jobject obj, jstring id, jstring variable) {\r
- /*\r
- const char *fmuId = env->GetStringUTFChars(id, 0);\r
- if(exists(fmuId)) {\r
- FMUControlStruct fmuStruct = fmus[fmuId];\r
- env->ReleaseStringUTFChars(id, fmuId);\r
- const char *name = env->GetStringUTFChars(variable, 0);\r
-\r
- if(referenceExists(fmuStruct, name)) {\r
- fmiValueReference vr = getReference(fmuStruct, name);\r
- fmiString result;\r
- fmuStruct.fmu.getString(fmuStruct.c, &vr, 1, &result);\r
- env->ReleaseStringUTFChars(variable, name);\r
- return env->NewStringUTF(result);\r
-\r
- } else {\r
- string nameString = name;\r
- string message = "Variable " + nameString + " not found";\r
- env->ReleaseStringUTFChars(variable, name);\r
- return 0; //throwException(env, message);\r
- }\r
-\r
- } else {\r
- string message = fmuId;\r
- env->ReleaseStringUTFChars(id, fmuId);\r
- return 0; //throwException(env, "unloadFMU: Model id " + message + " not found");\r
- }\r
- */\r
- return 0;\r
-\r
+/* -------------------------------------------------------------------------
+ * 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 <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <map>
+#include <string>
+#include <vector>
+#include <iostream>
+#include <regex>
+
+#include <org_simantics_fmil_FMILJNI.h>
+
+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 <direct.h>
+#define GetCurrentDir _getcwd
+
+using namespace std;
+
+struct FMI1 {
+
+ void *fmu;
+
+ vector<string> variables;
+ vector<string> descriptions;
+ vector<string> declaredTypes;
+ vector<int> valueReferences;
+ vector<int> types;
+ vector<int> variabilities;
+ vector<int> causalities;
+
+ vector<string> declaredTypeNames;
+ vector<string> typeDescriptions;
+ vector<string> quantities;
+ vector<string> units;
+
+ vector<int> 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<string,int> indexes; // indexes for variable names in vars-table
+ map<string,int>::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<fmiValueReference> subscription; // result subscriptions
+ vector<string> allVariables; // all variables in an initialized model
+ vector<fmiValueReference> fmiValueReferences; // all value references
+
+ string lastErrorMessage;
+
+ FMU fmu;
+};
+
+vector<FMI1> fmus;
+
+//map<string,FMUControlStruct> 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<string,FMUControlStruct>::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;i<variableCount;i++) {
+ fmi1.variables.push_back(string(vars[i].name));
+ if(vars[i].description)
+ fmi1.descriptions.push_back(string(vars[i].description));
+ else
+ fmi1.descriptions.push_back(string(""));
+ if(vars[i].declaredType)
+ fmi1.declaredTypes.push_back(string(vars[i].declaredType));
+ else
+ fmi1.declaredTypes.push_back(string(""));
+ fmi1.types.push_back(vars[i].type);
+ fmi1.causalities.push_back(vars[i].causality);
+ fmi1.variabilities.push_back(vars[i].variability);
+ fmi1.valueReferences.push_back(vars[i].vr);
+ }
+
+ if (fmi1.version == 1) {
+ types = FMI1_CS_GET_DECLARED_TYPES(fmi1.fmu, &typeCount, &error);
+ } else if (fmi1.version == 2) {
+ types = FMI2_CS_GET_DECLARED_TYPES(fmi1.fmu, &typeCount, &error);
+ }
+ if (!isEmpty(error)) {
+ string message = "Could not get declared types ";
+ return throwFMILException(env, message += error);
+ }
+
+ for(int i=0;i<typeCount;i++) {
+ fmi1.declaredTypeNames.push_back(string(types[i].name));
+ if(types[i].description)
+ fmi1.typeDescriptions.push_back(string(types[i].description));
+ else
+ fmi1.typeDescriptions.push_back(string(""));
+ if(types[i].quantity)
+ fmi1.quantities.push_back(string(types[i].quantity));
+ else
+ fmi1.quantities.push_back(string(""));
+ if(types[i].unit)
+ fmi1.units.push_back(string(types[i].unit));
+ else
+ fmi1.units.push_back(string(""));
+ }
+
+
+ fmus.push_back(fmi1);
+
+ env->ReleaseStringUTFChars(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<string,int>::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;i<fmus[id].variables.size();i++) {
+ env->SetObjectArrayElement(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;i<fmus[id].descriptions.size();i++) {
+ env->SetObjectArrayElement(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;i<fmus[id].declaredTypes.size();i++) {
+ env->SetObjectArrayElement(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;i<fmus[id].declaredTypeNames.size();i++) {
+ env->SetObjectArrayElement(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;i<fmus[id].typeDescriptions.size();i++) {
+ env->SetObjectArrayElement(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;i<fmus[id].quantities.size();i++) {
+ env->SetObjectArrayElement(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;i<fmus[id].units.size();i++) {
+ env->SetObjectArrayElement(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<fmuStruct.nx; i++)
+ fmuStruct.x[i] += dt*fmuStruct.xdot[i]; // forward Euler method
+
+ fmiFlag = fmu.setContinuousStates(fmuStruct.c, fmuStruct.x, fmuStruct.nx);
+ if (fmiFlag > 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<fmuStruct.nz; i++) fmuStruct.prez[i] = fmuStruct.z[i];
+ fmiFlag = fmu.getEventIndicators(fmuStruct.c, fmuStruct.z, fmuStruct.nz);
+ if (fmiFlag > fmiWarning) return throwException(env, "could not retrieve event indicators");
+ stateEvent = FALSE;
+ for (i=0; i<fmuStruct.nz; i++)
+ stateEvent = stateEvent || (fmuStruct.prez[i] * fmuStruct.z[i] < 0);
+
+
+ stepEvent = fmiTrue;
+ // handle events
+ if (timeEvent || stateEvent || stepEvent) {
+
+ // event iteration in one step, ignoring intermediate results
+ fmiFlag = fmu.eventUpdate(fmuStruct.c, fmiFalse, &(fmuStruct.eventInfo));
+ if (fmiFlag > 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
-package org.simantics.fmil.core;\r
-\r
-import java.io.File;\r
-import java.io.IOException;\r
-import java.io.RandomAccessFile;\r
-import java.nio.channels.FileChannel;\r
-import java.nio.channels.FileLock;\r
-import java.util.ArrayList;\r
-import java.util.HashSet;\r
-import java.util.List;\r
-import java.util.Set;\r
-import java.util.UUID;\r
-\r
-import org.eclipse.core.runtime.FileLocator;\r
-import org.eclipse.core.runtime.Platform;\r
-import org.osgi.framework.Bundle;\r
-import org.simantics.Simantics;\r
-import org.simantics.fmil.core.ExecEnvironment.ARCHType;\r
-import org.simantics.fmil.core.ExecEnvironment.OSType;\r
-import org.simantics.utils.FileUtils;\r
-\r
-import gnu.trove.list.array.TIntArrayList;\r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-\r
-\r
-public class FMIL {\r
-\r
- /**\r
- * Static variables\r
- */\r
- private static int ERROR = 0;\r
- private static int OK = 1;\r
- private static String UNSATISFIED_LINK = "Method not found. DLL might not be loaded properly."; \r
- private static String TEMP_FMU_DIRECTORY_NAME = "fmil"; \r
- public static String TEMP_FMU_COMMON_DIRECTORY; \r
- public static String LOCK_FILE_NAME = "fmil.lock";\r
-\r
- public static Object syncObject = new Object();\r
-\r
- /**\r
- * Static: load native libraries required for the FMU simulation to work.\r
- */\r
- static {\r
- \r
- File[] libraries = new File[2];\r
-\r
- Bundle bundle = null;\r
- \r
- ExecEnvironment env = ExecEnvironment.calculate();\r
- if (env.os == OSType.WINDOWS) {\r
- if (env.arch == ARCHType.X86) {\r
- bundle = Platform.getBundle("org.simantics.fmil.win32");\r
- } else if (env.arch == ARCHType.X86_64) {\r
- bundle = Platform.getBundle("org.simantics.fmil.win64");\r
- }\r
- }\r
- \r
- if (bundle != null) {\r
- try{\r
- String root = FileLocator.getBundleFile(bundle).getAbsolutePath();\r
-// if (env.arch == ARCHType.X86_64) {\r
-// File newFIle = new File(root, "libraries/libexpat.dll");\r
-// System.load(newFIle.getAbsolutePath());\r
-// }\r
-// libraries[0] = new File(root, "libraries/zlibwapi.dll");\r
-// libraries[1] = new File(root, "libraries/miniunz.dll");\r
- libraries[0] = new File(root, "libraries/fmilib_shared.dll");\r
- libraries[1] = new File(root, "libraries/FMUSimulator.dll");\r
- }\r
- catch (Exception e) {\r
- e.printStackTrace();\r
- }\r
- }\r
-\r
- for(File library : libraries) {\r
- if(library == null) {\r
- System.err.println("FMU library not loaded. FMU simulation not working.");\r
- continue;\r
- } else if(!library.isFile()) {\r
- System.err.println(library.getAbsolutePath() + " not found");\r
- } else {\r
- try {\r
- System.load(library.getAbsolutePath());\r
- } catch (Throwable t) {\r
- System.err.println(t.getMessage());\r
- }\r
- } \r
- }\r
- }\r
-\r
- /**\r
- * Static: initialize fmu temp folder\r
- */\r
- static {\r
- File dir = Simantics.getTemporaryDirectory(TEMP_FMU_DIRECTORY_NAME);\r
- TEMP_FMU_COMMON_DIRECTORY = dir.getAbsolutePath(); \r
- }\r
-\r
-\r
- private String fmuDir;\r
- private int id;\r
-\r
- public String TEMP_FOLDER_1;\r
- public String TEMP_FOLDER_2;\r
- public String TEMP_FMU_DIRECTORY;\r
- private String dirName;\r
-\r
- private String[] variableNames;\r
- private String[] variableDescriptions;\r
- private String[] variableDeclaredTypes;\r
- private int[] variableReferences;\r
- private int[] variableTypes;\r
- private int[] variableCausalities;\r
- private int[] variableVariabilities;\r
- \r
- private String[] declaredTypes;\r
- private String[] declaredTypeDescriptions;\r
- private String[] declaredTypeQuantities;\r
- private String[] declaredTypeUnits;\r
- \r
- private TObjectIntHashMap<String> variableMap = new TObjectIntHashMap<String>();\r
- \r
- private Set<String> subscriptionSet = new HashSet<String>();\r
- private TIntArrayList subscription = new TIntArrayList();\r
- private ArrayList<String> subscribedNames = new ArrayList<String>();\r
- \r
- public List<String> getSubscribedNames() {\r
- return subscribedNames;\r
- }\r
- \r
- public boolean subscribe(String name) throws FMILException {\r
- // Safety check\r
- int vr = variableMap.get(name);\r
- if(vr == 0) return false;\r
- if(!subscriptionSet.add(name)) return false;\r
- subscribedNames.add(name);\r
- System.err.println("subscribed : " + name + " => " + subscribedNames.size());\r
- subscription.add(vr);\r
- subscribe(new int[] { vr });\r
- return true;\r
- }\r
-\r
- public FMIL() {\r
- // Create a directory for this control\r
- File tempDir = new File(TEMP_FMU_COMMON_DIRECTORY, UUID.randomUUID().toString());\r
- tempDir.mkdir();\r
- TEMP_FMU_DIRECTORY = tempDir.getAbsolutePath();\r
-\r
- // Create two directories inside the temp directory for this control\r
- dirName = UUID.randomUUID().toString();\r
- File fmuDir = new File(TEMP_FMU_DIRECTORY, dirName);\r
- fmuDir.mkdir();\r
-\r
- TEMP_FOLDER_1 = fmuDir.toString();\r
- TEMP_FOLDER_2 = fmuDir.toString() + "_2";\r
-\r
- // Lock fmu directory in temp directory\r
- lockFMUDirectory();\r
- }\r
-\r
- public int getModelIDNew() {\r
- return id;\r
- }\r
-\r
- public String getModelID() {\r
- return dirName;\r
- }\r
-\r
- public String getFmuDir() {\r
- return fmuDir;\r
- }\r
-\r
- /**\r
- * Load fmu from a given file path. Releases the (possible) previously\r
- * loaded fmu.\r
- * \r
- * @param path absolute file path for fmu file\r
- * @throws FMILException\r
- */\r
- private int fmuN = 0;\r
- private boolean fmuLoaded = false;\r
- public void loadFMUFile(String path) throws FMILException {\r
-\r
- synchronized(syncObject) {\r
-\r
- if(fmuN % 2 == 0) {\r
- fmuDir = TEMP_FOLDER_1;\r
- fmuN++;\r
- } else {\r
- fmuDir = TEMP_FOLDER_2;\r
- fmuN = 0;\r
- }\r
-\r
- File tempDir = new File(fmuDir);\r
- if(tempDir.isDirectory()) {\r
- try {\r
- FileUtils.deleteAll(tempDir);\r
- } catch (IOException e) {\r
- throw new FMILException("Could not create temp folder for fmu");\r
- }\r
- tempDir.mkdir();\r
- } else {\r
- tempDir.mkdir();\r
- }\r
-\r
-\r
- try {\r
- String tmpPath = tempDir.getAbsolutePath();\r
- if(!tmpPath.endsWith("\\"))\r
- tmpPath = tmpPath + "\\";\r
- id = loadFMUFile_(path, tmpPath);\r
- \r
- getAllVariables();\r
- getAllVariableReferences();\r
- \r
- for(int i=0;i<variableNames.length;i++) {\r
- variableMap.put(variableNames[i], variableReferences[i]);\r
- }\r
-\r
- fmuLoaded = true;\r
- } catch (UnsatisfiedLinkError err) {\r
- throw new FMILException(UNSATISFIED_LINK, err);\r
- } catch (Exception e) {\r
- throw new FMILException(e.getMessage());\r
- }\r
- }\r
- }\r
-\r
- private native int loadFMUFile_(String path, String toDir);\r
-\r
- /**\r
- * Set a step length for simulation\r
- * \r
- * @param step Step length for simulation\r
- * @throws FMILException\r
- */\r
- public void setStepLength(double step) throws FMILException {\r
- synchronized(syncObject) {\r
-\r
- try {\r
-\r
- int ret = setStepLength_(getModelIDNew(), step);\r
- if(ret == ERROR)\r
- throw new FMILException(getLastErrorMessage());\r
-\r
- } catch (UnsatisfiedLinkError err) {\r
- throw new FMILException(UNSATISFIED_LINK);\r
- } catch (Exception e) {\r
- throw new FMILException(e.getMessage());\r
- }\r
- }\r
- }\r
-\r
- private native int setStepLength_(int id, double step);\r
-\r
- /**\r
- * Instantiates a simulation. \r
- * <p>\r
- * Make sure that an FMU is loaded first.\r
- * @throws FMILException\r
- */\r
- public void instantiateSimulation() throws FMILException {\r
- synchronized(syncObject) {\r
-\r
- try {\r
-\r
- int ret = instantiateSimulation_(getModelIDNew()); \r
- if(ret == ERROR)\r
- throw new FMILException(getLastErrorMessage());\r
-\r
- } catch (UnsatisfiedLinkError err) {\r
- throw new FMILException(UNSATISFIED_LINK);\r
- } catch (Exception e) {\r
- throw new FMILException(e.getMessage());\r
- }\r
- }\r
- }\r
-\r
- private native int instantiateSimulation_(int id);\r
-\r
- \r
- /**\r
- * Initializes a simulation. \r
- * <p>\r
- * Make sure that simulation is instantiated first!\r
- * @throws FMILException\r
- */\r
- public void initializeSimulation() throws FMILException {\r
- synchronized(syncObject) {\r
-\r
- try {\r
-\r
- int ret = initializeSimulation_(getModelIDNew()); \r
- if(ret == ERROR)\r
- throw new FMILException(getLastErrorMessage());\r
-\r
- } catch (UnsatisfiedLinkError err) {\r
- throw new FMILException(UNSATISFIED_LINK);\r
- } catch (Exception e) {\r
- throw new FMILException(e.getMessage());\r
- }\r
- }\r
- }\r
-\r
- private native int initializeSimulation_(int id);\r
-\r
- /**\r
- * Subscribe a set of variables from a loaded simulation.\r
- * <p>\r
- * Make sure that an FMU is loaded first.\r
- * @param variables Array of variables\r
- * @throws FMILException\r
- */\r
- public void subscribe(int[] variables) throws FMILException {\r
- synchronized(syncObject) {\r
-\r
- try {\r
-\r
- int ret = subscribe_(getModelIDNew(), variables); \r
- if(ret == ERROR)\r
- throw new FMILException(getLastErrorMessage());\r
-\r
- } catch (UnsatisfiedLinkError err) {\r
- throw new FMILException(UNSATISFIED_LINK);\r
- } catch (Exception e) {\r
- throw new FMILException(e.getMessage());\r
- }\r
- }\r
- }\r
-\r
- private native int subscribe_(int id, int[] variables);\r
-\r
- /**\r
- * Set a new (Real, double) value for a variable. If the variable is a \r
- * parameter, the change is effective immediately.\r
- * \r
- * @param name Variable\r
- * @param value New (Real, double) value\r
- * @throws FMILException\r
- */\r
- public void setRealValue(String name, double value) throws FMILException {\r
- \r
- synchronized(syncObject) {\r
-\r
- try {\r
-\r
- int ret = setRealValue_(getModelIDNew(), variableMap.get(name), value); \r
- if(ret == ERROR)\r
- throw new FMILException(getLastErrorMessage());\r
-\r
- } catch (UnsatisfiedLinkError err) {\r
- throw new FMILException(UNSATISFIED_LINK);\r
- } catch (Exception e) {\r
- throw new FMILException(e.getMessage());\r
- }\r
- \r
- }\r
- \r
- }\r
-\r
- public void setRealValue(int variableReference, double value) throws FMILException {\r
- \r
- synchronized(syncObject) {\r
-\r
- try {\r
-\r
- int ret = setRealValue_(getModelIDNew(), variableReference, value); \r
- if(ret == ERROR)\r
- throw new FMILException(getLastErrorMessage());\r
-\r
- } catch (UnsatisfiedLinkError err) {\r
- throw new FMILException(UNSATISFIED_LINK);\r
- } catch (Exception e) {\r
- throw new FMILException(e.getMessage());\r
- }\r
- \r
- }\r
- \r
- }\r
-\r
- private native int setRealValue_(int id, int variableReference, double value);\r
-\r
-// /**\r
-// * Set a new (integer) value for a variable. If the variable is a \r
-// * parameter, the change is effective immediately.\r
-// * \r
-// * @param name Variable\r
-// * @param value New (integer) value\r
-// * @throws FMILException\r
-// */\r
-// public void setIntegerValue(String name, int value) throws FMILException {\r
-// synchronized(syncObject) {\r
-//\r
-// try {\r
-//\r
-// int ret = setIntegerValue_(getModelID(), name, value); \r
-// if(ret == ERROR)\r
-// throw new FMILException(getLastErrorMessage());\r
-//\r
-// } catch (UnsatisfiedLinkError err) {\r
-// throw new FMILException(UNSATISFIED_LINK);\r
-// } catch (Exception e) {\r
-// throw new FMILException(e.getMessage());\r
-// }\r
-// }\r
-// }\r
-// private native int setIntegerValue_(String id, String name, int value);\r
-//\r
-// /**\r
-// * Set a new (boolean) value for a variable. If the variable is a \r
-// * parameter, the change is effective immediately.\r
-// * \r
-// * @param name Variable\r
-// * @param value New (boolean) value\r
-// * @throws FMILException\r
-// */\r
-// public void setBooleanValue(String name, boolean value) throws FMILException {\r
-// synchronized(syncObject) {\r
-//\r
-// try {\r
-//\r
-// int ret = setBooleanValue_(getModelID(), name, value); \r
-// if(ret == ERROR)\r
-// throw new FMILException(getLastErrorMessage());\r
-//\r
-// } catch (UnsatisfiedLinkError err) {\r
-// throw new FMILException(UNSATISFIED_LINK);\r
-// } catch (Exception e) {\r
-// throw new FMILException(e.getMessage());\r
-// }\r
-// }\r
-// }\r
-// private native int setBooleanValue_(String id, String name, boolean value);\r
-//\r
-// public void setTime(double time) throws FMILException {\r
-// synchronized(syncObject) {\r
-//\r
-// try {\r
-//\r
-// int ret = setTime_(getModelID(), time); \r
-// if(ret == ERROR)\r
-// throw new FMILException(getLastErrorMessage());\r
-//\r
-// } catch (UnsatisfiedLinkError err) {\r
-// throw new FMILException(UNSATISFIED_LINK);\r
-// } catch (Exception e) {\r
-// throw new FMILException(e.getMessage());\r
-// }\r
-// }\r
-// }\r
-// private native int setTime_(String id, double time);\r
-\r
- /**\r
- * Simulate one step forward. The step length can be set with\r
- * setStepLength()\r
- * \r
- * @throws FMILException\r
- */\r
- public void simulateStep() throws FMILException {\r
- synchronized(syncObject) {\r
-\r
- try {\r
-\r
- int ret = simulateStep_(getModelIDNew()); \r
- if(ret == ERROR)\r
- throw new FMILException(getLastErrorMessage());\r
-\r
- } catch (UnsatisfiedLinkError err) {\r
- throw new FMILException(UNSATISFIED_LINK);\r
- } catch (Exception e) {\r
- throw new FMILException(e.getMessage());\r
- }\r
- }\r
- }\r
- private native int simulateStep_(int id);\r
-\r
- /**\r
- * Get an array containing the current values for subscribed variables. The\r
- * values are in the same order as in the subscription.\r
- * \r
- * @param results An array the size of subscribed results\r
- * @return\r
- */\r
- public double[] getSubscribedResults() throws FMILException {\r
- synchronized(syncObject) {\r
-\r
- try {\r
-\r
- double[] results = new double[subscription.size()];\r
- return getSubscribedResults_(getModelIDNew(), results);\r
-\r
- } catch (UnsatisfiedLinkError err) {\r
- throw new FMILException(UNSATISFIED_LINK);\r
- } catch (Exception e) {\r
- throw new FMILException(e.getMessage());\r
- }\r
- }\r
- }\r
-\r
- private native double[] getSubscribedResults_(int id, double[] results);\r
- \r
-\r
- /**\r
- * Unload FMU and the dll:s that it requires.\r
- * <p>\r
- * To be called after all FMU simulations are ended. \r
- * If the fmu is loaded again / changed, call to loadFMUFile is sufficient. loadFMUFile \r
- * releases the previous fmu.dll \r
- * \r
- * @throws FMILException\r
- */\r
- public void unloadFMU() throws FMILException {\r
- synchronized(syncObject) {\r
-\r
- try {\r
-\r
- unlockFMUDirectory();\r
- if(fmuLoaded) {\r
- int ret = unloadFMU_(getModelIDNew()); \r
- if(ret == ERROR)\r
- throw new FMILException(getLastErrorMessage());\r
- }\r
- removeFMUDirectoryContents();\r
-\r
- } catch (UnsatisfiedLinkError err) {\r
- throw new FMILException(UNSATISFIED_LINK);\r
- } catch (Exception e) {\r
- throw new FMILException(e.getMessage());\r
- }\r
- }\r
- }\r
- private native int unloadFMU_(int id);\r
- \r
-// /**\r
-// * Checks if fmu has been initialized\r
-// * @return current simulation time\r
-// */\r
-// public boolean isInitialized() throws FMILException {\r
-// synchronized(syncObject) {\r
-// try {\r
-// return isInitialized_(getModelID());\r
-// } catch (UnsatisfiedLinkError err) {\r
-// throw new FMILException(UNSATISFIED_LINK);\r
-// } catch (Exception e) {\r
-// throw new FMILException(e.getMessage());\r
-// }\r
-// }\r
-// }\r
-//\r
-// private native boolean isInitialized_(String id);\r
-//\r
- /**\r
- * Get the current simulation time\r
- * @return current simulation time\r
- */\r
- public double getTime() throws FMILException {\r
- synchronized(syncObject) {\r
-\r
- try {\r
-\r
- return getTime_(getModelIDNew());\r
-\r
- } catch (UnsatisfiedLinkError err) {\r
- throw new FMILException(UNSATISFIED_LINK);\r
- } catch (Exception e) {\r
- throw new FMILException(e.getMessage());\r
- }\r
- }\r
- }\r
-\r
- private native double getTime_(int id);\r
-\r
- /**\r
- * Get all variables in a loaded model\r
- * @return all variables in a loaded model\r
- */\r
- public String[] getAllVariables() throws FMILException {\r
- synchronized(syncObject) {\r
-\r
- try {\r
-\r
- if(variableNames == null) {\r
- variableNames = getAllVariables_(getModelIDNew());\r
- }\r
- return variableNames;\r
-\r
- } catch (UnsatisfiedLinkError err) {\r
- throw new FMILException(UNSATISFIED_LINK);\r
- } catch (Exception e) {\r
- throw new FMILException(e.getMessage());\r
- }\r
- }\r
- }\r
-\r
- private native String[] getAllVariables_(int id);\r
-\r
- public String[] getAllVariableDescriptions() throws FMILException {\r
- synchronized(syncObject) {\r
-\r
- try {\r
-\r
- if(variableDescriptions == null) {\r
- variableDescriptions = getAllVariableDescriptions_(getModelIDNew());\r
- }\r
- return variableDescriptions;\r
-\r
- } catch (UnsatisfiedLinkError err) {\r
- throw new FMILException(UNSATISFIED_LINK);\r
- } catch (Exception e) {\r
- throw new FMILException(e.getMessage());\r
- }\r
- }\r
- }\r
-\r
- private native String[] getAllVariableDescriptions_(int id);\r
- \r
- public String[] getAllVariableDeclaredTypes() throws FMILException {\r
- synchronized(syncObject) {\r
-\r
- try {\r
-\r
- if(variableDeclaredTypes == null) {\r
- variableDeclaredTypes = getAllVariableDeclaredTypes_(getModelIDNew());\r
- }\r
- return variableDeclaredTypes;\r
-\r
- } catch (UnsatisfiedLinkError err) {\r
- throw new FMILException(UNSATISFIED_LINK);\r
- } catch (Exception e) {\r
- throw new FMILException(e.getMessage());\r
- }\r
- }\r
- }\r
-\r
- private native String[] getAllVariableDeclaredTypes_(int id);\r
-\r
- public int[] getAllVariableReferences() throws FMILException {\r
- synchronized(syncObject) {\r
-\r
- try {\r
-\r
- if(variableReferences == null) {\r
- variableReferences = getAllVariableReferences_(getModelIDNew(), new int[variableNames.length]); \r
- }\r
- return variableReferences;\r
-\r
- } catch (UnsatisfiedLinkError err) {\r
- throw new FMILException(UNSATISFIED_LINK);\r
- } catch (Exception e) {\r
- throw new FMILException(e.getMessage());\r
- }\r
- }\r
- }\r
-\r
- private native int[] getAllVariableReferences_(int id, int[] array);\r
-\r
- public int[] getAllVariableTypes() throws FMILException {\r
- synchronized(syncObject) {\r
-\r
- try {\r
-\r
- if(variableTypes == null) {\r
- variableTypes = getAllVariableTypes_(getModelIDNew(), new int[variableNames.length]); \r
- }\r
- return variableTypes;\r
-\r
- } catch (UnsatisfiedLinkError err) {\r
- throw new FMILException(UNSATISFIED_LINK);\r
- } catch (Exception e) {\r
- throw new FMILException(e.getMessage());\r
- }\r
- }\r
- }\r
-\r
- private native int[] getAllVariableTypes_(int id, int[] array);\r
-\r
- public int[] getAllVariableCausalities() throws FMILException {\r
- synchronized(syncObject) {\r
-\r
- try {\r
-\r
- if(variableCausalities == null) {\r
- variableCausalities = getAllVariableCausalities_(getModelIDNew(), new int[variableNames.length]); \r
- }\r
- return variableCausalities;\r
-\r
- } catch (UnsatisfiedLinkError err) {\r
- throw new FMILException(UNSATISFIED_LINK);\r
- } catch (Exception e) {\r
- throw new FMILException(e.getMessage());\r
- }\r
- }\r
- }\r
-\r
- private native int[] getAllVariableCausalities_(int id, int[] array);\r
-\r
- public int[] getAllVariableVariabilities() throws FMILException {\r
- synchronized(syncObject) {\r
-\r
- try {\r
-\r
- if(variableVariabilities == null) {\r
- variableVariabilities = getAllVariableVariabilities_(getModelIDNew(), new int[variableNames.length]); \r
- }\r
- return variableVariabilities;\r
-\r
- } catch (UnsatisfiedLinkError err) {\r
- throw new FMILException(UNSATISFIED_LINK);\r
- } catch (Exception e) {\r
- throw new FMILException(e.getMessage());\r
- }\r
- }\r
- }\r
-\r
- private native int[] getAllVariableVariabilities_(int id, int[] array);\r
-\r
- /**\r
- * Get all variables in a loaded model\r
- * @return all variables in a loaded model\r
- */\r
- public String[] getAllDeclaredTypes() throws FMILException {\r
- synchronized(syncObject) {\r
-\r
- try {\r
-\r
- if(declaredTypes == null) {\r
- declaredTypes = getAllDeclaredTypes_(getModelIDNew());\r
- }\r
- return declaredTypes;\r
-\r
- } catch (UnsatisfiedLinkError err) {\r
- throw new FMILException(UNSATISFIED_LINK);\r
- } catch (Exception e) {\r
- throw new FMILException(e.getMessage());\r
- }\r
- }\r
- }\r
-\r
- private native String[] getAllDeclaredTypes_(int id);\r
- \r
- public String[] getAllDeclaredTypeDescriptions() throws FMILException {\r
- synchronized(syncObject) {\r
-\r
- try {\r
-\r
- if(declaredTypeDescriptions == null) {\r
- declaredTypeDescriptions = getAllDeclaredTypeDescriptions_(getModelIDNew());\r
- }\r
- return declaredTypeDescriptions;\r
-\r
- } catch (UnsatisfiedLinkError err) {\r
- throw new FMILException(UNSATISFIED_LINK);\r
- } catch (Exception e) {\r
- throw new FMILException(e.getMessage());\r
- }\r
- }\r
- }\r
-\r
- private native String[] getAllDeclaredTypeDescriptions_(int id);\r
- \r
- public String[] getAllDeclaredTypeQuantities() throws FMILException {\r
- synchronized(syncObject) {\r
-\r
- try {\r
-\r
- if(declaredTypeQuantities == null) {\r
- declaredTypeQuantities = getAllDeclaredTypeQuantities_(getModelIDNew());\r
- }\r
- return declaredTypeQuantities;\r
-\r
- } catch (UnsatisfiedLinkError err) {\r
- throw new FMILException(UNSATISFIED_LINK);\r
- } catch (Exception e) {\r
- throw new FMILException(e.getMessage());\r
- }\r
- }\r
- }\r
-\r
- private native String[] getAllDeclaredTypeQuantities_(int id);\r
-\r
- public String[] getAllDeclaredTypeUnits() throws FMILException {\r
- synchronized(syncObject) {\r
-\r
- try {\r
-\r
- if(declaredTypeUnits == null) {\r
- declaredTypeUnits = getAllDeclaredTypeUnits_(getModelIDNew());\r
- }\r
- return declaredTypeUnits;\r
-\r
- } catch (UnsatisfiedLinkError err) {\r
- throw new FMILException(UNSATISFIED_LINK);\r
- } catch (Exception e) {\r
- throw new FMILException(e.getMessage());\r
- }\r
- }\r
- }\r
-\r
- private native String[] getAllDeclaredTypeUnits_(int id);\r
- \r
- \r
-//\r
-// /**\r
-// * Get all variables from model that match the filter (and time variable)\r
-// * \r
-// * @param regexp Regular expression filter\r
-// * @return An array of variable names that match regexp filter (and time-variable)\r
-// * @throws FMILException\r
-// */\r
-// public String[] filterVariables(String regexp) throws FMILException { \r
-// synchronized(syncObject) {\r
-// try {\r
-//\r
-// return filterVariables_(getModelID(), regexp + "|time");\r
-//\r
-// } catch (UnsatisfiedLinkError err) {\r
-// throw new FMILException(UNSATISFIED_LINK);\r
-// } catch (Exception e) {\r
-// throw new FMILException(e.getMessage());\r
-// }\r
-// }\r
-// }\r
-//\r
-// private native String[] filterVariables_(String id, String regexp);\r
-//\r
- /**\r
- * Get the last error message\r
- * @return Last error message\r
- */\r
- public String getLastErrorMessage() throws FMILException {\r
- synchronized(syncObject) {\r
-\r
- try {\r
-\r
- return "err";\r
- //return getLastErrorMessage_(getModelID());\r
-\r
- } catch (UnsatisfiedLinkError err) {\r
- throw new FMILException(UNSATISFIED_LINK);\r
- } catch (Exception e) {\r
- throw new FMILException(e.getMessage());\r
- }\r
- }\r
- }\r
-//\r
-// private native String getLastErrorMessage_(String id);\r
-\r
- /**\r
- * Get a real (double) value for variable\r
- * @param name Name of the variable\r
- * @return value\r
- * @throws FMILException\r
- */\r
- public double getRealValue(String name) throws FMILException {\r
- synchronized(syncObject) {\r
-\r
- try {\r
- // TODO: printtaa id ja name, jotta saadaan virheessä kiinni\r
- double result = getRealValue_(getModelIDNew(), variableMap.get(name));\r
- System.err.println("getRealValue " + name + " = " + result);\r
- return result;\r
- } catch (UnsatisfiedLinkError err) {\r
- throw new FMILException(UNSATISFIED_LINK);\r
- } catch (Exception e) {\r
- throw new FMILException(e.getMessage());\r
- }\r
- }\r
- }\r
-\r
- private native double getRealValue_(int id, int variableReference);\r
-\r
-// /**\r
-// * Get a string value for variable\r
-// * @param name Name of the variable\r
-// * @return value\r
-// * @throws FMILException\r
-// */\r
-// public String getStringValue(String name) throws FMILException {\r
-// synchronized(syncObject) {\r
-//\r
-// try {\r
-// return getStringValue_(getModelID(), name); \r
-// } catch (UnsatisfiedLinkError err) {\r
-// throw new FMILException(UNSATISFIED_LINK);\r
-// } catch (Exception e) {\r
-// throw new FMILException(e.getMessage());\r
-// }\r
-// }\r
-// }\r
-//\r
-// private native String getStringValue_(String id, String name);\r
-//\r
-// /**\r
-// * Get an integer value for variable\r
-// * @param name Name of the variable\r
-// * @return value\r
-// * @throws FMILException\r
-// */\r
-// public int getIntegerValue(String name) throws FMILException {\r
-// synchronized(syncObject) {\r
-//\r
-// try {\r
-// return getIntegerValue_(getModelID(), name); \r
-// } catch (UnsatisfiedLinkError err) {\r
-// throw new FMILException(UNSATISFIED_LINK);\r
-// } catch (Exception e) {\r
-// throw new FMILException(e.getMessage());\r
-// }\r
-// }\r
-// }\r
-//\r
-// private native int getIntegerValue_(String id, String name);\r
-//\r
-// /**\r
-// * Get a real (double) value for variable\r
-// * @param name Name of the variable\r
-// * @return value\r
-// * @throws FMILException\r
-// */\r
-// public boolean getBooleanValue(String name) throws FMILException {\r
-// synchronized(syncObject) {\r
-//\r
-// try {\r
-// return getBooleanValue_(getModelID(), name); \r
-// } catch (UnsatisfiedLinkError err) {\r
-// throw new FMILException(UNSATISFIED_LINK);\r
-// } catch (Exception e) {\r
-// throw new FMILException(e.getMessage());\r
-// }\r
-// }\r
-// }\r
-//\r
-// private native boolean getBooleanValue_(String id, String name);\r
-\r
- private FileChannel channel; \r
- private FileLock lock;\r
-\r
- @SuppressWarnings("resource")\r
- private boolean lockFMUDirectory() {\r
-\r
- try {\r
- // Get a file channel for the lock file\r
- File lockFile = new File(TEMP_FMU_DIRECTORY, LOCK_FILE_NAME);\r
- if(!lockFile.isFile())\r
- lockFile.createNewFile();\r
-\r
- channel = new RandomAccessFile(lockFile, "rw").getChannel();\r
-\r
- // Use the file channel to create a lock on the file.\r
- // This method blocks until it can retrieve the lock.\r
- lock = channel.lock();\r
-\r
- // // Try acquiring the lock without blocking. This method returns\r
- // // null or throws an exception if the file is already locked.\r
- // try {\r
- // lock = channel.tryLock();\r
- // } catch (OverlappingFileLockException e) {\r
- // // File is already locked in this thread or virtual machine\r
- // }\r
- } catch (IOException e) {\r
- return false;\r
- }\r
-\r
- return true;\r
- }\r
-\r
- private boolean unlockFMUDirectory() {\r
- try {\r
- // Release the lock\r
- if(lock != null)\r
- lock.release();\r
-\r
- // Close the file\r
- if(channel != null)\r
- channel.close();\r
- } catch (IOException e) {\r
- return false;\r
- }\r
- return true;\r
- }\r
-\r
- private boolean removeFMUDirectoryContents() {\r
- // Remove contents\r
- try {\r
- File tempDir = new File(TEMP_FMU_DIRECTORY);\r
- FileUtils.deleteAll(tempDir);\r
- tempDir.delete();\r
- } catch (IOException e) {\r
- return false;\r
- }\r
- return true;\r
- }\r
-}\r
+package org.simantics.fmil.core;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileLock;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.Platform;
+import org.osgi.framework.Bundle;
+import org.simantics.Simantics;
+import org.simantics.fmil.core.ExecEnvironment.ARCHType;
+import org.simantics.fmil.core.ExecEnvironment.OSType;
+import org.simantics.utils.FileUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import gnu.trove.list.array.TIntArrayList;
+import gnu.trove.map.hash.TObjectIntHashMap;
+
+
+public class FMIL {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(FMIL.class);
+
+ /**
+ * Static variables
+ */
+ private static int OK = 0;
+ private static int ERROR = 1;
+ private static String UNSATISFIED_LINK = "Method not found. DLL might not be loaded properly.";
+ private static String TEMP_FMU_DIRECTORY_NAME = "fmil";
+ public static String TEMP_FMU_COMMON_DIRECTORY;
+ public static String LOCK_FILE_NAME = "fmil.lock";
+
+ public static Object syncObject = new Object();
+
+ /**
+ * Static: load native libraries required for the FMU simulation to work.
+ */
+ static {
+
+ File[] libraries = new File[2];
+
+ Bundle bundle = null;
+
+ ExecEnvironment env = ExecEnvironment.calculate();
+ if (env.os == OSType.WINDOWS) {
+ if (env.arch == ARCHType.X86) {
+ bundle = Platform.getBundle("org.simantics.fmil.win32");
+ } else if (env.arch == ARCHType.X86_64) {
+ bundle = Platform.getBundle("org.simantics.fmil.win64");
+ }
+ }
+
+ if (bundle != null) {
+ try{
+ String root = FileLocator.getBundleFile(bundle).getAbsolutePath();
+// if (env.arch == ARCHType.X86_64) {
+// File newFIle = new File(root, "libraries/libexpat.dll");
+// System.load(newFIle.getAbsolutePath());
+// }
+// libraries[0] = new File(root, "libraries/zlibwapi.dll");
+// libraries[1] = new File(root, "libraries/miniunz.dll");
+ libraries[0] = new File(root, "libraries/fmilib_shared.dll");
+ libraries[1] = new File(root, "libraries/FMUSimulator.dll");
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ for(File library : libraries) {
+ if(library == null) {
+ System.err.println("FMU library not loaded. FMU simulation not working.");
+ continue;
+ } else if(!library.isFile()) {
+ System.err.println(library.getAbsolutePath() + " not found");
+ } else {
+ try {
+ System.load(library.getAbsolutePath());
+ } catch (Throwable t) {
+ System.err.println(t.getMessage());
+ }
+ }
+ }
+ }
+
+ /**
+ * Static: initialize fmu temp folder
+ */
+ static {
+ File dir = Simantics.getTemporaryDirectory(TEMP_FMU_DIRECTORY_NAME);
+ TEMP_FMU_COMMON_DIRECTORY = dir.getAbsolutePath();
+ }
+
+
+ private String fmuDir;
+ private int id;
+
+ public String TEMP_FOLDER_1;
+ public String TEMP_FOLDER_2;
+ public String TEMP_FMU_DIRECTORY;
+ private String dirName;
+
+ private String[] variableNames;
+ private String[] variableDescriptions;
+ private String[] variableDeclaredTypes;
+ private int[] variableReferences;
+ private int[] variableTypes;
+ private int[] variableCausalities;
+ private int[] variableVariabilities;
+
+ private String[] declaredTypes;
+ private String[] declaredTypeDescriptions;
+ private String[] declaredTypeQuantities;
+ private String[] declaredTypeUnits;
+
+ private TObjectIntHashMap<String> variableMap = new TObjectIntHashMap<String>();
+
+ private Set<String> subscriptionSet = new HashSet<String>();
+ private TIntArrayList subscription = new TIntArrayList();
+ private ArrayList<String> subscribedNames = new ArrayList<String>();
+
+ public List<String> getSubscribedNames() {
+ return subscribedNames;
+ }
+
+ public boolean subscribe(String name) throws FMILException {
+ // Safety check
+ int vr = variableMap.get(name);
+ if(vr == 0) return false;
+ if(!subscriptionSet.add(name)) return false;
+ subscribedNames.add(name);
+ System.err.println("subscribed : " + name + " => " + subscribedNames.size());
+ subscription.add(vr);
+ subscribe(new int[] { vr });
+ return true;
+ }
+
+ public FMIL() {
+ // Create a directory for this control
+ File tempDir = new File(TEMP_FMU_COMMON_DIRECTORY, UUID.randomUUID().toString());
+ tempDir.mkdir();
+ TEMP_FMU_DIRECTORY = tempDir.getAbsolutePath();
+
+ // Create two directories inside the temp directory for this control
+ dirName = UUID.randomUUID().toString();
+ File fmuDir = new File(TEMP_FMU_DIRECTORY, dirName);
+ fmuDir.mkdir();
+
+ TEMP_FOLDER_1 = fmuDir.toString();
+ TEMP_FOLDER_2 = fmuDir.toString() + "_2";
+
+ // Lock fmu directory in temp directory
+ lockFMUDirectory();
+ }
+
+ public int getModelIDNew() {
+ return id;
+ }
+
+ public String getModelID() {
+ return dirName;
+ }
+
+ public String getFmuDir() {
+ return fmuDir;
+ }
+
+ /**
+ * Load fmu from a given file path. Releases the (possible) previously
+ * loaded fmu.
+ *
+ * @param path absolute file path for fmu file
+ * @throws FMILException
+ */
+ private int fmuN = 0;
+ private boolean fmuLoaded = false;
+ public void loadFMUFile(String path) throws FMILException {
+
+ synchronized(syncObject) {
+
+ if(fmuN % 2 == 0) {
+ fmuDir = TEMP_FOLDER_1;
+ fmuN++;
+ } else {
+ fmuDir = TEMP_FOLDER_2;
+ fmuN = 0;
+ }
+
+ File tempDir = new File(fmuDir);
+ if(tempDir.isDirectory()) {
+ try {
+ FileUtils.deleteAll(tempDir);
+ } catch (IOException e) {
+ throw new FMILException("Could not create temp folder for fmu");
+ }
+ tempDir.mkdir();
+ } else {
+ tempDir.mkdir();
+ }
+
+
+ try {
+ String tmpPath = tempDir.getAbsolutePath();
+ if(!tmpPath.endsWith("\\"))
+ tmpPath = tmpPath + "\\";
+ id = loadFMUFile_(path, tmpPath);
+
+ getAllVariables();
+ getAllVariableReferences();
+
+ for(int i=0;i<variableNames.length;i++) {
+ variableMap.put(variableNames[i], variableReferences[i]);
+ }
+
+ fmuLoaded = true;
+ } catch (UnsatisfiedLinkError err) {
+ throw new FMILException(UNSATISFIED_LINK, err);
+ } catch (Exception e) {
+ throw new FMILException(e.getMessage());
+ }
+ }
+ }
+
+ private native int loadFMUFile_(String path, String toDir);
+
+ /**
+ * Set a step length for simulation
+ *
+ * @param step Step length for simulation
+ * @throws FMILException
+ */
+ public void setStepLength(double step) throws FMILException {
+ synchronized(syncObject) {
+
+ try {
+ int ret = setStepLength_(getModelIDNew(), step);
+ if(ret != OK)
+ LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
+
+ } catch (UnsatisfiedLinkError err) {
+ throw new FMILException(UNSATISFIED_LINK);
+ } catch (Exception e) {
+ throw new FMILException(e.getMessage());
+ }
+ }
+ }
+
+ private native int setStepLength_(int id, double step);
+
+ /**
+ * Instantiates a simulation.
+ * <p>
+ * Make sure that an FMU is loaded first.
+ * @throws FMILException
+ */
+ public void instantiateSimulation() throws FMILException {
+ synchronized(syncObject) {
+
+ try {
+
+ int ret = instantiateSimulation_(getModelIDNew());
+ if(ret != OK)
+ LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
+
+ } catch (FMILException e) {
+ throw e;
+ } catch (UnsatisfiedLinkError err) {
+ throw new FMILException(UNSATISFIED_LINK);
+ } catch (Exception e) {
+ throw new FMILException(e.getMessage());
+ }
+ }
+ }
+
+ private native int instantiateSimulation_(int id) throws FMILException;
+
+
+ /**
+ * Initializes a simulation.
+ * <p>
+ * Make sure that simulation is instantiated first!
+ * @throws FMILException
+ */
+ public void initializeSimulation() throws FMILException {
+ synchronized(syncObject) {
+
+ try {
+
+ int ret = initializeSimulation_(getModelIDNew());
+ if(ret != OK)
+ LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
+
+ } catch (FMILException e) {
+ throw e;
+ } catch (UnsatisfiedLinkError err) {
+ throw new FMILException(UNSATISFIED_LINK);
+ } catch (Exception e) {
+ throw new FMILException(e.getMessage());
+ }
+ }
+ }
+
+ private native int initializeSimulation_(int id) throws FMILException;
+
+ /**
+ * Subscribe a set of variables from a loaded simulation.
+ * <p>
+ * Make sure that an FMU is loaded first.
+ * @param variables Array of variables
+ * @throws FMILException
+ */
+ public void subscribe(int[] variables) throws FMILException {
+ synchronized(syncObject) {
+
+ try {
+
+ int ret = subscribe_(getModelIDNew(), variables);
+ if(ret != OK)
+ LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
+
+ } catch (UnsatisfiedLinkError err) {
+ throw new FMILException(UNSATISFIED_LINK);
+ } catch (Exception e) {
+ throw new FMILException(e.getMessage());
+ }
+ }
+ }
+
+ private native int subscribe_(int id, int[] variables);
+
+ /**
+ * Set a new (Real, double) value for a variable. If the variable is a
+ * parameter, the change is effective immediately.
+ *
+ * @param name Variable
+ * @param value New (Real, double) value
+ * @throws FMILException
+ */
+ public void setRealValue(String name, double value) throws FMILException {
+
+ synchronized(syncObject) {
+
+ try {
+
+ int ret = setRealValue_(getModelIDNew(), variableMap.get(name), value);
+ if(ret != OK)
+ LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
+
+ } catch (FMILException e) {
+ throw e;
+ } catch (UnsatisfiedLinkError err) {
+ throw new FMILException(UNSATISFIED_LINK);
+ } catch (Exception e) {
+ throw new FMILException(e.getMessage());
+ }
+
+ }
+
+ }
+
+ public void setRealValue(int variableReference, double value) throws FMILException {
+
+ synchronized(syncObject) {
+
+ try {
+
+ int ret = setRealValue_(getModelIDNew(), variableReference, value);
+ if(ret != OK)
+ LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
+
+ } catch (FMILException e) {
+ throw e;
+ } catch (UnsatisfiedLinkError err) {
+ throw new FMILException(UNSATISFIED_LINK);
+ } catch (Exception e) {
+ throw new FMILException(e.getMessage());
+ }
+
+ }
+
+ }
+
+ private native int setRealValue_(int id, int variableReference, double value) throws FMILException;
+
+// /**
+// * Set a new (integer) value for a variable. If the variable is a
+// * parameter, the change is effective immediately.
+// *
+// * @param name Variable
+// * @param value New (integer) value
+// * @throws FMILException
+// */
+// public void setIntegerValue(String name, int value) throws FMILException {
+// synchronized(syncObject) {
+//
+// try {
+//
+// int ret = setIntegerValue_(getModelID(), name, value);
+// if(ret == ERROR)
+// throw new FMILException(getLastErrorMessage());
+//
+// } catch (UnsatisfiedLinkError err) {
+// throw new FMILException(UNSATISFIED_LINK);
+// } catch (Exception e) {
+// throw new FMILException(e.getMessage());
+// }
+// }
+// }
+// private native int setIntegerValue_(String id, String name, int value);
+//
+// /**
+// * Set a new (boolean) value for a variable. If the variable is a
+// * parameter, the change is effective immediately.
+// *
+// * @param name Variable
+// * @param value New (boolean) value
+// * @throws FMILException
+// */
+// public void setBooleanValue(String name, boolean value) throws FMILException {
+// synchronized(syncObject) {
+//
+// try {
+//
+// int ret = setBooleanValue_(getModelID(), name, value);
+// if(ret == ERROR)
+// throw new FMILException(getLastErrorMessage());
+//
+// } catch (UnsatisfiedLinkError err) {
+// throw new FMILException(UNSATISFIED_LINK);
+// } catch (Exception e) {
+// throw new FMILException(e.getMessage());
+// }
+// }
+// }
+// private native int setBooleanValue_(String id, String name, boolean value);
+//
+// public void setTime(double time) throws FMILException {
+// synchronized(syncObject) {
+//
+// try {
+//
+// int ret = setTime_(getModelID(), time);
+// if(ret == ERROR)
+// throw new FMILException(getLastErrorMessage());
+//
+// } catch (UnsatisfiedLinkError err) {
+// throw new FMILException(UNSATISFIED_LINK);
+// } catch (Exception e) {
+// throw new FMILException(e.getMessage());
+// }
+// }
+// }
+// private native int setTime_(String id, double time);
+
+ /**
+ * Simulate one step forward. The step length can be set with
+ * setStepLength()
+ *
+ * @throws FMILException
+ */
+ public void simulateStep() throws FMILException {
+ synchronized(syncObject) {
+
+ try {
+
+ int ret = simulateStep_(getModelIDNew());
+ if(ret != OK)
+ LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
+
+ } catch (FMILException e) {
+ throw e;
+ } catch (UnsatisfiedLinkError err) {
+ throw new FMILException(UNSATISFIED_LINK);
+ } catch (Exception e) {
+ throw new FMILException(e.getMessage());
+ }
+ }
+ }
+ private native int simulateStep_(int id) throws FMILException;
+
+ /**
+ * Get an array containing the current values for subscribed variables. The
+ * values are in the same order as in the subscription.
+ *
+ * @param results An array the size of subscribed results
+ * @return
+ */
+ public double[] getSubscribedResults() throws FMILException {
+ synchronized(syncObject) {
+
+ try {
+
+ double[] results = new double[subscription.size()];
+ return getSubscribedResults_(getModelIDNew(), results);
+
+ } catch (UnsatisfiedLinkError err) {
+ throw new FMILException(UNSATISFIED_LINK);
+ } catch (Exception e) {
+ throw new FMILException(e.getMessage());
+ }
+ }
+ }
+
+ private native double[] getSubscribedResults_(int id, double[] results);
+
+
+ /**
+ * Unload FMU and the dll:s that it requires.
+ * <p>
+ * To be called after all FMU simulations are ended.
+ * If the fmu is loaded again / changed, call to loadFMUFile is sufficient. loadFMUFile
+ * releases the previous fmu.dll
+ *
+ * @throws FMILException
+ */
+ public void unloadFMU() throws FMILException {
+ synchronized(syncObject) {
+
+ try {
+
+ unlockFMUDirectory();
+ if(fmuLoaded) {
+ int ret = unloadFMU_(getModelIDNew());
+ if(ret != OK)
+ LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
+ fmuLoaded = false;
+ }
+ removeFMUDirectoryContents();
+
+ } catch (FMILException e) {
+ throw e;
+ } catch (UnsatisfiedLinkError err) {
+ throw new FMILException(UNSATISFIED_LINK);
+ } catch (Exception e) {
+ throw new FMILException(e.getMessage());
+ }
+ }
+ }
+ private native int unloadFMU_(int id) throws FMILException;
+
+// /**
+// * Checks if fmu has been initialized
+// * @return current simulation time
+// */
+// public boolean isInitialized() throws FMILException {
+// synchronized(syncObject) {
+// try {
+// return isInitialized_(getModelID());
+// } catch (UnsatisfiedLinkError err) {
+// throw new FMILException(UNSATISFIED_LINK);
+// } catch (Exception e) {
+// throw new FMILException(e.getMessage());
+// }
+// }
+// }
+//
+// private native boolean isInitialized_(String id);
+//
+ /**
+ * Get the current simulation time
+ * @return current simulation time
+ */
+ public double getTime() throws FMILException {
+ synchronized(syncObject) {
+
+ try {
+
+ return getTime_(getModelIDNew());
+
+ } catch (UnsatisfiedLinkError err) {
+ throw new FMILException(UNSATISFIED_LINK);
+ } catch (Exception e) {
+ throw new FMILException(e.getMessage());
+ }
+ }
+ }
+
+ private native double getTime_(int id);
+
+ /**
+ * Get all variables in a loaded model
+ * @return all variables in a loaded model
+ */
+ public String[] getAllVariables() throws FMILException {
+ synchronized(syncObject) {
+
+ try {
+
+ if(variableNames == null) {
+ variableNames = getAllVariables_(getModelIDNew());
+ }
+ return variableNames;
+
+ } catch (UnsatisfiedLinkError err) {
+ throw new FMILException(UNSATISFIED_LINK);
+ } catch (Exception e) {
+ throw new FMILException(e.getMessage());
+ }
+ }
+ }
+
+ private native String[] getAllVariables_(int id);
+
+ public String[] getAllVariableDescriptions() throws FMILException {
+ synchronized(syncObject) {
+
+ try {
+
+ if(variableDescriptions == null) {
+ variableDescriptions = getAllVariableDescriptions_(getModelIDNew());
+ }
+ return variableDescriptions;
+
+ } catch (UnsatisfiedLinkError err) {
+ throw new FMILException(UNSATISFIED_LINK);
+ } catch (Exception e) {
+ throw new FMILException(e.getMessage());
+ }
+ }
+ }
+
+ private native String[] getAllVariableDescriptions_(int id);
+
+ public String[] getAllVariableDeclaredTypes() throws FMILException {
+ synchronized(syncObject) {
+
+ try {
+
+ if(variableDeclaredTypes == null) {
+ variableDeclaredTypes = getAllVariableDeclaredTypes_(getModelIDNew());
+ }
+ return variableDeclaredTypes;
+
+ } catch (UnsatisfiedLinkError err) {
+ throw new FMILException(UNSATISFIED_LINK);
+ } catch (Exception e) {
+ throw new FMILException(e.getMessage());
+ }
+ }
+ }
+
+ private native String[] getAllVariableDeclaredTypes_(int id);
+
+ public int[] getAllVariableReferences() throws FMILException {
+ synchronized(syncObject) {
+
+ try {
+
+ if(variableReferences == null) {
+ variableReferences = getAllVariableReferences_(getModelIDNew(), new int[variableNames.length]);
+ }
+ return variableReferences;
+
+ } catch (UnsatisfiedLinkError err) {
+ throw new FMILException(UNSATISFIED_LINK);
+ } catch (Exception e) {
+ throw new FMILException(e.getMessage());
+ }
+ }
+ }
+
+ private native int[] getAllVariableReferences_(int id, int[] array);
+
+ public int[] getAllVariableTypes() throws FMILException {
+ synchronized(syncObject) {
+
+ try {
+
+ if(variableTypes == null) {
+ variableTypes = getAllVariableTypes_(getModelIDNew(), new int[variableNames.length]);
+ }
+ return variableTypes;
+
+ } catch (UnsatisfiedLinkError err) {
+ throw new FMILException(UNSATISFIED_LINK);
+ } catch (Exception e) {
+ throw new FMILException(e.getMessage());
+ }
+ }
+ }
+
+ private native int[] getAllVariableTypes_(int id, int[] array);
+
+ public int[] getAllVariableCausalities() throws FMILException {
+ synchronized(syncObject) {
+
+ try {
+
+ if(variableCausalities == null) {
+ variableCausalities = getAllVariableCausalities_(getModelIDNew(), new int[variableNames.length]);
+ }
+ return variableCausalities;
+
+ } catch (UnsatisfiedLinkError err) {
+ throw new FMILException(UNSATISFIED_LINK);
+ } catch (Exception e) {
+ throw new FMILException(e.getMessage());
+ }
+ }
+ }
+
+ private native int[] getAllVariableCausalities_(int id, int[] array);
+
+ public int[] getAllVariableVariabilities() throws FMILException {
+ synchronized(syncObject) {
+
+ try {
+
+ if(variableVariabilities == null) {
+ variableVariabilities = getAllVariableVariabilities_(getModelIDNew(), new int[variableNames.length]);
+ }
+ return variableVariabilities;
+
+ } catch (UnsatisfiedLinkError err) {
+ throw new FMILException(UNSATISFIED_LINK);
+ } catch (Exception e) {
+ throw new FMILException(e.getMessage());
+ }
+ }
+ }
+
+ private native int[] getAllVariableVariabilities_(int id, int[] array);
+
+ /**
+ * Get all variables in a loaded model
+ * @return all variables in a loaded model
+ */
+ public String[] getAllDeclaredTypes() throws FMILException {
+ synchronized(syncObject) {
+
+ try {
+
+ if(declaredTypes == null) {
+ declaredTypes = getAllDeclaredTypes_(getModelIDNew());
+ }
+ return declaredTypes;
+
+ } catch (UnsatisfiedLinkError err) {
+ throw new FMILException(UNSATISFIED_LINK);
+ } catch (Exception e) {
+ throw new FMILException(e.getMessage());
+ }
+ }
+ }
+
+ private native String[] getAllDeclaredTypes_(int id);
+
+ public String[] getAllDeclaredTypeDescriptions() throws FMILException {
+ synchronized(syncObject) {
+
+ try {
+
+ if(declaredTypeDescriptions == null) {
+ declaredTypeDescriptions = getAllDeclaredTypeDescriptions_(getModelIDNew());
+ }
+ return declaredTypeDescriptions;
+
+ } catch (UnsatisfiedLinkError err) {
+ throw new FMILException(UNSATISFIED_LINK);
+ } catch (Exception e) {
+ throw new FMILException(e.getMessage());
+ }
+ }
+ }
+
+ private native String[] getAllDeclaredTypeDescriptions_(int id);
+
+ public String[] getAllDeclaredTypeQuantities() throws FMILException {
+ synchronized(syncObject) {
+
+ try {
+
+ if(declaredTypeQuantities == null) {
+ declaredTypeQuantities = getAllDeclaredTypeQuantities_(getModelIDNew());
+ }
+ return declaredTypeQuantities;
+
+ } catch (UnsatisfiedLinkError err) {
+ throw new FMILException(UNSATISFIED_LINK);
+ } catch (Exception e) {
+ throw new FMILException(e.getMessage());
+ }
+ }
+ }
+
+ private native String[] getAllDeclaredTypeQuantities_(int id);
+
+ public String[] getAllDeclaredTypeUnits() throws FMILException {
+ synchronized(syncObject) {
+
+ try {
+
+ if(declaredTypeUnits == null) {
+ declaredTypeUnits = getAllDeclaredTypeUnits_(getModelIDNew());
+ }
+ return declaredTypeUnits;
+
+ } catch (UnsatisfiedLinkError err) {
+ throw new FMILException(UNSATISFIED_LINK);
+ } catch (Exception e) {
+ throw new FMILException(e.getMessage());
+ }
+ }
+ }
+
+ private native String[] getAllDeclaredTypeUnits_(int id);
+
+
+//
+// /**
+// * Get all variables from model that match the filter (and time variable)
+// *
+// * @param regexp Regular expression filter
+// * @return An array of variable names that match regexp filter (and time-variable)
+// * @throws FMILException
+// */
+// public String[] filterVariables(String regexp) throws FMILException {
+// synchronized(syncObject) {
+// try {
+//
+// return filterVariables_(getModelID(), regexp + "|time");
+//
+// } catch (UnsatisfiedLinkError err) {
+// throw new FMILException(UNSATISFIED_LINK);
+// } catch (Exception e) {
+// throw new FMILException(e.getMessage());
+// }
+// }
+// }
+//
+// private native String[] filterVariables_(String id, String regexp);
+////
+// /**
+// * Get the last error message
+// * @return Last error message
+// */
+// public String getLastErrorMessage() throws FMILException {
+// synchronized(syncObject) {
+//
+// try {
+//
+// return "err";
+// //return getLastErrorMessage_(getModelID());
+//
+// } catch (UnsatisfiedLinkError err) {
+// throw new FMILException(UNSATISFIED_LINK);
+// } catch (Exception e) {
+// throw new FMILException(e.getMessage());
+// }
+// }
+// }
+//
+// private native String getLastErrorMessage_(String id);
+
+ /**
+ * Get a real (double) value for variable
+ * @param name Name of the variable
+ * @return value
+ * @throws FMILException
+ */
+ public double getRealValue(String name) throws FMILException {
+ synchronized(syncObject) {
+
+ try {
+ // TODO: printtaa id ja name, jotta saadaan virheessä kiinni
+ double result = getRealValue_(getModelIDNew(), variableMap.get(name));
+ System.err.println("getRealValue " + name + " = " + result);
+ return result;
+ } catch (UnsatisfiedLinkError err) {
+ throw new FMILException(UNSATISFIED_LINK);
+ } catch (Exception e) {
+ throw new FMILException(e.getMessage());
+ }
+ }
+ }
+
+ private native double getRealValue_(int id, int variableReference);
+
+// /**
+// * Get a string value for variable
+// * @param name Name of the variable
+// * @return value
+// * @throws FMILException
+// */
+// public String getStringValue(String name) throws FMILException {
+// synchronized(syncObject) {
+//
+// try {
+// return getStringValue_(getModelID(), name);
+// } catch (UnsatisfiedLinkError err) {
+// throw new FMILException(UNSATISFIED_LINK);
+// } catch (Exception e) {
+// throw new FMILException(e.getMessage());
+// }
+// }
+// }
+//
+// private native String getStringValue_(String id, String name);
+//
+// /**
+// * Get an integer value for variable
+// * @param name Name of the variable
+// * @return value
+// * @throws FMILException
+// */
+// public int getIntegerValue(String name) throws FMILException {
+// synchronized(syncObject) {
+//
+// try {
+// return getIntegerValue_(getModelID(), name);
+// } catch (UnsatisfiedLinkError err) {
+// throw new FMILException(UNSATISFIED_LINK);
+// } catch (Exception e) {
+// throw new FMILException(e.getMessage());
+// }
+// }
+// }
+//
+// private native int getIntegerValue_(String id, String name);
+//
+// /**
+// * Get a real (double) value for variable
+// * @param name Name of the variable
+// * @return value
+// * @throws FMILException
+// */
+// public boolean getBooleanValue(String name) throws FMILException {
+// synchronized(syncObject) {
+//
+// try {
+// return getBooleanValue_(getModelID(), name);
+// } catch (UnsatisfiedLinkError err) {
+// throw new FMILException(UNSATISFIED_LINK);
+// } catch (Exception e) {
+// throw new FMILException(e.getMessage());
+// }
+// }
+// }
+//
+// private native boolean getBooleanValue_(String id, String name);
+
+ private FileChannel channel;
+ private FileLock lock;
+
+ @SuppressWarnings("resource")
+ private boolean lockFMUDirectory() {
+
+ try {
+ // Get a file channel for the lock file
+ File lockFile = new File(TEMP_FMU_DIRECTORY, LOCK_FILE_NAME);
+ if(!lockFile.isFile())
+ lockFile.createNewFile();
+
+ channel = new RandomAccessFile(lockFile, "rw").getChannel();
+
+ // Use the file channel to create a lock on the file.
+ // This method blocks until it can retrieve the lock.
+ lock = channel.lock();
+
+ // // Try acquiring the lock without blocking. This method returns
+ // // null or throws an exception if the file is already locked.
+ // try {
+ // lock = channel.tryLock();
+ // } catch (OverlappingFileLockException e) {
+ // // File is already locked in this thread or virtual machine
+ // }
+ } catch (IOException e) {
+ return false;
+ }
+
+ return true;
+ }
+
+ private boolean unlockFMUDirectory() {
+ try {
+ // Release the lock
+ if(lock != null)
+ lock.release();
+
+ // Close the file
+ if(channel != null)
+ channel.close();
+ } catch (IOException e) {
+ return false;
+ }
+ return true;
+ }
+
+ private boolean removeFMUDirectoryContents() {
+ // Remove contents
+ try {
+ File tempDir = new File(TEMP_FMU_DIRECTORY);
+ FileUtils.deleteAll(tempDir);
+ tempDir.delete();
+ } catch (IOException e) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ try {
+ unloadFMU();
+ } catch (Throwable t) {
+ LOGGER.error("Could not unload native FMU!", t);
+ } finally {
+ super.finalize();
+ }
+ }
+}