Hi, I am trying to understand to basic functions from ControlSystems package. Especially step() is mystery for me. In some cases this function predicts the simulation time to plot the whole response well, in others it simulates only few seconds (if not specified final time). For stable process, of course.
However, my biggest issue is about simulation of delayed systems. Here I share two similar cases - one works fine, the other one does not.
using Plots;
using ControlSystems;
WORKS = 1; # switch between 0,1: 1-works fine
# 0-doesn't work
s = tf("s");
if WORKS == 1
P = 1 / (0.85*s + 1)*exp(-0.15*s);
elseif WORKS == 0
P = 1 / (0.85*s + 1)*exp(-0.14*s);
end
display(nyquistplot(P)); #always works
y, t = step(P);
display(plot(t, y'));
The only difference is in dead time of the process, but for the numbers closer to 0 an error occures after calling step() function.
#=
ERROR in the case of WORKS=0
┌ Warning: dt(2.220446049250313e-16) <= dtmin(2.220446049250313e-16) at t=1.4000000000000001. Aborting. There is either an error in your model specification or the true solution is unstable.
└ @ SciMLBase C:...\.julia\packages\SciMLBase\chsnh\src\integrator_interface.jl:366
ERROR: BoundsError: attempt to access 21-element Vector{Tuple{Vector{Float64}, Vector{Float64}}} at index [22]
Stacktrace:
[1] getindex
@ .\array.jl:861 [inlined]
[2] _lsim(sys::DelayLtiSystem{Float64, Float64}, u!::Any, t::StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, x0::Vector{Float64}, alg::DelayDiffEq.MethodOfSteps{OrdinaryDiffEq.Tsit5{typeof(OrdinaryDiffEq.trivial_limiter!), typeof(OrdinaryDiffEq.trivial_limiter!), Static.False}, DiffEqBase.NLFunctional{Rational{Int64}, Rational{Int64}}, false}; kwargs::Base.Pairs{Symbol, Float64, Tuple{Symbol, Symbol}, NamedTuple{(:abstol, :reltol), Tuple{Float64, Float64}}})
@ ControlSystems C:...\.julia\packages\ControlSystems\J1JEd\src\delay_systems.jl:204
[3] lsim(sys::DelayLtiSystem{Float64, Float64}, u::ControlSystems.var"#327#328", t::StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}; x0::Vector{Float64}, alg::DelayDiffEq.MethodOfSteps{OrdinaryDiffEq.Tsit5{typeof(OrdinaryDiffEq.trivial_limiter!), typeof(OrdinaryDiffEq.trivial_limiter!), Static.False}, DiffEqBase.NLFunctional{Rational{Int64}, Rational{Int64}}, false}, abstol::Float64, reltol::Float64, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ ControlSystems C:...\.julia\packages\ControlSystems\J1JEd\src\delay_systems.jl:98
[4] step(sys::DelayLtiSystem{Float64, Float64}, t::StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ ControlSystems C:...\.julia\packages\ControlSystems\J1JEd\src\delay_systems.jl:247
[5] step
@ C:...\.julia\packages\ControlSystems\J1JEd\src\delay_systems.jl:240 [inlined]
[6] #step#185
@ C:...\.julia\packages\ControlSystems\J1JEd\src\timeresp.jl:66 [inlined]
[7] step(sys::DelayLtiSystem{Float64, Float64})
@ ControlSystems C:...\.julia\packages\ControlSystems\J1JEd\src\timeresp.jl:66
[8] top-level scope
@ c:\...\why_step_doesnt_work.jl:17
=#