Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • furuta
  • julia1
  • master
  • v0.1.0
  • v0.2.0
5 results

Target

Select target project
  • processes/LabProcesses.jl
  • martinheyden/LabProcesses.jl
2 results
Select Git revision
  • julia1
  • master
  • v0.1.0
  • v0.2.0
4 results
Show changes
Commits on Source (8)
...@@ -14,10 +14,10 @@ ...@@ -14,10 +14,10 @@
script: script:
# Let's run the tests. Substitute `coverage = false` below, if you do not # Let's run the tests. Substitute `coverage = false` below, if you do not
# want coverage results. # want coverage results.
- /opt/julia/bin/julia -e 'Pkg.rm("LabProcesses");Pkg.clone(pwd()); Pkg.test("LabProcesses",coverage = false)' - julia -e 'Pkg.rm("LabProcesses");Pkg.clone(pwd()); Pkg.test("LabProcesses",coverage = false)'
#- /opt/julia/bin/julia -e 'Pkg.update();Pkg.test("LabProcesses", coverage = true)' #- julia -e 'Pkg.update();Pkg.test("LabProcesses", coverage = true)'
# Comment out below if you do not want coverage results. # Comment out below if you do not want coverage results.
#- /opt/julia/bin/julia -e 'Pkg.add("Coverage"); cd(Pkg.dir("LabProcesses")); #- julia -e 'Pkg.add("Coverage"); cd(Pkg.dir("LabProcesses"));
# using Coverage; cl, tl = get_summary(process_folder()); # using Coverage; cl, tl = get_summary(process_folder());
# println("(", cl/tl*100, "%) covered")' # println("(", cl/tl*100, "%) covered")'
......
## News
2018-12-07: Updated to julia v1.0, see commit eac09291 for last julia v0.6 version
[![pipeline status](https://gitlab.control.lth.se/processes/LabProcesses.jl/badges/master/pipeline.svg)](https://gitlab.control.lth.se/processes/LabProcesses.jl/commits/master) [![pipeline status](https://gitlab.control.lth.se/processes/LabProcesses.jl/badges/master/pipeline.svg)](https://gitlab.control.lth.se/processes/LabProcesses.jl/commits/master)
[![coverage report](https://gitlab.control.lth.se/processes/LabProcesses.jl/badges/master/coverage.svg)](https://gitlab.control.lth.se/processes/LabProcesses.jl/commits/master) [![coverage report](https://gitlab.control.lth.se/processes/LabProcesses.jl/badges/master/coverage.svg)](https://gitlab.control.lth.se/processes/LabProcesses.jl/commits/master)
......
julia 0.6 julia 0.7
ControlSystems ControlSystems
Parameters Parameters
DSP
...@@ -22,12 +22,16 @@ to get the latest release. ...@@ -22,12 +22,16 @@ to get the latest release.
2. Install LabProcesses.jl using command `Pkg.clone("https://gitlab.control.lth.se/processes/LabProcesses.jl.git")` Lots of packages will now be installed, this will take some time. If this is your first time using Julia, you might have to run `julia> Pkg.init()` before you install any packages. 2. Install LabProcesses.jl using command `Pkg.clone("https://gitlab.control.lth.se/processes/LabProcesses.jl.git")` Lots of packages will now be installed, this will take some time. If this is your first time using Julia, you might have to run `julia> Pkg.init()` before you install any packages.
# How to implement a new process # How to implement a new process
1. Locate the file [interface.jl](https://gitlab.control.lth.se/processes/LabProcesses.jl/blob/master/src/interface.jl). When the package is installed, you find its directory under `~/.julia/v0.6/LabProcesses/`, if not, run `julia> Pkg.dir("LabProcesses")` to locate the directory. ### 1.
Locate the file [interface.jl](https://gitlab.control.lth.se/processes/LabProcesses.jl/blob/master/src/interface.jl). When the package is installed, you find its directory under `~/.julia/v0.6/LabProcesses/`, if not, run `julia> Pkg.dir("LabProcesses")` to locate the directory.
(Alternatively, you can copy all definitions from [/interface_implementations/ballandbeam.jl](https://gitlab.control.lth.se/processes/LabProcesses.jl/blob/master/src/interface_implementations/ballandbeam.jl) instead. Maybe it's easier to work from an existing implementaiton.) (Alternatively, you can copy all definitions from [/interface_implementations/ballandbeam.jl](https://gitlab.control.lth.se/processes/LabProcesses.jl/blob/master/src/interface_implementations/ballandbeam.jl) instead. Maybe it's easier to work from an existing implementaiton.)
2. Copy all function definitions. ### 2.
3. Create a new file under `/interface_implementations` where you paste all the Copy all function definitions.
### 3.
Create a new file under `/interface_implementations` where you paste all the
copied definitions and implement them. See [/interface_implementations/ballandbeam.jl](https://gitlab.control.lth.se/processes/LabProcesses.jl/blob/master/src/interface_implementations/ballandbeam.jl) for an example. copied definitions and implement them. See [/interface_implementations/ballandbeam.jl](https://gitlab.control.lth.se/processes/LabProcesses.jl/blob/master/src/interface_implementations/ballandbeam.jl) for an example.
4. Above all function implementations you must define the process type, e.g, ### 4.
Above all function implementations you must define the process type, e.g,
```julia ```julia
struct BallAndBeam <: PhysicalProcess struct BallAndBeam <: PhysicalProcess
h::Float64 h::Float64
...@@ -42,7 +46,8 @@ have different biases, hence this must be stored. A simulated process would have ...@@ -42,7 +46,8 @@ have different biases, hence this must be stored. A simulated process would have
to keep track of its state etc. in order to implement the measure and control to keep track of its state etc. in order to implement the measure and control
methods. See [Types in julia documentation](https://docs.julialang.org/en/stable/manual/types/#Composite-Types-1) methods. See [Types in julia documentation](https://docs.julialang.org/en/stable/manual/types/#Composite-Types-1)
for additional info regarding user defined types and (constructors)[https://docs.julialang.org/en/stable/manual/constructors/]. for additional info regarding user defined types and (constructors)[https://docs.julialang.org/en/stable/manual/constructors/].
5. Documentation of all interface functions is available in the file [interface_documentation.jl](https://gitlab.control.lth.se/processes/LabProcesses.jl/blob/master/src/interface_documentation.jl) ### 5.
Documentation of all interface functions is available in the file [interface_documentation.jl](https://gitlab.control.lth.se/processes/LabProcesses.jl/blob/master/src/interface_documentation.jl)
# How to control a process # How to control a process
The interface `AbstractProcess` defines the functions `control(P, u)` and `measure(P)`. The interface `AbstractProcess` defines the functions `control(P, u)` and `measure(P)`.
...@@ -150,12 +155,8 @@ the user is unsure about a reasonable value. ...@@ -150,12 +155,8 @@ the user is unsure about a reasonable value.
## Non-linear process ## Non-linear process
Your first option is to linearize the process and proceed like above. Your first option is to linearize the process and proceed like above.
Other options include Other options include
1. Make `control` perform forward Euler, i.e., `x' = f(x,u)*h` for a general 1. Make `control` perform forward Euler, i.e., `x[t+1] = x[t] + f(x[t],u[t])*h` for a general system model ``x' = f(x,u); y = g(x,u)`` and sample time ``h``.
system model ``x' = f(x,u); y = g(x,u)`` and sample time ``h``. 2. Integrate the system model using some fancy method like Runge-Kutta. See [DifferentialEquations.jl](http://docs.juliadiffeq.org/stable/types/discrete_types.html) for discrete-time solving of ODEs (don't be discouraged, this is almost as simple as forward Euler above).
2. Integrate the system model using some fancy method like Runge-Kutta. See
[DifferentialEquations.jl](http://docs.juliadiffeq.org/stable/types/discrete_types.html)
for discrete-time solving of ODEs (don't be discouraged, this is almost as simple as
forward Euler above).
# Exported functions and types # Exported functions and types
```@autodocs ```@autodocs
......
# __precompile__() # __precompile__()
using Pkg
installed_packages = Pkg.installed() installed_packages = Pkg.installed()
if "LabConnections" keys(installed_packages) if "LabConnections" keys(installed_packages)
Pkg.clone("https://gitlab.control.lth.se/cont-frb/LabConnections.jl") Pkg.clone("https://gitlab.control.lth.se/cont-frb/LabConnections.jl")
...@@ -8,7 +9,7 @@ end ...@@ -8,7 +9,7 @@ end
module LabProcesses module LabProcesses
using ControlSystems, LabConnections.Computer, Parameters using ControlSystems, LabConnections.Computer, Parameters, DSP, LinearAlgebra
include("utilities.jl") include("utilities.jl")
......
...@@ -27,16 +27,16 @@ function run_control_2DOF(P::AbstractProcess,sysFB, sysFF=nothing; duration = 10 ...@@ -27,16 +27,16 @@ function run_control_2DOF(P::AbstractProcess,sysFB, sysFF=nothing; duration = 10
rf = sysFF == nothing ? r[:,i] : Gff(r[:,i]) rf = sysFF == nothing ? r[:,i] : Gff(r[:,i])
e = rf-y[:,i] e = rf-y[:,i]
ui = Gfb(e) ui = Gfb(e)
ui + bias(P) ui .+ bias(P)
end end
simulation = isa(P, SimulatedProcess) simulation = isa(P, SimulatedProcess)
initialize(P) initialize(P)
for (i,t) = enumerate(0:h:duration) for (i,t) = enumerate(0:h:duration)
@periodically h simulation begin @periodically h simulation begin
y[:,i] = measure(P) y[:,i] .= measure(P)
r[:,i] = reference(t) r[:,i] .= reference(t)
u[:,i] = calc_control(i) # y,r must be updated before u u[:,i] .= calc_control(i) # y,r must be updated before u
control(P, [clamp.(u[j,i], inputrange(P)[j]...) for j=1:nu]) control(P, [clamp.(u[j,i], inputrange(P)[j]...) for j=1:nu])
end end
end end
......
...@@ -48,7 +48,7 @@ const beam_system, nice_beam_controller = define_beam_system() ...@@ -48,7 +48,7 @@ const beam_system, nice_beam_controller = define_beam_system()
struct BeamSimulator <: SimulatedProcess struct BeamSimulator <: SimulatedProcess
h::Float64 h::Float64
s::SysFilter s::SysFilter
BeamSimulator(;h::Real = 0.01) = new(Float64(h), SysFilter(beam_system, h)) BeamSimulator(;h::Real = 0.01, bias=0) = new(Float64(h), SysFilter(beam_system, h))
end end
struct BallAndBeam <: PhysicalProcess struct BallAndBeam <: PhysicalProcess
...@@ -96,15 +96,15 @@ bias(p::BallAndBeamSimulator) = 0 ...@@ -96,15 +96,15 @@ bias(p::BallAndBeamSimulator) = 0
function control(p::AbstractBeamOrBallAndBeam, u::AbstractArray) function control(p::AbstractBeamOrBallAndBeam, u::AbstractArray)
length(u) == 1 || error("Process $(typeof(p)) only accepts one control signal, tried to send u=$u.") length(u) == 1 || error("Process $(typeof(p)) only accepts one control signal, tried to send u=$u.")
send(p.control,u[1]) control(p,u[1])
end end
control(p::AbstractBeamOrBallAndBeam, u::Number) = send(p.control,u) control(p::AbstractBeamOrBallAndBeam, u::Number) = send(p.control,u)
control(p::BeamSimulator, u) = p.s(u) control(p::BeamSimulator, u::Number) = p.s(u)
control(p::BallAndBeamSimulator, u) = error("Not yet implemented") control(p::BallAndBeamSimulator, u::Number) = error("Not yet implemented")
measure(p::Beam) = read(p.measure) measure(p::Beam) = read(p.measure)
measure(p::BallAndBeam) = [read(p.measure1), read(p.measure2)] measure(p::BallAndBeam) = [read(p.measure1), read(p.measure2)]
measure(p::BeamSimulator) = vecdot(p.s.sys.C,p.s.state) measure(p::BeamSimulator) = dot(p.s.sys.C,p.s.state)
measure(p::BallAndBeamSimulator) = error("Not yet implemented") measure(p::BallAndBeamSimulator) = error("Not yet implemented")
......
using ControlSystems using ControlSystems, DSP
""" """
beammodel, beamcontroller = define_beam_system(;doplot=false) beammodel, beamcontroller = define_beam_system(;doplot=false)
......
...@@ -9,7 +9,7 @@ macro periodically(h, body) ...@@ -9,7 +9,7 @@ macro periodically(h, body)
local start_time = time() local start_time = time()
$(esc(body)) $(esc(body))
local execution_time = time()-start_time local execution_time = time()-start_time
sleep(max(0,$(esc(h))-execution_time)) Libc.systemsleep(max(0,$(esc(h))-execution_time))
end end
end end
...@@ -37,22 +37,22 @@ Create a SysFilter object that can be used to implement control loops and simula ...@@ -37,22 +37,22 @@ Create a SysFilter object that can be used to implement control loops and simula
with LTI systems, i.e., `U(z) = C(z)E(z)`. To filter a signal `u` through the filter, 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` call like `y = Csf(u)`. Calculates the filtered output `y` in `y = Cx+Du, x'=Ax+Bu`
""" """
struct SysFilter struct SysFilter{T<:StateSpace}
sys::StateSpace sys::T
state::Vector{Float64} state::Vector{Float64}
function SysFilter(sys::StateSpace, state::AbstractVector) function SysFilter(sys::StateSpace, state::AbstractVector)
@assert !ControlSystems.iscontinuous(sys) "Can not filter using continuous time model." @assert !ControlSystems.iscontinuous(sys) "Can not filter using continuous time model."
@assert length(state) == sys.nx "length(state) != sys.nx" @assert length(state) == sys.nx "length(state) != sys.nx"
new(sys, state) new{typeof(sys)}(sys, state)
end end
function SysFilter(sys::StateSpace) function SysFilter(sys::StateSpace)
@assert !ControlSystems.iscontinuous(sys) "Can not filter using continuous time model. Supply sample time." @assert !ControlSystems.iscontinuous(sys) "Can not filter using continuous time model. Supply sample time."
new(sys, init_sysfilter(sys)) new{typeof(sys)}(sys, init_sysfilter(sys))
end end
function SysFilter(sys::StateSpace, h::Real) function SysFilter(sys::StateSpace, h::Real)
@assert ControlSystems.iscontinuous(sys) "Sample time supplied byt system model is already in discrete time." @assert ControlSystems.iscontinuous(sys) "Sample time supplied byt system model is already in discrete time."
sysd = c2d(sys, h)[1] sysd = c2d(sys, h)[1]
new(sysd, init_sysfilter(sysd)) new{typeof(sysd)}(sysd, init_sysfilter(sysd))
end end
end end
(s::SysFilter)(input) = sysfilter!(s.state, s.sys, input) (s::SysFilter)(input) = sysfilter!(s.state, s.sys, input)
......
using LabProcesses, ControlSystems using LabProcesses, ControlSystems, DSP
using Base.Test using Test
# Reference generators # Reference generators
r = PRBSGenerator(Int(4)) r = PRBSGenerator(Int(4))
......