Skip to content

doc: updating MTK example to v11 in manual.#340

Closed
franckgaga wants to merge 1 commit intomainfrom
update_mtk_manual
Closed

doc: updating MTK example to v11 in manual.#340
franckgaga wants to merge 1 commit intomainfrom
update_mtk_manual

Conversation

@franckgaga
Copy link
Member

Hello @baggepinnen,

I'm trying to update the MTK example to v11 but i'm stuck at the varmat_to_vars function here:

using ModelPredictiveControl, ModelingToolkit
using ModelingToolkit: D_nounits as D, t_nounits as t, varmap_to_vars
@parameters g=9.8 L=0.4 K=1.2 m=0.3
@variables θ(t)=0 ω(t)=0 τ(t)=0 y(t)
eqs = [
    D(θ) ~ ω
    D(ω) ~ -g/L*sin(θ) - K/m*ω + τ/m/L^2
    y ~ θ * 180 / π
]
@named mtk_model = System(eqs, t)
function generate_f_h(model, inputs, outputs)
    (_, f_ip), x_sym, p_sym, io_sys = ModelingToolkit.generate_control_function(
        model, inputs, split=false, simplify=true
    )
    if any(ModelingToolkit.is_alg_equation, equations(io_sys)) 
        error("Systems with algebraic equations are not supported")
    end
    nu, nx, ny = length(inputs), length(x_sym), length(outputs)
    function f!(ẋ, x, u, _ , p)
        try
            f_ip(ẋ, x, u, p, nothing)
        catch err
            if err isa MethodError
                error("NonLinModel does not support a time argument t in the f function, "*
                      "see the constructor docstring for a workaround.")
            else
                rethrow()
            end
        end
        return nothing
    end
    (_, h_ip) = ModelingToolkit.build_explicit_observed_function(
        io_sys, outputs; inputs, return_inplace = true
    )
    u_nothing = fill(nothing, nu)
    function h!(y, x, _ , p)
        try
            # MTK.jl supports a `u` argument in `h_ip` function but not this package. We set
            # `u` as a vector of nothing and `h_ip` function will presumably throw an
            # MethodError if this argument is used inside the function
            h_ip(y, x, u_nothing, p, nothing)
        catch err
            if err isa MethodError
                error("NonLinModel only support strictly proper systems (no manipulated "*
                      "input argument u in the output function h)")
            else
                rethrow()
            end
        end
        return nothing
    end
    println(bindings(io_sys))
    p = varmap_to_vars(bindings(io_sys), p_sym) # crashes here
    return f!, h!, p, x_sym, nu, nx, ny
end
inputs, outputs = [τ], [y]
f!, h!, p, x_sym, nu, nx, ny = generate_f_h(mtk_model, inputs, outputs)
x_sym

this code prints:

ReadOnlyDicts.ReadOnlyDict{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}, SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}, ModelingToolkitBase.AtomicArrayDict{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}, Dict{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}, SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}}}}(τ(t) => missing)
ERROR: Initial condition underdefined. Some are missing from the variable map.
Please provide a default (`u0`), initialization equation, or guess
for the following variables:

L, K, m, g

Stacktrace:
 [1] varmap_to_vars(varmap::ReadOnlyDicts.ReadOnlyDict{…}, vars::Vector{…}; tofloat::Bool, use_union::Bool, container_type::Type, buffer_eltype::Type, toterm::Function, check::Bool, allow_symbolic::Bool, is_initializeprob::Bool, substitution_limit::Int64, missing_values::ModelingToolkitBase.MissingGuessValue.var"typeof(MissingGuessValue)")
   @ ModelingToolkitBase ~/.julia/packages/ModelingToolkitBase/uIKoY/src/systems/problem_utils.jl:378
 [2] varmap_to_vars
   @ ~/.julia/packages/ModelingToolkitBase/uIKoY/src/systems/problem_utils.jl:331 [inlined]
 [3] generate_f_h(model::System, inputs::Vector{Num}, outputs::Vector{Num})
   @ Main ~/.julia/dev/ModelPredictiveControl/docs/src/manual/mtk.md:89
 [4] top-level scope
   @ ~/.julia/dev/ModelPredictiveControl/docs/src/manual/mtk.md:93
Some type information was truncated. Use `show(err)` to see complete types.

Do you know why bindings(io_sys) does not contain the parameter values anymore ?

@codecov-commenter
Copy link

codecov-commenter commented Mar 20, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.59%. Comparing base (20f8634) to head (b5912f7).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #340   +/-   ##
=======================================
  Coverage   98.59%   98.59%           
=======================================
  Files          27       27           
  Lines        5190     5190           
=======================================
  Hits         5117     5117           
  Misses         73       73           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@baggepinnen
Copy link
Member

Try

p = ModelingToolkit.get_p(iosys, op_dict)

@franckgaga
Copy link
Member Author

Thanks for the answer but using p = ModelingToolkit.get_p(io_sys, bindings(io_sys)) returned the error:

ERROR: AssertionError: `promote_to_concrete` can't make type Missing uniform with Float64
Stacktrace:
 [1] promote_to_concrete(vs::Vector{Union{Missing, Real}}; tofloat::Bool, use_union::Bool)
   @ ModelingToolkitBase ~/.julia/packages/ModelingToolkitBase/uIKoY/src/utils.jl:1091
 [2] varmap_to_vars(varmap::ModelingToolkitBase.AtomicArrayDict{…}, vars::Vector{…}; tofloat::Bool, use_union::Bool, container_type::Type, buffer_eltype::Type, toterm::Function, check::Bool, allow_symbolic::Bool, is_initializeprob::Bool, substitution_limit::Int64, missing_values::ModelingToolkitBase.MissingGuessValue.var"typeof(MissingGuessValue)")
   @ ModelingToolkitBase ~/.julia/packages/ModelingToolkitBase/uIKoY/src/systems/problem_utils.jl:418
 [3] varmap_to_vars
   @ ~/.julia/packages/ModelingToolkitBase/uIKoY/src/systems/problem_utils.jl:331 [inlined]
 [4] get_p(sys::System, varmap::ReadOnlyDicts.ReadOnlyDict{…}; split::Bool, kwargs::@Kwargs{})
   @ ModelingToolkitBase ~/.julia/packages/ModelingToolkitBase/uIKoY/src/systems/problem_utils.jl:2059
 [5] get_p
   @ ~/.julia/packages/ModelingToolkitBase/uIKoY/src/systems/problem_utils.jl:2048 [inlined]
 [6] generate_f_h(model::System, inputs::Vector{Num}, outputs::Vector{Num})
   @ Main ~/.julia/dev/ModelPredictiveControl/docs/src/manual/mtk.md:91
 [7] top-level scope
   @ ~/.julia/dev/ModelPredictiveControl/docs/src/manual/mtk.md:96
Some type information was truncated. Use `show(err)` to see complete types.

If I do print(bindings(io_sys)), it prints a dict with only the τ key and the value is missing:

ReadOnlyDicts.ReadOnlyDict{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}, SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}, ModelingToolkitBase.AtomicArrayDict{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}, Dict{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}, SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}}}}(τ(t) => missing)

@baggepinnen
Copy link
Member

You should pass a varmap as the second argument, bindings should not be used

@franckgaga
Copy link
Member Author

And how do I get the varmap of the 4 parameters ? I tried passing p_sym directly and it does not work, the error is ArgumentError: The operating_point passed to the problem constructor must be a symbolic map.

Nothing about this in the documentation also.

@baggepinnen
Copy link
Member

a varmap is just

op = Dict(p1 => val1, p2 => val2, ...)

@franckgaga
Copy link
Member Author

Alright thanks, but I still need to access the current value that I set at the line @parameters g=9.8 L=0.4 K=1.2 m=0.3, how do I access them ?

@baggepinnen
Copy link
Member

@franckgaga
Copy link
Member Author

Not sure this is the good way of proceeding, constructing an ODEProblem just to extract the parameter vector.

I read the wall of text about this in the documentation here : https://docs.sciml.ai/ModelingToolkit/stable/tutorials/initialization/

Two observations:

  1. I'm completely lost, way too long and completely unreadable by someone who is not familiar with MTK internals. Pretty sure a good portion of it was written by LLMs...
  2. It seems that the only example about the initialization of parameters defined with @parameters p1=1 p2=4.3 is simply disable and not executed in the doc deployement. My feeling is this feature is not ready. So I think the right move is to wait before updating my pendulum example to v11.

@franckgaga franckgaga closed this Mar 24, 2026
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

Successfully merging this pull request may close these issues.

3 participants