From a957490cd811132efefdd62a5a8444bb6a31bf91 Mon Sep 17 00:00:00 2001 From: Imbus <> Date: Fri, 15 Nov 2024 09:27:17 +0100 Subject: [PATCH] Simpler temp and water controllers --- wash/src/wash/control/ControllerTemp.java | 107 +++++++----------- wash/src/wash/control/ControllerWater.java | 125 ++++++++------------- 2 files changed, 88 insertions(+), 144 deletions(-) diff --git a/wash/src/wash/control/ControllerTemp.java b/wash/src/wash/control/ControllerTemp.java index 3caef71..afd0b8b 100644 --- a/wash/src/wash/control/ControllerTemp.java +++ b/wash/src/wash/control/ControllerTemp.java @@ -6,94 +6,67 @@ import wash.control.WashingMessage.Order; public final class ControllerTemp extends ActorThread { private WashingIO io; - private Heater heater; private WashingMessage m; + private WashingMessage temp; + private boolean ackSent = true; + private Order heaterState = Order.TEMP_IDLE; public ControllerTemp(WashingIO io) { this.io = io; - heater = new Heater(0); } protected void sendAck() { m.sendAck(this); + ackSent = true; } @Override public void run() { - heater.start(); - while (true) { try { - m = take(); - } catch (Exception e) { - System.exit(1); - } + temp = receiveWithTimeout(10000 / Settings.SPEEDUP); - switch (m.order()) { - case Order.TEMP_SET_40 -> heater.setTarget(40); - case Order.TEMP_SET_60 -> heater.setTarget(60); - case Order.TEMP_IDLE -> heater.setTarget(0); // TODO: Error - default -> { - continue; + // If there is a new message, swap + if (temp != null) { + m = temp; + ackSent = false; // We have a new order } - } - } - } - /** - * Heater class that extends Thread and controls the temperature - * of the washing machine. - * - * Note that the heater has access to local variables in the - * TemperatureController class. - */ - class Heater extends Thread { - double target; - boolean hovering; + // If this message is not the same as last time + if (m != null && m.order() != heaterState) { + heaterState = m.order(); + } - Heater(double target) { - this.target = target; - this.hovering = true; // No acks before actual setpoint is acquired - } - - synchronized public void setTarget(double target) { - this.target = target; - this.hovering = false; - } - - @Override - public void run() { - double current; - try { - while (!isInterrupted()) { - current = io.getTemperature(); - - if (io.getWaterLevel() == 0) { - io.heat(false); - sleep(60000 / Settings.SPEEDUP); - continue; - } - - if (current < target) { - io.heat(true); - } - - else if (current >= target) { - io.heat(false); - - if (!hovering) { - sendAck(); - hovering = true; - sleep(60000 / Settings.SPEEDUP); - continue; + switch (heaterState) { + case Order.TEMP_SET_40 -> { + if (io.getTemperature() <= 39) { + io.heat(true); + } else { + io.heat(false); + if (!ackSent) + sendAck(); } } - - sleep(60000 / Settings.SPEEDUP); + case Order.TEMP_SET_60 -> { + if (io.getTemperature() <= 59) { + io.heat(true); + } else { + io.heat(false); + if (!ackSent) + sendAck(); + } + } + case Order.TEMP_IDLE -> { + io.heat(false); + if (!ackSent) + sendAck(); + } + default -> { + continue; + } } - } catch (InterruptedException e) { - io.heat(false); - Thread.currentThread().interrupt(); + } catch (Exception e) { + System.out.println("Exception: " + e); } } } diff --git a/wash/src/wash/control/ControllerWater.java b/wash/src/wash/control/ControllerWater.java index 0e7f647..6dcf200 100644 --- a/wash/src/wash/control/ControllerWater.java +++ b/wash/src/wash/control/ControllerWater.java @@ -1,5 +1,7 @@ package wash.control; +import static wash.control.WashingMessage.Order.WATER_IDLE; + import actor.ActorThread; import wash.control.WashingMessage.Order; import wash.io.WashingIO; @@ -8,98 +10,67 @@ public class ControllerWater extends ActorThread { WashingMessage.Order o; WashingMessage m; + WashingMessage temp; WashingIO io; - WaterPid waterpid; + + Order waterState = WATER_IDLE; + boolean ackSent = true; public ControllerWater(WashingIO io) { this.io = io; - this.waterpid = new WaterPid(0, 1); } public void sendAck() { + ackSent = true; m.sendAck(this); } @Override public void run() { - waterpid.start(); while (true) { - // m = poll(60000 / Settings.SPEEDUP).orElse(new WashingMessage(this, Order.NOOP)); try { - m = take(); + temp = receiveWithTimeout(10000 / Settings.SPEEDUP); + + // If there is a new message, swap + if (temp != null) { + m = temp; + ackSent = false; // We have a new order + } + + // If this message is not the same as last time + if (m != null && m.order() != waterState) { + waterState = m.order(); + } + + switch (waterState) { + case Order.WATER_DRAIN -> { + io.drain(true); + io.fill(false); + if (io.getWaterLevel() == 0 && !ackSent) + sendAck(); + } + case Order.WATER_FILL -> { + io.drain(false); + + if (io.getWaterLevel() < 19) + io.fill(true); + else { + io.fill(false); + if (!ackSent) { + sendAck(); + } + } + } + case Order.WATER_IDLE -> { + io.drain(false); + io.fill(false); + } + default -> { + continue; + } + } } catch (Exception e) { - System.exit(1); - } - - switch (m.order()) { - case Order.WATER_DRAIN -> waterpid.setTarget(0); - case Order.WATER_FILL -> waterpid.setTarget(20); - case Order.WATER_IDLE -> waterpid.setIdle(); - default -> { - continue; - } - } - } - } - - /** A pid controller that is not actually a pid controller */ - public final class WaterPid extends Thread { - private double target; - private final double tolerance; // Acceptable range around target - private boolean hover = false; // Indicates if we're close enough to the target - private boolean hasAcknowledged = true; // Tracks if ack has been sent - - public WaterPid(double targetLiter, double tolerance) { - this.target = targetLiter; - this.tolerance = tolerance; - } - - /** Set the target level */ - public synchronized void setTarget(double targetLiter) { - this.target = targetLiter; - this.hover = false; - this.hasAcknowledged = false; // Reset ack when target changes - } - - /** Just coast at current level */ - public synchronized void setIdle() { - this.setTarget(io.getWaterLevel()); - } - - /** Main control loop */ - @Override - public void run() { - while (!isInterrupted()) { - double currentLevel = io.getWaterLevel(); // Get current water level - double error = target - currentLevel; - hover = Math.abs(error) <= tolerance; - - // Open or close drain/fill based on current water level - if (!hover) { - if (error > 0) { - io.fill(true); // Open tap to increase water level - io.drain(false); // Ensure drain is closed - } else { - io.drain(true); // Open drain to decrease water level - io.fill(false); // Ensure tap is closed - } - } else { - // Stop adjustments if hovering near target - io.fill(false); - io.drain(false); - - // Send acknowledgment if target is reached for the first time - if (!hasAcknowledged) { - sendAck(); - hasAcknowledged = true; - } - } - - try { - Thread.sleep(100); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } + System.out.println("Exception: " + e); } } }