Skip to content

Commit ffd0d88

Browse files
authored
export enumeration definition to ssp (#1266)
* export enumeration definition to ssp * allow importing enumeration * import enumerations defintions from ssd
1 parent c920c75 commit ffd0d88

17 files changed

Lines changed: 348 additions & 8 deletions

src/OMSimulatorLib/Component.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ namespace oms
6565
virtual oms_status_enu_t exportToSSD(pugi::xml_node& node, Snapshot& snapshot, std::string variantName) const = 0;
6666
virtual oms_status_enu_t exportToSSV(pugi::xml_node& ssvNode) { return logError_NotImplemented; }
6767
virtual void getFilteredUnitDefinitionsToSSD(std::map<std::string, std::map<std::string, std::string>>& unitDefinitions) { return ; }
68+
virtual void getFilteredEnumerationDefinitionsToSSD(std::map<std::string, std::map<std::string, std::string>>& enumerationDefinitions) { return ; }
6869

6970
virtual oms_status_enu_t initialize() = 0;
7071
virtual oms_status_enu_t instantiate() = 0;

src/OMSimulatorLib/ComponentFMUCS.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,11 @@ oms::Component* oms::ComponentFMUCS::NewComponent(const oms::ComRef& cref, oms::
259259
std::string unitName = component->values.getUnitFromModeldescription(connectorCref);
260260
if (!unitName.empty())
261261
connector->connectorUnits[unitName] = component->values.modeldescriptionUnitDefinitions[unitName];
262+
263+
// get enumerationTypes
264+
std::string enumType = component->values.getEnumerationTypeFromModeldescription(connectorCref);
265+
if (!enumType.empty())
266+
connector->enumerationName[connectorCref] = enumType;
262267
}
263268
}
264269

@@ -304,6 +309,16 @@ oms::Component* oms::ComponentFMUCS::NewComponent(const pugi::xml_node& node, om
304309
if (!unitName.empty())
305310
component->connectors.back()->connectorUnits[unitName] = component->values.modeldescriptionUnitDefinitions[unitName];
306311
}
312+
// set enumeration definitions
313+
if ((*itConnectors).child(oms::ssp::Version1_0::ssc::enumeration_type))
314+
{
315+
std::string enumTypeName = (*itConnectors).child(oms::ssp::Version1_0::ssc::enumeration_type).attribute("name").as_string();
316+
if (!enumTypeName.empty())
317+
component->connectors.back()->enumerationName[component->connectors.back()->getName().c_str()] = enumTypeName;
318+
319+
// give priority to enum definitions in ssd over modeldescription.xml, it is possible the user might have manually change values in ssd file
320+
component->values.importEnumerationDefinitions(ssdNode, enumTypeName);
321+
}
307322
}
308323
}
309324
else if(name == oms::ssp::Draft20180219::ssd::element_geometry)
@@ -389,6 +404,11 @@ void oms::ComponentFMUCS::getFilteredUnitDefinitionsToSSD(std::map<std::string,
389404
return values.getFilteredUnitDefinitionsToSSD(unitDefinitions);
390405
}
391406

407+
void oms::ComponentFMUCS::getFilteredEnumerationDefinitionsToSSD(std::map<std::string, std::map<std::string, std::string>>& enumerationDefinitions)
408+
{
409+
return values.getFilteredEnumerationDefinitionsToSSD(enumerationDefinitions);
410+
}
411+
392412
oms_status_enu_t oms::ComponentFMUCS::exportToSSV(pugi::xml_node& ssvNode)
393413
{
394414
return values.exportToSSV(ssvNode);

src/OMSimulatorLib/ComponentFMUCS.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ namespace oms
6363
oms_status_enu_t exportToSSD(pugi::xml_node& node, Snapshot& snapshot, std::string variantName) const;
6464
oms_status_enu_t exportToSSV(pugi::xml_node& ssvNode);
6565
void getFilteredUnitDefinitionsToSSD(std::map<std::string, std::map<std::string, std::string>>& unitDefinitions);
66+
void getFilteredEnumerationDefinitionsToSSD(std::map<std::string, std::map<std::string, std::string>>& enumerationDefinitions);
6667
oms_status_enu_t exportToSSVTemplate(pugi::xml_node& ssvNode, Snapshot& snapshot);
6768
oms_status_enu_t exportToSSMTemplate(pugi::xml_node& ssmNode);
6869
oms_status_enu_t instantiate();

src/OMSimulatorLib/ComponentFMUME.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,11 @@ oms::Component* oms::ComponentFMUME::NewComponent(const oms::ComRef& cref, oms::
257257
std::string unitName = component->values.getUnitFromModeldescription(connectorCref);
258258
if (!unitName.empty())
259259
connector->connectorUnits[unitName] = component->values.modeldescriptionUnitDefinitions[unitName];
260+
261+
// get enumerationTypes
262+
std::string enumType = component->values.getEnumerationTypeFromModeldescription(connectorCref);
263+
if (!enumType.empty())
264+
connector->enumerationName[connectorCref] = enumType;
260265
}
261266
}
262267

@@ -302,6 +307,16 @@ oms::Component* oms::ComponentFMUME::NewComponent(const pugi::xml_node& node, om
302307
if (!unitName.empty())
303308
component->connectors.back()->connectorUnits[unitName] = component->values.modeldescriptionUnitDefinitions[unitName];
304309
}
310+
// set enumeration definitions
311+
if ((*itConnectors).child(oms::ssp::Version1_0::ssc::enumeration_type))
312+
{
313+
std::string enumTypeName = (*itConnectors).child(oms::ssp::Version1_0::ssc::enumeration_type).attribute("name").as_string();
314+
if (!enumTypeName.empty())
315+
component->connectors.back()->enumerationName[component->connectors.back()->getName().c_str()] = enumTypeName;
316+
317+
// give priority to enum definitions in ssd over modeldescription.xml
318+
component->values.importEnumerationDefinitions(ssdNode, enumTypeName);
319+
}
305320
}
306321
}
307322
else if(name == oms::ssp::Draft20180219::ssd::element_geometry)
@@ -387,6 +402,11 @@ void oms::ComponentFMUME::getFilteredUnitDefinitionsToSSD(std::map<std::string,
387402
return values.getFilteredUnitDefinitionsToSSD(unitDefinitions);
388403
}
389404

405+
void oms::ComponentFMUME::getFilteredEnumerationDefinitionsToSSD(std::map<std::string, std::map<std::string, std::string>>& enumerationDefinitions)
406+
{
407+
return values.getFilteredEnumerationDefinitionsToSSD(enumerationDefinitions);
408+
}
409+
390410
oms_status_enu_t oms::ComponentFMUME::exportToSSV(pugi::xml_node& ssvNode)
391411
{
392412
return values.exportToSSV(ssvNode);

src/OMSimulatorLib/ComponentFMUME.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ namespace oms
6161
oms_status_enu_t exportToSSD(pugi::xml_node& node, Snapshot& snapshot, std::string variantName) const;
6262
oms_status_enu_t exportToSSV(pugi::xml_node& ssvNode);
6363
void getFilteredUnitDefinitionsToSSD(std::map<std::string, std::map<std::string, std::string>>& unitDefinitions);
64+
void getFilteredEnumerationDefinitionsToSSD(std::map<std::string, std::map<std::string, std::string>>& enumerationDefinitions);
6465
oms_status_enu_t exportToSSVTemplate(pugi::xml_node& ssvNode, Snapshot& snapshot);
6566
oms_status_enu_t exportToSSMTemplate(pugi::xml_node& ssmNode);
6667
oms_status_enu_t instantiate();

src/OMSimulatorLib/Connector.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,8 @@ oms_status_enu_t oms::Connector::exportToSSD(pugi::xml_node &root) const
234234
break;
235235
case oms_signal_type_enum:
236236
node.append_child(oms::ssp::Version1_0::ssc::enumeration_type);
237+
for (const auto & it : this->enumerationName)
238+
node.child(oms::ssp::Version1_0::ssc::enumeration_type).append_attribute("name") = it.second.c_str();
237239
break;
238240
case oms_signal_type_integer:
239241
node.append_child(oms::ssp::Version1_0::ssc::integer_type);

src/OMSimulatorLib/Connector.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ namespace oms
7272
void setGeometry(const oms::ssd::ConnectorGeometry* newGeometry);
7373

7474
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
75+
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
7576

7677
const oms_causality_enu_t getCausality() const {return causality;}
7778
const oms_signal_type_enu_t getType() const {return type;}

src/OMSimulatorLib/Model.cpp

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -830,7 +830,7 @@ oms_status_enu_t oms::Model::exportToSSD(Snapshot& snapshot) const
830830
if (oms_status_ok != system->exportToSSD(system_node, snapshot, this->variantName))
831831
return logError("export of system failed");
832832
}
833-
833+
exportEnumerationDefinitionsToSSD(ssdNode);
834834
exportUnitDefinitionsToSSD(ssdNode);
835835

836836
pugi::xml_node default_experiment = ssdNode.append_child(oms::ssp::Draft20180219::ssd::default_experiment);
@@ -890,6 +890,10 @@ oms_status_enu_t oms::Model::importFromSnapshot(const Snapshot& snapshot)
890890
{
891891
// allow importing unitDefinitions, the unitDefinitions are handled in Values.cpp importFromSnapshot
892892
}
893+
else if (name == oms::ssp::Draft20180219::ssd::enumerations)
894+
{
895+
// allow importing enumerations, the enumerationDefinitions are handled in Values.cpp importFromSnapshot
896+
}
893897
else if (name == oms::ssp::Draft20180219::ssd::default_experiment)
894898
{
895899
startTime = it->attribute("startTime").as_double(0.0);
@@ -1520,6 +1524,34 @@ void oms::Model::exportUnitDefinitionsToSSD(pugi::xml_node& node) const
15201524
}
15211525
}
15221526

1527+
void oms::Model::exportEnumerationDefinitionsToSSD(pugi::xml_node& node) const
1528+
{
1529+
if (!system)
1530+
return;
1531+
1532+
std::map<std::string, std::map<std::string, std::string>> enumerationDefinitions;
1533+
for (const auto& component : system->getComponents())
1534+
component.second->getFilteredEnumerationDefinitionsToSSD(enumerationDefinitions);
1535+
1536+
if (enumerationDefinitions.empty())
1537+
return;
1538+
1539+
pugi::xml_node node_enumeration = node.append_child(oms::ssp::Draft20180219::ssd::enumerations);
1540+
1541+
for (const auto &it : enumerationDefinitions)
1542+
{
1543+
pugi::xml_node ssc_enumeration = node_enumeration.append_child(oms::ssp::Version1_0::ssc::enumeration_type);
1544+
ssc_enumeration.append_attribute("name") = it.first.c_str();
1545+
for (const auto & item: it.second)
1546+
{
1547+
pugi::xml_node enumItem = ssc_enumeration.append_child(oms::ssp::Version1_0::ssc::enum_item);
1548+
enumItem.append_attribute("name") = item.first.c_str();
1549+
enumItem.append_attribute("value") = item.second.c_str();
1550+
}
1551+
}
1552+
1553+
}
1554+
15231555
oms_status_enu_t oms::Model::importSignalFilter(const std::string& filename, const Snapshot& snapshot)
15241556
{
15251557
if (".*" == filename) // avoid error messages for older ssp files

src/OMSimulatorLib/Model.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ namespace oms
8585
oms_status_enu_t exportSSMTemplate(const ComRef& cref, const std::string& filename);
8686
void exportSignalFilter(Snapshot& snapshot) const;
8787
void exportUnitDefinitionsToSSD(pugi::xml_node& node) const;
88+
void exportEnumerationDefinitionsToSSD(pugi::xml_node& node) const;
8889
oms_status_enu_t importFromSnapshot(const Snapshot& snapshot);
8990
oms_status_enu_t importSnapshot(const char* snapshot, char** newCref);
9091
oms_status_enu_t importSignalFilter(const std::string& filename, const Snapshot& snapshot);

src/OMSimulatorLib/Values.cpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,19 @@ void oms::Values::getFilteredUnitDefinitionsToSSD(std::map<std::string, std::map
9696
}
9797
}
9898

99+
void oms::Values::getFilteredEnumerationDefinitionsToSSD(std::map<std::string, std::map<std::string, std::string>>& enumerationDefinitions)
100+
{
101+
if (modeldescriptionTypeDefinitions.empty())
102+
return;
103+
104+
for(const auto &it: modeldescriptionTypeDefinitions)
105+
{
106+
auto enumType = enumerationDefinitions.find(it.first);
107+
if (enumType == enumerationDefinitions.end())
108+
enumerationDefinitions[it.first] = it.second;
109+
}
110+
}
111+
99112
oms_status_enu_t oms::Values::setInteger(const ComRef& cref, int value)
100113
{
101114
integerStartValues[cref] = value;
@@ -575,6 +588,16 @@ std::string oms::Values::getUnitFromModeldescription(ComRef& cref) const
575588
return "";
576589
}
577590

591+
std::string oms::Values::getEnumerationTypeFromModeldescription(ComRef& cref) const
592+
{
593+
// search in modelDescription.xml
594+
auto enumType = modeldescriptionEnumeration.find(cref);
595+
if (enumType != modeldescriptionEnumeration.end())
596+
return enumType->second;
597+
598+
return "";
599+
}
600+
578601
oms_status_enu_t oms::Values::getIntegerFromModeldescription(const ComRef& cref, int& value)
579602
{
580603
// search in modelDescription.xml
@@ -1486,6 +1509,29 @@ void oms::Values::importUnitDefinitions(const pugi::xml_node& node)
14861509
}
14871510
}
14881511

1512+
void oms::Values::importEnumerationDefinitions(const pugi::xml_node& node, std::string& enumTypename)
1513+
{
1514+
1515+
if (!node)
1516+
return;
1517+
1518+
pugi::xml_node enumeration = node.child(oms::ssp::Draft20180219::ssd::enumerations);
1519+
1520+
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))
1521+
{
1522+
// entry found
1523+
if (enumItems.attribute("name").as_string() == enumTypename)
1524+
{
1525+
std::map<std::string, std::string> enumerationItems;
1526+
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))
1527+
{
1528+
enumerationItems[enumItem.attribute("name").as_string()] = enumItem.attribute("value").as_string();
1529+
}
1530+
modeldescriptionTypeDefinitions[enumTypename] = enumerationItems;
1531+
}
1532+
}
1533+
}
1534+
14891535
oms_status_enu_t oms::Values::parseModelDescription(const filesystem::path& root, std::string& guid_)
14901536
{
14911537

@@ -1513,6 +1559,21 @@ oms_status_enu_t oms::Values::parseModelDescription(const filesystem::path& root
15131559
for(pugi::xml_node_iterator it = node.begin(); it != node.end(); ++it)
15141560
{
15151561
std::string name = it->name();
1562+
if (name == "TypeDefinitions")
1563+
{
1564+
pugi::xml_node simpleType = it->child("SimpleType");
1565+
pugi::xml_node Enumeration = simpleType.child("Enumeration");
1566+
if (Enumeration)
1567+
{
1568+
std::map<std::string, std::string> enumerationItems;
1569+
for (pugi::xml_node enumItem = Enumeration.child("Item"); enumItem; enumItem = enumItem.next_sibling("Item"))
1570+
{
1571+
// std::cout << "\n loop: " << enumItem.attribute("name").as_string() << "==>" << enumItem.attribute("value").as_string();
1572+
enumerationItems[enumItem.attribute("name").as_string()] = enumItem.attribute("value").as_string();
1573+
}
1574+
modeldescriptionTypeDefinitions[simpleType.attribute("name").as_string()] = enumerationItems;
1575+
}
1576+
}
15161577
if (name == "UnitDefinitions")
15171578
{
15181579
//std::cout << "\nParse Unit Definitions";
@@ -1563,6 +1624,10 @@ oms_status_enu_t oms::Values::parseModelDescription(const filesystem::path& root
15631624
{
15641625
modelDescriptionBooleanStartValues[scalarVariable.attribute("name").as_string()] = scalarVariable.child("Boolean").attribute("start").as_bool();
15651626
}
1627+
if (strlen(scalarVariable.child("Enumeration").attribute("declaredType").as_string()) != 0)
1628+
{
1629+
modeldescriptionEnumeration[scalarVariable.attribute("name").as_string()] = scalarVariable.child("Enumeration").attribute("declaredType").as_string();
1630+
}
15661631
}
15671632
}
15681633
if (name == "ModelStructure")

0 commit comments

Comments
 (0)