Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
processes
DoubleTankLab.jl
Commits
9d248b8d
Commit
9d248b8d
authored
Mar 07, 2018
by
Jacob Wikmark
Browse files
More files, fixed refs
parent
9c076ea4
Changes
4
Hide whitespace changes
Inline
Side-by-side
src/livetankdemo.jl
View file @
9d248b8d
using
InteractNext
,
Mux
,
Plots
,
LabProcesses
,
LabConnections
,
LabGUI
include
(
"tankgraphic.jl"
)
include
(
"
d
ouble
t
ank.jl"
)
include
(
"
D
ouble
T
ank.jl"
)
include
(
"tanklabgui.jl"
)
...
...
src/tankdemo.jl
View file @
9d248b8d
using
InteractNext
,
Mux
,
Plots
,
LabProcesses
,
LabGUI
include
(
"tankgraphic.jl"
)
include
(
"
d
ouble
t
ank.jl"
)
include
(
"
D
ouble
T
ank.jl"
)
include
(
"tanklabgui.jl"
)
R
=
DoubleTankSimulator
(
σ
=
0.001
)
...
...
src/tankgraphic.jl
0 → 100644
View file @
9d248b8d
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)
=#
src/tanklabgui.jl
0 → 100644
View file @
9d248b8d
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
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment