6 import org.jetbrains.annotations.Contract;
7 import org.jetbrains.annotations.NotNull;
8 import org.slf4j.Logger;
9 import org.slf4j.LoggerFactory;
11 import java.io.IOException;
12 import java.time.Duration;
13 import java.util.Optional;
19 private static final Logger log = LoggerFactory.getLogger
21 private Double desiredVoltage = 28.0;
22 private Float pressureUpperBound = 1e-9f;
24 private Integer maximumIterations = 100;
26 private Boolean
isRunning = Boolean.FALSE;
33 isRunning = Boolean.TRUE;
35 VoltageSetPointTask task;
38 task =
new VoltageSetPointTask(
39 kernel, maximumIterations, pressureUpperBound, desiredVoltage
41 }
catch (IOException error){
42 log.error(
"Unable to create voltage setpoint task", error);
43 throw new UnableToRunControlAlgorithmException(
44 "Task creation threw IOException" 48 kernel.getTaskRunner().execute(task);
68 return desiredVoltage;
73 this.desiredVoltage = desiredVoltage;
78 return pressureUpperBound;
83 this.pressureUpperBound = pressureUpperBound;
88 return maximumIterations;
93 this.maximumIterations = maximumIterations;
97 Boolean canRun = hasKernel() &&
103 "control algorithm");
108 @Contract(pure =
true)
109 private Boolean hasKernel(){
110 return this.kernel != null;
114 private Boolean hasPowerSupply(){
116 return this.kernel.getDeviceRegistryView().hasPowerSupply();
118 return Boolean.FALSE;
122 private Boolean hasPressureGauge(){
124 return this.kernel.getDeviceRegistryView().hasPressureGauge();
126 return Boolean.FALSE;
134 voltage = kernel.getDeviceRegistryView().getPowerSupply()
135 .getMeasuredVoltage();
136 }
catch (IOException error){
140 return voltage/desiredVoltage;
143 public static class VoltageSetPointTask
implements Runnable {
144 private static final Logger log = LoggerFactory.getLogger
145 (VoltageSetPointTask.class);
147 private final Kernel kernel;
149 private final Integer maximumIterations;
151 private final Double startingVoltage;
153 private final Double voltageIncrement = 0.1;
155 private final Duration waitTime = Duration.ofSeconds(5);
157 private final Float maximumPressure;
159 private final Double desiredVoltage;
161 public VoltageSetPointTask(
162 Kernel kernel, Integer maximumIterations,
163 Float maximumPressure, Double desiredVoltage
166 this.kernel = kernel;
167 this.maximumIterations = maximumIterations;
168 this.maximumPressure = maximumPressure;
169 this.desiredVoltage = desiredVoltage;
171 startingVoltage = kernel.getDeviceRegistryView().getPowerSupply
172 ().getMeasuredVoltage();
177 log.info(
"Started setpoint task, with starting voltage {}",
179 Double measuredVoltage = startingVoltage;
180 Integer iterationNumber = 0;
184 while (shouldLoop(measuredVoltage, iterationNumber)) {
186 measuredVoltage = getVoltage();
187 log.debug(
"Measured voltage is {}", measuredVoltage);
189 setDeviceVoltage(measuredVoltage + voltageIncrement);
190 log.debug(
"Set output voltage to {}", measuredVoltage +
192 }
catch (IOException error){
193 log.error(
"IOException detected while attempting to set " +
195 handleIOException(error);
200 waitForPressureToDropBelowMinimum();
206 waitForActionInterval();
207 }
catch (InterruptedException error){
208 log.info(
"Voltage setter interrupted");
214 turnPowerSupplyOff();
218 @Contract(pure =
true)
219 private Boolean shouldLoop(
220 Double measuredVoltage, Integer iterationNumber
222 Boolean hasExceededIterations =
223 iterationNumber > maximumIterations;
225 Boolean hasExceededDesiredVoltage = measuredVoltage >
228 if (hasExceededDesiredVoltage){
229 log.info(
"Stopping loop");
230 return Boolean.FALSE;
233 if (hasExceededIterations) {
234 log.info(
"Stopping loop");
235 return Boolean.FALSE;
241 private Double getVoltage()
throws IOException {
242 return kernel.getDeviceRegistryView().getPowerSupply()
243 .getMeasuredVoltage();
246 private void turnPowerSupplyOn() {
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);
255 private void turnPowerSupplyOff(){
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);
264 private void setDeviceVoltage(Double newVoltage)
throws IOException {
265 log.debug(
"Setting power supply voltage to {}", newVoltage);
266 kernel.getDeviceRegistryView().getPowerSupply().setVoltage(newVoltage);
269 private void waitForActionInterval()
throws InterruptedException {
270 log.debug(
"Waiting for {} milliseconds", waitTime.toMillis());
271 Thread.sleep(waitTime.toMillis());
274 private void waitForPressureToDropBelowMinimum()
throws StopIteration {
275 Integer iterationNumber = 0;
276 Optional<Float> pressure = getMeasuredPressure();
278 if (!pressure.isPresent()){
279 log.debug(
"Returned pressure is null. Resuming algorithm.");
284 pressure.get() > maximumPressure &&
285 iterationNumber < maximumIterations) {
287 waitForActionInterval();
288 }
catch (InterruptedException error) {
292 pressure = getMeasuredPressure();
294 log.debug(
"Measured pressure {}, iteration {}",
295 pressure.get(), iterationNumber);
299 private Optional<Float> getMeasuredPressure(){
302 kernel.getDeviceRegistryView().getPressureGauge()
305 }
catch (Exception error){
306 log.error(
"Attempting to get pressure returned error {}",
308 return Optional.empty();
312 private static void handleIOException(IOException error){
313 log.error(
"Attempt to get voltage threw IOException",
Integer getMaximumIterations()
void setKernel(Kernel kernel)
void setPressureUpperBound(Float pressureUpperBound)
void setMaximumIterations(Integer maximumIterations)
Double getDesiredVoltage()
Float getPressureUpperBound()
void setDesiredVoltage(Double desiredVoltage)