Closed bradcarman closed 2 months ago
The problem here is that in MassSpringDamper
, there is no @parameters damping = damping
like there is for the other parameters. This is because a variable can't have a "double ParentScope
" metadata.
When @named wheel = MassSpringDamper(; mass=4*wheel_mass, gravity, damping=wheel_damping, stiffness=wheel_stiffness, initial_position=0.5)
is done, wheel_damping
gets its SymScope
metadata set to ParentScope
, indicating that it is a variable from the parent of the system it is being passed to (and thus shouldn't be namespaced). If it is aliased to a new parameter inside MassSpringDamper
via @parameters damping = damping
, then damping
doesn't have the SymScope
metadata, so when it is passed to Damper
, it gets assigned ParentScope
. Without the aliasing,ParentScope
can't be applied twice to wheel_damping
which is why Damper
thinks the variable is from MassSpringDamper
and not System
.
The long explanation is only to document the error and find a solution. It is definitely not something I'd expect a user to be concerned with, and we should either throw an error in such a scenario or handle it properly. I think DelayParentScope
should be used here.
Here's another example that throws the same error, but I'm not sure if the same explanation as to why applies
using ModelingToolkit
using ModelingToolkitStandardLibrary: Blocks
gravity = 9.81
gain_u1 = 0.89 / 1.4
d0 = 70
d1 = 17
n0 = 55
@named motor_dynamics = Blocks.FirstOrder(T = 0.001)
x0 = [0.85, 1, π/12, π/2]
@parameters t
@variables u(t)[1:2]=0
u = collect(u)
@variables y(t)=0.85 v(t)=1 ϕ(t)=π/12 ω(t)=π/2
D = Differential(t)
eqs = [
D(y) ~ v,
D(v) ~ -gravity + gain_u1 * cos(ϕ)*(motor_dynamics.output.u + gravity/gain_u1),
D(ϕ) ~ ω,
D(ω) ~ -d0 * ϕ - d1 * ω + n0 * u[2],
motor_dynamics.input.u ~ u[1]
]
@named model = ODESystem(eqs, t; systems=[motor_dynamics])
linearize(model, collect(u), [y, v, ϕ, ω])
julia> linearize(model, collect(u), [y, v, ϕ, ω])
ERROR: ArgumentError: v(t) is neither an observed nor an unknown variable.
Stacktrace:
[1] build_explicit_observed_function(sys::NonlinearSystem, ts::Vector{…}; inputs::Nothing, expression::Bool, output_type::Type, checkbounds::Bool, drop_expr::typeof(RuntimeGeneratedFunctions.drop_expr), ps::Vector{…}, return_inplace::Bool, op::Type, throw::Bool)
@ ModelingToolkit ~/.julia/dev/ModelingToolkit/src/systems/diffeqs/odesystem.jl:451
[2] build_explicit_observed_function(sys::NonlinearSystem, ts::Vector{SymbolicUtils.BasicSymbolic{Real}})
@ ModelingToolkit ~/.julia/dev/ModelingToolkit/src/systems/diffeqs/odesystem.jl:378
[3] observed(sys::NonlinearSystem, sym::Vector{SymbolicUtils.BasicSymbolic{Real}})
@ ModelingToolkit ~/.julia/dev/ModelingToolkit/src/systems/abstractsystem.jl:534
[4] _getu(sys::NonlinearSystem, ::SymbolicIndexingInterface.NotSymbolic, ::SymbolicIndexingInterface.ScalarSymbolic, sym::Vector{…})
@ SymbolicIndexingInterface ~/.julia/packages/SymbolicIndexingInterface/A1VUA/src/state_indexing.jl:158
[5] getu(sys::NonlinearSystem, sym::Vector{SymbolicUtils.BasicSymbolic{Real}})
@ SymbolicIndexingInterface ~/.julia/packages/SymbolicIndexingInterface/A1VUA/src/state_indexing.jl:32
[6] linearization_function(sys::ODESystem, inputs::Vector{…}, outputs::Vector{…}; simplify::Bool, initialize::Bool, op::Dict{…}, p::SciMLBase.NullParameters, zero_dummy_der::Bool, initialization_solver_alg::NonlinearSolve.GeneralizedFirstOrderAlgorithm{…}, kwargs::@Kwargs{})
@ ModelingToolkit ~/.julia/dev/ModelingToolkit/src/systems/abstractsystem.jl:1965
[7] linearization_function
@ ~/.julia/dev/ModelingToolkit/src/systems/abstractsystem.jl:1867 [inlined]
[8] linearize(sys::ODESystem, inputs::Vector{…}, outputs::Vector{…}; op::Dict{…}, t::Float64, allow_input_derivatives::Bool, zero_dummy_der::Bool, kwargs::@Kwargs{})
@ ModelingToolkit ~/.julia/dev/ModelingToolkit/src/systems/abstractsystem.jl:2325
[9] linearize(sys::ODESystem, inputs::Vector{Num}, outputs::Vector{Num})
@ ModelingToolkit ~/.julia/dev/ModelingToolkit/src/systems/abstractsystem.jl:2321
[10] top-level scope
@ REPL[3]:1
Some type information was truncated. Use `show(err)` to see complete types.
My example in the post above no longer errors
Example in OP now errors with
julia> prob = ODEProblem(sys, [], (0, 1), [sys.Kp=>1, sys.Ki=>1, sys.Kd=>1, sys.seat_stiffness=>1])
ERROR: Could not evaluate value of parameter car_and_suspension₊d₊d. Missing values for variables in expression car_and_suspension₊suspension_damping.
Stacktrace:
And I think that error is a good statement for what @AayushSabharwal said, so I think this is good to go.
Using
remake
on the below model causes an error about "neither an observed nor an unknown variable"This gives the error..
Note: the error occurs regardless of the parameter that is set in
remake
Environment: