Skip to content
Snippets Groups Projects
Commit 9f416c0e authored by Fredrik Bagge Carlson's avatar Fredrik Bagge Carlson
Browse files

updates to julia1

parent d2d6019f
No related branches found
No related tags found
1 merge request!3Julia1
Pipeline #667 failed
...@@ -5,3 +5,4 @@ Polynomials ...@@ -5,3 +5,4 @@ Polynomials
ProgressMeter ProgressMeter
JLD JLD
Documenter Documenter
DSP
using Pkg
installed_packages = Pkg.installed() installed_packages = Pkg.installed()
if "LabProcesses" keys(installed_packages) if "LabProcesses" keys(installed_packages)
Pkg.clone("https://gitlab.control.lth.se/processes/LabProcesses.jl.git") Pkg.clone("https://gitlab.control.lth.se/processes/LabProcesses.jl.git")
...@@ -19,7 +20,7 @@ bopl, bopl!, nypl, nypl!, plot, fbdesign, ffdesign, opendoc ...@@ -19,7 +20,7 @@ bopl, bopl!, nypl, nypl!, plot, fbdesign, ffdesign, opendoc
export SysFilter, run_control_2DOF # For documentation export SysFilter, run_control_2DOF # For documentation
using LabProcesses, Plots, Polynomials, ControlSystems, ProgressMeter using LabProcesses, Plots, Polynomials, ControlSystems, ProgressMeter, DSP, LinearAlgebra, Statistics
include("arx.jl") include("arx.jl")
...@@ -30,7 +31,7 @@ Perform fra-experiemnt For a single frequency `ω`. Called from inside `fra` ...@@ -30,7 +31,7 @@ Perform fra-experiemnt For a single frequency `ω`. Called from inside `fra`
""" """
function run_experiment(P::Beam, ω, duration, settling_time, amplitude) function run_experiment(P::Beam, ω, duration, settling_time, amplitude)
h = sampletime(P) h = sampletime(P)
data = zeros(0:h:duration) data = zeros(length(0:h:duration))
LabProcesses.initialize(P) LabProcesses.initialize(P)
for t = 0:h:settling_time for t = 0:h:settling_time
@periodically h begin @periodically h begin
...@@ -51,7 +52,7 @@ end ...@@ -51,7 +52,7 @@ end
function run_experiment(P::BeamSimulator, ω, duration, settling_time, amplitude) function run_experiment(P::BeamSimulator, ω, duration, settling_time, amplitude)
h = sampletime(P) h = sampletime(P)
data = zeros(0:h:duration) data = zeros(length(0:h:duration))
LabProcesses.initialize(P) LabProcesses.initialize(P)
for t = 0:h:settling_time for t = 0:h:settling_time
u = amplitude*sin(ω*t) u = amplitude*sin(ω*t)
...@@ -139,10 +140,16 @@ end ...@@ -139,10 +140,16 @@ end
@recipe function Nypl(p::Nypl) @recipe function Nypl(p::Nypl)
G = p.args[1] G = p.args[1]
@series begin
linestyle := :dash
color := :black
α = LinRange(0,2π,100)
cos.(α),sin.(α)
end
xlabel --> "\$Re(G)\$" xlabel --> "\$Re(G)\$"
ylabel --> "\$Im(G)\$" ylabel --> "\$Im(G)\$"
title --> "Nyquist plot" title --> "Nyquist plot"
real.(G[:,2]), imag.(G[:,2]) @series real.(G[:,2]), imag.(G[:,2])
end end
...@@ -175,7 +182,7 @@ function fbdesign(G::AbstractMatrix, polevect, zerovect, gain) ...@@ -175,7 +182,7 @@ function fbdesign(G::AbstractMatrix, polevect, zerovect, gain)
sysFB = ss(zpk(zerovect,polevect,gain*prod(abs.(polevect))/pzv)) sysFB = ss(zpk(zerovect,polevect,gain*prod(abs.(polevect))/pzv))
C = Number[ω freqresp(sysFB, ω)] C = Number[ω freqresp(sysFB, ω)]
L = Number[ω G[:,2].*C[:,2]] L = Number[ω G[:,2].*C[:,2]]
T = Number[ω L[:,2]./(1+L[:,2])] T = Number[ω L[:,2]./(1 .+L[:,2])]
sysFB,L,T,C sysFB,L,T,C
end end
...@@ -201,8 +208,8 @@ poles2poly(poles) = reduce((r,l) -> conv(r,[1, l]), [1], poles) #|> reverse |> P ...@@ -201,8 +208,8 @@ poles2poly(poles) = reduce((r,l) -> conv(r,[1, l]), [1], poles) #|> reverse |> P
Build and launch the documentation website. Build and launch the documentation website.
""" """
function opendoc() function opendoc()
include(Pkg.dir("BallAndBeam", "docs","make.jl")) include(joinpath(dirname(pathof("BallAndBeam")), "docs","make.jl"))
docpath = Pkg.dir("BallAndBeam", "docs","build","index.html") docpath = joinpath(dirname(pathof("BallAndBeam")), "docs","build","index.html")
run(`xdg-open $docpath`) run(`xdg-open $docpath`)
end end
......
using BallAndBeam, ControlSystems, JLD, LabProcesses, Plots using BallAndBeam, ControlSystems, LabProcesses, Plots, JLD
# @load "workspace.jld" # Run this command to restore a saved workspace # @load "workspace.jld" # Run this command to restore a saved workspace
P = LabProcesses.Beam(bias = 0.) # Replace for BeamSimulator() to run simulations P = LabProcesses.Beam(bias = 0.) # Replace for BeamSimulator() to run simulations
...@@ -11,15 +11,15 @@ nbr_of_periods = 3 ...@@ -11,15 +11,15 @@ nbr_of_periods = 3
# and run three experiments. You may modify the freqency vectors # and run three experiments. You may modify the freqency vectors
# any way you want and add/remove experiments as needed. # any way you want and add/remove experiments as needed.
w1_100 = logspace(log10(1),log10(300),8) w1_100 = exp10.(LinRange(log10(1),log10(300),8)) # exp10.(LinRange = logspace
G1 = fra(P, w1_100, amplitude=1, nbr_of_periods=nbr_of_periods, settling_time=settling_time) G1 = fra(P, w1_100, amplitude=1, nbr_of_periods=nbr_of_periods, settling_time=settling_time)
@save "workspace.jld" @save "workspace.jld"
w1_200 = logspace(log10(50),log10(100),10) w1_200 = exp10.(LinRange(log10(50),log10(100),10))
G2 = fra(P, w1_200, amplitude=2, nbr_of_periods=nbr_of_periods, settling_time=settling_time) G2 = fra(P, w1_200, amplitude=2, nbr_of_periods=nbr_of_periods, settling_time=settling_time)
@save "workspace.jld" @save "workspace.jld"
w1_300 = logspace(log10(100),log10(300),20) w1_300 = exp10.(LinRange(log10(100),log10(300),20))
G3 = fra(P, w1_300, amplitude=2, nbr_of_periods=nbr_of_periods, settling_time=settling_time) G3 = fra(P, w1_300, amplitude=2, nbr_of_periods=nbr_of_periods, settling_time=settling_time)
@save "workspace.jld" @save "workspace.jld"
...@@ -35,7 +35,7 @@ nypl(G123, m=:star) ...@@ -35,7 +35,7 @@ nypl(G123, m=:star)
polevect = [-10] polevect = [-10]
zerovect = [] zerovect = []
gain = 1 gain = 1
sysFBc,L,T,C = fbdesign(G, polevect, zerovect, gain) sysFBc,L,T,C = fbdesign(G123, polevect, zerovect, gain)
polevect = [-10] polevect = [-10]
zerovect = [] zerovect = []
...@@ -55,8 +55,8 @@ plot([y u r], lab = ["y" "u" "r"]) ...@@ -55,8 +55,8 @@ plot([y u r], lab = ["y" "u" "r"])
# If you have time, estimate ARX model ===================================================== # If you have time, estimate ARX model =====================================================
prbs = PRBSGenerator() prbs = PRBSGenerator()
function prbs_experiment(;amplitude = 1, duration = 10) function prbs_experiment(;amplitude = 1, duration = 10)
y = zeros(0:h:duration) y = zeros(length(0:h:duration))
u = zeros(0:h:duration) u = zeros(length(0:h:duration))
LabProcesses.initialize(P) LabProcesses.initialize(P)
for (i,t) = enumerate(0:h:duration) for (i,t) = enumerate(0:h:duration)
@periodically h begin @periodically h begin
...@@ -71,12 +71,12 @@ function prbs_experiment(;amplitude = 1, duration = 10) ...@@ -71,12 +71,12 @@ function prbs_experiment(;amplitude = 1, duration = 10)
y,u y,u
end end
y,u = prbs_experiment(duration = 10, amplitude = 1) y,u = prbs_experiment(duration = 10, amplitude = 1)
plot([y u], lab=["y" "u"]) plot([u y], lab=["u" "y"])
na = 4 # Order of A polynomial na = 4 # Order of A polynomial
nb = 2 # Order of B polynomial nb = 2 # Order of B polynomial
arxtf, Σ = arx(h, y, u, na, nb) # Estimate transfer function with ARX method arxtf, Σ = arx(h, y, u, na, nb) # Estimate transfer function with ARX method
bopl(G123, lab="Measured transfer function") bopl(G123, lab="Measured transfer function")
bodeconfidence!(arxtf, Σ, ω = logspace(0,3,200), linecolor=:red) # The exclamation mark (!) bodeconfidence!(arxtf, Σ, ω = exp10.(LinRange(0,3,200)), linecolor=:red) # The exclamation mark (!)
# adds to the previous plot. If there is no plot open, remove the ! # adds to the previous plot. If there is no plot open, remove the !
...@@ -8,10 +8,10 @@ fit(y,yh) = 100 * (1-rms(y-yh)./rms(y-mean(y))); ...@@ -8,10 +8,10 @@ fit(y,yh) = 100 * (1-rms(y-yh)./rms(y-mean(y)));
aic(x,d) = log(sse(x)) + 2d/length(x) aic(x,d) = log(sse(x)) + 2d/length(x)
""" """
toeplitz{T}(c::AbstractArray{T},r::AbstractArray{T}) toeplitz(c::AbstractArray,r::AbstractArray)
Returns a Toeplitz matrix where `c` is the first column and `r` is the first row. Returns a Toeplitz matrix where `c` is the first column and `r` is the first row.
""" """
function toeplitz{T}(c::AbstractVector{T},r::AbstractVector{T}) function toeplitz(c::AbstractVector{T},r::AbstractVector{T}) where T
nc = length(c) nc = length(c)
nr = length(r) nr = length(r)
A = zeros(T, nc, nr) A = zeros(T, nc, nr)
...@@ -38,13 +38,13 @@ B = [10,5] # B(z) coeffs ...@@ -38,13 +38,13 @@ B = [10,5] # B(z) coeffs
u = randn(100) # Simulate 100 time steps with Gaussian input u = randn(100) # Simulate 100 time steps with Gaussian input
y = filt(B,A,u) y = filt(B,A,u)
yr,A = getARXregressor(y,u,3,2) # We assume that we know the system order 3,2 yr,A = getARXregressor(y,u,3,2) # We assume that we know the system order 3,2
x = A\yr # Estimate model polynomials x = A\\yr # Estimate model polynomials
plot([yr A*x], lab=["Signal" "Prediction"]) plot([yr A*x], lab=["Signal" "Prediction"])
``` ```
For nonlinear ARX-models, see [BasisFunctionExpansions.jl](https://github.com/baggepinnen/BasisFunctionExpansions.jl/) For nonlinear ARX-models, see [BasisFunctionExpansions.jl](https://github.com/baggepinnen/BasisFunctionExpansions.jl/)
""" """
function getARXregressor(y::AbstractVector{Float64},u::AbstractVecOrMat{Float64}, na, nb) function getARXregressor(y::AbstractVector,u::AbstractVecOrMat, na, nb)
assert(length(nb) == size(u,2)) @assert(length(nb) == size(u,2))
m = max(na+1,maximum(nb)) m = max(na+1,maximum(nb))
n = length(y) - m+1 n = length(y) - m+1
offs = m-na-1 offs = m-na-1
...@@ -86,7 +86,7 @@ function arx(h,y::AbstractVector{Float64}, u::AbstractVector{Float64}, na, nb; ...@@ -86,7 +86,7 @@ function arx(h,y::AbstractVector{Float64}, u::AbstractVector{Float64}, na, nb;
if λ == 0 if λ == 0
w = A\y_train w = A\y_train
else else
w = (A'A + λ*eye(size(A,2)))\A'y_train w = (A'A + λ*I)\A'y_train
end end
a,b = params2poly(w,na,nb) a,b = params2poly(w,na,nb)
model = tf(b,a,h) model = tf(b,a,h)
...@@ -116,27 +116,27 @@ function parameter_covariance(y_train, A, w, λ=0) ...@@ -116,27 +116,27 @@ function parameter_covariance(y_train, A, w, λ=0)
ATAλ\ATA/ATAλ ATAλ\ATA/ATAλ
end end
iATA = (iATA+iATA')/2 iATA = (iATA+iATA')/2
Σ = σ²*iATA + sqrt(eps())*eye(iATA) Σ = σ²*iATA + sqrt(eps())*I
end end
""" """
bodeconfidence(arxtf::TransferFunction, Σ::Matrix; ω = logspace(0,3,200)) bodeconfidence(arxtf::TransferFunction, Σ::Matrix; ω = exp10.(LinRange(0,3,200)))
Plot a bode diagram of a transfer function estimated with [`arx`](@ref) with confidence bounds on magnitude and phase. Plot a bode diagram of a transfer function estimated with [`arx`](@ref) with confidence bounds on magnitude and phase.
""" """
bodeconfidence bodeconfidence
@userplot BodeConfidence @userplot BodeConfidence
@recipe function BodeConfidence(p::BodeConfidence; ω = logspace(-2,3,200)) @recipe function BodeConfidence(p::BodeConfidence; ω = exp10.(LinRange(-2,3,200)))
arxtfm = p.args[1] arxtfm = p.args[1]
Σ = p.args[2] Σ = p.args[2]
L = chol(Hermitian(Σ)) L = cholesky(Hermitian(Σ))
am, bm = -reverse(denpoly(arxtfm)[1].a[1:end-1]), reverse(arxtfm.matrix[1].num.a) am, bm = -reverse(denpoly(arxtfm)[1].a[1:end-1]), reverse(arxtfm.matrix[1].num.a)
wm = [am; bm] wm = [am; bm]
na,nb = length(am), length(bm) na,nb = length(am), length(bm)
mc = 100 mc = 100
res = map(1:mc) do _ res = map(1:mc) do _
w = L'randn(size(L,1)) .+ wm w = L.L*randn(size(L,1)) .+ wm
a,b = params2poly(w,na,nb) a,b = params2poly(w,na,nb)
arxtf = tf(b,a,arxtfm.Ts) arxtf = tf(b,a,arxtfm.Ts)
mag, phase, _ = bode(arxtf, ω) mag, phase, _ = bode(arxtf, ω)
...@@ -144,8 +144,8 @@ bodeconfidence ...@@ -144,8 +144,8 @@ bodeconfidence
end end
magmc = hcat(getindex.(res,1)...) magmc = hcat(getindex.(res,1)...)
phasemc = hcat(getindex.(res,2)...) phasemc = hcat(getindex.(res,2)...)
mag = mean(magmc,2)[:] mag = mean(magmc,dims=2)[:]
phase = mean(phasemc,2)[:] phase = mean(phasemc,dims=2)[:]
uppermag = getpercentile(magmc,0.95) uppermag = getpercentile(magmc,0.95)
lowermag = getpercentile(magmc,0.05) lowermag = getpercentile(magmc,0.05)
upperphase = getpercentile(phasemc,0.95) upperphase = getpercentile(phasemc,0.95)
...@@ -176,7 +176,7 @@ bodeconfidence ...@@ -176,7 +176,7 @@ bodeconfidence
end end
function getpercentile(mag,p) function getpercentile(mag,p)
uppermag = mapslices(mag, 2) do magω uppermag = mapslices(mag, dims=2) do magω
sort(magω)[round(Int,endof(magω)*p)] sort(magω)[round(Int,length(magω)*p)]
end end
end end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment