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

Add Simulator to readme

parent 91750c14
Branches
Tags
No related merge requests found
......@@ -78,4 +78,59 @@ end
```
`G1` and `G4` must here be represented by [`StateSpace`](http://juliacontrol.github.io/ControlSystems.jl/latest/lib/constructors/#ControlSystems.ss) types from [`ControlSystems.jl`](https://github.com/JuliaControl/ControlSystems.jl).
`TransferFunction` types can easily be converted to a `StateSpace` by `Gss = ss(Gtf)`.
Continuous time systems can be discretized using `Gd = c2d(Gc, h)`. (The sample time of a process is available through `h = sampletime(P)`.)
Continuous time systems can be discretized using `Gd = c2d(Gc, h)[1]`. (The sample time of a process is available through `h = sampletime(P)`.)
# How to implement a Simulated Process
## Linear process
This is very easy, just get a discrete time `StateSpace` model of your process
(if you have a transfer function, `Gss = ss(Gtf)` will do the trick, if you have continuous time, `Gd = c2d(Gc,h)[1]` is your friend).
You now have to implement the methods `control` and `measure` for your simulated type.
The implementation for `BeamSimulator` is shown below
```julia
function control(p::BeamSimulator, u)
sysfilter!(p.state, p.sys, u)
end
measure(P) = vecdot(p.sys.C,p.state)
```
The `control` method accepts a control signal (`u`) and propagates the system state
(`p.state`) forward using the statespace model (`p.sys`) of the beam. The function
[`sysfilter!`](@ref) is familiar from the "Control" section above. What it does
is essentially
```julia
function sysfilter!(state, sys, input)
state .= sys.A*state + sys.B*input
output = sys.C*state + sys.D*input
end
```
hence, it just performs one iteration of
```math
x' = Ax + Bu
y = Cx + Du
```
The `measure` method performs the computation `y = Cx`, the reason for the call
to `vecdot` is that `vecdot` produces a scalar output, whereas `C*x` produces a
1-element `Matrix`. A scalar output is preferred in this case since the `Beam`
is SISO.
It should now be obvious which fields are required in the `BeamSimulator` type.
It must know which sample time it has been discretized with, as well as its
discrete-time system model. It must also remember the current state of the system.
This is not needed in a physical process since it kind of remembers its own state.
The full type specification for `BeamSimulator` is given below
```julia
struct BeamSimulator <: SimulatedProcess
h::Float64
state::Vector{Float64} # states defined by the file define_beam_system
sys::StateSpace
BeamSimulator() = new(0.01, init_sysfilter(beam_system), c2d(beam_system, 0.01)[1])
BeamSimulator(h::Real) = new(Float64(h), init_sysfilter(beam_system), c2d(beam_system, h)[1])
end
```
It contains three fields and two inner constructors. The constructors initializes
the system state by calling `init_sysfilter`. The variable `beam_system` is already
defined outside the type specification.
One of the constructors provides a default value for the sample time, in case
the user is unsure about a reasonable value.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment