From 41e269d1fba84cd493c29f538ec0afb1c02ae4c5 Mon Sep 17 00:00:00 2001
From: Fredrik Bagge Carlson <cont-frb@ulund.org>
Date: Tue, 22 Aug 2017 09:52:33 +0200
Subject: [PATCH] Update readme and support MIMO in run_control_2dof

---
 README.md          |  3 ++-
 src/controllers.jl | 26 ++++++++++++++------------
 2 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/README.md b/README.md
index 60a77df..a4acfd0 100644
--- a/README.md
+++ b/README.md
@@ -17,7 +17,8 @@ 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.
 
 ## 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). (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.)
+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.)
 2. 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.
diff --git a/src/controllers.jl b/src/controllers.jl
index 74a2153..1e5f2fa 100644
--- a/src/controllers.jl
+++ b/src/controllers.jl
@@ -2,7 +2,7 @@ export run_control_2DOF
 
 """
 	y,u,r = run_control(process, sysFB[, sysFF]; duration = 10, reference(t) = sign(sin(2π*t)))
-Perform control experiemnt where the feedback and feedforward controllers are given by
+Perform control experiemnt on process where the feedback and feedforward controllers are given by
 `sysFB` and `sysFF`, both of type `StateSpace`.
 
 `reference` is a reference generating function that accepts a scalar `t` (time in seconds) and outputs a scalar `r`, default is `reference(t) = sign(sin(2π*t))`.
@@ -11,10 +11,12 @@ The outputs `y,u,r` are the beam angle, control signal and reference respectivel
 ![block diagram](docs/feedback4.png)
 """
 function run_control_2DOF(P::AbstractProcess,sysFB, sysFF=nothing; duration = 10, reference = t->sign(sin(2π*t)))
-	h 		= sampletime(P)
-	y       = zeros(0:h:duration)
-	u       = zeros(0:h:duration)
-	r       = zeros(0:h:duration)
+	nu = num_inputs(P)
+	ny = num_outputs(P)
+	h  = sampletime(P)
+	y  = zeros(ny, length(0:h:duration))
+	u  = zeros(nu, length(0:h:duration))
+	r  = zeros(ny, length(0:h:duration))
 
 	stateFB = init_sysfilter(sysFB)
 	if sysFF != nothing
@@ -22,19 +24,19 @@ function run_control_2DOF(P::AbstractProcess,sysFB, sysFF=nothing; duration = 10
 	end
 
 	function calc_control(i)
-		rf = sysFF == nothing ? r[i] : sysfilter!(stateFF, sysFF, r[i])
-		e  = rf-y[i]
-		ui = sysfilter!(stateFB, sysFB, e)[1]
+		rf = sysFF == nothing ? r[:,i] : sysfilter!(stateFF, sysFF, r[:,i])
+		e  = rf-y[:,i]
+		ui = sysfilter!(stateFB, sysFB, e)
 		ui + bias(P)
 	end
 
 	initialize(P)
 	for (i,t) = enumerate(0:h:duration)
 		@periodically h begin
-			y[i]       = measure(P)
-			r[i]       = reference(t)
-			u[i]       = calc_control(i) # y,r must be updated before u
-			control(P, u[i])
+			y[:,i]     = measure(P)
+			r[:,i]     = reference(t)
+			u[:,i]     = calc_control(i) # y,r must be updated before u
+			control(P, [clamp.(u[j,i], input_range(P)[j]...) for j=1:nu])
 		end
 	end
 	finalize(P)
-- 
GitLab