diff --git a/Project.toml b/Project.toml index 3109f74f..504fd7a5 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "ControlSystemIdentification" uuid = "3abffc1c-5106-53b7-b354-a47bfc086282" -version = "2.12.0" +version = "2.12.1" authors = ["baggepinnen "] [deps] diff --git a/src/frd.jl b/src/frd.jl index 4783fe03..d968e57b 100644 --- a/src/frd.jl +++ b/src/frd.jl @@ -91,11 +91,12 @@ end Base.lastindex(f::FRD) = length(f) function Base.getproperty(f::FRD, s::Symbol) s === :Ts && return π / maximum(f.w) + s === :timeevol && return Continuous() s === :nu && return ninputs(f) s === :ny && return noutputs(f) getfield(f, s) end -Base.propertynames(f::FRD, private::Bool = false) = (fieldnames(typeof(f))..., :Ts) +Base.propertynames(f::FRD, private::Bool = false) = (fieldnames(typeof(f))..., :Ts, :timeevol, :nu, :ny) function Base.show(io::IO, frd::FRD) write(io, "Frequency (rad/s)\n") @@ -120,7 +121,7 @@ function ControlSystemsBase.bode(f::FRD, w::AbstractVector = f.w; unwrap=true) reshape(abs.(f.r), f.ny, f.nu, :), angles, f.w end -function ControlSystemsBase.freqresp(f::FRD, w::AbstractVector{W} = f.w) where W <: Real +function ControlSystemsBase.freqresp(f::FRD, w::AbstractVector{W} = f.w; kwargs...) where W <: Real # kwargs such as balance do not apply to frequency-response data w == f.w || error("Frequency vector must match the one stored in the FRD") reshape(f.r, f.ny, f.nu, :) end diff --git a/src/subspace.jl b/src/subspace.jl index db3c6248..3a33b674 100644 --- a/src/subspace.jl +++ b/src/subspace.jl @@ -247,7 +247,7 @@ end m2vv(x) = collect.(eachcol(x)) -function LowLevelParticleFilters.forward_trajectory(kf::LowLevelParticleFilters.AbstractFilter, d::AbstractIdData, p=parameters(kf)) +function LowLevelParticleFilters.forward_trajectory(kf::LowLevelParticleFilters.AbstractFilter, d::AbstractIdData, p=LowLevelParticleFilters.parameters(kf)) y = time2(output(d)) u = input(d) U = m2vv(u) @@ -255,7 +255,7 @@ function LowLevelParticleFilters.forward_trajectory(kf::LowLevelParticleFilters. forward_trajectory(kf, U, Y, p) end -function LowLevelParticleFilters.smooth(kf::LowLevelParticleFilters.AbstractFilter, d::AbstractIdData, p=parameters(kf)) +function LowLevelParticleFilters.smooth(kf::LowLevelParticleFilters.AbstractFilter, d::AbstractIdData, p=LowLevelParticleFilters.parameters(kf)) y = time2(output(d)) u = input(d) U = m2vv(u) @@ -263,7 +263,7 @@ function LowLevelParticleFilters.smooth(kf::LowLevelParticleFilters.AbstractFilt LowLevelParticleFilters.smooth(kf, U, Y, p) end -function LowLevelParticleFilters.smooth(kf::LowLevelParticleFilters.AbstractFilter, M::Int, d::AbstractIdData, p=parameters(kf)) +function LowLevelParticleFilters.smooth(kf::LowLevelParticleFilters.AbstractFilter, M::Int, d::AbstractIdData, p=LowLevelParticleFilters.parameters(kf)) y = time2(output(d)) u = input(d) U = m2vv(u) diff --git a/test/test_basis_functions.jl b/test/test_basis_functions.jl index 65ce0298..591b0a02 100644 --- a/test/test_basis_functions.jl +++ b/test/test_basis_functions.jl @@ -9,7 +9,7 @@ for basis in [kautz(av), laguerre(1,n), laguerre_oo(1,n), adhocbasis(av)] F = sum_basis(basis, p) fr1 = freqresp(F, w) |> vec fr2 = freqresp(tf(1), basis, w, p) |> vec - @test norm(fr1-fr2) < 1e-10 + @test norm(fr1-fr2) < 2e-9 @test basislength(basis) == n end basis = laguerre_oo(1,n) diff --git a/test/test_frd.jl b/test/test_frd.jl index 2ba4b55d..bd2da1c8 100644 --- a/test/test_frd.jl +++ b/test/test_frd.jl @@ -176,6 +176,8 @@ frd = FRD(w, G); # Build a frequency-response data object @test bode(frd) == bode(G, w) @test nyquist(frd) == nyquist(G, w) +@test ControlSystemsBase.iscontinuous(frd) +@test freqresp(frd, w; balance = false) == freqresp(frd) @test size([frd frd]) == (ny, 2nu) @test size([frd; frd]) == (2ny, nu) diff --git a/test/test_subspace.jl b/test/test_subspace.jl index acbdba82..ef0bdb14 100644 --- a/test/test_subspace.jl +++ b/test/test_subspace.jl @@ -166,6 +166,13 @@ end @test kf.B == res.B @test kf.C == res.C + sol = ControlSystemIdentification.LowLevelParticleFilters.forward_trajectory(kf, d) + @test length(sol.x) == length(d) + if pkgversion(ControlSystemIdentification.LowLevelParticleFilters) >= v"3.33.1" # Earlier versions dispatch smooth(::KalmanFilter, ::AbstractIdData) to their own method + ssol = ControlSystemIdentification.LowLevelParticleFilters.smooth(kf, d) + @test length(ssol.xT) == length(d) + end + end # Test u scaling