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

State space may not contain all states when there are zeros in the matrix entries #125

Open
baggepinnen opened this issue Nov 4, 2022 · 2 comments

Comments

@baggepinnen
Copy link
Contributor

In the following example, there are three inputs passed along to io_preprocessing which in turn calls structural_simplify. All three inputs are present as states in the system upon calling io_preprocessing. Before markio! is called within structural_simplify, one of the inputs, (model₊input₊u(t))[2] has been removed from fullvars, leading to the error below:

ERROR: Some specified inputs were not found in system. The following Dict indicates the found variables
Dict{Num, Bool}(
    u(t) => 1,
    (model₊input₊u(t))[2] => 0,
    d(t) => 1
)
Stacktrace:
 [1] error(::String, ::Dict{Num, Bool})
   @ Base ./error.jl:44
 [2] markio!(state::TearingState{ODESystem}, inputs::Vector{Num}, outputs::Vector{Any}; check::Bool)
using ModelingToolkitStandardLibrary.Blocks
A,C = [randn(2,2) for i in 1:2]
B = [1.0 0; 0 0]
@named model = Blocks.StateSpace(A,B,C)
@named integrator = Blocks.StateSpace( [-0.001;;], [1.0;;], [1.0;;], [0.0;;])
ins = collect(model.input.u)
disturbed_input = ins[1]
@named dist_integ = ModelingToolkit.DisturbanceModel(disturbed_input, integrator)
function add_input_disturbance_(sys, dist::DisturbanceModel, inputs)
    t = ModelingToolkit.get_iv(sys)
    @variables d(t)=0 [disturbance = true]
    @variables u(t)=0 [input = true] # Potential new system input
    dsys = ModelingToolkit.get_disturbance_system(dist)
    all_inputs = inputs
    all_inputs = Base.setindex(all_inputs, u, findfirst(isequal(dist.input), inputs)) # The input where the disturbance acts is no longer an input, the new 
    eqs = [dsys.input.u[1] ~ d
           dist.input ~ u + dsys.output.u[1]]
    augmented_sys = ODESystem(eqs, t, systems = [sys, dsys], name = gensym(:outer))

    ModelingToolkit.generate_control_function(augmented_sys, all_inputs, [d])
end

add_input_disturbance_(model, dist_integ, ins)
@YingboMa
Copy link
Member

YingboMa commented Nov 4, 2022

This doesn't have anything to do with tearing solving inputs. It's because B[2,2]==0 so we get

julia> equations(model)
4-element Vector{Equation}:
 Differential(t)((x(t))[1]) ~ 1.4127911057946012(x(t))[1] + 1.6442707924892608(x(t))[2] + (input₊u(t))[1]
 Differential(t)((x(t))[2]) ~ 0.9732693843806025(x(t))[1] + 1.8506489974903615(x(t))[2]
 (output₊u(t))[1] ~ -0.27319983060901565(x(t))[1] - 0.028715875023662633(x(t))[2]
 (output₊u(t))[2] ~ 0.46630447252950014(x(t))[1] - 0.4643074023821421(x(t))[2]

and note that (input₊u(t))[2] appear in the system. If you need to assume all states still exist, then I suggest to keep A, B, C, and D parameters making all variables structurally visible. But then, MTK could accidentally divide by 0. Or, just simply remove the check in IO.

@YingboMa YingboMa transferred this issue from SciML/ModelingToolkit.jl Nov 4, 2022
@YingboMa YingboMa changed the title tearing may remove inputs before they have been marked as inputs by markio! State space may not contain all states when there are zeros in the matrix entries Nov 4, 2022
@YingboMa
Copy link
Member

YingboMa commented Nov 4, 2022

Alternatively, you need to filter ins = collect(model.input.u) based on B

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