From 526736d1ebeda265839220379b4a1b9917279bec Mon Sep 17 00:00:00 2001
From: Fredrik Bagge Carlson <cont-frb@ulund.org>
Date: Wed, 23 Aug 2017 08:18:44 +0200
Subject: [PATCH] Add Simulator to readme

---
 README.md | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 56 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index a4acfd0..60b2f22 100644
--- a/README.md
+++ b/README.md
@@ -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.
-- 
GitLab