-
Notifications
You must be signed in to change notification settings - Fork 85
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
WIP: Delayed LTI #178
WIP: Delayed LTI #178
Conversation
# TODO: Think through these promotions and conversions | ||
Base.promote_rule(::Type{<:StateSpace{T1}}, ::Type{DelayLtiSystem{T2}}) where {T1<:Number,T2<:Number} = DelayLtiSystem{promote_type(T1,T2)} | ||
Base.promote_rule(::Type{AbstractMatrix{T1}}, ::Type{DelayLtiSystem{T2}}) where {T1<:Number,T2<:Number} = DelayLtiSystem{promote_type(T1,T2)} | ||
Base.promote_rule(::Type{T1}, ::Type{DelayLtiSystem{T2}}) where {T1<:Number,T2<:Number} = DelayLtiSystem{promote_type(T1,T2)} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These should probably be caught somewhere else by
Type{AbstractMatrix}, ::Type{<:LTISystem}
and
Type{<:Number}, ::Type{<:LTISystem}
DelayLtiSystem(psys_new.P, Tau_new) | ||
end | ||
|
||
function delay(tau::Real, T::Type{<:Number}=Float64) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this the canonical way, or maybe we should have:
delay(tau::T) where T<:Real
and
delay(::Type{T}, tau::Real) where T<:Number
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, any of those options are probably better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is delay
a reasonable name for the function? It seems quite appropriate, but another option would be exp(-tau*tf("s")
. However this transfer function notation is a bit unfortunate since time delays and transfer functions tend to be numerically troublesome.
@@ -4,6 +4,9 @@ abstract type LTISystem <: AbstractSystem end | |||
*(sys1::LTISystem, sys2::LTISystem) = *(promote(sys1, sys2)...) | |||
/(sys1::LTISystem, sys2::LTISystem) = /(promote(sys1, sys2)...) | |||
|
|||
feedback(sys1::Union{LTISystem,Number,AbstractMatrix{<:Number}}, | |||
sys2::Union{LTISystem,Number,AbstractMatrix{<:Number}}) = feedback(promote(sys1, sys2)...) | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should think about being consistent here, but that discussion probably belongs elsewehere.
For /(sys1::LTISystem, sys2::LTISystem) = /(promote(sys1, sys2)...)
we dont allow matrices and scalars (and assume the specific implementation will solve it), but for
feedback
we provide a fallback here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think there are many places where more we should be more consistent.
src/types/PartionedStateSpace.jl
Outdated
|
||
|
||
# There should already exist a function like this somewhare? | ||
function blkdiag(A1::Matrix{T1}, A2::Matrix{T2}) where {T1<:Number, T2<:Number} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AbstractMatrix
maybe for future-proofing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although we would have to figure out a way of constructing the new matrix to be the promotetype, which might be tricky. So maybe we skip that
example/delayed_lti_timeresp.jl
Outdated
sys = feedback(1.0, ss(-1.0, 2, 1, 0) * (delay(2.0) + delay(3.0) + delay(2.5))) | ||
|
||
t = 0:0.02:8 | ||
@time t, x, y = lsim(sys, t; u=t->[t>=0 ? 1.0 : 0.0]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@time t, x, y = lsim(sys, t; u=t->[t>=0 ? 1.0 : 0.0]) | |
t, x, y = lsim(sys, t; u=t->[t>=0 ? 1.0 : 0.0]) |
gues this was a leftover from your benchmarking?
src/ControlSystems.jl
Outdated
@@ -75,9 +78,11 @@ export LTISystem, | |||
|
|||
|
|||
# QUESTION: are these used? LaTeXStrings, Requires, IterTools | |||
using Polynomials, OrdinaryDiffEq, Plots, LaTeXStrings, LinearAlgebra | |||
using Polynomials, Plots, LaTeXStrings, LinearAlgebra | |||
using DifferentialEquations, OrdinaryDiffEq, DelayDiffEq |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't DifferentialEquations
an umbrella that exports everything else?
src/types/DelayLtiSystem.jl
Outdated
ny = noutputs(sys) - length(Tau) | ||
|
||
if nu < 0 || ny < 0 | ||
error("Time vector is too long.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
error("Time vector is too long.") | |
throw(ArgumentError("Time vector is too long.")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the difference here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An argument error is more informative, and people doing error handling in applications sometimes rely on the proper type of error being thrown. See https://discourse.julialang.org/t/error-vs-throw-argumenterror/18915
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Being more specific also allows you to write tests with @test_throws that don’t just pass spuriously if the same type of error is thrown in some other part of the code under test.
ssold = sys.P.P | ||
# Add to direct term from input to output | ||
new_D = ssold.D | ||
new_D[1:ny, 1:nu] .+= n |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't do broadcast
…jl into pr-178/JuliaControl/delayed_lti
I rebased this on master, I think I managed to pull it off without screwing up. |
Do not pull yet, still WIP
List of problems, feel free to add to it:
Should be resolved:
Would be nice to have: