Skip to content

Commit d8b680a

Browse files
committed
Fix Pneumatic Valve
1 parent 2ef6655 commit d8b680a

File tree

2 files changed

+69
-9
lines changed

2 files changed

+69
-9
lines changed

src/prog_models/models/pneumatic_valve.py

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -240,16 +240,32 @@ def next_state(self, x, u, dt):
240240
vdot = pistonForces/params['m']
241241

242242
new_x = x['x']+x['v']*dt
243-
if (x['x']==0 and pistonForces<0) or (new_x<0):
244-
vel = 0
245-
pos = 0
246-
elif (x['x']==params['Ls'] and pistonForces>0) or (new_x>params['Ls']):
247-
vel = 0
248-
pos = params['Ls']
243+
244+
pos = minimum(maximum(new_x, 0.0), params['Ls'])
245+
246+
def calc_x(x, forces, Ls, new_x):
247+
lower_wall = (x==0 and forces<0) or (new_x<0)
248+
upper_wall = (x==Ls and forces>0) or (new_x>Ls)
249+
if lower_wall:
250+
return 0
251+
if upper_wall:
252+
return Ls
253+
return new_x
254+
255+
def calc_v(x, v, dv, forces, Ls, new_x):
256+
lower_wall = (x==0 and forces<0) or (new_x<0)
257+
upper_wall = (x==Ls and forces>0) or (new_x>Ls)
258+
if lower_wall or upper_wall:
259+
return 0
260+
return v + dv
261+
262+
if isscalar(pistonForces):
263+
vel = calc_v(x['x'], x['v'], vdot*dt, pistonForces, params['Ls'], new_x)
264+
pos = calc_x(x['x'], pistonForces, params['Ls'], new_x)
249265
else:
250-
# moving
251-
vel = x['v'] + vdot*dt
252-
pos = new_x
266+
# If array- run for each element
267+
vel = [calc_v(xi, vi, vdot_i*dt, force, params['Ls'], new_x_i) for xi, vi, vdot_i, force, new_x_i in zip(x['x'], x['v'], vdot, pistonForces, new_x)]
268+
vel = [calc_x(xi, force, params['Ls'], new_x_i) for xi, force, new_x_i in zip(x['x'], pistonForces, new_x)]
253269

254270
return {
255271
'x': pos,

tests/test_pneumatic_valve.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,52 @@
22

33
import unittest
44
from prog_models.models.pneumatic_valve import PneumaticValve, PneumaticValveWithWear, PneumaticValveBase
5+
from numpy import array
56

67
class TestPneumaticValve(unittest.TestCase):
8+
def test_pneumatic_valve_vectorized(self):
9+
m = PneumaticValveWithWear(process_noise= 0)
10+
11+
cycle_time = 20
12+
def future_loading(t, x=None):
13+
t = t % cycle_time
14+
if t < cycle_time/2:
15+
return {
16+
'pL': 3.5e5,
17+
'pR': 2.0e5,
18+
# Open Valve
19+
'uTop': False,
20+
'uBot': True
21+
}
22+
return {
23+
'pL': 3.5e5,
24+
'pR': 2.0e5,
25+
# Close Valve
26+
'uTop': True,
27+
'uBot': False
28+
}
29+
30+
x0 = {
31+
'x': array([0]*4),
32+
'v': array([0]*4),
33+
'Ai': array([0]*4),
34+
'r': array([6000]*4),
35+
'k': array([48000]*4),
36+
'Aeb': array([1e-5]*4),
37+
'Aet': array([1e-5]*4),
38+
'condition': array([1]*4),
39+
'mTop': array([0.069, 0.048, 0.027, 0.06]),
40+
'mBot': array([9.45e-4, 0.008, 0.016, 0.024]),
41+
'pDiff': array([1.5e5]*4),
42+
'wb': array([0]*4),
43+
'wi': array([0]*4),
44+
'wk': array([0]*4),
45+
'wr': array([0]*4),
46+
'wt': array([0]*4)
47+
}
48+
49+
x = m.next_state(x0, future_loading(0), 0.1)
50+
751
def test_pneumatic_valve_with_wear(self):
852
# Test using PneumaticValveWithWear
953
m = PneumaticValveWithWear(process_noise= 0)

0 commit comments

Comments
 (0)