123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595 |
- /* -------------------------------------------------------------------------
- * sim_support.c
- * Functions used by both FMU simulators fmu20sim_me and fmu20sim_cs
- * to parse command-line arguments, to unzip and load an fmu,
- * to write CSV file, and more.
- *
- * Revision history
- * 07.03.2014 initial version released in FMU SDK 2.0.0
- * 10.04.2014 use FMI 2.0 headers that prefix function and type names with 'fmi2'.
- * When 'fmi2' functions are not found in loaded DLL, look also for
- * FMI 2.0 RC1 function names.
- *
- * Author: Adrian Tirea
- * Copyright QTronic GmbH. All rights reserved.
- * -------------------------------------------------------------------------*/
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <assert.h>
- #include <stdarg.h>
- #include <dlfcn.h>
- #include "fmi2.h"
- #include "sim_support.h"
- #define FMI_COSIMULATION
- extern FMU fmu;
- //int unzip(const char *zipPath, const char *outPath) {
- // int code;
- // char cwd[BUFSIZE];
- // char binPath[BUFSIZE];
- // int n = strlen(UNZIP_CMD) + strlen(outPath) + 3 + strlen(zipPath) + 9;
- // char* cmd = (char*)calloc(sizeof(char), n);
- //
- // // remember current directory
- // if (!GetCurrentDirectory(BUFSIZE, cwd)) {
- // printf ("error: Could not get current directory\n");
- // return 0; // error
- // }
- //
- // // change to %FMUSDK_HOME%\bin to find 7z.dll and 7z.exe
- // if (!GetEnvironmentVariable("FMUSDK_HOME", binPath, BUFSIZE)) {
- // if (GetLastError() == ERROR_ENVVAR_NOT_FOUND) {
- // printf ("error: Environment variable FMUSDK_HOME not defined\n");
- // }
- // else {
- // printf ("error: Could not get value of FMUSDK_HOME\n");
- // }
- // return 0; // error
- // }
- // strcat(binPath, "\\bin");
- // if (!SetCurrentDirectory(binPath)) {
- // printf ("error: could not change to directory '%s'\n", binPath);
- // return 0; // error
- // }
- //
- // // run the unzip command
- // // remove "> NUL" to see the unzip protocol
- // sprintf(cmd, "%s\"%s\" \"%s\" > NUL", UNZIP_CMD, outPath, zipPath);
- // // printf("cmd='%s'\n", cmd);
- // code = system(cmd);
- // free(cmd);
- // if (code != SEVEN_ZIP_NO_ERROR) {
- // printf("7z: ");
- // switch (code) {
- // case SEVEN_ZIP_WARNING: printf("warning\n"); break;
- // case SEVEN_ZIP_ERROR: printf("error\n"); break;
- // case SEVEN_ZIP_COMMAND_LINE_ERROR: printf("command line error\n"); break;
- // case SEVEN_ZIP_OUT_OF_MEMORY: printf("out of memory\n"); break;
- // case SEVEN_ZIP_STOPPED_BY_USER: printf("stopped by user\n"); break;
- // default: printf("unknown problem\n");
- // }
- // }
- //
- // // restore current directory
- // SetCurrentDirectory(cwd);
- // return (code == SEVEN_ZIP_NO_ERROR || code == SEVEN_ZIP_WARNING) ? 1 : 0;
- //}
- //
- //// fileName is an absolute path, e.g. C:\test\a.fmu
- //// or relative to the current dir, e.g. ..\test\a.fmu
- //// Does not check for existence of the file
- //static char* getFmuPath(const char* fileName){
- // char pathName[MAX_PATH];
- // int n = GetFullPathName(fileName, MAX_PATH, pathName, NULL);
- // return n ? strdup(pathName) : NULL;
- //}
- //
- //static char* getTmpPath() {
- // char tmpPath[BUFSIZE];
- // if(! GetTempPath(BUFSIZE, tmpPath)) {
- // printf ("error: Could not find temporary disk space\n");
- // return NULL;
- // }
- // strcat(tmpPath, "fmu\\");
- // return strdup(tmpPath);
- //}
- //
- //char *getTempResourcesLocation() {
- // char *tempPath = getTmpPath();
- // char *resourcesLocation = (char *)calloc(sizeof(char), 9 + strlen(RESOURCES_DIR) + strlen(tempPath));
- // strcpy(resourcesLocation, "file:///");
- // strcat(resourcesLocation, tempPath);
- // strcat(resourcesLocation, RESOURCES_DIR);
- // free(tempPath);
- // return resourcesLocation;
- //}
- static void *getAdr(int *success, void *dllHandle, const char *functionName, const char* preamble) {
- int length = strlen(preamble) + strlen(functionName) + 1;
- char* new_name = malloc(length); // allocate memory
- strcpy(new_name, preamble); // copy first string
- strcat(new_name, functionName);
- void* fp = dlsym(dllHandle, new_name);
- if (!fp) {
- printf("warning: Function %s not found in dll\n", new_name);
- *success = 0;
- }
- free(new_name);
- return fp;
- }
- // Load the given dll and set function pointers in fmu
- // Return 0 to indicate failure
- int loadDll(const char* dllPath, FMU *fmu, const char* preamble) {
- int x = 1, s = 1;
- //HMODULE h = LoadLibrary(dllPath);
- void *h = dlopen(dllPath, RTLD_LAZY);
- printf("%s", dlerror());
- if (!h) {
- printf("error: Could not load %s\n", dllPath);
- return 0; // failure
- }
- fmu->dllHandle = h;
- fmu->getTypesPlatform = (fmi2GetTypesPlatformTYPE *) getAdr(&s, h, "fmi2GetTypesPlatform", preamble);
- fmu->getVersion = (fmi2GetVersionTYPE *) getAdr(&s, h, "fmi2GetVersion", preamble);
- fmu->setDebugLogging = (fmi2SetDebugLoggingTYPE *) getAdr(&s, h, "fmi2SetDebugLogging",preamble);
- fmu->instantiate = (fmi2InstantiateTYPE *) getAdr(&s, h, "fmi2Instantiate", preamble);
- fmu->freeInstance = (fmi2FreeInstanceTYPE *) getAdr(&s, h, "fmi2FreeInstance", preamble);
- fmu->setupExperiment = (fmi2SetupExperimentTYPE *) getAdr(&s, h, "fmi2SetupExperiment", preamble);
- fmu->enterInitializationMode = (fmi2EnterInitializationModeTYPE *) getAdr(&s, h, "fmi2EnterInitializationMode", preamble);
- fmu->exitInitializationMode = (fmi2ExitInitializationModeTYPE *) getAdr(&s, h, "fmi2ExitInitializationMode", preamble);
- fmu->terminate = (fmi2TerminateTYPE *) getAdr(&s, h, "fmi2Terminate", preamble);
- fmu->reset = (fmi2ResetTYPE *) getAdr(&s, h, "fmi2Reset", preamble);
- fmu->getReal = (fmi2GetRealTYPE *) getAdr(&s, h, "fmi2GetReal", preamble);
- fmu->getInteger = (fmi2GetIntegerTYPE *) getAdr(&s, h, "fmi2GetInteger", preamble);
- fmu->getBoolean = (fmi2GetBooleanTYPE *) getAdr(&s, h, "fmi2GetBoolean", preamble);
- fmu->getString = (fmi2GetStringTYPE *) getAdr(&s, h, "fmi2GetString", preamble);
- fmu->setReal = (fmi2SetRealTYPE *) getAdr(&s, h, "fmi2SetReal", preamble);
- fmu->setInteger = (fmi2SetIntegerTYPE *) getAdr(&s, h, "fmi2SetInteger", preamble);
- fmu->setBoolean = (fmi2SetBooleanTYPE *) getAdr(&s, h, "fmi2SetBoolean", preamble);
- fmu->setString = (fmi2SetStringTYPE *) getAdr(&s, h, "fmi2SetString", preamble);
- fmu->getFMUstate = (fmi2GetFMUstateTYPE *) getAdr(&s, h, "fmi2GetFMUstate", preamble);
- fmu->setFMUstate = (fmi2SetFMUstateTYPE *) getAdr(&s, h, "fmi2SetFMUstate", preamble);
- fmu->freeFMUstate = (fmi2FreeFMUstateTYPE *) getAdr(&s, h, "fmi2FreeFMUstate", preamble);
- fmu->serializedFMUstateSize = (fmi2SerializedFMUstateSizeTYPE *) getAdr(&s, h, "fmi2SerializedFMUstateSize", preamble);
- fmu->serializeFMUstate = (fmi2SerializeFMUstateTYPE *) getAdr(&s, h, "fmi2SerializeFMUstate", preamble);
- fmu->deSerializeFMUstate = (fmi2DeSerializeFMUstateTYPE *) getAdr(&s, h, "fmi2DeSerializeFMUstate", preamble);
- fmu->getDirectionalDerivative = (fmi2GetDirectionalDerivativeTYPE *) getAdr(&s, h, "fmi2GetDirectionalDerivative", preamble);
- #ifdef FMI_COSIMULATION
- fmu->setRealInputDerivatives = (fmi2SetRealInputDerivativesTYPE *) getAdr(&s, h, "fmi2SetRealInputDerivatives", preamble);
- fmu->getRealOutputDerivatives = (fmi2GetRealOutputDerivativesTYPE *) getAdr(&s, h, "fmi2GetRealOutputDerivatives", preamble);
- fmu->doStep = (fmi2DoStepTYPE *) getAdr(&s, h, "fmi2DoStep", preamble);
- fmu->cancelStep = (fmi2CancelStepTYPE *) getAdr(&s, h, "fmi2CancelStep", preamble);
- fmu->getStatus = (fmi2GetStatusTYPE *) getAdr(&s, h, "fmi2GetStatus", preamble);
- fmu->getRealStatus = (fmi2GetRealStatusTYPE *) getAdr(&s, h, "fmi2GetRealStatus", preamble);
- fmu->getIntegerStatus = (fmi2GetIntegerStatusTYPE *) getAdr(&s, h, "fmi2GetIntegerStatus", preamble);
- fmu->getBooleanStatus = (fmi2GetBooleanStatusTYPE *) getAdr(&s, h, "fmi2GetBooleanStatus", preamble);
- fmu->getStringStatus = (fmi2GetStringStatusTYPE *) getAdr(&s, h, "fmi2GetStringStatus", preamble);
- #else // FMI2 for Model Exchange
- fmu->enterEventMode = (fmi2EnterEventModeTYPE *) getAdr(&s, h, "fmi2EnterEventMode", preamble);
- fmu->newDiscreteStates = (fmi2NewDiscreteStatesTYPE *) getAdr(&s, h, "fmi2NewDiscreteStates", preamble);
- fmu->enterContinuousTimeMode = (fmi2EnterContinuousTimeModeTYPE *) getAdr(&s, h, "fmi2EnterContinuousTimeMode", preamble);
- fmu->completedIntegratorStep = (fmi2CompletedIntegratorStepTYPE *) getAdr(&s, h, "fmi2CompletedIntegratorStep", preamble);
- fmu->setTime = (fmi2SetTimeTYPE *) getAdr(&s, h, "fmi2SetTime", preamble);
- fmu->setContinuousStates = (fmi2SetContinuousStatesTYPE *) getAdr(&s, h, "fmi2SetContinuousStates", preamble);
- fmu->getDerivatives = (fmi2GetDerivativesTYPE *) getAdr(&s, h, "fmi2GetDerivatives", preamble);
- fmu->getEventIndicators = (fmi2GetEventIndicatorsTYPE *) getAdr(&s, h, "fmi2GetEventIndicators", preamble);
- fmu->getContinuousStates = (fmi2GetContinuousStatesTYPE *) getAdr(&s, h, "fmi2GetContinuousStates", preamble);
- fmu->getNominalsOfContinuousStates = (fmi2GetNominalsOfContinuousStatesTYPE *) getAdr(&s, h, "fmi2GetNominalsOfContinuousStates", preamble);
- #endif
- if (fmu->getVersion == NULL && fmu->instantiate == NULL) {
- printf("warning: Functions from FMI 2.0 could not be found in %s\n", dllPath);
- printf("warning: Simulator will look for FMI 2.0 RC1 functions names...\n");
- fmu->getTypesPlatform = (fmi2GetTypesPlatformTYPE *) getAdr(&s, h, "fmiGetTypesPlatform", preamble);
- fmu->getVersion = (fmi2GetVersionTYPE *) getAdr(&s, h, "fmiGetVersion", preamble);
- fmu->setDebugLogging = (fmi2SetDebugLoggingTYPE *) getAdr(&s, h, "fmiSetDebugLogging", preamble);
- fmu->instantiate = (fmi2InstantiateTYPE *) getAdr(&s, h, "fmiInstantiate", preamble);
- fmu->freeInstance = (fmi2FreeInstanceTYPE *) getAdr(&s, h, "fmiFreeInstance", preamble);
- fmu->setupExperiment = (fmi2SetupExperimentTYPE *) getAdr(&s, h, "fmiSetupExperiment", preamble);
- fmu->enterInitializationMode = (fmi2EnterInitializationModeTYPE *) getAdr(&s, h, "fmiEnterInitializationMode", preamble);
- fmu->exitInitializationMode = (fmi2ExitInitializationModeTYPE *) getAdr(&s, h, "fmiExitInitializationMode", preamble);
- fmu->terminate = (fmi2TerminateTYPE *) getAdr(&s, h, "fmiTerminate", preamble);
- fmu->reset = (fmi2ResetTYPE *) getAdr(&s, h, "fmiReset", preamble);
- fmu->getReal = (fmi2GetRealTYPE *) getAdr(&s, h, "fmiGetReal", preamble);
- fmu->getInteger = (fmi2GetIntegerTYPE *) getAdr(&s, h, "fmiGetInteger", preamble);
- fmu->getBoolean = (fmi2GetBooleanTYPE *) getAdr(&s, h, "fmiGetBoolean", preamble);
- fmu->getString = (fmi2GetStringTYPE *) getAdr(&s, h, "fmiGetString", preamble);
- fmu->setReal = (fmi2SetRealTYPE *) getAdr(&s, h, "fmiSetReal", preamble);
- fmu->setInteger = (fmi2SetIntegerTYPE *) getAdr(&s, h, "fmiSetInteger", preamble);
- fmu->setBoolean = (fmi2SetBooleanTYPE *) getAdr(&s, h, "fmiSetBoolean", preamble);
- fmu->setString = (fmi2SetStringTYPE *) getAdr(&s, h, "fmiSetString", preamble);
- fmu->getFMUstate = (fmi2GetFMUstateTYPE *) getAdr(&s, h, "fmiGetFMUstate", preamble);
- fmu->setFMUstate = (fmi2SetFMUstateTYPE *) getAdr(&s, h, "fmiSetFMUstate", preamble);
- fmu->freeFMUstate = (fmi2FreeFMUstateTYPE *) getAdr(&s, h, "fmiFreeFMUstate", preamble);
- fmu->serializedFMUstateSize = (fmi2SerializedFMUstateSizeTYPE *) getAdr(&s, h, "fmiSerializedFMUstateSize", preamble);
- fmu->serializeFMUstate = (fmi2SerializeFMUstateTYPE *) getAdr(&s, h, "fmiSerializeFMUstate", preamble);
- fmu->deSerializeFMUstate = (fmi2DeSerializeFMUstateTYPE *) getAdr(&s, h, "fmiDeSerializeFMUstate", preamble);
- fmu->getDirectionalDerivative = (fmi2GetDirectionalDerivativeTYPE *) getAdr(&s, h, "fmiGetDirectionalDerivative", preamble);
- #ifdef FMI_COSIMULATION
- fmu->setRealInputDerivatives = (fmi2SetRealInputDerivativesTYPE *) getAdr(&s, h, "fmiSetRealInputDerivatives", preamble);
- fmu->getRealOutputDerivatives = (fmi2GetRealOutputDerivativesTYPE *) getAdr(&s, h, "fmiGetRealOutputDerivatives", preamble);
- fmu->doStep = (fmi2DoStepTYPE *) getAdr(&s, h, "fmiDoStep", preamble);
- fmu->cancelStep = (fmi2CancelStepTYPE *) getAdr(&s, h, "fmiCancelStep", preamble);
- fmu->getStatus = (fmi2GetStatusTYPE *) getAdr(&s, h, "fmiGetStatus", preamble);
- fmu->getRealStatus = (fmi2GetRealStatusTYPE *) getAdr(&s, h, "fmiGetRealStatus", preamble);
- fmu->getIntegerStatus = (fmi2GetIntegerStatusTYPE *) getAdr(&s, h, "fmiGetIntegerStatus", preamble);
- fmu->getBooleanStatus = (fmi2GetBooleanStatusTYPE *) getAdr(&s, h, "fmiGetBooleanStatus", preamble);
- fmu->getStringStatus = (fmi2GetStringStatusTYPE *) getAdr(&s, h, "fmiGetStringStatus", preamble);
- #else // FMI2 for Model Exchange
- fmu->enterEventMode = (fmi2EnterEventModeTYPE *) getAdr(&s, h, "fmiEnterEventMode", preamble);
- fmu->newDiscreteStates = (fmi2NewDiscreteStatesTYPE *) getAdr(&s, h, "fmiNewDiscreteStates", preamble);
- fmu->enterContinuousTimeMode = (fmi2EnterContinuousTimeModeTYPE *) getAdr(&s, h, "fmiEnterContinuousTimeMode", preamble);
- fmu->completedIntegratorStep = (fmi2CompletedIntegratorStepTYPE *) getAdr(&s, h, "fmiCompletedIntegratorStep", preamble);
- fmu->setTime = (fmi2SetTimeTYPE *) getAdr(&s, h, "fmiSetTime", preamble);
- fmu->setContinuousStates = (fmi2SetContinuousStatesTYPE *) getAdr(&s, h, "fmiSetContinuousStates", preamble);
- fmu->getDerivatives = (fmi2GetDerivativesTYPE *) getAdr(&s, h, "fmiGetDerivatives", preamble);
- fmu->getEventIndicators = (fmi2GetEventIndicatorsTYPE *) getAdr(&s, h, "fmiGetEventIndicators", preamble);
- fmu->getContinuousStates = (fmi2GetContinuousStatesTYPE *) getAdr(&s, h, "fmiGetContinuousStates", preamble);
- fmu->getNominalsOfContinuousStates = (fmi2GetNominalsOfContinuousStatesTYPE *) getAdr(&s, h, "fmiGetNominalsOfContinuousStates", preamble);
- #endif
- }
- return s;
- }
- //static void printModelDescription(ModelDescription* md){
- // Element* e = (Element*)md;
- // int i;
- // int n; // number of attributes
- // const char **attributes = getAttributesAsArray(e, &n);
- // Component *component;
- //
- // if (!attributes) {
- // printf("ModelDescription printing aborted.");
- // return;
- // }
- // printf("%s\n", getElementTypeName(e));
- // for (i = 0; i < n; i += 2) {
- // printf(" %s=%s\n", attributes[i], attributes[i+1]);
- // }
- // free((void *)attributes);
- //
- //#ifdef FMI_COSIMULATION
- // component = getCoSimulation(md);
- // if (!component) {
- // printf("error: No CoSimulation element found in model description. This FMU is not for Co-Simulation.\n");
- // exit(EXIT_FAILURE);
- // }
- //#else // FMI_MODEL_EXCHANGE
- // component = getModelExchange(md);
- // if (!component) {
- // printf("error: No ModelExchange element found in model description. This FMU is not for Model Exchange.\n");
- // exit(EXIT_FAILURE);
- // }
- //#endif
- // printf("%s\n", getElementTypeName((Element *)component));
- // attributes = getAttributesAsArray((Element *)component, &n);
- // if (!attributes) {
- // printf("ModelDescription printing aborted.");
- // return;
- // }
- // for (i = 0; i < n; i += 2) {
- // printf(" %s=%s\n", attributes[i], attributes[i+1]);
- // }
- //
- // free((void *)attributes);
- //}
- //
- //void loadFMU(const char* fmuFileName) {
- // char* fmuPath;
- // char* tmpPath;
- // char* xmlPath;
- // char* dllPath;
- // const char *modelId;
- //
- // // get absolute path to FMU, NULL if not found
- // fmuPath = getFmuPath(fmuFileName);
- // if (!fmuPath) exit(EXIT_FAILURE);
- //
- // // unzip the FMU to the tmpPath directory
- // tmpPath = getTmpPath();
- // if (!unzip(fmuPath, tmpPath)) exit(EXIT_FAILURE);
- //
- // // parse tmpPath\modelDescription.xml
- // xmlPath = calloc(sizeof(char), strlen(tmpPath) + strlen(XML_FILE) + 1);
- // sprintf(xmlPath, "%s%s", tmpPath, XML_FILE);
- // fmu.modelDescription = parse(xmlPath);
- // free(xmlPath);
- // if (!fmu.modelDescription) exit(EXIT_FAILURE);
- // printModelDescription(fmu.modelDescription);
- //#ifdef FMI_COSIMULATION
- // modelId = getAttributeValue((Element *)getCoSimulation(fmu.modelDescription), att_modelIdentifier);
- //#else // FMI_MODEL_EXCHANGE
- // modelId = getAttributeValue((Element *)getModelExchange(fmu.modelDescription), att_modelIdentifier);
- //#endif
- // // load the FMU dll
- // dllPath = calloc(sizeof(char), strlen(tmpPath) + strlen(DLL_DIR)
- // + strlen(modelId) + strlen(".dll") + 1);
- // sprintf(dllPath, "%s%s%s.dll", tmpPath, DLL_DIR, modelId);
- // if (!loadDll(dllPath, &fmu)) {
- // exit(EXIT_FAILURE);
- // }
- // free(dllPath);
- // free(fmuPath);
- // free(tmpPath);
- //}
- //
- //void deleteUnzippedFiles() {
- // const char *fmuTempPath = getTmpPath();
- // char *cmd = (char *)calloc(15 + strlen(fmuTempPath), sizeof(char));
- // sprintf(cmd, "rmdir /S /Q %s", fmuTempPath);
- // system(cmd);
- // free(cmd);
- //}
- //
- //static void doubleToCommaString(char* buffer, double r){
- // char* comma;
- // sprintf(buffer, "%.16g", r);
- // comma = strchr(buffer, '.');
- // if (comma) *comma = ',';
- //}
- //
- //// output time and all variables in CSV format
- //// if separator is ',', columns are separated by ',' and '.' is used for floating-point numbers.
- //// otherwise, the given separator (e.g. ';' or '\t') is to separate columns, and ',' is used
- //// as decimal dot in floating-point numbers.
- //void outputRow(FMU *fmu, fmi2Component c, double time, FILE* file, char separator, fmi2Boolean header) {
- // int k;
- // fmi2Real r;
- // fmi2Integer i;
- // fmi2Boolean b;
- // fmi2String s;
- // fmi2ValueReference vr;
- // int n = getScalarVariableSize(fmu->modelDescription);
- // char buffer[32];
- //
- // // print first column
- // if (header) {
- // fprintf(file, "time");
- // } else {
- // if (separator==',')
- // fprintf(file, "%.16g", time);
- // else {
- // // separator is e.g. ';' or '\t'
- // doubleToCommaString(buffer, time);
- // fprintf(file, "%s", buffer);
- // }
- // }
- //
- // // print all other columns
- // for (k = 0; k < n; k++) {
- // ScalarVariable *sv = getScalarVariable(fmu->modelDescription, k);
- // if (header) {
- // // output names only
- // if (separator == ',') {
- // // treat array element, e.g. print a[1, 2] as a[1.2]
- // const char *s = getAttributeValue((Element *)sv, att_name);
- // fprintf(file, "%c", separator);
- // while (*s) {
- // if (*s != ' ') {
- // fprintf(file, "%c", *s == ',' ? '.' : *s);
- // }
- // s++;
- // }
- // } else {
- // fprintf(file, "%c%s", separator, getAttributeValue((Element *)sv, att_name));
- // }
- // } else {
- // // output values
- // vr = getValueReference(sv);
- // switch (getElementType(getTypeSpec(sv))) {
- // case elm_Real:
- // fmu->getReal(c, &vr, 1, &r);
- // if (separator == ',') {
- // fprintf(file, ",%.16g", r);
- // } else {
- // // separator is e.g. ';' or '\t'
- // doubleToCommaString(buffer, r);
- // fprintf(file, "%c%s", separator, buffer);
- // }
- // break;
- // case elm_Integer:
- // case elm_Enumeration:
- // fmu->getInteger(c, &vr, 1, &i);
- // fprintf(file, "%c%d", separator, i);
- // break;
- // case elm_Boolean:
- // fmu->getBoolean(c, &vr, 1, &b);
- // fprintf(file, "%c%d", separator, b);
- // break;
- // case elm_String:
- // fmu->getString(c, &vr, 1, &s);
- // fprintf(file, "%c%s", separator, s);
- // break;
- // default:
- // fprintf(file, "%cNoValueForType=%d", separator, getElementType(getTypeSpec(sv)));
- // }
- // }
- // } // for
- //
- // // terminate this row
- // fprintf(file, "\n");
- //}
- //
- static const char* fmi2StatusToString(fmi2Status status){
- switch (status){
- case fmi2OK: return "ok";
- case fmi2Warning: return "warning";
- case fmi2Discard: return "discard";
- case fmi2Error: return "error";
- case fmi2Fatal: return "fatal";
- #ifdef FMI_COSIMULATION
- case fmi2Pending: return "fmi2Pending";
- #endif
- default: return "?";
- }
- }
- // search a fmu for the given variable, matching the type specified.
- // return NULL if not found
- //static ScalarVariable* getSV(FMU* fmu, char type, fmi2ValueReference vr) {
- // return NULL;
- // int i;
- // int n = getScalarVariableSize(fmu->modelDescription);
- // Elm tp;
- //
- // switch (type) {
- // case 'r': tp = elm_Real; break;
- // case 'i': tp = elm_Integer; break;
- // case 'b': tp = elm_Boolean; break;
- // case 's': tp = elm_String; break;
- // default : tp = elm_BAD_DEFINED;
- // }
- // for (i = 0; i < n; i++) {
- // ScalarVariable* sv = getScalarVariable(fmu->modelDescription ,i);
- // if (vr == getValueReference(sv) && tp == getElementType(getTypeSpec(sv))) {
- // return sv;
- // }
- // }
- // return NULL;
- //}
- // replace e.g. #r1365# by variable name and ## by # in message
- // copies the result to buffer
- static void replaceRefsInMessage(const char* msg, char* buffer, int nBuffer, FMU* fmu){
- int i = 0; // position in msg
- int k = 0; // position in buffer
- int n;
- char c = msg[i];
- while (c != '\0' && k < nBuffer) {
- if (c != '#') {
- buffer[k++] = c;
- i++;
- c = msg[i];
- } else {
- char* end = strchr(msg + i + 1, '#');
- if (!end) {
- printf("unmatched '#' in '%s'\n", msg);
- buffer[k++] = '#';
- break;
- }
- n = end - (msg + i);
- if (n == 1) {
- // ## detected, output #
- buffer[k++] = '#';
- i += 2;
- c = msg[i];
- } else {
- char type = msg[i + 1]; // one of ribs
- fmi2ValueReference vr;
- int nvr = sscanf(msg + i + 2, "%u", &vr);
- if (nvr == 1) {
- // vr of type detected, e.g. #r12#
- //ScalarVariable* sv = getSV(fmu, type, vr);
- //const char* name = sv ? getAttributeValue((Element *)sv, att_name) : "?";
- //sprintf(buffer + k, "%s", name);
- //k += strlen(name);
- //i += (n+1);
- //c = msg[i];
- } else {
- // could not parse the number
- printf("illegal value reference at position %d in '%s'\n", i + 2, msg);
- buffer[k++] = '#';
- break;
- }
- }
- }
- } // while
- buffer[k] = '\0';
- }
- #define MAX_MSG_SIZE 1000
- void fmuLogger(void *componentEnvironment, fmi2String instanceName, fmi2Status status,
- fmi2String category, fmi2String message, ...) {
- char msg[MAX_MSG_SIZE];
- char* copy;
- va_list argp;
- // replace C format strings
- va_start(argp, message);
- vsprintf(msg, message, argp);
- va_end(argp);
- // replace e.g. ## and #r12#
- copy = strdup(msg);
- // replaceRefsInMessage(copy, msg, MAX_MSG_SIZE, NULL);
- free(copy);
- // print the final message
- if (!instanceName) instanceName = "?";
- if (!category) category = "?";
- printf("%s %s (%s): %s\n", fmi2StatusToString(status), instanceName, category, msg);
- }
- int error(const char* message){
- printf("%s\n", message);
- return 0;
- }
- //
- //void parseArguments(int argc, char *argv[], const char **fmuFileName, double *tEnd, double *h,
- // int *loggingOn, char *csv_separator, int *nCategories, char **logCategories[]) {
- // // parse command line arguments
- // if (argc > 1) {
- // *fmuFileName = argv[1];
- // } else {
- // printf("error: no fmu file\n");
- // printHelp(argv[0]);
- // exit(EXIT_FAILURE);
- // }
- // if (argc > 2) {
- // if (sscanf(argv[2],"%lf", tEnd) != 1) {
- // printf("error: The given end time (%s) is not a number\n", argv[2]);
- // exit(EXIT_FAILURE);
- // }
- // }
- // if (argc > 3) {
- // if (sscanf(argv[3],"%lf", h) != 1) {
- // printf("error: The given stepsize (%s) is not a number\n", argv[3]);
- // exit(EXIT_FAILURE);
- // }
- // }
- // if (argc > 4) {
- // if (sscanf(argv[4],"%d", loggingOn) != 1 || *loggingOn < 0 || *loggingOn > 1) {
- // printf("error: The given logging flag (%s) is not boolean\n", argv[4]);
- // exit(EXIT_FAILURE);
- // }
- // }
- // if (argc > 5) {
- // if (strlen(argv[5]) != 1) {
- // printf("error: The given CSV separator char (%s) is not valid\n", argv[5]);
- // exit(EXIT_FAILURE);
- // }
- // switch (argv[5][0]) {
- // case 'c': *csv_separator = ','; break; // comma
- // case 's': *csv_separator = ';'; break; // semicolon
- // default: *csv_separator = argv[5][0]; break; // any other char
- // }
- // }
- // if (argc > 6) {
- // int i;
- // *nCategories = argc - 6;
- // *logCategories = (char **)calloc(sizeof(char *), *nCategories);
- // for (i = 0; i < *nCategories; i++) {
- // (*logCategories)[i] = argv[i + 6];
- // }
- // }
- //}
- //
- //void printHelp(const char *fmusim) {
- // printf("command syntax: %s <model.fmu> <tEnd> <h> <loggingOn> <csv separator>\n", fmusim);
- // printf(" <model.fmu> .... path to FMU, relative to current dir or absolute, required\n");
- // printf(" <tEnd> ......... end time of simulation, optional, defaults to 1.0 sec\n");
- // printf(" <h> ............ step size of simulation, optional, defaults to 0.1 sec\n");
- // printf(" <loggingOn> .... 1 to activate logging, optional, defaults to 0\n");
- // printf(" <csv separator>. separator in csv file, optional, c for ',', s for';', defaults to c\n");
- // printf(" <logCategories>. list of active categories, optional, see modelDescription.xml for possible values\n");
- //}
|