-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Layered Standard to represent maps and curves #1
Comments
We at AVL currently use a vendor annotation to represent nd-lookup tables. <VendorAnnotations>
<Tool name="AVL_SDT">
<AVLAnnotations>
<RegularMaps>
<RegularMap name="map2d">
<Domains>
<Domain name="x" input="in_2d_x" />
<Domain name="y" input="in_2d_y" />
</Domains>
<Codomains>
<Codomain name="v" />
</Codomains>
</RegularMap>
<RegularMap name="lookup1d">
<Domains>
<Domain name="d" input="in_1d" />
</Domains>
<Codomains>
<Codomain name="cd" />
</Codomains>
</RegularMap>
</RegularMaps>
</AVLAnnotations>
</Tool>
</VendorAnnotations>
<ModelVariables>
<!-- 01 --><ScalarVariable name="x[1]" valueReference="0" causality="parameter" variability="tunable"> <Real start="2.0"/> </ScalarVariable>
<!-- 02 --><ScalarVariable name="x[2]" valueReference="1" causality="parameter" variability="tunable"> <Real start="3.0"/> </ScalarVariable>
<!-- 03 --><ScalarVariable name="y[1]" valueReference="2" causality="parameter" variability="tunable"> <Real start="10.0"/> </ScalarVariable>
<!-- 04 --><ScalarVariable name="y[2]" valueReference="3" causality="parameter" variability="tunable"> <Real start="25.0"/> </ScalarVariable>
<!-- 05 --><ScalarVariable name="y[3]" valueReference="4" causality="parameter" variability="tunable"> <Real start="30.0"/> </ScalarVariable>
<!-- 06 --><ScalarVariable name="v[1,1]" valueReference="5" causality="parameter" variability="tunable"> <Real start="11" /> </ScalarVariable>
<!-- 07 --><ScalarVariable name="v[1,2]" valueReference="6" causality="parameter" variability="tunable"> <Real start="12" /> </ScalarVariable>
<!-- 08 --><ScalarVariable name="v[1,3]" valueReference="7" causality="parameter" variability="tunable"> <Real start="13" /> </ScalarVariable>
<!-- 09 --><ScalarVariable name="v[2,1]" valueReference="8" causality="parameter" variability="tunable"> <Real start="21"/> </ScalarVariable>
<!-- 10 --><ScalarVariable name="v[2,2]" valueReference="9" causality="parameter" variability="tunable"> <Real start="22"/> </ScalarVariable>
<!-- 11 --><ScalarVariable name="v[2,3]" valueReference="10" causality="parameter" variability="tunable"> <Real start="23"/> </ScalarVariable>
<!-- 12 --><ScalarVariable name="d[1]" valueReference="11" causality="parameter" variability="tunable" > <Real start="10.0"/> </ScalarVariable>
<!-- 13 --><ScalarVariable name="d[2]" valueReference="12" causality="parameter" variability="tunable" > <Real start="20.0"/> </ScalarVariable>
<!-- 14 --><ScalarVariable name="d[3]" valueReference="13" causality="parameter" variability="tunable" > <Real start="25.0"/> </ScalarVariable>
<!-- 15 --><ScalarVariable name="d[4]" valueReference="14" causality="parameter" variability="tunable" > <Real start="30.0"/> </ScalarVariable>
<!-- 16 --><ScalarVariable name="cd[1]" valueReference="15" causality="parameter" variability="tunable" > <Real start="10.0"/> </ScalarVariable>
<!-- 17 --><ScalarVariable name="cd[2]" valueReference="16" causality="parameter" variability="tunable" > <Real start="20.0"/> </ScalarVariable>
<!-- 18 --><ScalarVariable name="cd[3]" valueReference="17" causality="parameter" variability="tunable" > <Real start="30.0"/> </ScalarVariable>
<!-- 19 --><ScalarVariable name="cd[4]" valueReference="18" causality="parameter" variability="tunable" > <Real start="40.0"/> </ScalarVariable>
<!-- 20 --><ScalarVariable name="in_2d_x" valueReference="19" causality="input" variability="discrete" > <Real start="2.0"/> </ScalarVariable>
<!-- 21 --><ScalarVariable name="in_2d_y" valueReference="20" causality="input" variability="discrete" > <Real start="10.0"/> </ScalarVariable>
<!-- 22 --><ScalarVariable name="out_2d" valueReference="21" causality="output" variability="discrete" > <Real/> </ScalarVariable>
<!-- 23 --><ScalarVariable name="in_1d" valueReference="22" causality="input" variability="discrete" > <Real start="10.0"/> </ScalarVariable>
<!-- 24 --><ScalarVariable name="out_1d" valueReference="23" causality="output" variability="discrete" > <Real/> </ScalarVariable>
</ModelVariables> Here two 1d-arrays and one 2d-array (the building blocks) are grouped into one 2d-lookup table called "map2d". |
Possible names for the XML elements/attributes:
|
We should aim at being compatible with ASAM Standards such as https://www.asam.net/standards/detail/cdf/ . |
There are a number of standards that deal with multi-dimensional arrays and unfortunately, they often disagree on how to represent these objects. One more is ASAP2 (a2l), or PAR, DCM, ... we should discuss the "compatibility", but not be discouraged, if we cannot find a good solution. We just might have to pick one of the ways and then live with that decision. |
I created the repository https://github.com/modelica/fmi-ls-struct in which the development will take place. |
This is what the definitions in https://github.com/klausschuch/Reference-FMUs/blob/lookup_tables/LookupMaps/FMI3.xml would look like in a separate file: <?xml version="1.0" encoding="UTF-8"?>
<fmiRegularMaps version="1.0">
<RegularMap name="map2d">
<Domain name="x" input="map_x"/>
<Domain name="y" input="map_y"/>
<Codomain name="v"/>
</RegularMap>
<RegularMap name="lookup1d">
<Domain name="d" input="curve_x"/>
<Codomain name="cd"/>
</RegularMap>
</fmiRegularMaps> |
We should also consider maps in the style of [edit]: Further information that might be important:
|
FMI Design meeting: Christian: What does "regular" mean? |
An FMU that contains such a CombiTable1Ds object could still expose several parameter I think, we could either
or b) allow shared axes (preferred, this can be aligned with a2l) <RegularMap name="map2d_v1">
<Domain name="x" input="map_x"/>
<Domain name="y" input="map_y"/>
<Codomain name="v1"/>
</RegularMap>
<RegularMap name="map2d_v2">
<Domain name="x" input="map_x"/>
<Domain name="y" input="map_y"/>
<Codomain name="v2"/>
</RegularMap>
If an FMU-exporter wants to let the user decide how the data is used (i.e., which interpolation method), the FMU should expose parameters for this. <RegularMap name="map2d">
<Domain name="x" input="map_x"/>
<Domain name="y" input="map_y"/>
<Codomain name="v"/>
<RelatedParameter name="MyInterpolMechanism">
<RelatedParameter name="Interpol.poly.order"/>
</RegularMap>
...
<TypeDefinitions>
<EnumerationType name="AvailableMechanisms">
<Item name="const" value="0">
<Item name="linear" value="1">
</EnumerationType>
</TypeDefinition>
...
<Int32 name="Interpol.poly.order" causality="parameter" variability="tunable" start="1" />
<Enumeration name="MyInterpolMechanism" declaredType="AvailableMechanisms" causality="parameter" variability="tunable" start="0"/>
Wouldn't such constraints just be defined at the linked parameter |
Web-Meeting 7th March 2023: @TorstenBlochwitz brought up the idea to have a more general xml element <Record kind="LookupTable" name="my2dmap">
<Variable kind="Domain" name="x" input="map_x" />
<Variable kind="Domain" name="y" input="map_y" />
<Variable kind="Codomain" name="v" input="map_y" />
<Variable kind="Other" name="MyInterpolMechanism" />
</Record> A tool that doesn't care about regular maps could still show the parts of a A grouping of <Record name="mystruct" >
<Variable name="a" />
<Variable name="b" />
<Variable name="c" />
</Record>
<Record name="mystruct_nested" >
<Variable name="x" />
<Variable name="y" />
<Record name="mystruct" />
</Record> Discussion about further parameters of a lookup table like inter-/extrapolation types. @andreas-junghanns pointed out that more could be done with this info. For example the user might want to give values on a different grid than the FMU exports. @t-sommer mentioned that we should cover the modelica specific CombiTable1Ds (see https://www.maplesoft.com/documentation_center/online_manuals/modelica/Modelica_Blocks_Tables.html#Modelica.Blocks.Tables.CombiTable1Ds) @klausschuch: The FMU export could hide the internals and still export a variable for the first time column and a Variable for each other column and then just combine this in a RegularMap. <RegularMap name="myCombiTable1Ds">
<Domain name="v" input="time" index="0"/>
<Codomain name="v" index="1"/>
<Codomain name="v" index="2"/>
<Codomain name="v" index="3"/>
<Codomain name="v" index="4"/>
</RegularMap> |
@TorstenBlochwitz What would be the main benefit of such a generic grouping of variables as records in comparison to the already available (and still available) structural naming convention using dots? |
@klausschuch : The structural naming convention requires parsing of the names, which is not really a nice concept. More imporatnt: A generic record approach allows to add additional semantics to groups of variables, which in case of utilizing the naming convention must be given to each of the variable belonging to such a record. |
The biggest advantage of using a generic record approach compared to a special syntax only for look-up-tables is for importers. In this way, importers have to implement the treatment of such records only once. Tools which do not provide a high sophisticated GUI for look-up tables simply keep the parameters belonging to this group together, which is definitely of some help for the user. The same mechanism would work for records of parameters and other applications we don't know yet. There are lots of different look-up table implementations outside. The definition of a generic look-up table thing might be a lot of work. No importer will ever support all kinds of look-up tables. That's why, from my point of view, utilizing a more general concept from the beginning might be useful. |
Here is a Modelica model that in contains all table blocks from the MSL. I'm not sure if we can (and should) consider them because of the messy way the parameters are provided (i.e. scales as part of the data, no units, etc.). model ModelicaTables
Modelica.Blocks.Tables.CombiTable1Ds combiTable1Ds(
table=[0,0.1,1.1; 1,0.3,1.3; 2,0.2,1.2],
smoothness=Modelica.Blocks.Types.Smoothness.LinearSegments,
extrapolation=Modelica.Blocks.Types.Extrapolation.HoldLastPoint,
verboseExtrapolation=true)
annotation (Placement(transformation(extent={{-10,120},{10,140}})));
Modelica.Blocks.Tables.CombiTable1Dv combiTable1Dv(
table=[0,0,2; 1,1,1; 2,4,5],
smoothness=Modelica.Blocks.Types.Smoothness.ContinuousDerivative,
extrapolation=Modelica.Blocks.Types.Extrapolation.LastTwoPoints,
verboseExtrapolation=true)
annotation (Placement(transformation(extent={{-10,80},{10,100}})));
Modelica.Blocks.Tables.CombiTable2Ds combiTable2Ds(
table=[0.0,0,1,2; 0,0,0,0; 1,0,1,2; 2,0,2,4],
smoothness=Modelica.Blocks.Types.Smoothness.MonotoneContinuousDerivative1,
extrapolation=Modelica.Blocks.Types.Extrapolation.Periodic)
annotation (Placement(transformation(extent={{-10,40},{10,60}})));
Modelica.Blocks.Tables.CombiTable2Dv combiTable2Dv(
n=2,
table=[0.0,0,1,2; 0,0,0,0; 1,0,1,2; 2,0,2,4],
smoothness=Modelica.Blocks.Types.Smoothness.MonotoneContinuousDerivative2,
extrapolation=Modelica.Blocks.Types.Extrapolation.NoExtrapolation)
annotation (Placement(transformation(extent={{-10,0},{10,20}})));
Modelica.Blocks.Sources.TimeTable timeTable(
table=[0,1; 1,3; 2,2],
timeScale=1,
offset=1,
startTime=1,
shiftTime=1)
annotation (Placement(transformation(extent={{-10,-40},{10,-20}})));
Modelica.Blocks.Sources.CombiTimeTable combiTimeTable(
table=[0,1; 1,3; 2,2],
smoothness=Modelica.Blocks.Types.Smoothness.ContinuousDerivative,
extrapolation=Modelica.Blocks.Types.Extrapolation.Periodic,
timeScale=1,
offset={0},
startTime=0,
shiftTime=1)
annotation (Placement(transformation(extent={{-10,-80},{10,-60}})));
// ...
end ModelicaTables; |
A Simulink 2-d lookup table block exported with FMI Kit's grtfmi.tlc looks like this: <?xml version="1.0" encoding="UTF-8"?>
<fmiModelDescription
fmiVersion="2.0"
guid="{3f6f5fd6-ed86-452c-9658-ebc2a1d5453f}"
modelName="tables"
generationTool="Simulink 9.8 (R2022b) 13-May-2022 with FMI Kit 3.0 (grtfmi.tlc, FixedStepDiscrete, 0.2 s)"
generationDateAndTime="2023-03-23T16:24:19"
author="TSR2"
version="1.2">
<CoSimulation
modelIdentifier="tables"
canBeInstantiatedOnlyOncePerProcess="true"
canHandleVariableCommunicationStepSize="true">
</CoSimulation>
<DefaultExperiment
startTime="0.0"
stopTime="10.0"
stepSize="0.2"/>
<ModelVariables>
<!-- Parameters -->
<ScalarVariable name="Parameters.uDLookupTable_tableData[0,0]" valueReference="1" causality="parameter" variability="tunable">
<Real start="4.0"/>
</ScalarVariable>
<ScalarVariable name="Parameters.uDLookupTable_tableData[1,0]" valueReference="2" causality="parameter" variability="tunable">
<Real start="16.0"/>
</ScalarVariable>
<ScalarVariable name="Parameters.uDLookupTable_tableData[2,0]" valueReference="3" causality="parameter" variability="tunable">
<Real start="10.0"/>
</ScalarVariable>
<ScalarVariable name="Parameters.uDLookupTable_tableData[0,1]" valueReference="4" causality="parameter" variability="tunable">
<Real start="5.0"/>
</ScalarVariable>
<ScalarVariable name="Parameters.uDLookupTable_tableData[1,1]" valueReference="5" causality="parameter" variability="tunable">
<Real start="19.0"/>
</ScalarVariable>
<ScalarVariable name="Parameters.uDLookupTable_tableData[2,1]" valueReference="6" causality="parameter" variability="tunable">
<Real start="18.0"/>
</ScalarVariable>
<ScalarVariable name="Parameters.uDLookupTable_tableData[0,2]" valueReference="7" causality="parameter" variability="tunable">
<Real start="6.0"/>
</ScalarVariable>
<ScalarVariable name="Parameters.uDLookupTable_tableData[1,2]" valueReference="8" causality="parameter" variability="tunable">
<Real start="20.0"/>
</ScalarVariable>
<ScalarVariable name="Parameters.uDLookupTable_tableData[2,2]" valueReference="9" causality="parameter" variability="tunable">
<Real start="23.0"/>
</ScalarVariable>
<ScalarVariable name="Parameters.uDLookupTable_bp01Data[0]" valueReference="10" causality="parameter" variability="tunable">
<Real start="1.0"/>
</ScalarVariable>
<ScalarVariable name="Parameters.uDLookupTable_bp01Data[1]" valueReference="11" causality="parameter" variability="tunable">
<Real start="2.0"/>
</ScalarVariable>
<ScalarVariable name="Parameters.uDLookupTable_bp01Data[2]" valueReference="12" causality="parameter" variability="tunable">
<Real start="3.0"/>
</ScalarVariable>
<ScalarVariable name="Parameters.uDLookupTable_bp02Data[0]" valueReference="13" causality="parameter" variability="tunable">
<Real start="1.0"/>
</ScalarVariable>
<ScalarVariable name="Parameters.uDLookupTable_bp02Data[1]" valueReference="14" causality="parameter" variability="tunable">
<Real start="2.0"/>
</ScalarVariable>
<ScalarVariable name="Parameters.uDLookupTable_bp02Data[2]" valueReference="15" causality="parameter" variability="tunable">
<Real start="3.0"/>
</ScalarVariable>
<ScalarVariable name="Parameters.uDLookupTable_maxIndex[0]" valueReference="16" causality="parameter" variability="tunable">
<Integer start="2"/>
</ScalarVariable>
<ScalarVariable name="Parameters.uDLookupTable_maxIndex[1]" valueReference="17" causality="parameter" variability="tunable">
<Integer start="2"/>
</ScalarVariable>
<!-- Inputs -->
<ScalarVariable name="In1" valueReference="18" causality="input">
<Real start="0"/>
</ScalarVariable>
<ScalarVariable name="In2" valueReference="19" causality="input">
<Real start="0"/>
</ScalarVariable>
<!-- Outputs -->
<ScalarVariable name="Out1" valueReference="20" causality="output">
<Real/>
</ScalarVariable>
</ModelVariables>
<ModelStructure>
<Outputs>
<Unknown index="20"/>
</Outputs>
<InitialUnknowns>
<Unknown index="20"/>
</InitialUnknowns>
</ModelStructure>
</fmiModelDescription> |
(FMI Design Webmeeting) Klaus: the most important questions is, whether to have something special for maps and curves, or have something more general. Poll: Should we
1 ) Klaus, Antoine, Masoud, Daniel, Oliver (5) Andreas: which option would hinder us most? |
Klaus: this looks comlicated. (Difference to A2L, XCP) Andreas: Are there quantities,... in this proposal |
FMI-Design Meeting (Klaus, Irina, Christian, Torsten S.) With both approaches we can reach what we want for look-up tables. Main concerns for "Record" approach:
Issues for both approaches:
|
Discussion in the larger group at the FMI Design meeting: Why not use the terminals of the core standard instead of a new concept of "records" that does similar things? |
(Discussion: Klaus, Irina, Christian)
A first draft could looks like:
tbd. What to define what "matching" means in this context, define also "None" for matching rule. |
The draft PR for clarification of terminals in 3.0.1 is modelica/fmi-standard#1885, please add further needed clarifications and add feedback... |
Discussion Web-meeting Torsten B.: Usage of Terminals for parameter records and maps and curves seems far-fetched. Maps and curves helps users to display them. Problem description:
Pierre: Look-up tables have more specific semantic than grouping of parameters. Poll: Should we 1.) define something specific for maps and curves, (multiple votes possible) 1: (Torsten B.) (Pierre) Klaus, (Irina), (Christian), (Matthias), (Kahramon) Next steps: Klaus: what has to be changed in 3.0.x? Pierre: I will start a PR to clarify Signals ... i.e. --> e.g. Start with layered standard: Klaus: I will change our examples on this variant. Klaus: displayNames vs. MemberNames? There is no "any" in XSD? Next meeting: in two weeks web meeting |
I think this issue can be closed, as IMHO the poins are all reflected in the current draft |
@klausschuch had presented an initial draft at a previous meeting. Could you please provide more information?
The text was updated successfully, but these errors were encountered: