Skip to content

Commit

Permalink
export enumeration definition to ssp (OpenModelica#1266)
Browse files Browse the repository at this point in the history
* export enumeration definition to ssp

* allow importing enumeration

* import enumerations defintions from ssd
  • Loading branch information
arun3688 committed Oct 24, 2023
1 parent c920c75 commit ffd0d88
Show file tree
Hide file tree
Showing 17 changed files with 348 additions and 8 deletions.
1 change: 1 addition & 0 deletions src/OMSimulatorLib/Component.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ namespace oms
virtual oms_status_enu_t exportToSSD(pugi::xml_node& node, Snapshot& snapshot, std::string variantName) const = 0;
virtual oms_status_enu_t exportToSSV(pugi::xml_node& ssvNode) { return logError_NotImplemented; }
virtual void getFilteredUnitDefinitionsToSSD(std::map<std::string, std::map<std::string, std::string>>& unitDefinitions) { return ; }
virtual void getFilteredEnumerationDefinitionsToSSD(std::map<std::string, std::map<std::string, std::string>>& enumerationDefinitions) { return ; }

virtual oms_status_enu_t initialize() = 0;
virtual oms_status_enu_t instantiate() = 0;
Expand Down
20 changes: 20 additions & 0 deletions src/OMSimulatorLib/ComponentFMUCS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,11 @@ oms::Component* oms::ComponentFMUCS::NewComponent(const oms::ComRef& cref, oms::
std::string unitName = component->values.getUnitFromModeldescription(connectorCref);
if (!unitName.empty())
connector->connectorUnits[unitName] = component->values.modeldescriptionUnitDefinitions[unitName];

// get enumerationTypes
std::string enumType = component->values.getEnumerationTypeFromModeldescription(connectorCref);
if (!enumType.empty())
connector->enumerationName[connectorCref] = enumType;
}
}

Expand Down Expand Up @@ -304,6 +309,16 @@ oms::Component* oms::ComponentFMUCS::NewComponent(const pugi::xml_node& node, om
if (!unitName.empty())
component->connectors.back()->connectorUnits[unitName] = component->values.modeldescriptionUnitDefinitions[unitName];
}
// set enumeration definitions
if ((*itConnectors).child(oms::ssp::Version1_0::ssc::enumeration_type))
{
std::string enumTypeName = (*itConnectors).child(oms::ssp::Version1_0::ssc::enumeration_type).attribute("name").as_string();
if (!enumTypeName.empty())
component->connectors.back()->enumerationName[component->connectors.back()->getName().c_str()] = enumTypeName;

// give priority to enum definitions in ssd over modeldescription.xml, it is possible the user might have manually change values in ssd file
component->values.importEnumerationDefinitions(ssdNode, enumTypeName);
}
}
}
else if(name == oms::ssp::Draft20180219::ssd::element_geometry)
Expand Down Expand Up @@ -389,6 +404,11 @@ void oms::ComponentFMUCS::getFilteredUnitDefinitionsToSSD(std::map<std::string,
return values.getFilteredUnitDefinitionsToSSD(unitDefinitions);
}

void oms::ComponentFMUCS::getFilteredEnumerationDefinitionsToSSD(std::map<std::string, std::map<std::string, std::string>>& enumerationDefinitions)
{
return values.getFilteredEnumerationDefinitionsToSSD(enumerationDefinitions);
}

oms_status_enu_t oms::ComponentFMUCS::exportToSSV(pugi::xml_node& ssvNode)
{
return values.exportToSSV(ssvNode);
Expand Down
1 change: 1 addition & 0 deletions src/OMSimulatorLib/ComponentFMUCS.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ namespace oms
oms_status_enu_t exportToSSD(pugi::xml_node& node, Snapshot& snapshot, std::string variantName) const;
oms_status_enu_t exportToSSV(pugi::xml_node& ssvNode);
void getFilteredUnitDefinitionsToSSD(std::map<std::string, std::map<std::string, std::string>>& unitDefinitions);
void getFilteredEnumerationDefinitionsToSSD(std::map<std::string, std::map<std::string, std::string>>& enumerationDefinitions);
oms_status_enu_t exportToSSVTemplate(pugi::xml_node& ssvNode, Snapshot& snapshot);
oms_status_enu_t exportToSSMTemplate(pugi::xml_node& ssmNode);
oms_status_enu_t instantiate();
Expand Down
20 changes: 20 additions & 0 deletions src/OMSimulatorLib/ComponentFMUME.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,11 @@ oms::Component* oms::ComponentFMUME::NewComponent(const oms::ComRef& cref, oms::
std::string unitName = component->values.getUnitFromModeldescription(connectorCref);
if (!unitName.empty())
connector->connectorUnits[unitName] = component->values.modeldescriptionUnitDefinitions[unitName];

// get enumerationTypes
std::string enumType = component->values.getEnumerationTypeFromModeldescription(connectorCref);
if (!enumType.empty())
connector->enumerationName[connectorCref] = enumType;
}
}

Expand Down Expand Up @@ -302,6 +307,16 @@ oms::Component* oms::ComponentFMUME::NewComponent(const pugi::xml_node& node, om
if (!unitName.empty())
component->connectors.back()->connectorUnits[unitName] = component->values.modeldescriptionUnitDefinitions[unitName];
}
// set enumeration definitions
if ((*itConnectors).child(oms::ssp::Version1_0::ssc::enumeration_type))
{
std::string enumTypeName = (*itConnectors).child(oms::ssp::Version1_0::ssc::enumeration_type).attribute("name").as_string();
if (!enumTypeName.empty())
component->connectors.back()->enumerationName[component->connectors.back()->getName().c_str()] = enumTypeName;

// give priority to enum definitions in ssd over modeldescription.xml
component->values.importEnumerationDefinitions(ssdNode, enumTypeName);
}
}
}
else if(name == oms::ssp::Draft20180219::ssd::element_geometry)
Expand Down Expand Up @@ -387,6 +402,11 @@ void oms::ComponentFMUME::getFilteredUnitDefinitionsToSSD(std::map<std::string,
return values.getFilteredUnitDefinitionsToSSD(unitDefinitions);
}

void oms::ComponentFMUME::getFilteredEnumerationDefinitionsToSSD(std::map<std::string, std::map<std::string, std::string>>& enumerationDefinitions)
{
return values.getFilteredEnumerationDefinitionsToSSD(enumerationDefinitions);
}

oms_status_enu_t oms::ComponentFMUME::exportToSSV(pugi::xml_node& ssvNode)
{
return values.exportToSSV(ssvNode);
Expand Down
1 change: 1 addition & 0 deletions src/OMSimulatorLib/ComponentFMUME.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ namespace oms
oms_status_enu_t exportToSSD(pugi::xml_node& node, Snapshot& snapshot, std::string variantName) const;
oms_status_enu_t exportToSSV(pugi::xml_node& ssvNode);
void getFilteredUnitDefinitionsToSSD(std::map<std::string, std::map<std::string, std::string>>& unitDefinitions);
void getFilteredEnumerationDefinitionsToSSD(std::map<std::string, std::map<std::string, std::string>>& enumerationDefinitions);
oms_status_enu_t exportToSSVTemplate(pugi::xml_node& ssvNode, Snapshot& snapshot);
oms_status_enu_t exportToSSMTemplate(pugi::xml_node& ssmNode);
oms_status_enu_t instantiate();
Expand Down
2 changes: 2 additions & 0 deletions src/OMSimulatorLib/Connector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@ oms_status_enu_t oms::Connector::exportToSSD(pugi::xml_node &root) const
break;
case oms_signal_type_enum:
node.append_child(oms::ssp::Version1_0::ssc::enumeration_type);
for (const auto & it : this->enumerationName)
node.child(oms::ssp::Version1_0::ssc::enumeration_type).append_attribute("name") = it.second.c_str();
break;
case oms_signal_type_integer:
node.append_child(oms::ssp::Version1_0::ssc::integer_type);
Expand Down
1 change: 1 addition & 0 deletions src/OMSimulatorLib/Connector.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ namespace oms
void setGeometry(const oms::ssd::ConnectorGeometry* newGeometry);

std::map<std::string, std::map<std::string, std::string>> connectorUnits; ///< single entry map which contains unit as key and BaseUnits as value for a connector
std::map<std::string, std::string> enumerationName; ///< single entry map which contains connector name as key and enumerationName as value for a connector of type ssc:Enumeration

const oms_causality_enu_t getCausality() const {return causality;}
const oms_signal_type_enu_t getType() const {return type;}
Expand Down
34 changes: 33 additions & 1 deletion src/OMSimulatorLib/Model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -830,7 +830,7 @@ oms_status_enu_t oms::Model::exportToSSD(Snapshot& snapshot) const
if (oms_status_ok != system->exportToSSD(system_node, snapshot, this->variantName))
return logError("export of system failed");
}

exportEnumerationDefinitionsToSSD(ssdNode);
exportUnitDefinitionsToSSD(ssdNode);

pugi::xml_node default_experiment = ssdNode.append_child(oms::ssp::Draft20180219::ssd::default_experiment);
Expand Down Expand Up @@ -890,6 +890,10 @@ oms_status_enu_t oms::Model::importFromSnapshot(const Snapshot& snapshot)
{
// allow importing unitDefinitions, the unitDefinitions are handled in Values.cpp importFromSnapshot
}
else if (name == oms::ssp::Draft20180219::ssd::enumerations)
{
// allow importing enumerations, the enumerationDefinitions are handled in Values.cpp importFromSnapshot
}
else if (name == oms::ssp::Draft20180219::ssd::default_experiment)
{
startTime = it->attribute("startTime").as_double(0.0);
Expand Down Expand Up @@ -1520,6 +1524,34 @@ void oms::Model::exportUnitDefinitionsToSSD(pugi::xml_node& node) const
}
}

void oms::Model::exportEnumerationDefinitionsToSSD(pugi::xml_node& node) const
{
if (!system)
return;

std::map<std::string, std::map<std::string, std::string>> enumerationDefinitions;
for (const auto& component : system->getComponents())
component.second->getFilteredEnumerationDefinitionsToSSD(enumerationDefinitions);

if (enumerationDefinitions.empty())
return;

pugi::xml_node node_enumeration = node.append_child(oms::ssp::Draft20180219::ssd::enumerations);

for (const auto &it : enumerationDefinitions)
{
pugi::xml_node ssc_enumeration = node_enumeration.append_child(oms::ssp::Version1_0::ssc::enumeration_type);
ssc_enumeration.append_attribute("name") = it.first.c_str();
for (const auto & item: it.second)
{
pugi::xml_node enumItem = ssc_enumeration.append_child(oms::ssp::Version1_0::ssc::enum_item);
enumItem.append_attribute("name") = item.first.c_str();
enumItem.append_attribute("value") = item.second.c_str();
}
}

}

oms_status_enu_t oms::Model::importSignalFilter(const std::string& filename, const Snapshot& snapshot)
{
if (".*" == filename) // avoid error messages for older ssp files
Expand Down
1 change: 1 addition & 0 deletions src/OMSimulatorLib/Model.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ namespace oms
oms_status_enu_t exportSSMTemplate(const ComRef& cref, const std::string& filename);
void exportSignalFilter(Snapshot& snapshot) const;
void exportUnitDefinitionsToSSD(pugi::xml_node& node) const;
void exportEnumerationDefinitionsToSSD(pugi::xml_node& node) const;
oms_status_enu_t importFromSnapshot(const Snapshot& snapshot);
oms_status_enu_t importSnapshot(const char* snapshot, char** newCref);
oms_status_enu_t importSignalFilter(const std::string& filename, const Snapshot& snapshot);
Expand Down
65 changes: 65 additions & 0 deletions src/OMSimulatorLib/Values.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,19 @@ void oms::Values::getFilteredUnitDefinitionsToSSD(std::map<std::string, std::map
}
}

void oms::Values::getFilteredEnumerationDefinitionsToSSD(std::map<std::string, std::map<std::string, std::string>>& enumerationDefinitions)
{
if (modeldescriptionTypeDefinitions.empty())
return;

for(const auto &it: modeldescriptionTypeDefinitions)
{
auto enumType = enumerationDefinitions.find(it.first);
if (enumType == enumerationDefinitions.end())
enumerationDefinitions[it.first] = it.second;
}
}

oms_status_enu_t oms::Values::setInteger(const ComRef& cref, int value)
{
integerStartValues[cref] = value;
Expand Down Expand Up @@ -575,6 +588,16 @@ std::string oms::Values::getUnitFromModeldescription(ComRef& cref) const
return "";
}

std::string oms::Values::getEnumerationTypeFromModeldescription(ComRef& cref) const
{
// search in modelDescription.xml
auto enumType = modeldescriptionEnumeration.find(cref);
if (enumType != modeldescriptionEnumeration.end())
return enumType->second;

return "";
}

oms_status_enu_t oms::Values::getIntegerFromModeldescription(const ComRef& cref, int& value)
{
// search in modelDescription.xml
Expand Down Expand Up @@ -1486,6 +1509,29 @@ void oms::Values::importUnitDefinitions(const pugi::xml_node& node)
}
}

void oms::Values::importEnumerationDefinitions(const pugi::xml_node& node, std::string& enumTypename)
{

if (!node)
return;

pugi::xml_node enumeration = node.child(oms::ssp::Draft20180219::ssd::enumerations);

for (pugi::xml_node enumItems = enumeration.child(oms::ssp::Version1_0::ssc::enumeration_type); enumItems; enumItems = enumItems.next_sibling(oms::ssp::Version1_0::ssc::enumeration_type))
{
// entry found
if (enumItems.attribute("name").as_string() == enumTypename)
{
std::map<std::string, std::string> enumerationItems;
for (pugi::xml_node enumItem = enumItems.child(oms::ssp::Version1_0::ssc::enum_item); enumItem; enumItem = enumItem.next_sibling(oms::ssp::Version1_0::ssc::enum_item))
{
enumerationItems[enumItem.attribute("name").as_string()] = enumItem.attribute("value").as_string();
}
modeldescriptionTypeDefinitions[enumTypename] = enumerationItems;
}
}
}

oms_status_enu_t oms::Values::parseModelDescription(const filesystem::path& root, std::string& guid_)
{

Expand Down Expand Up @@ -1513,6 +1559,21 @@ oms_status_enu_t oms::Values::parseModelDescription(const filesystem::path& root
for(pugi::xml_node_iterator it = node.begin(); it != node.end(); ++it)
{
std::string name = it->name();
if (name == "TypeDefinitions")
{
pugi::xml_node simpleType = it->child("SimpleType");
pugi::xml_node Enumeration = simpleType.child("Enumeration");
if (Enumeration)
{
std::map<std::string, std::string> enumerationItems;
for (pugi::xml_node enumItem = Enumeration.child("Item"); enumItem; enumItem = enumItem.next_sibling("Item"))
{
// std::cout << "\n loop: " << enumItem.attribute("name").as_string() << "==>" << enumItem.attribute("value").as_string();
enumerationItems[enumItem.attribute("name").as_string()] = enumItem.attribute("value").as_string();
}
modeldescriptionTypeDefinitions[simpleType.attribute("name").as_string()] = enumerationItems;
}
}
if (name == "UnitDefinitions")
{
//std::cout << "\nParse Unit Definitions";
Expand Down Expand Up @@ -1563,6 +1624,10 @@ oms_status_enu_t oms::Values::parseModelDescription(const filesystem::path& root
{
modelDescriptionBooleanStartValues[scalarVariable.attribute("name").as_string()] = scalarVariable.child("Boolean").attribute("start").as_bool();
}
if (strlen(scalarVariable.child("Enumeration").attribute("declaredType").as_string()) != 0)
{
modeldescriptionEnumeration[scalarVariable.attribute("name").as_string()] = scalarVariable.child("Enumeration").attribute("declaredType").as_string();
}
}
}
if (name == "ModelStructure")
Expand Down
7 changes: 6 additions & 1 deletion src/OMSimulatorLib/Values.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ namespace oms
oms_status_enu_t setUnit(const ComRef& cref, const std::string& value);
void setUnitDefinitions(const ComRef& cref);
void getFilteredUnitDefinitionsToSSD(std::map<std::string, std::map<std::string, std::string>>& unitDefinitions);
void getFilteredEnumerationDefinitionsToSSD(std::map<std::string, std::map<std::string, std::string>>& enumerationDefinitions);
void updateModelDescriptionRealStartValue(const ComRef& cref, double value);
void updateModelDescriptionIntegerStartValue(const ComRef& cref, int value);
void updateModelDescriptionBooleanStartValue(const ComRef& cref, bool value);
Expand Down Expand Up @@ -86,7 +87,7 @@ namespace oms

std::string getUnit(ComRef& cref) const;
std::string getUnitFromModeldescription(ComRef& cref) const;

std::string getEnumerationTypeFromModeldescription(ComRef& cref) const;
oms_status_enu_t exportToSSD(pugi::xml_node& node) const;
oms_status_enu_t importFromSnapshot(const pugi::xml_node& node, const std::string& sspVersion, const Snapshot& snapshot, std::string variantName);
oms_status_enu_t importFromSnapshot(const Snapshot& snapshot, const std::string& ssvFilePath, const std::string& ssmFilename);
Expand All @@ -102,6 +103,7 @@ namespace oms
oms_status_enu_t exportUnitDefinitions(Snapshot &snapshot, std::string filename, std::string variantName) const;
oms_status_enu_t exportUnitDefinitionsToSSVTemplate(Snapshot &snapshot, std::string filename);
void importUnitDefinitions(const pugi::xml_node& node);
void importEnumerationDefinitions(const pugi::xml_node& node, std::string& enumTypeName);

void exportToSSVTemplate(pugi::xml_node& ssvNode, const ComRef& cref); ///< start values read from modelDescription.xml and creates a ssv template
void exportReduceSSV(pugi::xml_node& ssvNode, const ComRef& cref); ///< reduced SSV file which contains only the referenced crefs in parametermapping
Expand Down Expand Up @@ -167,6 +169,9 @@ namespace oms

std::map<std::string, std::map<std::string, std::string>> modeldescriptionUnitDefinitions; ///< <UnitDefinitions> list read from modeldescription.xml

std::map<std::string, std::map<std::string, std::string>> modeldescriptionTypeDefinitions; ///< <TypeDefinitions> list read from modeldescription.xml
std::map<std::string, std::string> modeldescriptionEnumeration; ///< enumeration declared type list list read from modeldescription.xml

std::multimap<ComRef, ComRef> mappedEntry; ///< parameter names and values provided in the parameter source are to be mapped to the parameters of the component or system

std::vector<Values> parameterResources; ///< list of parameter resources provided inline or .ssv files
Expand Down
5 changes: 4 additions & 1 deletion src/OMSimulatorLib/XercesValidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,12 @@ oms_status_enu_t oms::XercesValidator::validateSSP(const char *ssd, const std::s
return logError("executable path could not be found");

filesystem::path schemaRootPath (path);
filesystem::path schemaSSDPath, schemaSSVPath, schemaSSMPath;
filesystem::path schemaSSDPath, schemaSSVPath, schemaSSMPath, schemaSSCPath;

schemaSSDPath = schemaRootPath / "../share/OMSimulator/schema/ssp/SystemStructureDescription.xsd";
schemaSSVPath = schemaRootPath / "../share/OMSimulator/schema/ssp/SystemStructureParameterValues.xsd";
schemaSSMPath = schemaRootPath / "../share/OMSimulator/schema/ssp/SystemStructureParameterMapping.xsd";
schemaSSCPath = schemaRootPath / "../share/OMSimulator/schema/ssp/SystemStructureCommon.xsd";

// std::cout << "schemaPath: " << schemaFilePath.generic_string() << "\n" << filesystem::absolute(schemaFilePath).generic_string() << "\n";

Expand All @@ -165,6 +166,7 @@ oms_status_enu_t oms::XercesValidator::validateSSP(const char *ssd, const std::s
schemaSSDPath = schemaRootPath / "../../share/OMSimulator/schema/ssp/SystemStructureDescription.xsd";
schemaSSVPath = schemaRootPath / "../../share/OMSimulator/schema/ssp/SystemStructureParameterValues.xsd";
schemaSSMPath = schemaRootPath / "../../share/OMSimulator/schema/ssp/SystemStructureParameterMapping.xsd";
schemaSSCPath = schemaRootPath / "../../share/OMSimulator/schema/ssp/SystemStructureCommon.xsd";
}

XercesDOMParser domParser;
Expand Down Expand Up @@ -195,6 +197,7 @@ oms_status_enu_t oms::XercesValidator::validateSSP(const char *ssd, const std::s
std::string ssdTargetNameSpacePath = "http://ssp-standard.org/SSP1/SystemStructureDescription " + schemaSSDPath.generic_string();
ssdTargetNameSpacePath = ssdTargetNameSpacePath + " http://ssp-standard.org/SSP1/SystemStructureParameterValues " + schemaSSVPath.generic_string();
ssdTargetNameSpacePath = ssdTargetNameSpacePath + " http://ssp-standard.org/SSP1/SystemStructureParameterMapping " + schemaSSMPath.generic_string();
ssdTargetNameSpacePath = ssdTargetNameSpacePath + " http://ssp-standard.org/SSP1/SystemStructureCommon " + schemaSSCPath.generic_string();

domParser.setExternalSchemaLocation(ssdTargetNameSpacePath.c_str());

Expand Down
Loading

0 comments on commit ffd0d88

Please sign in to comment.