diff --git a/src/livetankdemo.jl b/src/livetankdemo.jl
index ba74c63ae1e58a6e5b10eeb891b42f1d24b2d63d..acf4ea5376ce596a62a653a5109f54ef3d10d999 100644
--- a/src/livetankdemo.jl
+++ b/src/livetankdemo.jl
@@ -1,6 +1,6 @@
 using InteractNext, Mux, Plots, LabProcesses, LabConnections, LabGUI
 include("tankgraphic.jl")
-include("doubletank.jl")
+include("DoubleTank.jl")
 include("tanklabgui.jl")
 
 
diff --git a/src/tankdemo.jl b/src/tankdemo.jl
index 927098b313227f9466a7ac949f99a1878fd924ac..037138203a5427dcc9972c7dafd373217a8604fa 100644
--- a/src/tankdemo.jl
+++ b/src/tankdemo.jl
@@ -1,6 +1,6 @@
 using InteractNext, Mux, Plots, LabProcesses, LabGUI
 include("tankgraphic.jl")
-include("doubletank.jl")
+include("DoubleTank.jl")
 include("tanklabgui.jl")
 
 R = DoubleTankSimulator(σ = 0.001)
diff --git a/src/tankgraphic.jl b/src/tankgraphic.jl
new file mode 100644
index 0000000000000000000000000000000000000000..bbe687bcd4edb4c5e07c87830c4409338f3c8aff
--- /dev/null
+++ b/src/tankgraphic.jl
@@ -0,0 +1,164 @@
+using InteractNext, Mux, Plots, LabGUI
+
+const lightblue = (150, 150, 255)
+const wall_thickness = 5
+const mouth_width = 20
+const animationspeed = 1500
+
+inspectdr(show=false)
+
+
+function stream(width, height, x, y)
+    bigstyle = Dict(:fill => "rgb$s_blue")
+    smallstyle = Dict(:fill => "rgb$lightblue")
+    lines = 10
+    sp = "$(height/animationspeed)s"
+    thickness = 10
+    speed = 10
+    ht = height - thickness
+    attr_small = Dict("width"=> "$(width)", "height" => "$(thickness)", "x" => "$(x)", "y"=>"$(y)")
+
+    #we may want to rethink this a little bit
+    animate1 = Dict("attributeType" => "XML", "attributeName" => "y", "from" => "$(y)", 
+                    "to" => "$(y+ht/2)", "dur" => sp, "repeatCount" => "indefinite")
+    animate2 = Dict("attributeType" => "XML", "attributeName" => "y", "from" => "$(y+ht/2)", 
+                   "to" => "$(y+ht)", "dur" => sp, "repeatCount" => "indefinite")
+    anim1 = dom"svg:animate"(attributes=animate1)
+    anim2 = dom"svg:animate"(attributes=animate2)
+    stline1 = Node(instanceof(dom"svg:rect"()), anim1, style = smallstyle, attributes = attr_small)
+    stline2 = Node(instanceof(dom"svg:rect"()), anim2, style = smallstyle, attributes = attr_small)
+    #stlines = (svg_rect(width, thickness, x, y+(speed*time() + i)%ht, smallstyle) 
+    #for i in 0:ht/lines:ht)
+    #(svg_rect(width, height, x, y, bigstyle), stlines...)
+    (svg_rect(width, height, x, y, bigstyle), stline1, stline2)
+end
+
+
+function water_container(width, height, fill, x=0, y=0)
+    #Produces an SVG water container of size height, width, filled from the
+    #bottom to the height fill (as a proportion of height
+    #fill_level = fill*height
+    fill_level = fill*height
+    water_style = Dict(:fill => "rgb$s_blue")
+    wall_style  = Dict(:fill => "rgb$s_black")
+    container_attr =  Dict("x" => "$x",
+                           "y" => "$y",
+                           "width" => "$width",
+                          "height" => "$height")
+    #svg_rect(width, fill_level, height-fill_level, water_style)
+    Node(svgsvg_symb, 
+         svg_rect(width, fill_level, 0, height-fill_level, water_style),
+         svg_rect(wall_thickness, height, 0, 0, wall_style),
+         svg_rect(wall_thickness, height, width-wall_thickness, 0, wall_style),
+         svg_rect((width-mouth_width)/2, wall_thickness, 0, height-wall_thickness, wall_style),
+         svg_rect((width-mouth_width)/2, wall_thickness, (width+mouth_width)/2, height-wall_thickness, wall_style),
+         attributes = container_attr)
+end
+
+
+function tank_construct(upper, lower, pump_speed = 1, tnum = 0, r = -1)
+    height = 250
+    width  = 200
+
+    arrowwidth = 0
+    arrowheight= 20
+    arrowtext = ""
+    #level_upper = height*upper
+    #level_lower = height*lower
+    upper_x = 75
+    upper_y = 100
+    lower_x = 75
+    lower_y = upper_y + height+50
+
+    tank_x      = 0
+    tank_y      = upper_y + height*2 + 100
+    tank_width  = 2*lower_x+width
+    tank_height = 50
+    pipe_thickness = 25
+    pd = (pipe_thickness-mouth_width)/2
+    pt = pipe_thickness/2
+
+    if r>=0 && r<=1
+        arrowwidth = 20
+    end
+    redarrow = svg_polygon([(upper_x+width, 50+tnum*(height+50)-r*height), 
+                            (upper_x+width+arrowwidth, 50+tnum*(height+50)-r*height-arrowheight),
+                            (upper_x+width+arrowwidth, 50+tnum*(height+50)-r*height+arrowheight)], s_red)
+    pipe = svg_polyline([(pipe_thickness/2, height*2+250), (pt,pt), (tank_width/2, pt), (tank_width/2, 50-pt)],
+                        pipe_thickness, s_black)
+    funnel = svg_polygon([(tank_width/2, 2*pt), (tank_width/2-pipe_thickness*2, 4*pt), 
+                          (tank_width/2+pipe_thickness*2, 4*pt)], s_black)
+
+
+    #remove constraints later when controller is bug free
+    w1 = mouth_width*sqrt(max(0,pump_speed))
+    w2 = mouth_width*sqrt(max(0, upper))
+    w3 = mouth_width*sqrt(max(0, lower))
+
+    container1 = water_container(width, height, upper, upper_x, upper_y)
+    container2 = water_container(width, height, lower, lower_x, lower_y)
+
+
+    #The order of svg objects is important, latter elements are laid on top of existing ones
+    Node(svgsvg_symb, 
+         stream(w1, height+50, upper_x+(width-w1)/2, 50)...,
+    stream(w2, height+50, upper_x+(width-w2)/2, height+100)...,
+    stream(w3, 100, upper_x+(width-w3)/2, 2*height+150)...,
+    container1, container2, redarrow, 
+    #water_container(width, height, upper, upper_x, upper_y), 
+    #water_container(width, height, lower, lower_x, lower_y),
+    svg_rect(tank_width, tank_height, tank_x, tank_y),
+    pipe,
+    funnel,
+    id = "tank",
+    attributes = stdattr)
+end
+
+#=
+gui = GUI()
+widgets, garbage = @construct for upper in 0:16, 
+    lower in 0:16
+    Node(:div, "", id = "blarf")
+end
+
+set!(gui, widgets)
+
+dummy, graphic = @construct for tankvar in 0:1
+    tank_construct(gui[:upper]/16, gui[:lower]/16)
+end
+
+add!(gui, dummy)
+
+widgets2, graphic2 = @construct for t in 0:0.1:10
+    plot(linspace(0,2pi), sin.(gui[:lower]*linspace(0,2pi)))
+    plot!(linspace(0,2pi), cos.(gui[:upper]*linspace(0,2pi)))
+end
+
+add!(gui, widgets2)
+
+layout = make_grid(2,2)
+options_grid = make_grid(2,1)
+options_grid = setindex_(options_grid, widgets[1], 1, 1)
+options_grid = setindex_(options_grid, widgets[2], 2, 1)
+layout = setindex_(layout, options_grid, 1, 1)
+layout = setindex_(layout, graphic, 1, 2)
+layout = setindex_(layout, garbage, 2, 1)
+layout = setindex_(layout, graphic2, 2, 2)
+
+set!(gui, layout)
+
+
+function initialize()
+    print("Initializing...\n")
+    #WebIO.newid()
+    LabGUI.animate(gui, [:tankvar, :t], [:upper, :lower])
+    #animate(gui, :tankvar, 1)
+end
+
+function responder(req) 
+    initialize()
+    gui.dom
+end
+
+webio_serve(page("/", responder), 8004)
+=#
diff --git a/src/tanklabgui.jl b/src/tanklabgui.jl
new file mode 100644
index 0000000000000000000000000000000000000000..d21a2cfe067abfc121fc704208768c776d97c528
--- /dev/null
+++ b/src/tanklabgui.jl
@@ -0,0 +1,114 @@
+function makegui(P, plottingframerate = 10, guiframerate = 10)
+    #tankpid = PID(1.0, 1.0, R.h, 1.0, 1.0, 0.51, 10, P)
+    tankpid = PID()
+    scale = 100/16
+    boundsupper = (0,1)
+    boundslower = (-2,2)
+    maxplotlength = 800
+    gui = GUI()
+    #ptfr = P.α/(P.a1*sqrt(2*P.g*(outputrange(P)[1][2]))) #pump to flow ratio
+	ptfr = 3.8 #the accuracy here isn't very important
+
+    widgets, graphic1 = @construct for 
+        u      in slider(0:0.01:1, label="  u"),
+        run    in button("Run"), #This should only exist in the simulated version
+        K      in slider(0:50, label="K"),
+        Ti     in slider(0:50, label="Ti"),
+        Td     in slider(0:50, label="Td"),
+        r      in slider(0:0.01:1.0, label="  r"), 
+        mode   in togglebuttons(["Manual", "Automatic"], label=""),
+        tankno in togglebuttons(["Upper", "Lower"], label=""),
+        pOn    in togglebuttons(["On", "Off"], label="P"),
+        iOn    in togglebuttons(["On", "Off"], label="I"),
+        dOn    in togglebuttons(["On", "Off"], label="D")
+
+        tankpid.K = K
+        tankpid.Ti = Ti
+        tankpid.Td = Td
+        if tankno=="Upper"
+				tankg = tank_construct(measure(P)..., u*ptfr, 1, r)
+        elseif tankno=="Lower"
+				tankg = tank_construct(measure(P)..., u*ptfr, 2, r)
+        else
+				tankg = tank_construct(measure(P)..., u*ptfr)
+        end
+        Node(:div, tankg, id="tanks")
+    end
+
+    w2, graphic2 = @construct for 
+        dummy in checkbox(false, label="This button does nothing")
+        if length(gui.data[1])>maxplotlength
+            start = length(gui.data[1])-maxplotlength
+        else
+            start=1
+        end
+        p = plot(layout=(2,1), size=(700, 600))
+        plot!(p[1], gui.data[1][start:end], label="y", ylim = boundsupper)
+        plot!(p[1], gui.data[2][start:end], label="r")
+        plot!(p[2], gui.data[3][start:end], label="P", ylim = boundslower)
+        plot!(p[2], gui.data[4][start:end], label="I")
+        plot!(p[2], gui.data[5][start:end], label="D")
+        plot!(p[2], gui.data[6][start:end], label="Tot", color=:black)
+    end
+
+    #-----------------------------------------------#
+    #This should only exist in the simulated version#
+    on(obs(run)) do val
+        if val==1
+            @async prbs_experiment(P, gui, tankpid)
+        else
+            obs(run).listeners[end] = x ->()
+        end
+    end
+    #-----------------------------------------------#
+
+    layout = make_grid(1, 2)
+    left_element  = make_grid(2,1)
+    settings_element = make_grid(5,1)
+    corner_element = make_grid(1,4)
+
+
+    p_element = make_grid(2,1)
+    p_element = setindex_(p_element, dom"div"(widgets[:pOn]), 1, 1)
+    p_element = setindex_(p_element, dom"div"(widgets[:K]), 2, 1)
+
+    i_element = make_grid(2,1)
+    i_element = setindex_(i_element, dom"div"(widgets[:iOn]), 1, 1)
+    i_element = setindex_(i_element, dom"div"(widgets[:Ti]), 2, 1)
+
+    d_element = make_grid(2,1)
+    d_element = setindex_(d_element, dom"div"(widgets[:dOn]), 1, 1)
+    d_element = setindex_(d_element, dom"div"(widgets[:Td]), 2, 1)
+
+
+    settings_element = setindex_(settings_element, dom"div"(widgets[:run]), 1, 1)
+    #settings_element = setindex_(settings_element, runbutton, 1, 1)
+    settings_element = setindex_(settings_element, dom"div"(widgets[:tankno]), 2, 1)
+    settings_element = setindex_(settings_element, dom"div"(widgets[:mode]), 3, 1)
+    settings_element = setindex_(settings_element, dom"div"(widgets[:r]), 4, 1)
+    settings_element = setindex_(settings_element, dom"div"(widgets[:u]), 5, 1)
+
+
+    corner_element = setindex_(corner_element, settings_element, 1, 1)
+    corner_element = setindex_(corner_element, p_element, 1, 2)
+    corner_element = setindex_(corner_element, i_element, 1, 3)
+    corner_element = setindex_(corner_element, d_element, 1, 4)
+
+    left_element = setindex_(left_element, corner_element, 1, 1)
+    left_element = setindex_(left_element, graphic2, 2, 1)
+    layout = setindex_(layout, left_element, 1, 1)
+    layout = setindex_(layout, graphic1, 1, 2)
+
+
+
+    LabGUI.set!(gui, widgets)
+    LabGUI.set!(gui, layout)
+    add!(gui, w2)
+
+    LabGUI.animate(gui, :u, 1/guiframerate)
+    LabGUI.animate(gui, :dummy, 1/plottingframerate)
+    function responder(req) 
+        gui() #With Mux
+    end
+    return (gui, responder, tankpid)
+end