diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..bd66ab6862d1707cb6a96a1f169833ab0b3c7bf2
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,48 @@
+# This file is a template, and might need editing before it works on your project.
+# An example .gitlab-ci.yml file to test (and optionally report the coverage
+# results of) your [Julia][1] packages. Please refer to the [documentation][2]
+# for more information about package development in Julia.
+#
+# Here, it is assumed that your Julia package is named `MyPackage`. Change it to
+# whatever name you have given to your package.
+#
+# [1]: http://julialang.org/
+# [2]: http://julia.readthedocs.org/
+
+# Below is the template to run your tests in Julia
+.test_template: &test_definition
+  # Uncomment below if you would like to run the tests on specific references
+  # only, such as the branches `master`, `development`, etc.
+  # only:
+  #   - master
+  #   - development
+  script:
+    # Let's run the tests. Substitute `coverage = false` below, if you do not
+    # want coverage results.
+    - /opt/julia/bin/julia -e 'Pkg.clone(pwd()); Pkg.test("BallAndBeam",
+      coverage = true)'
+    # Comment out below if you do not want coverage results.
+    - /opt/julia/bin/julia -e 'Pkg.add("Coverage"); cd(Pkg.dir("BallAndBeam"));
+      using Coverage; cl, tl = get_summary(process_folder());
+      println("(", cl/tl*100, "%) covered")'
+
+# Name a test and select an appropriate image.
+test:0.6.0:
+  image: julialang/julia:v0.6.0
+  <<: *test_definition
+
+
+# REMARK: Do not forget to enable the coverage feature for your project, if you
+# are using code coverage reporting above. This can be done by
+#
+# - Navigating to the `CI/CD Pipelines` settings of your project,
+# - Copying and pasting the default `Simplecov` regex example provided, i.e.,
+#   `\(\d+.\d+\%\) covered` in the `test coverage parsing` textfield.
+#
+# WARNING: This template is using the `julialang/julia` images from [Docker
+# Hub][3]. One can use custom Julia images and/or the official ones found
+# in the same place. However, care must be taken to correctly locate the binary
+# file (`/opt/julia/bin/julia` above), which is usually given on the image's
+# description page.
+#
+# [3]: http://hub.docker.com/
diff --git a/README.md b/README.md
index 6e0c14890a76d4c94522af4e6849503636295693..6830c545f24bbc867977744872453e415cb333c6 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,9 @@
-# Installation
+# Installation (specific to lab 1 FRTN35: Frequency response analysis)
 1. Open a terminal
-2. Type `printf 'export JULIA_PKGDIR=/work/$USER\nexport JULIA_EDITOR=gedit' >> .bashrc`. Restart the terminal. (Feel free to choose another text editor if you don't like gedit.)
+2. Type `export JULIA_PKGDIR=/var/tmp/$USER; export JULIA_EDITOR=gedit`. (Feel free to choose another text editor if you don't like gedit.) At the moment, this has to be done every time you restart the terminal (Anders Blomdell will fix). 
 3. Type `mkdir FRTN35_lab1; cd FRTN35_lab1`
 4. Start `julia`
-5. Install `BallAndBeam.jl` using command `Pkg.clone("https://gitlab.control.lth.se/processes/BallAndBeam.jl.git")` Lots of packages will now be installed, this will take some time.
+5. Install `BallAndBeam.jl` using command `Pkg.clone("https://gitlab.control.lth.se/processes/BallAndBeam.jl.git"); using BallAndBeam` Lots of packages will now be installed, this will take some time.
 6. Type `cp(Pkg.dir("BallAndBeam","src","FRTN35_lab1.jl"), "FRTN35_lab1.jl"); edit("FRTN35_lab1.jl")`. The script `FRTN35_lab1.jl` will now open in the chosen text editor, edit it while following the lab manual. If unsure about how a function works, type `?function_name` for help.
 
 # Documentation
diff --git a/docs/src/feedback4.png b/docs/src/feedback4.png
new file mode 100644
index 0000000000000000000000000000000000000000..696bf353a387ba1ef2f86ba0b3dbb0c62cdb7252
Binary files /dev/null and b/docs/src/feedback4.png differ
diff --git a/docs/src/index.md b/docs/src/index.md
index f998ddc838210c7d4fe73a3d21c08d1a339d4590..cd0a6019e63ab41aa20792b4b2591aa7e4ecac02 100644
--- a/docs/src/index.md
+++ b/docs/src/index.md
@@ -5,8 +5,7 @@ Depth = 3
 ```
 
 # Installation
-Install `BallAndBeam.jl` using command `Pkg.clone("https://gitlab.control.lth.se/labdev/software/tree/master/julia_ballandbeam/BallAndBeam.jl.git")` Lots of packages will now be installed, this will take some time.
-Example usage is illustrated for lab 1 in FRTN35: Frequency Response Analysis of the beam (see below).
+Install `BallAndBeam.jl` using command `Pkg.clone("https://gitlab.control.lth.se/processes/BallAndBeam.jl.git")` Lots of packages will now be installed, this will take some time.
 
 
 # Exported functions and types
@@ -21,13 +20,13 @@ Pages   = ["BallAndBeam.jl"]
 
 # Lab 1 FRTN35
 The script `FRTN35_lab1.jl` provides example usage of the functionality required to perform the lab. To get started, do the following
+
 1. Open a terminal
-2. Type `export JULIA_PKGDIR=/work/$USER\n export JULIA_EDITOR=gedit >> .bashrc`. Restart the terminal.
+2. Type `export JULIA_PKGDIR=/var/tmp/$USER; export JULIA_EDITOR=gedit`. Restart the terminal. (Feel free to choose another text editor if you don't like gedit.)
 3. Type `mkdir FRTN35_lab1; cd FRTN35_lab1`
 4. Start `julia`
-5. Install `BallAndBeam.jl` using command `Pkg.clone("https://gitlab.control.lth.se/labdev/software/tree/master/julia_ballandbeam/BallAndBeam.jl.git")` Lots of packages will now be installed, this will take some time.
-6. Type `cp(Pkg.dir("BallAndBeam","src","FRTN35_lab1.jl"), "."); edit("FRTN35_lab1.jl")`. The script `FRTN35_lab1.jl` will now open in a text editor, edit it while following the lab manual. If unsure about how a function works, type `?function_name` for help.
-
+5. Install `BallAndBeam.jl` using command `Pkg.clone("https://gitlab.control.lth.se/processes/BallAndBeam.jl.git"); using BallAndBeam` Lots of packages will now be installed, this will take some time.
+6. Type `cp(Pkg.dir("BallAndBeam","src","FRTN35_lab1.jl"), "FRTN35_lab1.jl"); edit("FRTN35_lab1.jl")`. The script `FRTN35_lab1.jl` will now open in the chosen text editor, edit it while following the lab manual. If unsure about how a function works, type `?function_name` for help.
 
 # Index
 
diff --git a/src/BallAndBeam.jl b/src/BallAndBeam.jl
index 812e6947dbea9d22cf478d8a5b73854b329c30fb..508f2cfc62547e63f21f93378fd50b20fe1bcddd 100644
--- a/src/BallAndBeam.jl
+++ b/src/BallAndBeam.jl
@@ -9,13 +9,14 @@ end
 This module contains a controller for the Ball and Beam. It connects to the
 process through the gray analog IO boxes.
 
-Apart from 2DOF controller funcitonality [`run_control`](@ref), the module contains functions for performing
+Apart from 2DOF controller funcitonality [`run_control_2DOF`](@ref), the module contains functions for performing
 frequency response analysis [`fra`](@ref).
 """
 module BallAndBeam
 
 export run_experiment, fra, sortfqs,
-bopl, bopl!, nypl, nypl!, plot, fbdesign, ffdesign, init_sysfilter, sysfilter!, opendoc
+bopl, bopl!, nypl, nypl!, plot, fbdesign, ffdesign, opendoc
+export init_sysfilter, sysfilter!, run_control_2DOF # For documentation
 
 using LabProcesses, Plots, Polynomials, ControlSystems, ProgressMeter
 
@@ -155,7 +156,34 @@ Build and launch the documentation website.
 function opendoc()
 	include(Pkg.dir("BallAndBeam", "docs","make.jl"))
 	docpath = Pkg.dir("BallAndBeam", "docs","build","index.html")
-	run(`sensible-browser $docpath`)
+	run(`xdg-open $docpath`)
 end
 
+"""
+	state = init_sysfilter(sys::StateSpace)
+Use together with [`sysfilter!`](@ref)
+"""
+init_sysfilter
+
+"""
+	output = sysfilter!(state, sys::StateSpace, input)
+Returns the filtered output `y` in `y = Cx+Du, x'=Ax+Bu`
+
+This function is used to implement control loops where a signal is filtered through a
+dynamical system, i.e., `U(z) = C(z)E(z)`. Initialize `state` using [`init_sysfilter`](@ref).
+"""
+sysfilter!
+
+"""
+	y,u,r = run_control_2DOF(process, sysFB[, sysFF]; duration = 10, reference(t) = sign(sin(2π*t)))
+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))`.
+
+The outputs `y,u,r` are the beam angle, control signal and reference respectively.
+![block diagram](feedback4.png)
+"""
+run_control_2DOF
+
 end # module BallAndBeam
diff --git a/src/FRTN35_lab1.jl b/src/FRTN35_lab1.jl
index 3d8eaf7c8a325b926765b0b757566afce76a7729..abcd4d87bf98ba413e9e12d4c5c2c9fc71df22bc 100644
--- a/src/FRTN35_lab1.jl
+++ b/src/FRTN35_lab1.jl
@@ -1,8 +1,8 @@
 using BallAndBeam, LabProcesses, ControlSystems, JLD
 # @load "workspace.jld" # Run this command to restore a saved workspace
 
-bias = 0 # Change this if your process drifts over time
-P    = LabProcesses.BeamSimulator(0.01)
+bias = 0.01 # Change this if your process drifts over time
+P    = LabProcesses.Beam(0.01, bias)
 h    = sampletime(P)
 
 settling_time  = 1
@@ -27,25 +27,25 @@ G3     = fra(P, w1_300, amplitude=2, bias=bias, nbr_of_periods=nbr_of_periods, s
 # Concatenate (overlapping) estimates to be used and sort based on freq
 G123 = sortfqs([G1; G2; G3])
 
-bopl(G123)
+bopl(G123, m=:star)
 nypl(G123)
 
 ## Control ==================================================================================
-# polevect = [-10]
-# zerovect = []
-# gain     = 1
-# sysFBc,L,T,C = fbdesign(G, polevect, zerovect, gain)
-
-# polevect = [-10]
-# zerovect = []
-# gain     = 1
-# sysFFc,YR,FF = ffdesign(T, polevect, zerovect, gain)
-
-# bopl(C, lab="Controller")
-# bopl!(L, lab="Closed-loop system e->y")
-# bopl!(FF, lab="Feedforward compensator")
-# bopl!(YR, lab="Closed-loop system r->y")
-
-# sysFB,sysFF  = c2d(sysFBc,h)[1],c2d(sysFFc,h)[1]
-# y,u,r        = run_control_2DOF(P, sysFB, sysFF, duration=5, reference = t->2sign(sin(2π/3*t)))
-# plot([y u r], lab = ["y" "u" "r"])
+polevect = [-10]
+zerovect = []
+gain     = 1
+sysFBc,L,T,C = fbdesign(G, polevect, zerovect, gain)
+
+polevect = [-10]
+zerovect = []
+gain     = 1
+sysFFc,YR,FF = ffdesign(T, polevect, zerovect, gain)
+
+bopl(C, lab="Controller")
+bopl!(L, lab="Closed-loop system e->y")
+bopl!(FF, lab="Feedforward compensator")
+bopl!(YR, lab="Closed-loop system r->y")
+
+sysFB,sysFF  = c2d(sysFBc,h)[1],c2d(sysFFc,h)[1]
+y,u,r        = run_control_2DOF(P, sysFB, sysFF, duration=5, reference = t->2sign(sin(2π/3*t)))
+plot([y u r], lab = ["y" "u" "r"])
diff --git a/test/runtests.jl b/test/runtests.jl
index 8955f27a16766e433dba8e70afda0046dbb0b0df..22258e3260d9a9adc9d1179ceb0304faf6e114ec 100644
--- a/test/runtests.jl
+++ b/test/runtests.jl
@@ -1,5 +1,10 @@
 using Base.Test
-using BallAndBeam, ControlSystems
+using BallAndBeam, ControlSystems, LabProcesses
+
+P = LabProcesses.Beam()
+P = LabProcesses.Beam(0.01,0.)
+h = sampletime(P)
+@test h == 0.01
 
 function test_sysfilter()
         N = 10
@@ -18,7 +23,6 @@ end
 
 test_sysfilter()
 
-bias           = 0 # Change this if your process drifts over time
 settling_time  = 1
 nbr_of_periods = 5
 
@@ -30,6 +34,7 @@ G2 = Number[w1_200 Complex.(ones(20),0)]
 
 # Concatenate (overlapping) estimates to be used and sort based on freq
 G12 = sortfqs([G1; G2])
+@test issorted(G12[:,1])
 
 bopl(G12)
 nypl(G12)
@@ -41,4 +46,4 @@ gain     = 1
 
 sysFBc,L,T,C = fbdesign(G12, polevect, zerovect, gain)
 sysFFc,YR,FF = ffdesign(T, polevect, zerovect, gain)
-sysFB,sysFF  = c2d(sysFBc,BallAndBeam.h),c2d(sysFFc,BallAndBeam.h)
+sysFB,sysFF  = c2d(sysFBc,h),c2d(sysFFc,h)