forked from alexliebmanp/strain_control
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsimulation.py
More file actions
128 lines (115 loc) · 4.71 KB
/
simulation.py
File metadata and controls
128 lines (115 loc) · 4.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
'''
classes and methods for simulating the strain control system, mainly for testing code.
'''
from concurrency_classes import LockedVar, StoppableThread
import threading
import time
class SimulatedLCR:
'''
simulation of LCR meter measuring CS130 capacitor for testing purposes.
'''
def __init__(self, val):
self.impedance = [val, val] # complex impedance
class SimulatedPS:
'''
simulation of Razorbill power supply for testing purposes. Includes method v_to_imp(), which is meant to simulate the piezo response (and hence capacitor reading) expected for a given output voltage, such that when a new voltage is set the SimulatedLCR object responds accordingly.
'''
def __init__(self, lcr):
self.voltage_1 = LockedVar(0) # tension stack
self.voltage_2 = LockedVar(0) # compression stack
self.output_1 = LockedVar(False)
self.output_2 = LockedVar(False)
self.slew_rate = LockedVar(10) # V/s
self.tol = 0.01 # V
self.lcr = lcr
self.vmax = 120 # V
self.vim = -20 # V
self.voltage_setter1 = StoppableThread(target=self.set_new_voltage, args=(1, self.voltage_1.locked_read(),))
self.voltage_setter2 = StoppableThread(target=self.set_new_voltage, args=(2, self.voltage_2.locked_read(),))
def set_voltage(self, channel, v):
''' use this for immediate update (no ramping)
self.voltage_1 = v
self.voltage_2 = v
self.lcr.impedance = self.v_to_imp(v)
'''
if channel==1:
if self.voltage_setter1.is_alive():
self.voltage_setter1.stop()
self.voltage_setter1 = StoppableThread(target=self.set_new_voltage, args=(channel, v))
self.voltage_setter1.start()
elif channel==2:
if self.voltage_setter2.is_alive():
self.voltage_setter2.stop()
self.voltage_setter2 = StoppableThread(target=self.set_new_voltage, args=(channel, v))
self.voltage_setter2.start()
def set_new_voltage(self, channel, v): # incorporates ramp rate
if channel==1:
t0 = time.time()
sign = 1
v1 = self.voltage_1.locked_read()
if v1 > v:
sign = -1
while v1 < (v-self.tol) or v1 > (v+self.tol):
current_thread = threading.current_thread()
if current_thread.stopped()==True:
break
t = time.time()
dt = t-t0
dv = sign*self.slew_rate.locked_read()*dt
# only accept dv if it doesn't overshoot
if sign==1:
if v1 + dv > v:
dv = v - v1
elif sign==-1:
if v1 + dv < v:
dv = v - v1
v_new = v1 + dv
v1 = v_new
self.voltage_1.locked_update(v_new)
self.lcr.impedance = self.v_to_imp(v_new)
t0 = t
if channel==2:
t0 = time.time()
sign = 1
v2 = self.voltage_2.locked_read()
if v2 > v:
sign = -1
while v2 < (v-self.tol) or v2 > (v+self.tol):
current_thread = threading.current_thread()
if current_thread.stopped()==True:
break
t = time.time()
dt = t-t0
dv = sign*self.slew_rate.locked_read()*dt
# only accept dv if it gets you closer to the setpoint
if sign==1:
if v2 + dv > v:
dv = v - v2
elif sign==-1:
if v2 + dv < v:
dv = v - v2
v_new = v1 + dv
v2 = v_new
self.voltage_2.locked_update(v_new)
#self.lcr.impedance = self.v_to_imp(v_new)
t0 = t
def v_to_imp(self, v):
# 0.05 um/V (assuming linear relation between dl and v)
dl = 0.05*v
l0 = 68.68 # um
area = 5.95e6 # um^2
response = 12e-3 # pF/um - can be used for simpler approx
eps0 = 8.854e-6 # pF/um - vacuum permitivity
cap = eps0*area/(dl+l0) + 0.04
return [cap/1e12, cap/1e12]
class SimulatedMontana:
'''
simulation of Montana CryoAdvance 100 for reading temperaure
'''
def __init__(self):
self.platform_temperature = LockedVar(300)
def get_platform_temperature(self):
'''
returns the simulated temperature in same form as Montana command.
'''
return [True, self.platform_temperature.locked_read()]