My first little success doing this. It is something probably very easy for you 
guys, but I have struggle A LOT (no pro-dev speaking).

First I create bindings to 
[fmuTemplate.h](https://github.com/qtronic/fmusdk/blob/master/fmu20/src/models/fmuTemplate.h).
 I did so with a wrapper similar to the following: 
    
    
    import os
    import nimterop/cimport
    
    const
      base = currentSourcePath.parentDir()
    
    static:
      cDebug()
    cDefine("DISABLE_PREFIX")
    
    cIncludeDir(base/"src/shared/include")
    cIncludeDir(base/"src/shared")
    cIncludeDir(base/"src")
    cImport(base/"src/fmuTemplate.h", recurse=true)
    
    
    Run

I did:
    
    
    $ nim c wrapper.nim > fmutemplate.nim

I had to manually modify **fmutemplate.nim** as suggested 
[here](https://forum.nim-lang.org/t/5393).

Then I ported a model. As an example I ported the 
[inc](https://github.com/qtronic/fmusdk/tree/master/fmu20/src/models/inc) 
model. I convert the file 
[inc.c](https://github.com/qtronic/fmusdk/blob/master/fmu20/src/models/inc/inc.c)
 into:
    
    
    # nim c --nimcache:.cache --app:lib -o:inc.so inc.nim
    import fmuTemplate
    import strformat
    
    # Porting inc.c (a particular model)
    const
       MODEL_IDENTIFIER="inc"
       MODEL_GUID="{8c4e810f-3df3-4a00-8276-176fa3c9f008}"
       
       #define model size
       NUMBER_OF_REALS= 0
       NUMBER_OF_INTEGERS=1
       NUMBER_OF_BOOLEANS=0
       NUMBER_OF_STRINGS=0
       NUMBER_OF_STATES=0
       NUMBER_OF_EVENT_INDICATORS=0
    
    const
       counter = 0
    
    proc setStartValues(comp:ptr ModelInstance) {.exportc: "$1".} =
        comp.i[counter] = 1
    
    proc calculateValues(comp:ptr ModelInstance) {.exportc: "$1".}=
        if comp.state == modelInitializationMode:
            # set first time event
            comp.eventInfo.nextEventTimeDefined = fmi2True
            comp.eventInfo.nextEventTime        = 1 + comp.time
    
    proc eventUpdate(comp:ptr ModelInstance, eventInfo:ptr fmi2EventInfo, 
timeEvent:cint, isNewEventIteration:cint) {.exportc: "$1".} =
        if timeEvent != 0:
            comp.i[counter] += 1;
            if comp.i[counter] == 13:
                eventInfo.terminateSimulation  = fmi2True
                eventInfo.nextEventTimeDefined = fmi2False
            else:
                eventInfo.nextEventTimeDefined = fmi2True
                eventInfo.nextEventTime        = 1 + comp.time
    
    {.passC: "-Ifmi/shared/include -w -fmax-errors=5".}
    
    {.passC: "-DMODEL_IDENTIFIER=\\\"" & MODEL_IDENTIFIER & "\\\"".}
    {.passC: "-DMODEL_GUID=\\\"" & MODEL_GUID & "\\\"".}
    {.passC: "-DNUMBER_OF_REALS=" & $NUMBER_OF_REALS .}
    {.passC: "-DNUMBER_OF_INTEGERS=" & $NUMBER_OF_INTEGERS .}
    {.passC: "-DNUMBER_OF_BOOLEANS=" & $NUMBER_OF_BOOLEANS .}
    {.passC: "-DNUMBER_OF_STRINGS=" & $NUMBER_OF_STRINGS .}
    {.passC: "-DNUMBER_OF_STATES=" & $NUMBER_OF_STATES .}
    {.passC: "-DNUMBER_OF_EVENT_INDICATORS=" & $NUMBER_OF_EVENT_INDICATORS .}
    {.compile: "./src/fmuTemplate.c".}
    
    
    Run

I manually modified added to **fmuTemplate.c** the line: 
    
    
    include "fmuTemplate.h"
    
    
    Run

I compiled the model into a library as follows:
    
    
    nim c --nimcache:.cache --app:lib -o:inc.so inc.nim

This produced the file **inc.so**.

Later, I used directly the [fmusdk](https://github.com/qtronic/fmusdk) to 
create all the model's folder structure with all the files by doing:
    
    
    build_fmu me inc

This creates a Model Exchange model for **inc**.

I replaced the file **inc.so** created with **fmusdk** with the one created 
using **inc.nim**. The file is stored in **fmu /binaries/linux64/inc.so**.

The whole folder structure is stored as:
    
    
    cd fmu
    zip -r ../inc.fmu ./

The file **inc.fmu** is the model that can be integrated in OpenModelica, 
Dymola, Simulink, ...

I have only tested it with 
[FMUComplianceChecker](https://github.com/modelica-tools/FMUComplianceChecker) 
and it looks good.

As a proof of concept, I am happy.

The way forward:

  * [ ] To create the folder structure in nim.
  * [ ] To create the 
[modelDescription.xml](https://github.com/qtronic/fmusdk/blob/master/fmu20/src/models/inc/modelDescription_me.xml)
 file in nim.
  * [ ] To define the model in [Modelica-like 
language](https://en.wikipedia.org/wiki/Modelica) using macros in order to 
build the models. Something like what is being done with 
[Modia](https://github.com/ModiaSim/Modia.jl) in Julia.



I don't think I will be capable of doing the last bullet, but I will try.

Reply via email to