Skip to content

Commit 28ca23a

Browse files
authored
import parameter bindings at hierarchical level (#905)
1 parent c286f9e commit 28ca23a

15 files changed

Lines changed: 328 additions & 50 deletions

src/OMSimulatorLib/Model.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -507,9 +507,9 @@ oms_status_enu_t oms::Model::updateParameterBindingsToSSD(pugi::xml_node& node,
507507
// update the ssd with the top level parameterBindings (e.g) <ParameterBinding source="resources/ControlledTemperature.ssv">
508508
for(pugi::xml_node_iterator it = node.begin(); it != node.end(); ++it)
509509
{
510-
if (std::string(it->name()) == oms::ssp::Draft20180219::ssd::connectors) // insert the parameter bindings after top-level connectors node
510+
if (std::string(it->name()) == oms::ssp::Draft20180219::ssd::elements) // insert the parameter bindings after top-level connectors node
511511
{
512-
pugi::xml_node node_parameters_bindings = node.insert_child_after(oms::ssp::Version1_0::ssd::parameter_bindings, *it);
512+
pugi::xml_node node_parameters_bindings = node.insert_child_before(oms::ssp::Version1_0::ssd::parameter_bindings, *it);
513513
pugi::xml_node node_parameter_binding = node_parameters_bindings.append_child(oms::ssp::Version1_0::ssd::parameter_binding);
514514
std::string ssvFileName = "resources/" + std::string(this->getCref()) + ".ssv";
515515
node_parameter_binding.append_attribute("source") = ssvFileName.c_str();
@@ -787,10 +787,10 @@ oms_status_enu_t oms::Model::exportToFile(const std::string& filename) const
787787
// update the ssd with the top level parameterBindings (e.g) <ParameterBinding source="resources/ControlledTemperature.ssv">
788788
for(pugi::xml_node_iterator it = node.begin(); it != node.end(); ++it)
789789
{
790-
pugi::xml_node node_connectors = it->child(oms::ssp::Draft20180219::ssd::connectors);
791-
if (node_connectors) // insert the parameter bindings after top-level connectors node
790+
pugi::xml_node node_elements = it->child(oms::ssp::Draft20180219::ssd::elements);
791+
if (node_elements) // insert the parameter bindings before <ssd:Elements>
792792
{
793-
pugi::xml_node node_parameters_bindings = it->insert_child_after(oms::ssp::Version1_0::ssd::parameter_bindings, node_connectors);
793+
pugi::xml_node node_parameters_bindings = it->insert_child_before(oms::ssp::Version1_0::ssd::parameter_bindings, node_elements);
794794
pugi::xml_node node_parameter_binding = node_parameters_bindings.append_child(oms::ssp::Version1_0::ssd::parameter_binding);
795795
node_parameter_binding.append_attribute("source") = ssvFileName.c_str();
796796
break;

src/OMSimulatorLib/System.cpp

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -514,37 +514,48 @@ oms_status_enu_t oms::System::importFromSSD(const pugi::xml_node& node, const st
514514
}
515515
else if(name == oms::ssp::Version1_0::ssd::parameter_bindings)
516516
{
517-
// check for multiple ssv files or parameter bindings
518-
for (pugi::xml_node parameterBindingNode = it->child(oms::ssp::Version1_0::ssd::parameter_binding); parameterBindingNode; parameterBindingNode = parameterBindingNode.next_sibling(oms::ssp::Version1_0::ssd::parameter_binding))
517+
std::string parent_node = it->parent().parent().name();
518+
// top level parameter bindings belonging to <ssd:SystemStructureDescription> provided either as inline or .ssv files
519+
if (parent_node == oms::ssp::Draft20180219::ssd::system_structure_description)
519520
{
520-
std::string ssvFileSource = parameterBindingNode.attribute("source").as_string();
521-
522-
// set parameter bindings associated with the system
523-
if (ssvFileSource.empty()) // inline parameterBinding
524-
{
525-
std::string tempdir = getModel()->getTempDirectory();
526-
if (oms_status_ok != values.importFromSSD(*it, sspVersion, tempdir))
527-
return logError("Failed to import " + std::string(oms::ssp::Version1_0::ssd::parameter_bindings));
528-
}
529-
else
521+
// check for multiple ssv files or parameter bindings
522+
for (pugi::xml_node parameterBindingNode = it->child(oms::ssp::Version1_0::ssd::parameter_binding); parameterBindingNode; parameterBindingNode = parameterBindingNode.next_sibling(oms::ssp::Version1_0::ssd::parameter_binding))
530523
{
531-
// store the ssv and ssm files and process it later while handling the connection, so all the components are loaded
532-
pugi::xml_node parameterMapping = parameterBindingNode.child(oms::ssp::Version1_0::ssd::parameter_mapping);
524+
std::string ssvFileSource = parameterBindingNode.attribute("source").as_string();
533525

534-
// check for parameterMapping (e.g) <ssd:ParameterMapping>
535-
if (parameterMapping)
526+
// set parameter bindings associated with the system
527+
if (ssvFileSource.empty()) // inline parameterBinding
536528
{
537-
// parameterMapping provided
538-
std::string ssmFileSource = parameterMapping.attribute("source").as_string();
539-
startValuesFileSources[ssvFileSource] = ssmFileSource;
529+
std::string tempdir = getModel()->getTempDirectory();
530+
if (oms_status_ok != values.importFromSSD(*it, sspVersion, tempdir))
531+
return logError("Failed to import " + std::string(oms::ssp::Version1_0::ssd::parameter_bindings));
540532
}
541533
else
542534
{
543-
// no parameterMapping
544-
startValuesFileSources[ssvFileSource] = "";
535+
// store the ssv and ssm files and process it later while handling the connection, so all the components are loaded
536+
pugi::xml_node parameterMapping = parameterBindingNode.child(oms::ssp::Version1_0::ssd::parameter_mapping);
537+
538+
// check for parameterMapping (e.g) <ssd:ParameterMapping>
539+
if (parameterMapping)
540+
{
541+
// parameterMapping provided
542+
std::string ssmFileSource = parameterMapping.attribute("source").as_string();
543+
startValuesFileSources[ssvFileSource] = ssmFileSource;
544+
}
545+
else
546+
{
547+
// no parameterMapping
548+
startValuesFileSources[ssvFileSource] = "";
549+
}
545550
}
546551
}
547552
}
553+
else
554+
// heirarchial level parameter bindings belonging to <ssd:Elements> provided either as inline or .ssv files
555+
{
556+
if (oms_status_ok != values.importFromSSD(*it, sspVersion, getModel()->getTempDirectory()))
557+
return logError("Failed to import " + std::string(oms::ssp::Version1_0::ssd::parameter_bindings));
558+
}
548559
}
549560
else if (name == oms::ssp::Draft20180219::ssd::connections)
550561
{
@@ -2364,7 +2375,7 @@ oms_status_enu_t oms::System::importStartValuesFromSSV()
23642375
// check for parameter mapping file ".ssm file"
23652376
if (!file.second.empty())
23662377
{
2367-
importParamterMappingFromSSM(file.second, mappedEntry);
2378+
importParameterMappingFromSSM(file.second, mappedEntry);
23682379
importStartValuesFromSSVHelper(file.first, mappedEntry);
23692380
}
23702381
else
@@ -2478,7 +2489,7 @@ oms_status_enu_t oms::System::importStartValuesFromSSVHelper(std::string fileNam
24782489
return oms_status_ok;
24792490
}
24802491

2481-
oms_status_enu_t oms::System::importParamterMappingFromSSM(std::string fileName, std::multimap<ComRef, ComRef> &mappedEntry)
2492+
oms_status_enu_t oms::System::importParameterMappingFromSSM(std::string fileName, std::multimap<ComRef, ComRef> &mappedEntry)
24822493
{
24832494
std::string tempdir = getModel()->getTempDirectory();
24842495
filesystem::path temp_root(tempdir);
@@ -2490,6 +2501,10 @@ oms_status_enu_t oms::System::importParamterMappingFromSSM(std::string fileName,
24902501
{
24912502
parameterMapping = ssmdoc.document_element(); // ssm:ParameterMapping
24922503
}
2504+
else
2505+
{
2506+
return logError("loading \"" + std::string(fileName) + "\" failed (" + std::string(result.description()) + ")");
2507+
}
24932508

24942509
if (parameterMapping)
24952510
{

src/OMSimulatorLib/System.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ namespace oms
216216
oms_status_enu_t importBusConnectorGeometry(const pugi::xml_node& node);
217217
oms_status_enu_t importStartValuesFromSSV();
218218
oms_status_enu_t importStartValuesFromSSVHelper(std::string fileName, std::multimap<ComRef, ComRef> &mappedEntry);
219-
oms_status_enu_t importParamterMappingFromSSM(std::string fileName, std::multimap<ComRef, ComRef> &mappedEntry);
219+
oms_status_enu_t importParameterMappingFromSSM(std::string fileName, std::multimap<ComRef, ComRef> &mappedEntry);
220220
};
221221
}
222222

src/OMSimulatorLib/Values.cpp

Lines changed: 55 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -129,29 +129,65 @@ oms_status_enu_t oms::Values::importFromSSD(const pugi::xml_node& node, const st
129129
{
130130
for (pugi::xml_node parameterBindingNode = node.child(oms::ssp::Version1_0::ssd::parameter_binding); parameterBindingNode; parameterBindingNode = parameterBindingNode.next_sibling(oms::ssp::Version1_0::ssd::parameter_binding))
131131
{
132-
/* parameter bindings from ssv files are handled at system level (System.h) importStartValuesFromSSV()
133-
(e.g) parameterBindingNode.attribute("source").as_string(); */
134-
135-
// inline ParameterBindings
136-
if (parameterBindingNode.child(oms::ssp::Version1_0::ssv::parameter_set))
132+
std::string ssvFile = parameterBindingNode.attribute("source").as_string();
133+
// parameter binding provided with .ssv file
134+
if (!ssvFile.empty())
137135
{
138-
logWarning_deprecated;
139-
}
140-
pugi::xml_node parameterValues = parameterBindingNode.child(oms::ssp::Version1_0::ssd::parameter_values);
141-
pugi::xml_node parameterSet = parameterValues.child(oms::ssp::Version1_0::ssv::parameter_set);
142-
std::string paramsetVersion = parameterSet.attribute("version").as_string();
143-
pugi::xml_node parameters = parameterSet.child(oms::ssp::Version1_0::ssv::parameters);
136+
filesystem::path temp_root(tempdir);
137+
pugi::xml_document ssvdoc;
138+
pugi::xml_parse_result result = ssvdoc.load_file((temp_root / ssvFile).string().c_str());
139+
if (!result)
140+
return logError("loading \"" + std::string(ssvFile) + "\" failed (" + std::string(result.description()) + ")");
144141

145-
// check for parameterMapping (e.g) <ssd:ParameterMapping>
146-
pugi::xml_node ssd_parameterMapping = parameterBindingNode.child(oms::ssp::Version1_0::ssd::parameter_mapping);
147-
pugi::xml_node ssm_parameterMapping = ssd_parameterMapping.child(oms::ssp::Version1_0::ssm::parameter_mapping);
142+
pugi::xml_node parameterSet = ssvdoc.document_element(); // ssd:SystemStructureDescription
143+
pugi::xml_node parameters = parameterSet.child(oms::ssp::Version1_0::ssv::parameters);
148144

149-
if (ssm_parameterMapping)
150-
{
151-
importParameterMappingInline(ssm_parameterMapping);
145+
// check for parameterMapping (e.g) <ssd:ParameterMapping>
146+
pugi::xml_node ssd_parameterMapping = parameterBindingNode.child(oms::ssp::Version1_0::ssd::parameter_mapping);
147+
148+
if (ssd_parameterMapping)
149+
{
150+
// parameterMapping provided
151+
std::string ssmFileSource = ssd_parameterMapping.attribute("source").as_string();
152+
pugi::xml_document ssmdoc;
153+
pugi::xml_parse_result ssm_result = ssmdoc.load_file((temp_root / ssmFileSource).string().c_str());
154+
155+
if (ssm_result) // check from ssm file
156+
{
157+
pugi::xml_node ssm_parameterMapping = ssmdoc.document_element(); // ssm:ParameterMapping
158+
importParameterMapping(ssm_parameterMapping);
159+
}
160+
else
161+
{
162+
return logError("loading \"" + std::string(ssmFileSource) + "\" failed (" + std::string(ssm_result.description()) + ")");
163+
}
164+
}
165+
166+
importStartValuesHelper(parameters);
152167
}
168+
else
169+
{
170+
// inline ParameterBindings
171+
if (parameterBindingNode.child(oms::ssp::Version1_0::ssv::parameter_set))
172+
{
173+
logWarning_deprecated;
174+
}
175+
pugi::xml_node parameterValues = parameterBindingNode.child(oms::ssp::Version1_0::ssd::parameter_values);
176+
pugi::xml_node parameterSet = parameterValues.child(oms::ssp::Version1_0::ssv::parameter_set);
177+
std::string paramsetVersion = parameterSet.attribute("version").as_string();
178+
pugi::xml_node parameters = parameterSet.child(oms::ssp::Version1_0::ssv::parameters);
153179

154-
importStartValuesHelper(parameters);
180+
// check for parameterMapping (e.g) <ssd:ParameterMapping>
181+
pugi::xml_node ssd_parameterMapping = parameterBindingNode.child(oms::ssp::Version1_0::ssd::parameter_mapping);
182+
pugi::xml_node ssm_parameterMapping = ssd_parameterMapping.child(oms::ssp::Version1_0::ssm::parameter_mapping);
183+
184+
if (ssm_parameterMapping)
185+
{
186+
importParameterMapping(ssm_parameterMapping);
187+
}
188+
189+
importStartValuesHelper(parameters);
190+
}
155191
}
156192

157193
return oms_status_ok;
@@ -483,7 +519,7 @@ oms_status_enu_t oms::Values::parseModelDescription(const char *filename)
483519
return oms_status_ok;
484520
}
485521

486-
oms_status_enu_t oms::Values::importParameterMappingInline(pugi::xml_node& parameterMapping)
522+
oms_status_enu_t oms::Values::importParameterMapping(pugi::xml_node& parameterMapping)
487523
{
488524
if (parameterMapping)
489525
{

src/OMSimulatorLib/Values.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ namespace oms
5959
oms_status_enu_t exportStartValuesHelper(pugi::xml_node& node) const;
6060
oms_status_enu_t exportParameterMappingInline(pugi::xml_node& node) const;
6161
oms_status_enu_t importStartValuesHelper(pugi::xml_node& parameters);
62-
oms_status_enu_t importParameterMappingInline(pugi::xml_node& parameterMapping);
62+
oms_status_enu_t importParameterMapping(pugi::xml_node& parameterMapping);
6363
oms_status_enu_t parseModelDescription(const char *filename);
6464

6565
oms::ComRef getMappedCrefEntry(ComRef cref) const;

testsuite/OMSimulator/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import_export_parameters_to_ssv.lua \
1515
import_export_snapshot.lua \
1616
import_export.lua \
1717
import_export.py \
18+
import_hierarchical_ssv_sources.lua \
1819
import_parameter_mapping_from_ssm.lua \
1920
import_parameter_mapping_inline.lua \
2021
importStartValues.lua \
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
-- status: correct
2+
-- linux: yes
3+
-- mingw: yes
4+
-- win: no
5+
-- mac: no
6+
7+
oms_setCommandLineOption("--suppressPath=true")
8+
oms_setTempDirectory("./import_hierarchical_ssv_sources_lua/")
9+
10+
oms_importFile("../resources/import_hierarchical_ssv_sources.ssp");
11+
12+
oms_instantiate("import_hierarchical_ssv_sources")
13+
14+
print("info: Instantiation")
15+
print("info: import_hierarchical_ssv_sources.root.System1.Input_1 : " .. oms_getReal("import_hierarchical_ssv_sources.root.System1.Input_1"))
16+
print("info: import_hierarchical_ssv_sources.root.System1.parameter_1 : " .. oms_getReal("import_hierarchical_ssv_sources.root.System1.parameter_1"))
17+
print("info: import_hierarchical_ssv_sources.root.System2.Input_1 : " .. oms_getReal("import_hierarchical_ssv_sources.root.System2.Input_1"))
18+
print("info: import_hierarchical_ssv_sources.root.System2.Input_2 : " .. oms_getReal("import_hierarchical_ssv_sources.root.System2.Input_2"))
19+
print("info: import_hierarchical_ssv_sources.root.System2.parameter_1 : " .. oms_getReal("import_hierarchical_ssv_sources.root.System2.parameter_1"))
20+
print("info: import_hierarchical_ssv_sources.root.System3.Input_1 : " .. oms_getReal("import_hierarchical_ssv_sources.root.System3.Input_1"))
21+
print("info: import_hierarchical_ssv_sources.root.System3.parameter_1 : " .. oms_getReal("import_hierarchical_ssv_sources.root.System3.parameter_1"))
22+
23+
oms_initialize("import_hierarchical_ssv_sources")
24+
print("info: Initialization")
25+
print("info: import_hierarchical_ssv_sources.root.System1.Input_1 : " .. oms_getReal("import_hierarchical_ssv_sources.root.System1.Input_1"))
26+
print("info: import_hierarchical_ssv_sources.root.System1.parameter_1 : " .. oms_getReal("import_hierarchical_ssv_sources.root.System1.parameter_1"))
27+
print("info: import_hierarchical_ssv_sources.root.System2.Input_1 : " .. oms_getReal("import_hierarchical_ssv_sources.root.System2.Input_1"))
28+
print("info: import_hierarchical_ssv_sources.root.System2.Input_2 : " .. oms_getReal("import_hierarchical_ssv_sources.root.System2.Input_2"))
29+
print("info: import_hierarchical_ssv_sources.root.System2.parameter_1 : " .. oms_getReal("import_hierarchical_ssv_sources.root.System2.parameter_1"))
30+
print("info: import_hierarchical_ssv_sources.root.System3.Input_1 : " .. oms_getReal("import_hierarchical_ssv_sources.root.System3.Input_1"))
31+
print("info: import_hierarchical_ssv_sources.root.System3.parameter_1 : " .. oms_getReal("import_hierarchical_ssv_sources.root.System3.parameter_1"))
32+
33+
oms_simulate("import_hierarchical_ssv_sources")
34+
print("info: Simulate")
35+
print("info: import_hierarchical_ssv_sources.root.System1.Input_1 : " .. oms_getReal("import_hierarchical_ssv_sources.root.System1.Input_1"))
36+
print("info: import_hierarchical_ssv_sources.root.System1.parameter_1 : " .. oms_getReal("import_hierarchical_ssv_sources.root.System1.parameter_1"))
37+
print("info: import_hierarchical_ssv_sources.root.System2.Input_1 : " .. oms_getReal("import_hierarchical_ssv_sources.root.System2.Input_1"))
38+
print("info: import_hierarchical_ssv_sources.root.System2.Input_2 : " .. oms_getReal("import_hierarchical_ssv_sources.root.System2.Input_2"))
39+
print("info: import_hierarchical_ssv_sources.root.System2.parameter_1 : " .. oms_getReal("import_hierarchical_ssv_sources.root.System2.parameter_1"))
40+
print("info: import_hierarchical_ssv_sources.root.System3.Input_1 : " .. oms_getReal("import_hierarchical_ssv_sources.root.System3.Input_1"))
41+
print("info: import_hierarchical_ssv_sources.root.System3.parameter_1 : " .. oms_getReal("import_hierarchical_ssv_sources.root.System3.parameter_1"))
42+
43+
oms_terminate("import_hierarchical_ssv_sources")
44+
oms_delete("import_hierarchical_ssv_sources")
45+
46+
47+
-- Result:
48+
-- info: model doesn't contain any continuous state
49+
-- info: model doesn't contain any continuous state
50+
-- info: model doesn't contain any continuous state
51+
-- info: Instantiation
52+
-- info: import_hierarchical_ssv_sources.root.System1.Input_1 : -10.0
53+
-- info: import_hierarchical_ssv_sources.root.System1.parameter_1 : -20.0
54+
-- info: import_hierarchical_ssv_sources.root.System2.Input_1 : -30.0
55+
-- info: import_hierarchical_ssv_sources.root.System2.Input_2 : -100.0
56+
-- info: import_hierarchical_ssv_sources.root.System2.parameter_1 : -40.0
57+
-- info: import_hierarchical_ssv_sources.root.System3.Input_1 : -70.0
58+
-- info: import_hierarchical_ssv_sources.root.System3.parameter_1 : -70.0
59+
-- info: Result file: import_hierarchical_ssv_sources_res.mat (bufferSize=10)
60+
-- info: Initialization
61+
-- info: import_hierarchical_ssv_sources.root.System1.Input_1 : -10.0
62+
-- info: import_hierarchical_ssv_sources.root.System1.parameter_1 : -20.0
63+
-- info: import_hierarchical_ssv_sources.root.System2.Input_1 : -30.0
64+
-- info: import_hierarchical_ssv_sources.root.System2.Input_2 : -100.0
65+
-- info: import_hierarchical_ssv_sources.root.System2.parameter_1 : -40.0
66+
-- info: import_hierarchical_ssv_sources.root.System3.Input_1 : -70.0
67+
-- info: import_hierarchical_ssv_sources.root.System3.parameter_1 : -70.0
68+
-- info: Simulate
69+
-- info: import_hierarchical_ssv_sources.root.System1.Input_1 : -10.0
70+
-- info: import_hierarchical_ssv_sources.root.System1.parameter_1 : -20.0
71+
-- info: import_hierarchical_ssv_sources.root.System2.Input_1 : -30.0
72+
-- info: import_hierarchical_ssv_sources.root.System2.Input_2 : -100.0
73+
-- info: import_hierarchical_ssv_sources.root.System2.parameter_1 : -40.0
74+
-- info: import_hierarchical_ssv_sources.root.System3.Input_1 : -70.0
75+
-- info: import_hierarchical_ssv_sources.root.System3.parameter_1 : -70.0
76+
-- endResult

testsuite/OMSimulator/import_parameter_mapping_from_ssm.lua

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ print("info: import_parameter_mapping.co_sim.System2.Input_2 : " .. om
6666
print("info: import_parameter_mapping.co_sim.System2.parameter_1 : " .. oms_getReal("import_parameter_mapping.co_sim.System2.parameter_1"))
6767
print("info: import_parameter_mapping.co_sim.System2.parameter_2 : " .. oms_getReal("import_parameter_mapping.co_sim.System2.parameter_2"))
6868

69+
oms_terminate("import_parameter_mapping")
70+
oms_delete("import_parameter_mapping")
71+
6972
-- Result:
7073
-- info: model doesn't contain any continuous state
7174
-- info: model doesn't contain any continuous state

0 commit comments

Comments
 (0)