Commit 526736d1 authored by Fredrik Bagge Carlson's avatar Fredrik Bagge Carlson
Browse files

Add Simulator to readme

parent 91750c14
......@@ -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.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment