Skip to content
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

Create FMU with simple PT1 model #39

Open
Sciemon opened this issue Nov 24, 2023 · 1 comment
Open

Create FMU with simple PT1 model #39

Sciemon opened this issue Nov 24, 2023 · 1 comment
Assignees

Comments

@Sciemon
Copy link

Sciemon commented Nov 24, 2023

I don't want to bombard you with issues, you can also guide me to some documents to improve my general understanding of the FMI if they are helpful for the practical implementation in FMIExport.

I'm trying to create an FMU with a simple PT1 model. I tried to stay as close as possible to the bouncing ball example. I added an event although there are no events, but if I don't define an eventFct then an error is thrown. There are also no discrete states.

From the error message (below) I figure that there might be something wrong with FMU_FCT_OUTPUT, but I don't understand what exactly is happening. Help is much appreciated.

Code:

using FMIExport 
using FMIExport.FMICore: fmi2True, fmi2False 

FMU_FCT_INIT = function()
    T = 1.0         # time constant 
    t = 0.0       
    x = [0.0]      
    ẋ = [0.0]
    x_d = [] 
    u = [0.0]
    p = [T]

    return (t, x, ẋ, x_d, u, p)
end

FMU_FCT_EVALUATE = function(t, x, ẋ, x_d, u, p, eventMode)
    T = (p...,)
    old_state = (x...,)

    derivative = (u[0] - old_state)/T

    x = [old_state]
    ẋ = [derivative]
    p = [T]
    x_d = [] 

    return (x, ẋ, x_d, p)
end

FMU_FCT_OUTPUT = function(t, x, ẋ, x_d, u, p)
    state = (x...,)
    y = [state]
    return y
end

FMU_FCT_EVENT = function(t, x_c, ẋ_c, x_d, u, p)
    return [0.0]
end

FMIBUILD_CONSTRUCTOR = function(resPath=".")
    fmu = fmi2CreateSimple(initializationFct=FMU_FCT_INIT,
                        evaluationFct=FMU_FCT_EVALUATE,
                        outputFct=FMU_FCT_OUTPUT,
                        eventFct=FMU_FCT_EVENT)

    fmu.modelDescription.modelName = "PT1"
    # modes 
    fmi2ModelDescriptionAddModelExchange(fmu.modelDescription, "PT1")

    fmi2AddStateAndDerivative(fmu, "PT1.state"; stateDescr="state", derivativeDescr="state derivative")
    fmi2AddRealOutput(fmu, "PT1.state"; description="state")
    fmi2AddRealParameter(fmu, "T";     description="Time constant")

    fmi2AddEventIndicator(fmu)

    return fmu
end

tmpDir = mktempdir(; prefix="fmibuildjl_test_", cleanup=false) 
@info "Saving example files at: $(tmpDir)"
fmu_save_path = joinpath(tmpDir, "BouncingBall.fmu")  

fmu = FMIBUILD_CONSTRUCTOR()

Error:
ERROR: MethodError: Cannot convert an object of type
Tuple{Float64} to an object of type
Union{Float64, Int32}

Closest candidates are:
convert(::Type{T}, ::Union{Static.StaticBool{N}, Static.StaticFloat64{N}, Static.StaticInt{N}} where N) where T<:Number
@ Static C:\Users\seberlein.julia\packages\Static\dLrtk\src\Static.jl:414
convert(::Type{<:Number}, ::SciMLOperators.AddedScalarOperator)
@ SciMLOperators C:\Users\seberlein.julia\packages\SciMLOperators\hFLNz\src\scalar.jl:243
convert(::Type{T}, ::AbstractChar) where T<:Number
@ Base char.jl:185
...

Stacktrace:
[1] setindex!(h::Dict{UInt32, Union{Float64, Int32}}, v0::Tuple{Float64}, key::UInt32)
@ Base .\dict.jl:369
[2] applyValues(_component::Ptr{Nothing}, xc::Vector{Float64}, ẋc::Vector{Float64}, xd::Vector{Any}, u::Vector{Float64}, y::Vector{Tuple{Float64}}, p::Vector{Float64})
@ FMIExport C:\Users\seberlein.julia\packages\FMIExport\j8bGN\src\FMI2_simple.jl:113
[3] reset(_component::Ptr{Nothing})
@ FMIExport C:\Users\seberlein.julia\packages\FMIExport\j8bGN\src\FMI2_simple.jl:45
[4] simple_fmi2Instantiate(instanceName::Ptr{UInt8}, fmuType::UInt32, fmuGUID::Ptr{UInt8}, fmuResourceLocation::Ptr{UInt8}, functions::Ptr{FMICore.fmi2CallbackFunctions}, visible::Int32, loggingOn::Int32)
@ FMIExport C:\Users\seberlein.julia\packages\FMIExport\j8bGN\src\FMI2_simple.jl:170
[5] fmi2Instantiate(cfunc::Ptr{Nothing}, instanceName::Ptr{UInt8}, fmuType::UInt32, fmuGUID::Ptr{UInt8}, fmuResourceLocation::Ptr{UInt8}, functions::Ptr{FMICore.fmi2CallbackFunctions}, visible::Int32, loggingOn::Int32)
@ FMICore C:\Users\seberlein.julia\packages\FMICore\l1OAc\src\FMI2\cfunc.jl:20
[6] (::FMIImport.var"#74#75"{String, UInt32, Bool, Bool, Bool, FMU2, String, FMICore.fmi2CallbackFunctions, FMICore.FMU2ComponentEnvironment})()
@ FMIImport C:\Users\seberlein.julia\packages\FMIImport\7xJzL\src\FMI2\ext.jl:509
[7] lock(f::FMIImport.var"#74#75"{String, UInt32, Bool, Bool, Bool, FMU2, String, FMICore.fmi2CallbackFunctions, FMICore.FMU2ComponentEnvironment}, l::ReentrantLock)
@ Base .\lock.jl:229
[8] fmi2Instantiate!(fmu::FMU2; instanceName::String, type::UInt32, pushComponents::Bool, visible::Bool, loggingOn::Bool, externalCallbacks::Bool, logStatusOK::Bool, logStatusWarning::Bool, logStatusDiscard::Bool, logStatusError::Bool, logStatusFatal::Bool, logStatusPending::Bool)
@ FMIImport C:\Users\seberlein.julia\packages\FMIImport\7xJzL\src\FMI2\ext.jl:506
[9] fmi2Instantiate!
@ C:\Users\seberlein.julia\packages\FMIImport\7xJzL\src\FMI2\ext.jl:447 [inlined]
[10] (::FMIImport.var"#12#13"{Nothing, Bool, typeof(FMIImport.handleEvents), FMU2, UInt32, Nothing, Float64, Float64, Nothing})()
@ FMIImport C:\Users\seberlein.julia\packages\FMIImport\7xJzL\src\FMI2\prep.jl:67
[11] ignore_derivatives
@ C:\Users\seberlein.julia\packages\ChainRulesCore\7MWx2\src\ignore_derivatives.jl:26 [inlined]
[12] #prepareSolveFMU#11
@ C:\Users\seberlein.julia\packages\FMIImport\7xJzL\src\FMI2\prep.jl:39 [inlined]
[13] fmi2SimulateME(fmu::FMU2, c::Nothing, tspan::Tuple{Float64, Float64}; tolerance::Nothing, dt::Nothing, solver::Nothing, customFx::Nothing, recordValues::Nothing, recordEventIndicators::Nothing, recordEigenvalues::Bool, saveat::Nothing, x0::Nothing, setup::Nothing, reset::Nothing, instantiate::Nothing, freeInstance::Nothing, terminate::Nothing, inputValueReferences::Nothing, inputFunction::Nothing, parameters::Nothing, dtmax::Float64, callbacksBefore::Vector{Any}, callbacksAfter::Vector{Any}, showProgress::Bool, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ FMI C:\Users\seberlein.julia\packages\FMI\iK3kv\src\FMI2\sim.jl:453
[14] fmi2SimulateME
@ C:\Users\seberlein.julia\packages\FMI\iK3kv\src\FMI2\sim.jl:363 [inlined]
[15] #fmi2SimulateME#8
@ C:\Users\seberlein.julia\packages\FMI\iK3kv\src\FMI2\comp_wraps.jl:38 [inlined]
[16] fmi2SimulateME
@ C:\Users\seberlein.julia\packages\FMI\iK3kv\src\FMI2\comp_wraps.jl:37 [inlined]
[17] #fmiSimulateME#292
@ C:\Users\seberlein.julia\packages\FMI\iK3kv\src\FMI.jl:851 [inlined]
[18] top-level scope
@ d:\User\seberlein\Julia\FMI\src\simple_PT1_example.jl:68

@ThummeTo
Copy link
Owner

There are multiple issues here (that need to be fixed):

  • the actual error message (applyValue dispatch)
  • support for non-event FMUs (the default dispatch is bad)
  • add PT1 and no-state examples

Independent from that, please define FMU_FCT_EVENT as function that returns != [0.0] like [1.0] because events are located at == 0.0. This will result in a FMU with state events for every time instance, which won't simulate I think.

@ThummeTo ThummeTo self-assigned this Nov 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants