]> gerrit.simantics Code Review - simantics/fmil.git/blob - org.simantics.fmil/native/FMUSimulator/fmi_util.c.txt
(refs #6290) Import initial FMI Studio codebase
[simantics/fmil.git] / org.simantics.fmil / native / FMUSimulator / fmi_util.c.txt
1 /*\r
2     Copyright (C) 2012 Modelon AB\r
3 \r
4     This program is free software: you can redistribute it and/or modify\r
5     it under the terms of the BSD style license.\r
6 \r
7      This program is distributed in the hope that it will be useful,\r
8     but WITHOUT ANY WARRANTY; without even the implied warranty of\r
9     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
10     FMILIB_License.txt file for more details.\r
11 \r
12     You should have received a copy of the FMILIB_License.txt file\r
13     along with this program. If not, contact Modelon AB <http://www.modelon.com>.\r
14 */\r
15 \r
16 #include <assert.h>\r
17 #include <string.h>\r
18 #include <stdio.h>\r
19 #include <FMI/fmi_util.h>\r
20 #include <FMI/fmi_zip_unzip.h>\r
21 \r
22 char* fmi_construct_dll_dir_name(jm_callbacks* callbacks, const char* fmu_unzipped_path) {\r
23         char* dir_path;\r
24         size_t len;\r
25 \r
26         assert( fmu_unzipped_path && callbacks);\r
27 \r
28         len = \r
29                 strlen(fmu_unzipped_path) + strlen(FMI_FILE_SEP)\r
30                 + strlen(FMI_BINARIES) + strlen(FMI_FILE_SEP) \r
31                 + strlen(FMI_PLATFORM) + strlen(FMI_FILE_SEP) + 1;\r
32 \r
33         dir_path = (char*)callbacks->malloc(len);\r
34         if (dir_path == NULL) {\r
35                 jm_log_fatal(callbacks, "FMIUT", "Failed to allocate memory.");\r
36                 return NULL;\r
37         }\r
38 \r
39         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
40 \r
41         return dir_path;\r
42 }\r
43 \r
44 char* fmi_construct_dll_file_name(jm_callbacks* callbacks, const char* dll_dir_name, const char* model_identifier) {\r
45         char* fname;\r
46         size_t len;\r
47         assert(callbacks && model_identifier);\r
48         len = \r
49                 strlen(dll_dir_name) +\r
50                 strlen(model_identifier) \r
51                 + strlen(FMI_DLL_EXT) + 1;\r
52         fname = (char*)callbacks->malloc(len);\r
53         if (fname == NULL) {\r
54                 jm_log_fatal(callbacks, "FMIUT", "Failed to allocate memory.");\r
55                 return NULL;\r
56         }\r
57         sprintf(fname, "%s%s%s", dll_dir_name, model_identifier, FMI_DLL_EXT);/*safe */\r
58 \r
59         return fname;\r
60 }\r
61 \r
62 \r
63 ////\r
64 \r
65 #include <stdio.h>\r
66 #include <stdlib.h>\r
67 #include <stdarg.h>\r
68 #include <string.h>\r
69 #include <errno.h>\r
70 \r
71 #include <fmilib.h>\r
72 \r
73 #ifdef __cplusplus\r
74 extern "C" {\r
75 #endif\r
76 \r
77 typedef struct {\r
78         char *name;\r
79         char *description;\r
80         long vr;\r
81         // 0 = real\r
82         // 1 = integer\r
83         // 2 = boolean\r
84         // 3 = string\r
85         // 4 = enumeration\r
86         int type;\r
87         // 0 = constant\r
88         // 1 = parameter\r
89         // 2 = discrete\r
90         // 3 = continuous\r
91         // 4 = unknown\r
92         int variability;\r
93         // 0 = input\r
94         // 1 = output\r
95         // 2 = internal\r
96         // 3 = none\r
97         // 4 = unknown\r
98         int causality;\r
99 } FMIL_Variable;\r
100 \r
101 __declspec(dllexport) void* FMI1_CS_LOAD(const char *zipFilePath, const char *unzipFolder);\r
102 __declspec(dllexport) int FMI1_CS_UNLOAD(void* fmu);\r
103 __declspec(dllexport) FMIL_Variable *FMI1_CS_GET_VARIABLES(void* fmu, int *count);\r
104 __declspec(dllexport) int FMI1_CS_INSTANTIATE(void* fmu);\r
105 __declspec(dllexport) int FMI1_CS_INITIALIZE(void* fmu);\r
106 __declspec(dllexport) int FMI1_CS_STEP(void* fmu, double masterTime, double stepSize);\r
107 __declspec(dllexport) int FMI1_CS_SET_REAL(void* fmu, int vr, double value);\r
108 __declspec(dllexport) double FMI1_CS_GET_REAL(void* fmu, int vr);\r
109 __declspec(dllexport) int FMI1_CS_GET_REALS(void* fmu, int *vrs, double *values, int count);\r
110 \r
111 #ifdef __cplusplus\r
112 }\r
113 #endif\r
114 \r
115 #define BUFFER 4096\r
116 \r
117 /* Logger function used by the C-API */\r
118 void importlogger(jm_callbacks* c, jm_string module, jm_log_level_enu_t log_level, jm_string message)\r
119 {\r
120         printf("module = %s, log level = %d: %s\n", module, log_level, message);\r
121 }\r
122 \r
123 /* Logger function used by the FMU internally */\r
124 void fmilogger(fmi1_component_t c, fmi1_string_t instanceName, fmi1_status_t status, fmi1_string_t category, fmi1_string_t message, ...)\r
125 {\r
126         char msg[BUFFER];\r
127     int len;\r
128         va_list argp;   \r
129         va_start(argp, message);\r
130         /*len=jm_vsnprintf(msg, BUFFER, message, argp);\r
131         printf("fmiStatus = %d;  %s (%s): %s\n", status, instanceName, category, msg);\r
132     if(len > BUFFER) {\r
133         printf("Warning: message was trancated");\r
134     }*/\r
135 }\r
136 \r
137 void *FMI1_CS_LOAD(char *zipFilePath, char *unzipFolder) {\r
138 \r
139         fmi1_callback_functions_t callBackFunctions;\r
140         fmi_import_context_t* context;\r
141         fmi1_fmu_kind_enu_t standard = fmi1_fmu_kind_enu_cs_standalone; \r
142         fmi_version_enu_t version;\r
143     jm_status_enu_t status;\r
144         fmi1_import_t *fmu;\r
145         jm_callbacks* callbacks;\r
146 \r
147         callbacks = (jm_callbacks *)calloc(1, sizeof(jm_callbacks));\r
148 \r
149         callbacks->malloc = malloc;\r
150     callbacks->calloc = calloc;\r
151     callbacks->realloc = realloc;\r
152     callbacks->free = free;\r
153     callbacks->logger = importlogger;\r
154     callbacks->log_level = jm_log_level_debug;\r
155     callbacks->context = 0;\r
156 \r
157         callBackFunctions.logger = fmilogger;\r
158         callBackFunctions.allocateMemory = calloc;\r
159         callBackFunctions.freeMemory = free;\r
160 \r
161         context = fmi_import_allocate_context(callbacks);\r
162 \r
163         version = fmi_import_get_fmi_version(context, zipFilePath, unzipFolder);\r
164 \r
165         fmu = fmi1_import_parse_xml(context, unzipFolder);\r
166 \r
167         status = fmi1_import_create_dllfmu(fmu, callBackFunctions, 0);\r
168 \r
169         fmi_import_free_context(context);\r
170 \r
171         return fmu;\r
172 \r
173 }\r
174 \r
175 int FMI1_CS_UNLOAD(void *fmu_) {\r
176 \r
177         fmi1_import_t *fmu = (fmi1_import_t *)fmu_;\r
178 \r
179         fmi1_import_destroy_dllfmu(fmu);\r
180 \r
181         fmi1_import_free(fmu);\r
182 \r
183         return 1;\r
184 \r
185 }\r
186 \r
187 \r
188 FMIL_Variable *FMI1_CS_GET_VARIABLES(void *fmu, int *count) {\r
189 \r
190     int i;\r
191         FMIL_Variable *result;\r
192     fmi1_import_variable_list_t* vl = fmi1_import_get_variable_list((fmi1_import_t *)fmu);\r
193 \r
194     count[0] = fmi1_import_get_variable_list_size(vl);\r
195 \r
196         result = (FMIL_Variable *)malloc(count[0]*sizeof(FMIL_Variable));\r
197 \r
198     for(i = 0; i < count[0]; i++) {\r
199 \r
200         fmi1_import_variable_t* var = fmi1_import_get_variable(vl, i);\r
201         if(!var) {\r
202 \r
203                         printf("Something wrong with variable %d \n",i);\r
204                         return 0;\r
205 \r
206                 } else {\r
207 \r
208                         result[i].name = fmi1_import_get_variable_name(var);\r
209                         result[i].description = fmi1_import_get_variable_description(var);\r
210 \r
211                         switch  (fmi1_import_get_variability(var)) {\r
212                         case fmi1_variability_enu_constant:\r
213                                 result[i].variability = 0;\r
214                                 break;\r
215                         case fmi1_variability_enu_parameter:\r
216                                 result[i].variability = 1;\r
217                                 break;\r
218                         case fmi1_variability_enu_discrete:\r
219                                 result[i].variability = 2;\r
220                                 break;\r
221                         case fmi1_variability_enu_continuous:\r
222                                 result[i].variability = 3;\r
223                                 break;\r
224                         case fmi1_variability_enu_unknown:\r
225                                 result[i].variability = 4;\r
226                                 break;\r
227                         }\r
228 \r
229                         switch  (fmi1_import_get_causality(var)) {\r
230                         case fmi1_causality_enu_input:\r
231                                 result[i].causality = 0;\r
232                                 break;\r
233                         case fmi1_causality_enu_output:\r
234                                 result[i].causality = 1;\r
235                                 break;\r
236                         case fmi1_causality_enu_internal:\r
237                                 result[i].causality = 2;\r
238                                 break;\r
239                         case fmi1_causality_enu_none:\r
240                                 result[i].causality = 3;\r
241                                 break;\r
242                         case fmi1_causality_enu_unknown:\r
243                                 result[i].causality = 4;\r
244                                 break;\r
245                         }\r
246 \r
247                         switch  (fmi1_import_get_variable_base_type(var)) {\r
248                         case fmi1_base_type_real:\r
249                                 result[i].type = 0;\r
250                                 break;\r
251                         case fmi1_base_type_int:\r
252                                 result[i].type = 1;\r
253                                 break;\r
254                         case fmi1_base_type_bool:\r
255                                 result[i].type = 2;\r
256                                 break;\r
257                         case fmi1_base_type_str:\r
258                                 result[i].type = 3;\r
259                                 break;\r
260                         case fmi1_base_type_enum:\r
261                                 result[i].type = 4;\r
262                                 break;\r
263                         }\r
264                         \r
265                         result[i].vr = fmi1_import_get_variable_vr(var);\r
266 \r
267                 }\r
268 \r
269     }\r
270 \r
271     fmi1_import_free_variable_list(vl);\r
272 \r
273         return result;\r
274 \r
275 }\r
276 \r
277 #define INSTANCE_NAME           "kekkeli"\r
278 \r
279 int FMI1_CS_INSTANTIATE(void *fmu) {\r
280 \r
281         fmi1_string_t fmuLocation;\r
282         fmi1_string_t mimeType;\r
283         fmi1_real_t timeout;\r
284         fmi1_boolean_t visible;\r
285         fmi1_boolean_t interactive;\r
286         fmi1_boolean_t loggingOn;\r
287 \r
288         fmuLocation = "";\r
289         mimeType = "";\r
290         timeout = 0;\r
291         visible = fmi1_false;\r
292         interactive = fmi1_false;\r
293         loggingOn = fmi1_true;\r
294 \r
295         if (fmi1_import_instantiate_slave(fmu, INSTANCE_NAME, NULL, NULL, timeout, fmi1_false, fmi1_false) == NULL) {           \r
296                 printf("fmi1_capi_instantiate_slave:             Failed\n");\r
297                 return 0;\r
298         } else {\r
299                 printf("fmi1_capi_instantiate_slave:             Success\n");\r
300         }\r
301         return 0;\r
302 \r
303 }\r
304 \r
305 int FMI1_CS_INITIALIZE(void *fmu) {\r
306 \r
307         fmi1_status_t status;\r
308         fmi1_real_t tStart;\r
309         fmi1_real_t tStop;\r
310         fmi1_boolean_t StopTimeDefined;\r
311 \r
312         tStart = 0;\r
313         tStop = 10;\r
314         StopTimeDefined = fmi1_false;\r
315 \r
316         status = fmi1_import_initialize_slave((fmi1_import_t *)fmu, tStart, StopTimeDefined, tStop);\r
317         if (status == fmi1_status_error || status == fmi1_status_fatal) {\r
318                 printf("fmi1_capi_initialize_slave:              Failed\n");\r
319                 return 0;\r
320         } else {\r
321                 printf("fmi1_capi_initialize_slave:              Success\n");\r
322         }\r
323         return 0;\r
324 \r
325 }\r
326 \r
327 int FMI1_CS_STEP(void *fmu, double masterTime, double stepSize) {\r
328 \r
329     fmi1_status_t status;\r
330 \r
331         status = fmi1_import_do_step((fmi1_import_t *)fmu, (fmi1_real_t)masterTime, (fmi1_real_t)stepSize, fmi1_true);\r
332         if (status == fmi1_status_error || status == fmi1_status_fatal) {\r
333                 printf("fmi1_capi_do_step:                       Failed\n");\r
334                 return 0;\r
335         } else {\r
336                 printf("fmi1_capi_do_step:                       Success\n");\r
337         }\r
338 \r
339         return 0;\r
340 \r
341 }\r
342 \r
343 int FMI1_CS_SET_REAL(void *fmu, long valueId, double value) {\r
344 \r
345         fmi1_value_reference_t vr = valueId;\r
346         fmi1_import_set_real((fmi1_import_t *)fmu, &vr, 1, &value);\r
347 \r
348         return 0;\r
349 \r
350 }\r
351 \r
352 double FMI1_CS_GET_REAL(void *fmu, int valueReference) {\r
353 \r
354         fmi1_value_reference_t vr = valueReference;\r
355         fmi1_real_t value;\r
356         fmi1_import_get_real((fmi1_import_t *)fmu, &vr, 1, &value);\r
357         return value;\r
358 \r
359 }\r
360 \r
361 int FMI1_CS_GET_REALS(void *fmu, int *valueReferences, double *result, int count) {\r
362 \r
363         fmi1_value_reference_t *vrs = valueReferences;\r
364         fmi1_real_t value;\r
365         fmi1_import_get_real((fmi1_import_t *)fmu, vrs, count, result);\r
366         return 1;\r
367 \r
368 }\r