Skip to content

Commit

Permalink
Add demo FMUs for FMI-LS-BUS
Browse files Browse the repository at this point in the history
This includes:
- A demo FMU for a CAN node with triggered output clocks
- A demo FMU for a simple CAN bus simulation

Each demo includes a script to pack it into a source-code FMU
  • Loading branch information
ClemensB committed Nov 27, 2023
1 parent 544348d commit 1a19ee4
Show file tree
Hide file tree
Showing 25 changed files with 3,521 additions and 0 deletions.
2 changes: 2 additions & 0 deletions ls-bus-guide/demos/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Do not store FMU artifacts in here
*.fmu
41 changes: 41 additions & 0 deletions ls-bus-guide/demos/can-bus-simulation/PackFmu.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import urllib.request
import zipfile

from pathlib import Path


# Output FMU path
FMU_PATH = Path('DemoCanBusSimulation.fmu')

# Repository to fetch the LS-BUS headers from
LS_BUS_REPO = 'modelica/fmi-ls-bus'
LS_BUS_REV = '473bd5b80730c47373bf41f1c31d44f50de82dd0'
LS_BUS_HEADERS = [ 'fmi3LsBus.h', 'fmi3LsBusCan.h' ]


def main():
demo_dir = Path(__file__).parent

with zipfile.ZipFile(FMU_PATH, 'w') as fmu:
# Add LS-BUS headers from GitHub repository
for ls_bus_header in LS_BUS_HEADERS:
with urllib.request.urlopen(f'https://raw.githubusercontent.com/{LS_BUS_REPO}/{LS_BUS_REV}/headers/{ls_bus_header}') as f:
fmu.writestr(f'sources/{ls_bus_header}', f.read())

# Add LS-BUS utility headers
for file in (demo_dir.parent.parent / 'headers').iterdir():
fmu.write(file, f'sources/{file.name}')

# Add source files
for file in (demo_dir / 'src').iterdir():
fmu.write(file, f'sources/{file.name}')

# Add description files
fmu.write(demo_dir / 'description' / 'modelDescription.xml', 'modelDescription.xml')
fmu.write(demo_dir / 'description' / 'buildDescription.xml', 'sources/buildDescription.xml')
fmu.write(demo_dir / 'description' / 'terminalsAndIcons.xml', 'terminalsAndIcons/terminalsAndIcons.xml')
fmu.write(demo_dir / 'description' / 'fmi-ls-manifest.xml', 'extra/org.fmi-standard.fmi-ls-bus/fmi-ls-manifest.xml')


if __name__ == '__main__':
main()
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<fmiBuildDescription fmiVersion="3.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/modelica/fmi-standard/v3.0.1/schema/fmi3BuildDescription.xsd">
<BuildConfiguration modelIdentifier="DemoBusSimulation">
<SourceFileSet language="C99">
<SourceFile name="App.c"/>
<SourceFile name="Fmu.c"/>
<SourceFile name="Logging.c"/>
</SourceFileSet>
</BuildConfiguration>
</fmiBuildDescription>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<fmiLayeredStandardManifest
xmlns:fmi-ls="http://fmi-standard.org/fmi-ls-manifest"
fmi-ls:fmi-ls-name="org.fmi-standard.fmi-ls-bus"
fmi-ls:fmi-ls-version="1.0.0"
fmi-ls:fmi-ls-description="Layered Standard for the simulation of bus communication on a signal or network abstraction based level."
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../Fmi3LsBus/schemas/fmi3LayeredStandardBusManifest.xsd"/>
101 changes: 101 additions & 0 deletions ls-bus-guide/demos/can-bus-simulation/description/modelDescription.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>
<fmiModelDescription
fmiVersion="3.0"
modelName="DemoBusSimulation"
instantiationToken=""
variableNamingConvention="structured"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/modelica/fmi-standard/v3.0.1/schema/fmi3ModelDescription.xsd">

<CoSimulation
modelIdentifier="DemoTriggeredOutput"
needsExecutionTool="false"
canGetAndSetFMUState="false"
canSerializeFMUState="false"
canHandleVariableCommunicationStepSize="true"
canBeInstantiatedOnlyOncePerProcess="false"
providesIntermediateUpdate="false"
canReturnEarlyAfterIntermediateUpdate="false"
providesEvaluateDiscreteStates="true"
hasEventMode="true">
</CoSimulation>

<LogCategories>
<Category name="logStatusDiscard"
description="Log messages when returning fmi3Discard status from any function." />
<Category name="logStatusError"
description="Log messages when returning fmi3Error status from any function." />

<Category name="Trace"
description="Trace log messages." />
<Category name="Info"
description="Info log messages." />
<Category name="Warning"
description="Warning log messages." />
<Category name="Error"
description="Error log messages." />
</LogCategories>

<DefaultExperiment
startTime="0"
stepSize="0.001" />

<ModelVariables>
<Float64 name="time" valueReference="1024" causality="independent" variability="continuous" description="Simulation time" />

<Binary name="Node1.Rx_Data"
valueReference="0"
causality="input"
variability="discrete"
initial="exact"
maxSize="2048"
clocks="2"
mimeType="org.fmi-standard.fmi-ls-bus.v1.can">
<Dimension start="1" />
<Start value="" />
</Binary>

<Binary name="Node1.Tx_Data"
valueReference="1"
causality="output"
variability="discrete"
initial="calculated"
maxSize="2048"
clocks="3"
mimeType="org.fmi-standard.fmi-ls-bus.v1.can">
</Binary>

<Clock name="Node1.Rx_Clock" valueReference="2" causality="input" intervalVariability="triggered" />
<Clock name="Node1.Tx_Clock" valueReference="3" causality="input" intervalVariability="countdown" />

<Binary name="Node2.Rx_Data"
valueReference="4"
causality="input"
variability="discrete"
initial="exact"
maxSize="2048"
clocks="6"
mimeType="org.fmi-standard.fmi-ls-bus.v1.can">
<Dimension start="1" />
<Start value="" />
</Binary>

<Binary name="Node2.Tx_Data"
valueReference="5"
causality="output"
variability="discrete"
initial="calculated"
maxSize="2048"
clocks="7"
mimeType="org.fmi-standard.fmi-ls-bus.v1.can">
</Binary>

<Clock name="Node2.Rx_Clock" valueReference="6" causality="input" intervalVariability="triggered" />
<Clock name="Node2.Tx_Clock" valueReference="7" causality="input" intervalVariability="countdown" />
</ModelVariables>

<ModelStructure>
<Output valueReference="1" dependencies="3" />
<Output valueReference="5" dependencies="7" />
</ModelStructure>
</fmiModelDescription>
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<fmiTerminalsAndIcons fmiVersion="3.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/modelica/fmi-standard/v3.0.1/schema/fmi3TerminalsAndIcons.xsd">
<Terminals>
<Terminal terminalKind="org.fmi-ls-bus.network-terminal"
matchingRule="org.fmi-ls-bus.transceiver"
name="Node1"
description="CAN bus terminal definition">
<TerminalMemberVariable variableKind="signal"
variableName="Node1.Rx_Clock"
memberName="Rx_Clock" />
<TerminalMemberVariable variableKind="signal"
variableName="Node1.Rx_Data"
memberName="Rx_Data" />
<TerminalMemberVariable variableKind="signal"
variableName="Node1.Tx_Clock"
memberName="Tx_Clock" />
<TerminalMemberVariable variableKind="signal"
variableName="Node1.Tx_Data"
memberName="Tx_Data" />
</Terminal>
<Terminal terminalKind="org.fmi-ls-bus.network-terminal"
matchingRule="org.fmi-ls-bus.transceiver"
name="Node2"
description="CAN bus terminal definition">
<TerminalMemberVariable variableKind="signal"
variableName="Node2.Rx_Clock"
memberName="Rx_Clock" />
<TerminalMemberVariable variableKind="signal"
variableName="Node2.Rx_Data"
memberName="Rx_Data" />
<TerminalMemberVariable variableKind="signal"
variableName="Node2.Tx_Clock"
memberName="Tx_Clock" />
<TerminalMemberVariable variableKind="signal"
variableName="Node2.Tx_Data"
memberName="Tx_Data" />
</Terminal>
</Terminals>
</fmiTerminalsAndIcons>
Loading

0 comments on commit 1a19ee4

Please sign in to comment.