FMI Library: part of JModelica.org
fmi2_import_cs_test.c
Go to the documentation of this file.
1 /*
2  Copyright (C) 2012 Modelon AB
3 
4  This program is free software: you can redistribute it and/or modify
5  it under the terms of the BSD style license.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  FMILIB_License.txt file for more details.
11 
12  You should have received a copy of the FMILIB_License.txt file
13  along with this program. If not, contact Modelon AB <http://www.modelon.com>.
14 */
15 
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <stdarg.h>
19 
20 #include "config_test.h"
21 
22 #include <fmilib.h>
23 #include <JM/jm_portability.h>
24 
25 
26 #define BUFFER 1000
27 
29 {
30  printf("module = %s, log level = %s: %s\n", module, jm_log_level_to_string(log_level), message);
31 }
32 
33 /* Logger function used by the FMU internally */
34 
35 void fmilogger(fmi2_component_t c, fmi2_string_t instanceName, fmi2_status_t status, fmi2_string_t category, fmi2_string_t message, ...)
36 {
37  /* int len;
38  char msg[BUFFER]; */
39  va_list argp;
40  va_start(argp, message);
41  /* len = jm_vsnprintf(msg, BUFFER, message, argp); */
42  fmi2_log_forwarding_v(c, instanceName, status, category, message, argp);
43  va_end(argp);
44 }
45 
46 void do_exit(int code)
47 {
48  printf("Press 'Enter' to exit\n");
49  /* getchar(); */
50  exit(code);
51 }
52 
54 {
55  fmi2_status_t fmistatus;
56  jm_status_enu_t jmstatus;
57 
58  fmi2_string_t instanceName = "Test CS model instance";
59  fmi2_string_t fmuGUID;
60  fmi2_string_t fmuLocation = "";
61  fmi2_boolean_t visible = fmi2_false;
62  fmi2_real_t relativeTol = 1e-4;
63 /* fmi2_boolean_t loggingOn = fmi2_true; */
64 
65  /* fmi2_real_t simulation_results[] = {-0.001878, -1.722275}; */
66  fmi2_real_t simulation_results[] = {0.0143633, -1.62417};
67  fmi2_value_reference_t compare_real_variables_vr[] = {0, 1};
68  size_t k;
69 
70  fmi2_real_t tstart = 0.0;
71  fmi2_real_t tcur = tstart;
72  fmi2_real_t hstep = 0.1;
73  fmi2_real_t tend = 2.0;
74  fmi2_boolean_t StopTimeDefined = fmi2_false;
75 
76  if (sizeof(compare_real_variables_vr)/sizeof(fmi2_value_reference_t) != sizeof(simulation_results)/sizeof(fmi2_real_t)) {
77  printf("Number of simulation values and reference values are different\n");
78  do_exit(CTEST_RETURN_FAIL);
79  }
80 
81  printf("Version returned from FMU: %s\n", fmi2_import_get_version(fmu));
82  printf("Platform type returned: %s\n", fmi2_import_get_types_platform(fmu));
83 
84  fmuGUID = fmi2_import_get_GUID(fmu);
85  printf("GUID: %s\n", fmuGUID);
86 
87 
88  jmstatus = fmi2_import_instantiate(fmu, instanceName, fmi2_cosimulation, fmuLocation, visible);
89  if (jmstatus == jm_status_error) {
90  printf("fmi2_import_instantiate failed\n");
91  do_exit(CTEST_RETURN_FAIL);
92  }
93 
94  fmistatus = fmi2_import_setup_experiment(fmu, fmi2_true,
95  relativeTol, tstart, StopTimeDefined, tend);
96  if(fmistatus != fmi2_status_ok) {
97  printf("fmi2_import_setup_experiment failed\n");
98  do_exit(CTEST_RETURN_FAIL);
99  }
100 
101  fmistatus = fmi2_import_enter_initialization_mode(fmu);
102  if(fmistatus != fmi2_status_ok) {
103  printf("fmi2_import_enter_initialization_mode failed\n");
104  do_exit(CTEST_RETURN_FAIL);
105  }
106 
107  fmistatus = fmi2_import_exit_initialization_mode(fmu);
108  if(fmistatus != fmi2_status_ok) {
109  printf("fmi2_import_exit_initialization_mode failed\n");
110  do_exit(CTEST_RETURN_FAIL);
111  }
112 
113  tcur = tstart;
114  printf("%10s %10s\n", "Ball height", "Ball speed");
115  while (tcur < tend) {
116  fmi2_boolean_t newStep = fmi2_true;
117 #if 0 /* Prints a real value.. */
118  fmi2_real_t rvalue;
119  fmi2_value_reference_t vr = 0;
120 
121  fmistatus = fmi2_import_get_real(fmu, &vr, 1, &rvalue);
122  printf("rvalue = %f\n", rvalue);
123 #endif
124  fmistatus = fmi2_import_do_step(fmu, tcur, hstep, newStep);
125 
126  for (k = 0; k < sizeof(compare_real_variables_vr)/sizeof(fmi2_value_reference_t); k++) {
127  fmi2_value_reference_t vr = compare_real_variables_vr[k];
128  fmi2_real_t rvalue;
129  fmistatus = fmi2_import_get_real(fmu, &vr, 1, &rvalue);
130  }
131  {
132  fmi2_real_t val[2];
133  fmi2_import_get_real(fmu, compare_real_variables_vr, 2, val);
134  printf("%10g %10g\n", val[0],val[1]);
135  }
136 
137  tcur += hstep;
138  }
139 
140  printf("Simulation finished. Checking results\n");
141 
142  /* Validate result */
143  for (k = 0; k < sizeof(compare_real_variables_vr)/sizeof(fmi2_value_reference_t); k++) {
144  fmi2_value_reference_t vr = compare_real_variables_vr[k];
145  fmi2_real_t rvalue;
146  fmi2_real_t res;
147  fmistatus = fmi2_import_get_real(fmu, &vr, 1, &rvalue);
148  res = rvalue - simulation_results[k];
149  res = res > 0 ? res: -res; /* Take abs */
150  if (res > 3e-3) {
151  printf("Simulation results is wrong!\n");
152  printf("State [%u] %g != %g, |res| = %g\n", (unsigned)k, rvalue, simulation_results[k], res);
153  printf("\n");
154  do_exit(CTEST_RETURN_FAIL);
155  }
156  }
157 
158  fmistatus = fmi2_import_terminate(fmu);
159 
161 
162  return 0;
163 }
164 
165 int main(int argc, char *argv[])
166 {
167  fmi2_callback_functions_t callBackFunctions;
168  const char* FMUPath;
169  const char* tmpPath;
171  fmi_import_context_t* context;
172  fmi_version_enu_t version;
173  jm_status_enu_t status;
174  int k;
175 
176  fmi2_import_t* fmu;
177 
178  if(argc < 3) {
179  printf("Usage: %s <fmu_file> <temporary_dir>\n", argv[0]);
180  do_exit(CTEST_RETURN_FAIL);
181  }
182  for (k = 0; k < argc; k ++)
183  printf("argv[%d] = %s\n", k, argv[k]);
184 
185  FMUPath = argv[1];
186  tmpPath = argv[2];
187 
188 
189  callbacks.malloc = malloc;
190  callbacks.calloc = calloc;
191  callbacks.realloc = realloc;
192  callbacks.free = free;
193  callbacks.logger = importlogger;
194  callbacks.log_level = jm_log_level_debug;
195  callbacks.context = 0;
196 
197 #ifdef FMILIB_GENERATE_BUILD_STAMP
198  printf("Library build stamp:\n%s\n", fmilib_get_build_stamp());
199 #endif
200 
201  context = fmi_import_allocate_context(&callbacks);
202 
203  version = fmi_import_get_fmi_version(context, FMUPath, tmpPath);
204 
205  if(version != fmi_version_2_0_enu) {
206  printf("The code only supports version 2.0\n");
207  do_exit(CTEST_RETURN_FAIL);
208  }
209 
210  fmu = fmi2_import_parse_xml(context, tmpPath, 0);
211 
212  if(!fmu) {
213  printf("Error parsing XML, exiting\n");
214  do_exit(CTEST_RETURN_FAIL);
215  }
216 
218  printf("Only CS 2.0 is supported by this code\n");
219  do_exit(CTEST_RETURN_FAIL);
220  }
221 
222  callBackFunctions.logger = fmi2_log_forwarding;
223  callBackFunctions.allocateMemory = calloc;
224  callBackFunctions.freeMemory = free;
225  callBackFunctions.componentEnvironment = fmu;
226 
227  status = fmi2_import_create_dllfmu(fmu, fmi2_fmu_kind_cs, &callBackFunctions);
228  if (status == jm_status_error) {
229  printf("Could not create the DLL loading mechanism(C-API) (error: %s).\n", fmi2_import_get_last_error(fmu));
230  do_exit(CTEST_RETURN_FAIL);
231  }
232 
233  test_simulate_cs(fmu);
234 
236 
237  fmi2_import_free(fmu);
238  fmi_import_free_context(context);
239 
240  printf("Everything seems to be OK since you got this far=)!\n");
241 
242  do_exit(CTEST_RETURN_SUCCESS);
243 
244  return 0;
245 }
246 
247 
jm_calloc_f calloc
Allocate zero initialized memory.
Definition: jm_callbacks.h:77
void fmilogger(fmi2_component_t c, fmi2_string_t instanceName, fmi2_status_t status, fmi2_string_t category, fmi2_string_t message,...)
size_t jm_callbacks * c
FMILIB_EXPORT void fmi2_import_free_instance(fmi2_import_t *fmu)
Wrapper for the FMI function fmiFreeInstance(...)
FMILIB_EXPORT void fmi2_log_forwarding_v(fmi2_component_t c, fmi2_string_t instanceName, fmi2_status_t status, fmi2_string_t category, fmi2_string_t message, va_list args)
An implementation of FMI 2.0 logger that forwards the messages to logger function inside jm_callbacks...
void importlogger(jm_callbacks *c, jm_string module, jm_log_level_enu_t log_level, jm_string message)
fmi_version_enu_t
Suported versions of FMI standard.
Definition: fmi_version.h:34
fmi2_callback_allocate_memory_ft allocateMemory
void do_exit(int code)
FMILIB_EXPORT const char * jm_log_level_to_string(jm_log_level_enu_t level)
Convert log level into a string.
FMILIB_EXPORT const char * fmi2_import_get_version(fmi2_import_t *fmu)
Wrapper for the FMI function fmiGetVersion()
jm_log_level_enu_t
Log levels supported via the logger functions in jm_callbacks.
Definition: jm_types.h:51
FMILIB_EXPORT fmi2_import_t * fmi2_import_parse_xml(fmi_import_context_t *context, const char *dirPath, fmi2_xml_callbacks_t *xml_callbacks)
Create fmi2_import_t structure and parse the FMI 2.0 XML file found in the directory dirName...
int test_simulate_cs(fmi2_import_t *fmu)
FMILIB_EXPORT fmi2_fmu_kind_enu_t fmi2_import_get_fmu_kind(fmi2_import_t *fmu)
Get the type of the FMU (model exchange or co-simulation)
FMILIB_EXPORT fmi2_status_t fmi2_import_do_step(fmi2_import_t *fmu, fmi2_real_t currentCommunicationPoint, fmi2_real_t communicationStepSize, fmi2_boolean_t newStep)
Wrapper for the FMI function fmiDoStep(...)
jm_log_level_enu_t log_level
Logging level.
Definition: jm_callbacks.h:85
v callbacks
fmi1_capi_t * fmu
FMILIB_EXPORT void fmi2_import_destroy_dllfmu(fmi2_import_t *fmu)
Free a C-API struct. All memory allocated since the struct was created is freed.
fmi2_status_t
FMILIB_EXPORT fmi2_status_t fmi2_import_exit_initialization_mode(fmi2_import_t *fmu)
Calls the FMI function fmiExitInitializationMode(...)
fmi2_callback_logger_ft logger
Verbose messages.
Definition: jm_types.h:58
Include file to be used in client applications of the FMI Library.
jm_malloc_f malloc
Allocate non-initialized memory.
Definition: jm_callbacks.h:75
fmi2_callback_free_memory_ft freeMemory
jm_voidp context
Arbitrary context pointer passed to the logger function.
Definition: jm_callbacks.h:87
const char * jm_string
A constant string.
Definition: jm_types.h:33
fmi2_component_environment_t componentEnvironment
FMILIB_EXPORT fmi2_status_t fmi2_import_setup_experiment(fmi2_import_t *fmu, fmi2_boolean_t toleranceDefined, fmi2_real_t tolerance, fmi2_real_t startTime, fmi2_boolean_t stopTimeDefined, fmi2_real_t stopTime)
Calls the FMI function fmiSetupExperiment(...)
FMILIB_EXPORT jm_status_enu_t fmi2_import_create_dllfmu(fmi2_import_t *fmu, fmi2_fmu_kind_enu_t fmuKind, const fmi2_callback_functions_t *callBackFunctions)
Create a C-API struct. The C-API struct is a placeholder for the FMI DLL functions.
The callbacks struct is sent to all the modules in the library.
Definition: jm_callbacks.h:73
FMILIB_EXPORT fmi2_status_t fmi2_import_enter_initialization_mode(fmi2_import_t *fmu)
Calls the FMI function fmiEnterInitializationMode(...)
struct fmi_xml_context_t fmi_import_context_t
FMI version independent library context. Opaque struct returned from fmi_import_allocate_context() ...
FMILIB_EXPORT void fmi2_import_free(fmi2_import_t *fmu)
Release the memory allocated.
FMILIB_EXPORT fmi_import_context_t * fmi_import_allocate_context(jm_callbacks *callbacks)
Create fmi_import_context_t structure.
FMILIB_EXPORT const char * fmi2_import_get_types_platform(fmi2_import_t *fmu)
Wrapper for the FMI function fmiGetTypesPlatform(...)
FMILIB_EXPORT const char * fmi2_import_get_GUID(fmi2_import_t *fmu)
Get FMU GUID.
FMILIB_EXPORT fmi2_status_t fmi2_import_terminate(fmi2_import_t *fmu)
Wrapper for the FMI function fmiTerminate(...)
FMILIB_EXPORT fmi2_status_t fmi2_import_get_real(fmi2_import_t *fmu, const fmi2_value_reference_t vr[], size_t nvr, fmi2_real_t value[])
Wrapper for the FMI function fmiGetReal(...)
FMILIB_EXPORT fmi_version_enu_t fmi_import_get_fmi_version(fmi_import_context_t *c, const char *fileName, const char *dirName)
Unzip an FMU specified by the fileName into directory dirName and parse XML to get FMI standard versi...
FMILIB_EXPORT void fmi_import_free_context(fmi_import_context_t *c)
Free memory allocated for the library context.
jm_realloc_f realloc
Re-allocate memory.
Definition: jm_callbacks.h:79
FMILIB_EXPORT const char * fmi2_import_get_last_error(fmi2_import_t *fmu)
Retrieve the last error message.
jm_status_enu_t
Return status codes.
Definition: jm_types.h:44
FMILIB_EXPORT jm_status_enu_t fmi2_import_instantiate(fmi2_import_t *fmu, fmi2_string_t instanceName, fmi2_type_t fmuType, fmi2_string_t fmuResourceLocation, fmi2_boolean_t visible)
Wrapper for the FMI function fmiInstantiate(...)
jm_free_f free
Free-allocated memory.
Definition: jm_callbacks.h:81
jm_logger_f logger
Logging callback.
Definition: jm_callbacks.h:83
FMILIB_EXPORT void fmi2_log_forwarding(fmi2_component_t c, fmi2_string_t instanceName, fmi2_status_t status, fmi2_string_t category, fmi2_string_t message,...)
An implementation of FMI 2.0 logger that forwards the messages to logger function inside jm_callbacks...
int main(int argc, char *argv[])
struct fmi2_import_t fmi2_import_t
FMU version 2.0 object.