Coder Social home page Coder Social logo

sspgen's Introduction

sspgen

A Kotlin DSL for generating SSP archives.

sspgen is Kotlin DSL designed to ease the work of creating SSP compliant simulation systems.

Among other things, sspgen can validate the SystemStructureDefinition, e.g. checking that connectors exists and that connections are made between the same variable type.

Resources bundled with the generated .ssp may be specified both as local files and remote URLs.

Pre-requisites

Either download the latest kotlin-compiler and add the bin folder to PATH.

OR, (recommended) run the script in the context of IntelliJ, which additionally adds script auto completion.

Maven artifact

sspgen is hosted through Maven Central

Example

Imagine a file named ExampleSspGen.main.kts with the following content:

note: File names MUST end with .main.kts

#!kotlin

@file:DependsOn("info.laht.sspgen:dsl:0.5.2")

import no.ntnu.ihb.sspgen.dsl.*

ssp("TestSsdGen") {
    
    resources {
        file("path/to/FMU1.fmu")
        file("path/to/FMU2.fmu")
        url("example.com/someFile.txt")
    }

    ssd("A simple CLI test") {

        author = "John Doe"
        description = "A simple description"

        system("Test") {

            description = "An even simpler description"

            elements {
                component("FMU1", "resources/FMU1.fmu") {
                    connectors {
                        real("output", output) {
                            unit("m/s")
                        }
                        real("input", input)
                        integer("counter", output)
                    }
                    parameterBindings {
                        parameterSet("initialValues") {
                            real("input", 2.0)
                            integer("counter", 99)
                        }
                    }
                }
                component("FMU2", "resources/FMU2.fmu") {
                    connectors {
                        real("input", input)
                        real("output", output)
                    }
                }
            }

            connections {
                "FMU2.output" to "FMU1.input"
                ("FMU1.output" to "FMU2.input").linearTransformation(factor = 1.5)
            }

        }

        defaultExperiment(startTime = 1.0)

    }

}.build()

Executing ./ExampleSsdGen.main.kts in a shell would result in an SSP archive named TestSsdGen.ssp with two FMUs and someFile.txt located under /resources and a SystemStructure.ssd in the root directory with the content:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ssd:SystemStructureDescription xmlns:ssd="http://ssp-standard.org/SSP1/SystemStructureDescription" xmlns:ssc="http://ssp-standard.org/SSP1/SystemStructureCommon" xmlns:ssb="http://ssp-standard.org/SSP1/SystemStructureSignalDictionary" version="1.0" name="A simple CLI test" description="A simple description" author="John Doe" generationTool="sspgen">
    <ssd:System name="Test">
        <ssd:Elements>
            <ssd:Component source="resources/FMU1.fmu" name="FMU1">
                <ssd:Connectors>
                    <ssd:Connector name="output" kind="output">
                        <ssc:Real unit="m/s"/>
                    </ssd:Connector>
                    <ssd:Connector name="input" kind="input">
                        <ssc:Real/>
                    </ssd:Connector>
                    <ssd:Connector name="counter" kind="output">
                        <ssc:Integer/>
                    </ssd:Connector>
                </ssd:Connectors>
                <ssd:ParameterBindings>
                    <ssd:ParameterBinding>
                        <ssd:ParameterValues>
                            <ssv:ParameterSet version="1.0" name="initialValues">
                                <ssv:Parameters>
                                    <ssv:Parameter name="input">
                                        <ssv:Real value="2.0"/>
                                    </ssv:Parameter>
                                    <ssv:Parameter name="counter">
                                        <ssv:Integer value="99"/>
                                    </ssv:Parameter>
                                </ssv:Parameters>
                            </ssv:ParameterSet>
                        </ssd:ParameterValues>
                    </ssd:ParameterBinding>
                </ssd:ParameterBindings>
            </ssd:Component>
            <ssd:Component source="resources/FMU2.fmu" name="FMU2">
                <ssd:Connectors>
                    <ssd:Connector name="input" kind="input">
                        <ssc:Real/>
                    </ssd:Connector>
                    <ssd:Connector name="output" kind="output">
                        <ssc:Real/>
                    </ssd:Connector>
                </ssd:Connectors>
            </ssd:Component>
        </ssd:Elements>
        <ssd:Connections>
            <ssd:Connection startElement="FMU2" startConnector="output" endElement="FMU1" endConnector="input"/>
            <ssd:Connection startElement="FMU1" startConnector="output" endElement="FMU2" endConnector="input">
                <ssc:LinearTransformation factor="1.5" offset="0.0"/>
            </ssd:Connection>
        </ssd:Connections>
    </ssd:System>
    <ssd:DefaultExperiment startTime="1.0"/>
</ssd:SystemStructureDescription>

Another convenient feature of the DSL is the ability for copying connectors and parameterSets from one component to another. Additionally, OSP-IS is supported, allowing high-level connections to be formed.

API

ssp(archiveName: String) {

    resources {
        file(path: String)
        url(path: String)
        pythonfmu(sourcePath: String, vararg projectFiles: String)
    }

    ssd(name: String) {

        author: String
        description: String
        fileVersion: String
        copyright: String
        license: String
        
        system(name: String) {

            description: String

            elements {
                component(name: String, source: String) {
                    connectors {
                        integer(name: String, kind: String)
                        real(name: String, kind: String) {
                            unit(name: String)
                        }
                        string(name: String, kind: String)
                        boolean(name: String, kind: String)
                        enumeration(name: String, kind: String)
                        copyFrom(componentName: String) {
                            //declare additional connectors as above
                        }       
                    }
                    parameterBindings {
                        parameterSet(name: String) {
                            integer(name: String, value: Int)
                            real(name: String, value: Number)
                            string(name: String, value: String)
                            boolean(name: String, value: Boolean)
                            enumeration(name: String, value: String)
                            copyFrom(componentName: String, parameterSetName: String) {
                                //declare additional parameters or override existing ones
                            }       
                        }
                    }              
                    annotations {
                        annotation(rawString: String) {
                            // e.g: 
                            """
                            <MyElement>
                                <ChildElement value="something"/>
                            </MyElement>
                            """
                        }
                        copyFrom(component: String)       
                    }
                }
            }
            connections(inputsFirst: Boolean = false) {
                "StartElement.StartConnector" to "EndElement.EndConnector" //inputsFirst=true swaps this
            }
            ospConnections {
                "component1.bond" to "component2.bond"
            }      
        }

        defaultExperiment(startTime: Number, stopTime: Number) {       
            annotations {
                annotation(rawString: String) {
                    // e.g: 
                    """
                    <MyElement>
                        <ChildElement value="something"/>
                    </MyElement>
                    """
                }   
    
            }

        }

    }

    namespaces {
        namespace(namespace: String, uri: String)
    }

}

Integration with FMI-VDM-Model

sspgen integrates with FMI-VDM-Model, allowing optional static analysis of the included FMUs for informative purposes. To use, simply provide the path to the fmi2vdm.jar when invoking validate or build.

sspgen's People

Contributors

markaren avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

sspgen's Issues

Integrate with pythonfmu

Let users directly point to the python sources without having them do the intermediate step of building the FMU first.

Allow OSP-IS connections

Rather than transpiling OSP-IS, just use the meta-data available from supported FMUs to allow higher level connections.

Superseeds #3

Verify parametersets

Verify that the variables referenced in parameter-sets exists and that the type is correct.

Transpile OSP-IS to SSP

The open-simulation-platform has developed the OSP-IS, which basically is an alternative to SSP. It should be entirely possible to apply the OSP-IS format to ssp-gen and transpile it to SSP, so that the system can be simulated in tools other than libcosim.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.