我提出了一个“繁琐”的解决方案。希望我能从我得到的输入中更好地构建它。感谢改进建议,以便代码可以更短。我觉得元组处理很笨拙。表格的进一步创建和以后的图表可以与坦克过程更加分离。这将有助于重用于 CodeWorld 中的其他模拟任务。欢迎改进!
--
我现在更新了代码并使其更短,但也在表格中添加了更多数据点。 state_and_table 必须是 CodeWorld 中的元组,并且无法使用索引处理元组。
此外,您现在可以使用上下箭头更改泵速 qin。
扩展到两个(或更多)水箱,让控制水位变得更具挑战性,并将其作为练习留给您!尽情享受吧!
运行链接https://code.world/#P2uQaw2KBSbyspnQSn5E4Gw
program = activityOf(initial, change, tank_water)
-- Initial values of the total state, i.e. state_and_table
initial(rs) = state_and_table
state_and_table = (time_0, h_0, u_0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
time_0 = 0
h_0 = 7
u_0 = 0
-- Functions to read elements of state_and_table
time_of(time_value,_,_,_,_,_,_,_,_,_,_,_,_,
_,_,_,_,_,_,_,_,_,_) = time_value
h_of(_,h_value,_,_,_,_,_,_,_,_,_,_,_,
_,_,_,_,_,_,_,_,_,_) = h_value
u_of(_,_,u_value,_,_,_,_,_,_,_,_,_,_,
_,_,_,_,_,_,_,_,_,_) = u_value
table_entry((_,_,_,x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,
x11,x12,x13,x14,x15,x16,x17,x18,x19,x20), k)
| k==1 = x1
| k==2 = x2
| k==3 = x3
| k==4 = x4
| k==5 = x5
| k==6 = x6
| k==7 = x7
| k==8 = x8
| k==9 = x9
| k==10 = x10
| k==11 = x11
| k==12 = x12
| k==13 = x13
| k==14 = x14
| k==15 = x15
| k==16 = x16
| k==17 = x17
| k==18 = x18
| k==19 = x19
| k==20 = x20
-- Events of recording state to table at the following times
table_time = [ 5*t-5 | t <- [1..20]]
-- Parameters related to the water flow
g = 9.81
area = 0.025
-- Parameters of the tank
width = 5
height = 8
position = -5
-- Inlet and outlet flow
qin(u) = max(u, 0)
qout(h) = area*sqrt(2*g*max(h,0)) -- Bernoulli's physical model
-- Change of state_and_table
change(state_and_table, TimePassing(dt)) =
-- Update time
(time_of(state_and_table) + dt,
-- Physical state equation -- Euler approximation of differantial equation
max(h_of(state_and_table),0) - qout(h_of(state_and_table))*dt + qin(u_of(state_and_table))*dt,
-- Control variable u
u_of(state_and_table),
-- Event of recording state to table at predfined times
table_update(state_and_table,1),
table_update(state_and_table,2),
table_update(state_and_table,3),
table_update(state_and_table,4),
table_update(state_and_table,5),
table_update(state_and_table,6),
table_update(state_and_table,7),
table_update(state_and_table,8),
table_update(state_and_table,9),
table_update(state_and_table,10),
table_update(state_and_table,11),
table_update(state_and_table,12),
table_update(state_and_table,13),
table_update(state_and_table,14),
table_update(state_and_table,15),
table_update(state_and_table,16),
table_update(state_and_table,17),
table_update(state_and_table,18),
table_update(state_and_table,19),
table_update(state_and_table,20))
-- Key input
change(state_and_table, KeyPress("Up")) =
(time_of(state_and_table),
h_of(state_and_table),
u_of(state_and_table)+0.1,
table_update(state_and_table,1),
table_update(state_and_table,2),
table_update(state_and_table,3),
table_update(state_and_table,4),
table_update(state_and_table,5),
table_update(state_and_table,6),
table_update(state_and_table,7),
table_update(state_and_table,8),
table_update(state_and_table,9),
table_update(state_and_table,10),
table_update(state_and_table,11),
table_update(state_and_table,12),
table_update(state_and_table,13),
table_update(state_and_table,14),
table_update(state_and_table,15),
table_update(state_and_table,16),
table_update(state_and_table,17),
table_update(state_and_table,18),
table_update(state_and_table,19),
table_update(state_and_table,20))
change(state_and_table, KeyPress("Down")) =
(time_of(state_and_table),
h_of(state_and_table),
u_of(state_and_table)-0.1,
table_update(state_and_table,1),
table_update(state_and_table,2),
table_update(state_and_table,3),
table_update(state_and_table,4),
table_update(state_and_table,5),
table_update(state_and_table,6),
table_update(state_and_table,7),
table_update(state_and_table,8),
table_update(state_and_table,9),
table_update(state_and_table,10),
table_update(state_and_table,11),
table_update(state_and_table,12),
table_update(state_and_table,13),
table_update(state_and_table,14),
table_update(state_and_table,15),
table_update(state_and_table,16),
table_update(state_and_table,17),
table_update(state_and_table,18),
table_update(state_and_table,19),
table_update(state_and_table,20))
-- Default equation
change(state_and_table, other) = state_and_table
table_update(state_and_table, k)
| time_of(state_and_table) > table_time # k && table_entry(state_and_table,k)==0 = h_of(state_and_table)
| otherwise = table_entry(state_and_table, k)
-- Animation of system
composedOf = pictures
tank_water(state_and_table) = composedOf [headline, pump(qin(u_of(state_and_table))),
tank, water(h_of(state_and_table)),
graph(state_and_table),
coordinatePlane]
headline = translated(lettering("Tank dynamics"),5,7.5)
pump(qin) = translated(composedOf [lettering("- pump rate ="), translated(lettering(printed(qin)),3.7,0)], 4.5,6.5)
tank = translated(thickRectangle(width,height,0.2),position,4)
water(h) = translated(colored(solidPolygon [(-width/2, 0), (-width/2, h), (width/2, h), (width/2,0)],
light(blue)), position,0)
-- Graph of evolution of h(t) - note time scale is 1 = 10 s etc
scale = 1/10
graph(state_and_table) = colored(polyline [(scale*table_time#k, table_entry(state_and_table, k))
| k <- [1..length(table_time)], table_entry(state_and_table, k) /=0],
light(blue))