diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1a7d65c6c9c054b691b33dc7ce9539d52a4f16eb..1180735158dfb0eb5754f949dd7748895b621c62 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -14,13 +14,12 @@ script: # Let's run the tests. Substitute `coverage = false` below, if you do not # want coverage results. - # - /opt/julia/bin/julia -e 'Pkg.clone(pwd()); Pkg.test("BallAndBeam", - # coverage = true)' - - /opt/julia/bin/julia -e 'Pkg.update();Pkg.test("BallAndBeam", coverage = true)' + - /opt/julia/bin/julia -e 'Pkg.rm("BallAndBeam");Pkg.clone(pwd()); Pkg.test("BallAndBeam",coverage = false)' + #- /opt/julia/bin/julia -e 'Pkg.update();Pkg.test("BallAndBeam", coverage = true)' # Comment out below if you do not want coverage results. - - /opt/julia/bin/julia -e 'Pkg.add("Coverage"); cd(Pkg.dir("BallAndBeam")); - using Coverage; cl, tl = get_summary(process_folder()); - println("(", cl/tl*100, "%) covered")' + #- /opt/julia/bin/julia -e 'Pkg.add("Coverage"); cd(Pkg.dir("BallAndBeam")); + # using Coverage; cl, tl = get_summary(process_folder()); + # println("(", cl/tl*100, "%) covered")' # Name a test and select an appropriate image. test:0.6.0: diff --git a/README.md b/README.md index 7592e7b06860ff063d31af5c4fa9dec55fc932e0..b82a5eaa05cfc7a2df5bd531f065ebdb6563063b 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ +[](https://gitlab.control.lth.se/processes/BallAndBeam.jl/commits/master) +[](https://gitlab.control.lth.se/processes/BallAndBeam.jl/commits/master) + # Installation (specific to lab 1 FRTN35: Frequency response analysis) 1. Open a terminal 2. Type `mkdir FRTN35_lab1; cd FRTN35_lab1` diff --git a/src/BallAndBeam.jl b/src/BallAndBeam.jl index ec52790d3e654f46373403b0d3febcb717e5898c..2d185fd95d9151d853c354674aa26dc53e641e91 100644 --- a/src/BallAndBeam.jl +++ b/src/BallAndBeam.jl @@ -16,7 +16,7 @@ module BallAndBeam export run_experiment, fra, sortfqs, bopl, bopl!, nypl, nypl!, plot, fbdesign, ffdesign, opendoc -export init_sysfilter, sysfilter!, run_control_2DOF # For documentation +export SysFilter, run_control_2DOF # For documentation using LabProcesses, Plots, Polynomials, ControlSystems, ProgressMeter @@ -139,7 +139,7 @@ nypl(G; kwargs...) = (plot();nypl!(G;kwargs...)) sysFB,L,T,C = fbdesign(G::AbstractMatrix, polevect, zerovect, gain) Frequency Compensation to determine polynominals in compensator C=S/R. Frequency responses for loop transfer, closed loop and controller are calculated. -`sys` is of type `StateSpace`, to be used together with [`sysfilter!`](@ref) +`sys` is of type `StateSpace`, to be used together with [`SysFilter!`](@ref) `G` is a frequency response matrix with ω in the first column and G(iω) in the second. """ function fbdesign(G::AbstractMatrix, polevect, zerovect, gain) @@ -156,7 +156,7 @@ end sysFF,YR,FF = ffdesign(G, polevect, zerovect, gain) Feedforward filter BFF/AFF to shape transfer function from `r` to `y`. Frequency responses for closed loop with FF-filter and FF-filter are calculated. -`sys` is of type `StateSpace`, to be used together with [`sysfilter!`](@ref) +`sys` is of type `StateSpace`, to be used together with [`SysFilter!`](@ref) """ function ffdesign(G, polevect, zerovect, gain) sysFF,YR,_,FF = fbdesign(G, polevect, zerovect, gain) @@ -179,20 +179,15 @@ function opendoc() run(`xdg-open $docpath`) end -""" - state = init_sysfilter(sys::StateSpace) -Use together with [`sysfilter!`](@ref) -""" -init_sysfilter """ - output = sysfilter!(state, sys::StateSpace, input) -Returns the filtered output `y` in `y = Cx+Du, x'=Ax+Bu` - -This function is used to implement control loops where a signal is filtered through a -dynamical system, i.e., `U(z) = C(z)E(z)`. Initialize `state` using [`init_sysfilter`](@ref). + Csf = SysFilter(sys::StateSpace) +Returns an object used for filtering signals through LTI systems. +Create a SysFilter object that can be used to implement control loops and simulators +with LTI systems, i.e., `U(z) = C(z)E(z)`. To filter a signal `u` through the filter, +call like `y = Csf(u)`. Calculates the filtered output `y` in `y = Cx+Du, x'=Ax+Bu` """ -sysfilter! +SysFilter """ y,u,r = run_control_2DOF(process, sysFB[, sysFF]; duration = 10, reference(t) = sign(sin(2π*t))) diff --git a/src/FRTN35_lab1.jl b/src/FRTN35_lab1.jl index 623de70fb239dc626e2ae3ee30c1fe4a786ee326..2d4860e3718eefe9278470ba9db62b3c652d6a08 100644 --- a/src/FRTN35_lab1.jl +++ b/src/FRTN35_lab1.jl @@ -77,6 +77,6 @@ nb = 2 # Order of B polynomial arxtf = arx(h, y, u, na, nb) # Estimate trasfer function with ARX method mag, phase, ω = bode(arxtf, logspace(-1,3,200)) -bopl(G1, lab="Measured transfer function") +bopl(G123, lab="Measured transfer function") plot!(ω, mag[:], subplot=1, lab = "ARX estimate") plot!(ω, phase[:], subplot=2) diff --git a/src/arx.jl b/src/arx.jl index f670c20b1cff6404fc73c6b4410215234457986f..5eecff1bb446b67e8cb6300696eccd17358670f8 100644 --- a/src/arx.jl +++ b/src/arx.jl @@ -86,10 +86,8 @@ function arx(h,y::AbstractVector{Float64}, u::AbstractVector{Float64}, na, nb; if λ == 0 w = A\y_train - method = :LS else w = (A'A + λ*eye(size(A,2)))\A'y_train - method = :LS_reg end a = [1; -w[1:na]] diff --git a/test/runtests.jl b/test/runtests.jl index ccd72776ab913fc6e4f28a588cc660168588281c..da621af70840675041437e0afb30791a2762892e 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -6,22 +6,7 @@ P = LabProcesses.Beam(0.01,0.) h = sampletime(P) @test h == 0.01 -function test_sysfilter() - N = 10 - u = randn(N) - b = [1, 1] - a = [1, 0.1, 1] - sys = ss(tf(b,a,1)) - state = init_sysfilter(sys) - yf = filt(b,a,u) - yff = similar(yf) - for i in eachindex(u) - yff[i] = sysfilter!(state, sys, u[i])[1] - end - @test sum(abs,yf - yff) < √(eps()) -end -test_sysfilter() settling_time = 1 nbr_of_periods = 5 @@ -61,7 +46,7 @@ nbr_of_periods = 2 w1_100 = logspace(-1,log10(300),500) G1 = fra(P, w1_100, amplitude=1, nbr_of_periods=nbr_of_periods, settling_time=settling_time) -true_resp = freqresp(P.sys, w1_100) +true_resp = freqresp(P.s.sys, w1_100) @test sum(abs, log.(abs.(G1[:,2])) - log.(abs.(true_resp[1][:]))) < 3.2 # Some numerical errors expected phase_id = angle.(G1[:,2]) |> ControlSystems.unwrap phase_true = angle.(true_resp[1][:]) |> ControlSystems.unwrap @@ -87,7 +72,7 @@ nb = 5 arxtf = arx(h, y[:], u, na, nb; λ = 0) w1_100 = logspace(-1,log10(100),500) -true_resp = freqresp(P.sys, w1_100) +true_resp = freqresp(P.s.sys, w1_100) phase_true = angle.(true_resp[1][:]) |> ControlSystems.unwrap arx_resp = freqresp(arxtf, w1_100) @test sum(abs, log.(abs.(arx_resp[1][:])) - log.(abs.(true_resp[1][:]))) < 1.25