Skip to content

Commit

Permalink
- Wrapping the FMIL code for simulation.
Browse files Browse the repository at this point in the history
git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@12905 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
adeas31 committed Sep 12, 2012
1 parent dc540c3 commit 0286fcc
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 21 deletions.
2 changes: 1 addition & 1 deletion Compiler/FrontEnd/ModelicaBuiltin.mo
Expand Up @@ -1857,7 +1857,7 @@ function importFMUNew "Imports the Functional Mockup Unit
importFMU(\"A.fmu\");"
input String filename "the fmu file name";
input String workdir := "<default>" "The output directory for imported FMU files. <default> will put the files to current working directory.";
input Integer loglevel := 6 "loglevel_nothing=0;loglevel_fatal=1;loglevel_error=2;loglevel_warning=3;loglevel_info=4;loglevel_verbose=5;loglevel_debug=6";
input Integer loglevel := 2 "loglevel_nothing=0;loglevel_fatal=1;loglevel_error=2;loglevel_warning=3;loglevel_info=4;loglevel_verbose=5;loglevel_debug=6";
output String generatedFileName "Returns the full path of the generated file.";
external "builtin";
annotation(preferredView="text");
Expand Down
5 changes: 3 additions & 2 deletions Compiler/Script/CevalScript.mo
Expand Up @@ -1450,8 +1450,9 @@ algorithm
fmiModelVariablesInstance, fmiModelVariablesList) = FMI.initializeFMIImport(filename, workdir, fmiLogLevel);
true = b; /* if something goes wrong while initializing */
fmiModelVariablesList1 = listReverse(fmiModelVariablesList);
str = Tpl.tplString(CodegenFMU.importFMUModelica, FMI.FMIIMPORT(fmiContext, fmiInstance, fmiModelIdentifier, fmiDescription, fmiExperimentStartTime,
fmiExperimentStopTime, fmiExperimentTolerance, fmiModelVariablesInstance, fmiModelVariablesList1));
str = Tpl.tplString(CodegenFMU.importFMUModelica, FMI.FMIIMPORT(filename, workdir, fmiLogLevel, fmiContext, fmiInstance, fmiModelIdentifier, fmiDescription,
fmiExperimentStartTime, fmiExperimentStopTime, fmiExperimentTolerance,
fmiModelVariablesInstance, fmiModelVariablesList1));
pd = System.pathDelimiter();
filename_1 = stringAppendList({workdir,pd,fmiModelIdentifier,"FMUImportNew.mo"});
System.writeFile(filename_1, str);
Expand Down
80 changes: 73 additions & 7 deletions Compiler/Template/CodegenFMU.tpl
Expand Up @@ -1105,8 +1105,9 @@ case FMIIMPORT(__) then
class fmiImportContext
extends ExternalObject;
function constructor
input Integer fmiLogLevel;
output fmiImportContext context;
external "C" context = fmi_import_allocate_context_OMC() annotation(Library = {"omcruntime", "fmilib"});
external "C" context = fmi_import_allocate_context_OMC(fmiLogLevel) annotation(Library = {"omcruntime", "fmilib"});
end constructor;

function destructor
Expand All @@ -1120,16 +1121,61 @@ case FMIIMPORT(__) then
function constructor
input fmiImportContext context;
input String tempPath;
output fmiImportInstance fmu;
external "C" fmu = fmiImportInstance_OMC(context, tempPath) annotation(Library = {"omcruntime", "fmilib"});
output fmiImportInstance fmi;
external "C" fmi = fmiImportInstance_OMC(context, tempPath) annotation(Library = {"omcruntime", "fmilib"});
end constructor;

function destructor
input fmiImportInstance fmu;
external "C" fmiImportFreeInstance_OMC(fmu) annotation(Library = {"omcruntime", "fmilib"});
input fmiImportInstance fmi;
external "C" fmiImportFreeInstance_OMC(fmi) annotation(Library = {"omcruntime", "fmilib"});
end destructor;
end fmiImportInstance;

package fmiFunctions
function fmiInstantiateModel
input fmiImportInstance fmi;
input String instanceName;
output Integer status;
external "C" status = fmiInstantiateModel_OMC(fmi, instanceName) annotation(Library = {"omcruntime", "fmilib"});
end fmiInstantiateModel;

function fmiSetTime
input fmiImportInstance fmi;
input Real in_time;
output Integer status;
external "C" status = fmiSetTime_OMC(fmi, in_time) annotation(Library = {"omcruntime", "fmilib"});
end fmiSetTime;

function fmiInitialize
input fmiImportInstance fmi;
output Integer status;
external "C" status = fmiInitialize_OMC(fmi) annotation(Library = {"omcruntime", "fmilib"});
end fmiInitialize;

function fmiGetContinuousStates
input fmiImportInstance fmi;
input Integer numberOfContinuousStates;
input Real fmi_x[numberOfContinuousStates];
output Integer status;
external "C" status = fmiGetContinuousStates_OMC(fmi, fmi_x, numberOfContinuousStates) annotation(Library = {"omcruntime", "fmilib"});
end fmiGetContinuousStates;

function fmiGetEventIndicators
input fmiImportInstance fmi;
input Integer numberOfEventIndicators;
input Real fmi_z[numberOfEventIndicators];
output Integer status;
external "C" status = fmiGetEventIndicators_OMC(fmi, fmi_z, numberOfEventIndicators) annotation(Library = {"omcruntime", "fmilib"});
end fmiGetEventIndicators;

function fmiSetDebugLogging
input fmiImportInstance fmi;
input Boolean debugLogging;
output Integer status;
external "C" status = fmiSetDebugLogging_OMC(fmi, debugLogging) annotation(Library = {"omcruntime", "fmilib"});
end fmiSetDebugLogging;
end fmiFunctions;

package fmiStatus
constant Integer fmiOK=0;
constant Integer fmiWarning=1;
Expand All @@ -1146,9 +1192,29 @@ case FMIIMPORT(__) then
end jmStatus;

model FMUModel <%if stringEq(fmiDescription, "") then "" else " \"fmiDescription\""%>
constant String fmuFile = "<%fmuFileName%>";
constant String fmuWorkingDir = "<%fmuWorkingDirectory%>";
constant Integer fmiLogLevel = <%fmiLogLevel%>;
<%dumpFMIModelVariablesList(fmiModelVariablesList)%>
constant Integer numberOfContinuousStates=<%getFMINumberOfContinuousStates(fmiInstance)%>;
constant Integer numberOfEventIndicators=<%getFMINumberOfEventIndicators(fmiInstance)%>;
constant Integer numberOfContinuousStates = <%getFMINumberOfContinuousStates(fmiInstance)%>;
Real fmi_x[numberOfContinuousStates] "States";
constant Integer numberOfEventIndicators = <%getFMINumberOfEventIndicators(fmiInstance)%>;
Real fmi_z[numberOfEventIndicators] "Event indicators";
constant Boolean debugLogging = true;
Integer fmi_status;
fmiImportInstance fmi = fmiImportInstance(context, fmuWorkingDir);
fmiImportContext context = fmiImportContext(fmiLogLevel);
initial algorithm
fmiFunctions.fmiInstantiateModel(fmi, "<%fmiModelIdentifier%>");
fmi_status := fmiFunctions.fmiSetTime(fmi, time);
fmi_status := fmiFunctions.fmiInitialize(fmi);
fmi_status := fmiFunctions.fmiGetContinuousStates(fmi, fmi_x, numberOfContinuousStates);
fmi_status := fmiFunctions.fmiGetEventIndicators(fmi, fmi_z, numberOfEventIndicators);
fmi_status := fmiFunctions.fmiSetDebugLogging(fmi, debugLogging);
equation
fmi_status = fmiFunctions.fmiSetTime(fmi, time);
assert(fmi_status<>fmiStatus.fmiFatal, "fmiInitialize returned a fatal error.");
assert(fmi_status<>fmiStatus.fmiError, "fmiInitialize returned an error.");
annotation(experiment(StartTime=<%fmiExperimentStartTime%>, StopTime=<%fmiExperimentStopTime%>, Tolerance=<%fmiExperimentTolerance%>));
end FMUModel;
end <%fmiModelIdentifier%>_FMU;
Expand Down
3 changes: 3 additions & 0 deletions Compiler/Template/SimCodeTV.mo
Expand Up @@ -2557,6 +2557,9 @@ package FMI

uniontype FmiImport
record FMIIMPORT
String fmuFileName;
String fmuWorkingDirectory;
Integer fmiLogLevel;
Integer fmiContext;
Integer fmiInstance;
String fmiModelIdentifier;
Expand Down
3 changes: 3 additions & 0 deletions Compiler/Util/FMI.mo
Expand Up @@ -35,6 +35,9 @@

uniontype FmiImport
record FMIIMPORT
String fmuFileName;
String fmuWorkingDirectory;
Integer fmiLogLevel;
Integer fmiContext;
Integer fmiInstance;
String fmiModelIdentifier;
Expand Down
50 changes: 39 additions & 11 deletions Compiler/runtime/FMIWrapper.c
Expand Up @@ -62,7 +62,7 @@ static void fmilogger(fmi1_component_t c, fmi1_string_t instanceName, fmi1_statu
/*
* Creates an instance of the FMI Import Context i.e fmi_import_context_t
*/
void* fmi_import_allocate_context_OMC()
void* fmi_import_allocate_context_OMC(int fmi_log_level)
{
// JM callbacks
static int init = 0;
Expand All @@ -74,7 +74,7 @@ void* fmi_import_allocate_context_OMC()
callbacks.realloc = realloc;
callbacks.free = free;
callbacks.logger = importlogger;
callbacks.log_level = jm_log_level_debug;
callbacks.log_level = fmi_log_level;
callbacks.context = 0;
}
fmi_import_context_t* context = fmi_import_allocate_context(&callbacks);
Expand Down Expand Up @@ -106,31 +106,59 @@ void* fmiImportInstance_OMC(void* context, char* working_directory)
callback_functions.freeMemory = free;
}
// parse the xml file
fmi1_import_t* fmu;
fmu = fmi1_import_parse_xml((fmi_import_context_t*)context, working_directory);
if(!fmu) {
fmi1_import_t* fmi;
fmi = fmi1_import_parse_xml((fmi_import_context_t*)context, working_directory);
if(!fmi) {
fprintf(stderr, "Error parsing the XML file contained in %s\n", working_directory);
return 0;
}
// Load the binary (dll/so)
jm_status_enu_t status;
status = fmi1_import_create_dllfmu(fmu, callback_functions, 0);
status = fmi1_import_create_dllfmu(fmi, callback_functions, 0);
if (status == jm_status_error) {
fprintf(stderr, "Could not create the DLL loading mechanism(C-API).\n");
return 0;
}
return fmu;
return fmi;
}

/*
* Destroys the instance of the FMI Import i.e fmi1_import_t
* Also destroys the loaded binary (dll/so).
*/
void fmiImportFreeInstance_OMC(void* fmu)
void fmiImportFreeInstance_OMC(void* fmi)
{
fmi1_import_t* fmu1 = (fmi1_import_t*)fmu;
fmi1_import_destroy_dllfmu(fmu1);
fmi1_import_free(fmu1);
fmi1_import_t* fmi1 = (fmi1_import_t*)fmi;
fmi1_import_destroy_dllfmu(fmi1);
fmi1_import_free(fmi1);
}

int fmiInstantiateModel_OMC(void* fmi, const char* instanceName)
{
return fmi1_import_instantiate_model((fmi1_import_t*)fmi, instanceName);
}

int fmiSetTime_OMC(void* fmi, double time)
{
return fmi1_import_set_time((fmi1_import_t*)fmi, time);
}

int fmiInitialize_OMC(void* fmi)
{
fmi1_boolean_t toleranceControlled = fmi1_true;
fmi1_real_t relativeTolerance = 0.001;
fmi1_event_info_t eventInfo;
return fmi1_import_initialize((fmi1_import_t*)fmi, toleranceControlled, relativeTolerance, &eventInfo);
}

int fmiGetContinuousStates_OMC(void* fmi, const double* states, int numberOfContinuousStates)
{
return fmi1_import_get_continuous_states((fmi1_import_t*)fmi, (fmi1_real_t*)states, numberOfContinuousStates);
}

int fmiGetEventIndicators_OMC(void* fmi, const double* events, int numberOfEventIndicators)
{
return fmi1_import_get_event_indicators((fmi1_import_t*)fmi, (fmi1_real_t*)events, numberOfEventIndicators);
}

#ifdef __cplusplus
Expand Down

0 comments on commit 0286fcc

Please sign in to comment.