From 403a712015c4a6a96bc51f80b80a1a10f44de81a Mon Sep 17 00:00:00 2001 From: Lennart Ochel Date: Mon, 3 Nov 2025 13:30:55 +0100 Subject: [PATCH] New api: oms_addAlias --- include/OMSimulator/OMSimulator.h | 1 + src/OMSimulatorLib/Model.cpp | 81 ++++++++++++++++++++++++++++++ src/OMSimulatorLib/Model.h | 4 ++ src/OMSimulatorLib/OMSimulator.cpp | 21 ++++++++ 4 files changed, 107 insertions(+) diff --git a/include/OMSimulator/OMSimulator.h b/include/OMSimulator/OMSimulator.h index d222d8363..ac1359972 100644 --- a/include/OMSimulator/OMSimulator.h +++ b/include/OMSimulator/OMSimulator.h @@ -59,6 +59,7 @@ extern "C" #endif OMSAPI oms_status_enu_t OMSCALL oms_activateVariant(const char* crefA, const char* crefB); +OMSAPI oms_status_enu_t OMSCALL oms_addAlias(const char* cref, const char* rhs); OMSAPI oms_status_enu_t OMSCALL oms_addBus(const char* cref); OMSAPI oms_status_enu_t OMSCALL oms_addConnection(const char* crefA, const char* crefB, bool suppressUnitConversion); OMSAPI oms_status_enu_t OMSCALL oms_addConnector(const char* cref, oms_causality_enu_t causality, oms_signal_type_enu_t type); diff --git a/src/OMSimulatorLib/Model.cpp b/src/OMSimulatorLib/Model.cpp index c8dd3a80c..ca48a6a92 100644 --- a/src/OMSimulatorLib/Model.cpp +++ b/src/OMSimulatorLib/Model.cpp @@ -1392,6 +1392,47 @@ oms_status_enu_t oms::Model::registerSignalsForResultFile() if (system) if (oms_status_ok != system->registerSignalsForResultFile(*resultFile)) return oms_status_error; + + for (auto &it : aliases) + { + const ComRef& alias = it.first; + ComRef rhs; + oms_signal_type_enu_t varType = oms_signal_type_real; + int result_file_id = -1; + std::tie(rhs, varType, result_file_id) = it.second; + + std::string description = std::string("Alias target: ") + std::string(rhs); + oms::SignalType_t sigType; + switch (std::get<1>(it.second)) + { + case oms_signal_type_real: + sigType = oms::SignalType_t::SignalType_REAL; + break; + case oms_signal_type_integer: + sigType = oms::SignalType_t::SignalType_INT; + break; + case oms_signal_type_boolean: + sigType = oms::SignalType_t::SignalType_BOOL; + break; + default: + return logError("Unsupported signal type for alias \"" + std::string(alias) + "\" in model \"" + std::string(getCref()) + "\""); + } + + result_file_id = resultFile->addSignal(alias, description, sigType); + it.second = std::make_tuple(rhs, varType, result_file_id); + } + + return oms_status_ok; +} + +oms_status_enu_t oms::Model::addAlias(const ComRef& alias, const ComRef& rhs, oms_signal_type_enu_t type) +{ + // check that alias does not already exist + if (aliases.find(alias) != aliases.end()) + return logError("Alias \"" + std::string(alias) + "\" already exists in model \"" + std::string(getCref()) + "\""); + + // insert tuple (rhs, type, result_file_id) with result_file_id = -1 (not yet registered) + aliases[alias] = std::make_tuple(rhs, type, -1); return oms_status_ok; } @@ -1415,6 +1456,46 @@ oms_status_enu_t oms::Model::emit(double time, bool force, bool* emitted) if (oms_status_ok != system->updateSignals(*resultFile)) return oms_status_error; + // emit alias variables + for (const auto &it : aliases) + { + const ComRef& alias = it.first; + ComRef rhs; + oms_signal_type_enu_t varType; + int result_file_id = -1; + std::tie(rhs, varType, result_file_id) = it.second; + + if (result_file_id < 0) + continue; // not registered in result file + + SignalValue_t value; + oms_status_enu_t status = oms_status_ok; + if (varType == oms_signal_type_real) + { + double v; + status = system->getReal(rhs, v); + if (status == oms_status_ok) + value.realValue = v; + } + else if (varType == oms_signal_type_integer || varType == oms_signal_type_enum) + { + int v; + status = system->getInteger(rhs, v); + if (status == oms_status_ok) + value.intValue = v; + } + else if (varType == oms_signal_type_boolean) + { + bool v; + status = system->getBoolean(rhs, v); + if (status == oms_status_ok) + value.boolValue = v; + } + + if (status == oms_status_ok) + resultFile->updateSignal(static_cast(result_file_id), value); + } + resultFile->emit(time); lastEmit = time; if (emitted) diff --git a/src/OMSimulatorLib/Model.h b/src/OMSimulatorLib/Model.h index 01bb67720..5c59a8039 100644 --- a/src/OMSimulatorLib/Model.h +++ b/src/OMSimulatorLib/Model.h @@ -43,6 +43,7 @@ #include #include +#include namespace oms { @@ -123,6 +124,7 @@ namespace oms oms_status_enu_t addSignalsToResults(const char* regex); oms_status_enu_t removeSignalsFromResults(const char* regex); std::string escapeSpecialCharacters(const std::string& regex); + oms_status_enu_t addAlias(const ComRef& alias, const ComRef& rhs, oms_signal_type_enu_t type); bool validState(int validStates) const {return (modelState & validStates);} @@ -178,6 +180,8 @@ namespace oms std::vector externalResources; ///< list of external ssv or ssm resources from filesystem + std::map> aliases; ///< list of aliases: (rhs, type, result_file_id) + bool isolatedFMU = false; ctpl::thread_pool* pool = nullptr; diff --git a/src/OMSimulatorLib/OMSimulator.cpp b/src/OMSimulatorLib/OMSimulator.cpp index 25168f82c..52c2aab5e 100644 --- a/src/OMSimulatorLib/OMSimulator.cpp +++ b/src/OMSimulatorLib/OMSimulator.cpp @@ -625,6 +625,27 @@ oms_status_enu_t oms_getConnections(const char *cref, oms_connection_t ***connec return oms_status_ok; } +oms_status_enu_t oms_addAlias(const char* cref, const char* rhs_) +{ + oms::ComRef tail(cref); + oms::ComRef modelCref = tail.pop_front(); + oms::ComRef aliasCref = tail.pop_front(); + oms::Model* model = oms::Scope::GetInstance().getModel(modelCref); + if (!model) { + return logError_ModelNotInScope(modelCref); + } + + if (!rhs_) + return logError("Invalid argument: rhs=NULL"); + + oms::ComRef rhs(rhs_); + oms_signal_type_enu_t type; + if (oms_status_ok != oms_getVariableType(rhs_, &type)) + return logError("The rhs \"" + std::string(rhs_) + "\" does not exist."); + + return model->addAlias(aliasCref, rhs, type); +} + oms_status_enu_t oms_addBus(const char *cref) { oms::ComRef tail(cref);