BakeoutController-Basic  0.1
A Controller for the Omicron vacuum chamber
models/VoltageSetPointAlgorithm.java
1 package kernel.models;
2 
5 import kernel.Kernel;
6 import org.jetbrains.annotations.Contract;
7 import org.jetbrains.annotations.NotNull;
8 import org.slf4j.Logger;
9 import org.slf4j.LoggerFactory;
10 
11 import java.io.IOException;
12 import java.time.Duration;
13 import java.util.Optional;
14 
18 public class VoltageSetPointAlgorithm implements kernel.controllers.VoltageSetPointAlgorithm {
19  private static final Logger log = LoggerFactory.getLogger
21  private Double desiredVoltage = 28.0;
22  private Float pressureUpperBound = 1e-9f;
23 
24  private Integer maximumIterations = 100;
25 
26  private Boolean isRunning = Boolean.FALSE;
27 
28  private Kernel kernel;
29 
30  @Override
32  assertCanRun();
33  isRunning = Boolean.TRUE;
34 
35  VoltageSetPointTask task;
36 
37  try {
38  task = new VoltageSetPointTask(
39  kernel, maximumIterations, pressureUpperBound, desiredVoltage
40  );
41  } catch (IOException error){
42  log.error("Unable to create voltage setpoint task", error);
43  throw new UnableToRunControlAlgorithmException(
44  "Task creation threw IOException"
45  );
46  }
47 
48  kernel.getTaskRunner().execute(task);
49  }
50 
51  @Override
52  public Kernel getKernel(){
53  return kernel;
54  }
55 
56  @Override
57  public void setKernel(Kernel kernel){
58  this.kernel = kernel;
59  }
60 
61  @Override
62  public Boolean isRunning(){
63  return isRunning;
64  }
65 
66  @Override
67  public Double getDesiredVoltage(){
68  return desiredVoltage;
69  }
70 
71  @Override
72  public void setDesiredVoltage(Double desiredVoltage){
73  this.desiredVoltage = desiredVoltage;
74  }
75 
76  @Override
77  public Float getPressureUpperBound(){
78  return pressureUpperBound;
79  }
80 
81  @Override
82  public void setPressureUpperBound(Float pressureUpperBound){
83  this.pressureUpperBound = pressureUpperBound;
84  }
85 
86  @Override
87  public Integer getMaximumIterations(){
88  return maximumIterations;
89  }
90 
91  @Override
92  public void setMaximumIterations(Integer maximumIterations){
93  this.maximumIterations = maximumIterations;
94  }
95 
96  private void assertCanRun() throws UnableToRunControlAlgorithmException {
97  Boolean canRun = hasKernel() &&
98  hasPowerSupply() &&
99  hasPressureGauge();
100 
101  if (!canRun){
102  throw new UnableToRunControlAlgorithmException("Unable to start " +
103  "control algorithm");
104  }
105  }
106 
107  @NotNull
108  @Contract(pure = true)
109  private Boolean hasKernel(){
110  return this.kernel != null;
111  }
112 
113  @NotNull
114  private Boolean hasPowerSupply(){
115  if (hasKernel()){
116  return this.kernel.getDeviceRegistryView().hasPowerSupply();
117  } else {
118  return Boolean.FALSE;
119  }
120  }
121 
122  private Boolean hasPressureGauge(){
123  if (hasKernel()){
124  return this.kernel.getDeviceRegistryView().hasPressureGauge();
125  } else {
126  return Boolean.FALSE;
127  }
128  }
129 
130  @Override
131  public Double getProgress(){
132  Double voltage;
133  try {
134  voltage = kernel.getDeviceRegistryView().getPowerSupply()
135  .getMeasuredVoltage();
136  } catch (IOException error){
137  voltage = 0.0;
138  }
139 
140  return voltage/desiredVoltage;
141  }
142 
143  public static class VoltageSetPointTask implements Runnable {
144  private static final Logger log = LoggerFactory.getLogger
145  (VoltageSetPointTask.class);
146 
147  private final Kernel kernel;
148 
149  private final Integer maximumIterations;
150 
151  private final Double startingVoltage;
152 
153  private final Double voltageIncrement = 0.1;
154 
155  private final Duration waitTime = Duration.ofSeconds(5);
156 
157  private final Float maximumPressure;
158 
159  private final Double desiredVoltage;
160 
161  public VoltageSetPointTask(
162  Kernel kernel, Integer maximumIterations,
163  Float maximumPressure, Double desiredVoltage
164  )
165  throws IOException {
166  this.kernel = kernel;
167  this.maximumIterations = maximumIterations;
168  this.maximumPressure = maximumPressure;
169  this.desiredVoltage = desiredVoltage;
170 
171  startingVoltage = kernel.getDeviceRegistryView().getPowerSupply
172  ().getMeasuredVoltage();
173  }
174 
175  @Override
176  public void run(){
177  log.info("Started setpoint task, with starting voltage {}",
178  startingVoltage);
179  Double measuredVoltage = startingVoltage;
180  Integer iterationNumber = 0;
181 
182  turnPowerSupplyOn();
183 
184  while (shouldLoop(measuredVoltage, iterationNumber)) {
185  try {
186  measuredVoltage = getVoltage();
187  log.debug("Measured voltage is {}", measuredVoltage);
188 
189  setDeviceVoltage(measuredVoltage + voltageIncrement);
190  log.debug("Set output voltage to {}", measuredVoltage +
191  voltageIncrement);
192  } catch (IOException error){
193  log.error("IOException detected while attempting to set " +
194  "voltage", error);
195  handleIOException(error);
196  break;
197  }
198 
199  try {
200  waitForPressureToDropBelowMinimum();
201  } catch (StopIteration error){
202  break;
203  }
204 
205  try {
206  waitForActionInterval();
207  } catch (InterruptedException error){
208  log.info("Voltage setter interrupted");
209  break;
210  }
211  iterationNumber++;
212  }
213 
214  turnPowerSupplyOff();
215  }
216 
217  @NotNull
218  @Contract(pure = true)
219  private Boolean shouldLoop(
220  Double measuredVoltage, Integer iterationNumber
221  ){
222  Boolean hasExceededIterations =
223  iterationNumber > maximumIterations;
224 
225  Boolean hasExceededDesiredVoltage = measuredVoltage >
226  desiredVoltage;
227 
228  if (hasExceededDesiredVoltage){
229  log.info("Stopping loop");
230  return Boolean.FALSE;
231  }
232 
233  if (hasExceededIterations) {
234  log.info("Stopping loop");
235  return Boolean.FALSE;
236  }
237 
238  return Boolean.TRUE;
239  }
240 
241  private Double getVoltage() throws IOException {
242  return kernel.getDeviceRegistryView().getPowerSupply()
243  .getMeasuredVoltage();
244  }
245 
246  private void turnPowerSupplyOn() {
247  try {
248  kernel.getDeviceRegistryView().getPowerSupply().outputOn();
249  log.debug("Power supply turned on.");
250  } catch (IOException error){
251  log.error("Unable to switch on power supply.", error);
252  }
253  }
254 
255  private void turnPowerSupplyOff(){
256  try {
257  kernel.getDeviceRegistryView().getPowerSupply().outputOff();
258  log.debug("Power supply turned off.");
259  } catch (IOException error) {
260  log.error("Unable to switch off power supply.", error);
261  }
262  }
263 
264  private void setDeviceVoltage(Double newVoltage) throws IOException {
265  log.debug("Setting power supply voltage to {}", newVoltage);
266  kernel.getDeviceRegistryView().getPowerSupply().setVoltage(newVoltage);
267  }
268 
269  private void waitForActionInterval() throws InterruptedException {
270  log.debug("Waiting for {} milliseconds", waitTime.toMillis());
271  Thread.sleep(waitTime.toMillis());
272  }
273 
274  private void waitForPressureToDropBelowMinimum() throws StopIteration {
275  Integer iterationNumber = 0;
276  Optional<Float> pressure = getMeasuredPressure();
277 
278  if (!pressure.isPresent()){
279  log.debug("Returned pressure is null. Resuming algorithm.");
280  throw new StopIteration();
281  }
282 
283  while (
284  pressure.get() > maximumPressure &&
285  iterationNumber < maximumIterations) {
286  try {
287  waitForActionInterval();
288  } catch (InterruptedException error) {
289  break;
290  }
291 
292  pressure = getMeasuredPressure();
293  iterationNumber++;
294  log.debug("Measured pressure {}, iteration {}",
295  pressure.get(), iterationNumber);
296  }
297  }
298 
299  private Optional<Float> getMeasuredPressure(){
300  try {
301  return Optional.of(
302  kernel.getDeviceRegistryView().getPressureGauge()
303  .getPressure()
304  );
305  } catch (Exception error){
306  log.error("Attempting to get pressure returned error {}",
307  error);
308  return Optional.empty();
309  }
310  }
311 
312  private static void handleIOException(IOException error){
313  log.error("Attempt to get voltage threw IOException",
314  error);
315  }
316  }
317 }
Git Repo