Hello all. I am trying to create a Schmitt trigger component in ModelingToolkit.jl. Specifically the circuit in the image below (source):
I am using the IdealOpAmp
component from the MTK standard library, I am assuming it is setup in the same way as the figure below (source):
However I am running into some problems with my code:
using ModelingToolkit
using ModelingToolkitStandardLibrary
using DifferentialEquations
using Plots
const B = ModelingToolkitStandardLibrary.Blocks
const E = ModelingToolkitStandardLibrary.Electrical
@parameters t
@named R1 = E.Resistor(R = 1)
@named R2 = E.Resistor(R = 2)
@named voltage_signal = B.Sine(frequency=1, amplitude=10)
@named source = E.Voltage()
@named op_amp = E.IdealOpAmp()
@named ground = E.Ground()
@named output_pin = E.OnePort()
eqs = [
connect(voltage_signal.output, source.V)
connect(source.p, R1.p)
connect(source.n, ground.g)
connect(R1.n, op_amp.p1)
connect(R1.n, R2.p)
connect(ground.g, op_amp.n1)
connect(ground.g, op_amp.n2)
connect(R2.n, output_pin.p)
connect(op_amp.p2, output_pin.p)
connect(output_pin.n, ground.g)
]
@named model = ODESystem(
eqs, t; systems = [R1, R2, voltage_signal, source, op_amp, ground, output_pin]
)
sys = structural_simplify(model)
prob = ODEProblem(sys, [], (0, 10.0), [])
I get the following error when running the ODEProblem
function:
ArgumentError: Equations (1) and states (0) are of different lengths. To allow these to differ use kwarg check_length=false.
#check_eqs_u0#150@abstractsystem.jl:1672[inlined]
var"#process_DEProblem#548"(::Bool, ::Nothing, ::Nothing, ::Bool, ::Bool, ::Bool, ::Bool, ::Bool, ::Bool, ::Symbolics.SerialForm, ::Bool, ::Bool, ::Bool, ::Base.Pairs{Symbol, Integer, Tuple{Symbol, Symbol, Symbol}, NamedTuple{(:t, :has_difference, :check_length), Tuple{Int64, Bool, Bool}}}, ::typeof(ModelingToolkit.process_DEProblem), ::Type, ::ModelingToolkit.ODESystem, ::Vector{Any}, ::Vector{Any})@abstractodesystem.jl:621
var"#_#555"(::Nothing, ::Bool, ::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::Type{SciMLBase.ODEProblem{true, SciMLBase.AutoSpecialize}}, ::ModelingToolkit.ODESystem, ::Vector{Any}, ::Tuple{Int64, Float64}, ::Vector{Any})@abstractodesystem.jl:719
ODEProblem@abstractodesystem.jl:712[inlined]
#_#553@abstractodesystem.jl:699[inlined]
ODEProblem@abstractodesystem.jl:698[inlined]
#ODEProblem#552@abstractodesystem.jl:695[inlined]
ODEProblem@abstractodesystem.jl:694[inlined]
top-level scope@Local: 1[inlined]
Setting the keyword argument check_length=false
results in another error when running solve
:
Mass matrix size is incompatible with initial condition
sizing. The mass matrix must represent the `vec`
form of the initial condition `u0`, i.e.
`size(mm,1) == size(mm,2) == length(u)`
size(prob.f.mass_matrix,1): 1
length(u0):
Some of the types have been truncated in the stacktrace for improved reading. To emit complete information
in the stack trace, evaluate `TruncatedStacktraces.VERBOSE[] = true` and re-run the code.
get_concrete_u0@solve.jl:1197[inlined]
var"#get_concrete_problem#46"(::Base.Pairs{Symbol, Union{Nothing, Vector{Float64}}, Tuple{Symbol, Symbol}, NamedTuple{(:u0, :p), Tuple{Nothing, Vector{Float64}}}}, ::typeof(DiffEqBase.get_concrete_problem), ::SciMLBase.ODEProblem{Nothing, Tuple{Float64, Float64}, true, Vector{Float64}, SciMLBase.ODEFunction{true, SciMLBase.AutoSpecialize, ModelingToolkit.var"#f#522"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0xb7b77d1d, 0x7ab1eaa7, 0x99752a83, 0x405ba9ae, 0xa2972979), Expr}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x25da9c91, 0x42425f27, 0xecfdcda6, 0x60e772c3, 0xcf06bdb2), Expr}}, Matrix{Float64}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Vector{Any}, Symbol, Vector{Symbol}, ModelingToolkit.var"#570#generated_observed#530"{Bool, ModelingToolkit.ODESystem, Dict{Any, Any}}, Nothing, ModelingToolkit.ODESystem}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, SciMLBase.StandardODEProblem}, ::Bool)@solve.jl:1059
get_concrete_problem@solve.jl:1056[inlined]
#solve_up#30@solve.jl:969[inlined]
solve_up@solve.jl:945[inlined]
#solve#28@solve.jl:882[inlined]
solve@solve.jl:872[inlined]
top-level scope@Local: 1[inlined]
I am not an expert with electronic circuits, so I am unsure if my connections are setup correctly. Or let me know if there are other/better ways to model the behaviour of a Schmitt trigger using MTK. Any help with this would be greatly appreciated, thank you!