Compare commits
	
		
			5 commits
		
	
	
		
			819da6a4c3
			...
			1f880a1167
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 1f880a1167 | ||
|   | 43374804b3 | ||
|   | a957490cd8 | ||
|   | a3167aff1e | ||
|   | f195c39db7 | 
					 9 changed files with 181 additions and 244 deletions
				
			
		|  | @ -25,12 +25,12 @@ public abstract class ActorThread<M> extends Thread { | ||||||
|      * milliseconds if none available. Returns null if no message is obtained |      * milliseconds if none available. Returns null if no message is obtained | ||||||
|      * within 'timeout' milliseconds. |      * within 'timeout' milliseconds. | ||||||
|      */ |      */ | ||||||
|     @Deprecated |  | ||||||
|     protected M receiveWithTimeout(long timeout) throws InterruptedException { |     protected M receiveWithTimeout(long timeout) throws InterruptedException { | ||||||
|         return q.poll(timeout, TimeUnit.MILLISECONDS); |         return q.poll(timeout, TimeUnit.MILLISECONDS); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** Wait for a message continuously */ |     /** Wait for a message continuously */ | ||||||
|  |     @Deprecated | ||||||
|     protected M take() throws InterruptedException { |     protected M take() throws InterruptedException { | ||||||
|         return q.take(); |         return q.take(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -6,94 +6,67 @@ import wash.control.WashingMessage.Order; | ||||||
| 
 | 
 | ||||||
| public final class ControllerTemp extends ActorThread<WashingMessage> { | public final class ControllerTemp extends ActorThread<WashingMessage> { | ||||||
|     private WashingIO io; |     private WashingIO io; | ||||||
|     private Heater heater; |  | ||||||
|     private WashingMessage m; |     private WashingMessage m; | ||||||
|  |     private WashingMessage temp; | ||||||
|  |     private boolean ackSent = true; | ||||||
|  |     private Order heaterState = Order.TEMP_IDLE; | ||||||
| 
 | 
 | ||||||
|     public ControllerTemp(WashingIO io) { |     public ControllerTemp(WashingIO io) { | ||||||
|         this.io = io; |         this.io = io; | ||||||
|         heater = new Heater(0); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     protected void sendAck() { |     protected void sendAck() { | ||||||
|         m.sendAck(this); |         m.sendAck(this); | ||||||
|  |         ackSent = true; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     public void run() { |     public void run() { | ||||||
|         heater.start(); |  | ||||||
| 
 |  | ||||||
|         while (true) { |         while (true) { | ||||||
|             try { |             try { | ||||||
|                 m = take(); |                 temp = receiveWithTimeout(10000 / Settings.SPEEDUP); | ||||||
|             } catch (Exception e) { |  | ||||||
|                 System.exit(1); |  | ||||||
|             } |  | ||||||
| 
 | 
 | ||||||
|             switch (m.order()) { |                 // If there is a new message, swap | ||||||
|                 case Order.TEMP_SET_40 -> heater.setTarget(40); |                 if (temp != null) { | ||||||
|                 case Order.TEMP_SET_60 -> heater.setTarget(60); |                     m = temp; | ||||||
|                 case Order.TEMP_IDLE -> heater.setTarget(0); // TODO: Error |                     ackSent = false; // We have a new order | ||||||
|                 default -> { |  | ||||||
|                     continue; |  | ||||||
|                 } |                 } | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     /** |                 // If this message is not the same as last time | ||||||
|      * Heater class that extends Thread and controls the temperature |                 if (m != null && m.order() != heaterState) { | ||||||
|      * of the washing machine. |                     heaterState = m.order(); | ||||||
|      * |                 } | ||||||
|      * Note that the heater has access to local variables in the |  | ||||||
|      * TemperatureController class. |  | ||||||
|      */ |  | ||||||
|     class Heater extends Thread { |  | ||||||
|         double target; |  | ||||||
|         boolean hovering; |  | ||||||
| 
 | 
 | ||||||
|         Heater(double target) { |                 switch (heaterState) { | ||||||
|             this.target = target; |                     case Order.TEMP_SET_40 -> { | ||||||
|             this.hovering = true; // No acks before actual setpoint is acquired |                         if (io.getTemperature() <= 39) { | ||||||
|         } |                             io.heat(true); | ||||||
| 
 |                         } else { | ||||||
|         synchronized public void setTarget(double target) { |                             io.heat(false); | ||||||
|             this.target = target; |                             if (!ackSent) | ||||||
|             this.hovering = false; |                                 sendAck(); | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         @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; |  | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
| 
 |                     case Order.TEMP_SET_60 -> { | ||||||
|                     sleep(60000 / Settings.SPEEDUP); |                         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) { |             } catch (Exception e) { | ||||||
|                 io.heat(false); |                 System.out.println("Exception: " + e); | ||||||
|                 Thread.currentThread().interrupt(); |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -1,5 +1,7 @@ | ||||||
| package wash.control; | package wash.control; | ||||||
| 
 | 
 | ||||||
|  | import static wash.control.WashingMessage.Order.WATER_IDLE; | ||||||
|  | 
 | ||||||
| import actor.ActorThread; | import actor.ActorThread; | ||||||
| import wash.control.WashingMessage.Order; | import wash.control.WashingMessage.Order; | ||||||
| import wash.io.WashingIO; | import wash.io.WashingIO; | ||||||
|  | @ -8,98 +10,67 @@ public class ControllerWater extends ActorThread<WashingMessage> { | ||||||
| 
 | 
 | ||||||
|     WashingMessage.Order o; |     WashingMessage.Order o; | ||||||
|     WashingMessage m; |     WashingMessage m; | ||||||
|  |     WashingMessage temp; | ||||||
|     WashingIO io; |     WashingIO io; | ||||||
|     WaterPid waterpid; | 
 | ||||||
|  |     Order waterState = WATER_IDLE; | ||||||
|  |     boolean ackSent = true; | ||||||
| 
 | 
 | ||||||
|     public ControllerWater(WashingIO io) { |     public ControllerWater(WashingIO io) { | ||||||
|         this.io = io; |         this.io = io; | ||||||
|         this.waterpid = new WaterPid(0, 1); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public void sendAck() { |     public void sendAck() { | ||||||
|  |         ackSent = true; | ||||||
|         m.sendAck(this); |         m.sendAck(this); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     public void run() { |     public void run() { | ||||||
|         waterpid.start(); |  | ||||||
|         while (true) { |         while (true) { | ||||||
|             // m = poll(60000 / Settings.SPEEDUP).orElse(new WashingMessage(this, Order.NOOP)); |  | ||||||
|             try { |             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) { |             } catch (Exception e) { | ||||||
|                 System.exit(1); |                 System.out.println("Exception: " + e); | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             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(); |  | ||||||
|                 } |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -3,5 +3,5 @@ package wash.control; | ||||||
| public interface Settings { | public interface Settings { | ||||||
|     // simulation speed-up factor: 50 means the simulation is 50 times faster than |     // simulation speed-up factor: 50 means the simulation is 50 times faster than | ||||||
|     // real time. Modify this as you wish. |     // real time. Modify this as you wish. | ||||||
|     int SPEEDUP = 50; |     int SPEEDUP = 400; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -32,7 +32,7 @@ public class Wash { | ||||||
|             // if the user presses button 0, and a program has been started, stop it |             // if the user presses button 0, and a program has been started, stop it | ||||||
| 
 | 
 | ||||||
|             switch (n) { |             switch (n) { | ||||||
|                 case 0 -> t = new WashingProgramStop(io, temp, water, spin); |                 case 0 -> t.interrupt(); | ||||||
|                 case 1 -> t = new WashingProgram1(io, temp, water, spin); |                 case 1 -> t = new WashingProgram1(io, temp, water, spin); | ||||||
|                 case 2 -> t = new WashingProgram2(io, temp, water, spin); |                 case 2 -> t = new WashingProgram2(io, temp, water, spin); | ||||||
|                 case 3 -> t = new WashingProgram3(io, temp, water, spin); |                 case 3 -> t = new WashingProgram3(io, temp, water, spin); | ||||||
|  | @ -42,7 +42,8 @@ public class Wash { | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             t.start(); |             if (!t.isInterrupted()) | ||||||
|  |                 t.start(); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         temp.interrupt(); |         temp.interrupt(); | ||||||
|  |  | ||||||
|  | @ -39,19 +39,39 @@ public final class WashingProgram1 extends ActorThread<WashingMessage> { | ||||||
|             // Lock the hatch |             // Lock the hatch | ||||||
|             io.lock(true); |             io.lock(true); | ||||||
| 
 | 
 | ||||||
|  |             // Let water into the machine | ||||||
|             water.send(new WashingMessage(this, WATER_FILL)); |             water.send(new WashingMessage(this, WATER_FILL)); | ||||||
|             receive(); |             receive(); | ||||||
| 
 | 
 | ||||||
|             // Instruct SpinController to rotate barrel slowly, back and forth |             // Heat to 40 C | ||||||
|             // Expect an acknowledgment in response. |             temp.send(new WashingMessage(this, TEMP_SET_40)); | ||||||
|             spin.send(new WashingMessage(this, SPIN_SLOW)); |  | ||||||
|             receive(); |             receive(); | ||||||
| 
 | 
 | ||||||
|             // Spin for five simulated minutes (one minute == 60000 milliseconds) |             // Keep the temperature for 30 min | ||||||
|  |             Thread.sleep(30 * 60000 / Settings.SPEEDUP); | ||||||
|  | 
 | ||||||
|  |             // Drain | ||||||
|  |             temp.send(new WashingMessage(this, TEMP_IDLE)); | ||||||
|  |             receive(); | ||||||
|  |             water.send(new WashingMessage(this, WATER_DRAIN)); | ||||||
|  |             receive(); | ||||||
|  | 
 | ||||||
|  |             // Rinse 5*2 minutes in cold water | ||||||
|  |             for(int a = 0; a < 5; a++) { | ||||||
|  |                 water.send(new WashingMessage(this, WATER_FILL)); | ||||||
|  |                 receive(); | ||||||
|  | 
 | ||||||
|  |                 Thread.sleep(2 * 60000 / Settings.SPEEDUP); | ||||||
|  | 
 | ||||||
|  |                 water.send(new WashingMessage(this, WATER_DRAIN)); | ||||||
|  |                 receive(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             // Centrifuge for five minutes | ||||||
|  |             spin.send(new WashingMessage(this, SPIN_FAST)); | ||||||
|  |             receive(); | ||||||
|             Thread.sleep(5 * 60000 / Settings.SPEEDUP); |             Thread.sleep(5 * 60000 / Settings.SPEEDUP); | ||||||
| 
 | 
 | ||||||
|             // Instruct SpinController to stop spin barrel spin. |  | ||||||
|             // Expect an acknowledgment in response. |  | ||||||
|             spin.send(new WashingMessage(this, SPIN_OFF)); |             spin.send(new WashingMessage(this, SPIN_OFF)); | ||||||
|             receive(); |             receive(); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -40,9 +40,62 @@ public final class WashingProgram2 extends ActorThread<WashingMessage> { | ||||||
|             // Lock the hatch |             // Lock the hatch | ||||||
|             io.lock(true); |             io.lock(true); | ||||||
| 
 | 
 | ||||||
|             // Spin for five simulated minutes (one minute == 60000 milliseconds) |             // Let water into the machine | ||||||
|  |             water.send(new WashingMessage(this, WATER_FILL)); | ||||||
|  |             receive(); | ||||||
|  | 
 | ||||||
|  |             // Heat to 40 C | ||||||
|  |             temp.send(new WashingMessage(this, TEMP_SET_40)); | ||||||
|  |             receive(); | ||||||
|  | 
 | ||||||
|  |             // Keep the temperature for 20 min | ||||||
|  |             Thread.sleep(20 * 60000 / Settings.SPEEDUP); | ||||||
|  | 
 | ||||||
|  |             // Drain | ||||||
|  |             temp.send(new WashingMessage(this, TEMP_IDLE)); | ||||||
|  |             receive(); | ||||||
|  |             water.send(new WashingMessage(this, WATER_DRAIN)); | ||||||
|  |             receive(); | ||||||
|  | 
 | ||||||
|  |             // Let water into the machine | ||||||
|  |             water.send(new WashingMessage(this, WATER_FILL)); | ||||||
|  |             receive(); | ||||||
|  |             // Heat to 60 C | ||||||
|  |             temp.send(new WashingMessage(this, TEMP_SET_60)); | ||||||
|  |             receive(); | ||||||
|  | 
 | ||||||
|  |             // Keep the temperature for 20 min | ||||||
|  |             Thread.sleep(30 * 60000 / Settings.SPEEDUP); | ||||||
|  | 
 | ||||||
|  |             // Kill the heat | ||||||
|  |             temp.send(new WashingMessage(this, TEMP_IDLE)); | ||||||
|  |             receive(); | ||||||
|  | 
 | ||||||
|  |             // Rinse 5*2 minutes in cold water | ||||||
|  |             for(int a = 0; a < 5; a++) { | ||||||
|  |                 water.send(new WashingMessage(this, WATER_FILL)); | ||||||
|  |                 receive(); | ||||||
|  | 
 | ||||||
|  |                 Thread.sleep(2 * 60000 / Settings.SPEEDUP); | ||||||
|  | 
 | ||||||
|  |                 water.send(new WashingMessage(this, WATER_DRAIN)); | ||||||
|  |                 receive(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             // Centrifuge for five minutes | ||||||
|  |             spin.send(new WashingMessage(this, SPIN_FAST)); | ||||||
|  |             receive(); | ||||||
|             Thread.sleep(5 * 60000 / Settings.SPEEDUP); |             Thread.sleep(5 * 60000 / Settings.SPEEDUP); | ||||||
| 
 | 
 | ||||||
|  |             spin.send(new WashingMessage(this, SPIN_OFF)); | ||||||
|  |             receive(); | ||||||
|  | 
 | ||||||
|  |             temp.send(new WashingMessage(this, TEMP_IDLE)); | ||||||
|  |             receive(); | ||||||
|  | 
 | ||||||
|  |             water.send(new WashingMessage(this, WATER_DRAIN)); | ||||||
|  |             receive(); | ||||||
|  | 
 | ||||||
|             // Now that the barrel has stopped, it is safe to open the hatch. |             // Now that the barrel has stopped, it is safe to open the hatch. | ||||||
|             io.lock(false); |             io.lock(false); | ||||||
|             System.out.println("WashingProgram2 Finished..."); |             System.out.println("WashingProgram2 Finished..."); | ||||||
|  |  | ||||||
|  | @ -41,17 +41,16 @@ public final class WashingProgram3 extends ActorThread<WashingMessage> { | ||||||
|             io.lock(true); |             io.lock(true); | ||||||
|              |              | ||||||
|             // Switch off heating |             // Switch off heating | ||||||
|             // temp.send(new WashingMessage(this, TEMP_IDLE)); |             temp.send(new WashingMessage(this, TEMP_IDLE)); | ||||||
|             // System.out.println(receive()); |             receive(); | ||||||
|             // temp.send(new WashingMessage(this, TEMP_SET_40)); |  | ||||||
|             // System.out.println(receive()); |  | ||||||
| 
 | 
 | ||||||
|             temp.send(new WashingMessage(this, WATER_FILL)); |             // Spin off just to be sure | ||||||
|             System.out.println(receive()); |             spin.send(new WashingMessage(this, SPIN_OFF)); | ||||||
|             temp.send(new WashingMessage(this, WATER_DRAIN)); |             receive(); | ||||||
|             System.out.println(receive()); |  | ||||||
| 
 | 
 | ||||||
|             // Thread.sleep(5 * 60000 / Settings.SPEEDUP); |             // Drain water | ||||||
|  |             water.send(new WashingMessage(this, WATER_DRAIN)); | ||||||
|  |             receive(); | ||||||
| 
 | 
 | ||||||
|             // Unlock hatch |             // Unlock hatch | ||||||
|             io.lock(false); |             io.lock(false); | ||||||
|  |  | ||||||
|  | @ -1,80 +0,0 @@ | ||||||
| package wash.program; |  | ||||||
| 
 |  | ||||||
| import actor.ActorThread; |  | ||||||
| import wash.control.WashingMessage; |  | ||||||
| import wash.io.WashingIO; |  | ||||||
| 
 |  | ||||||
| import static wash.control.WashingMessage.Order.*; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Program 3 for washing machine. This also serves as an example of how washing |  | ||||||
|  * programs can be structured. |  | ||||||
|  *  |  | ||||||
|  * This short program stops all regulation of temperature and water levels, |  | ||||||
|  * stops the barrel from spinning, and drains the machine of water. |  | ||||||
|  *  |  | ||||||
|  * It can be used after an emergency stop (program 0) or a power failure. |  | ||||||
|  */ |  | ||||||
| public final class WashingProgramStop extends ActorThread<WashingMessage> { |  | ||||||
| 
 |  | ||||||
|     private WashingIO io; |  | ||||||
|     private ActorThread<WashingMessage> temp; |  | ||||||
|     private ActorThread<WashingMessage> water; |  | ||||||
|     private ActorThread<WashingMessage> spin; |  | ||||||
|      |  | ||||||
|     public WashingProgramStop(WashingIO io, |  | ||||||
|                            ActorThread<WashingMessage> temp, |  | ||||||
|                            ActorThread<WashingMessage> water, |  | ||||||
|                            ActorThread<WashingMessage> spin)  |  | ||||||
|     { |  | ||||||
|         this.io = io; |  | ||||||
|         this.temp = temp; |  | ||||||
|         this.water = water; |  | ||||||
|         this.spin = spin; |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     @Override |  | ||||||
|     public void run() { |  | ||||||
|         try { |  | ||||||
|             System.out.println("WashingProgramStop Starting..."); |  | ||||||
|              |  | ||||||
|             // Switch off heating |  | ||||||
|             temp.send(new WashingMessage(this, TEMP_IDLE)); |  | ||||||
|              |  | ||||||
|             // Wait for temperature controller to acknowledge  |  | ||||||
|             WashingMessage ack1 = receive(); |  | ||||||
|             System.out.println("got " + ack1); |  | ||||||
| 
 |  | ||||||
|             // Drain barrel, which may take some time. To ensure the barrel |  | ||||||
|             // is drained before we continue, an acknowledgment is required. |  | ||||||
|             water.send(new WashingMessage(this, WATER_DRAIN)); |  | ||||||
|             WashingMessage ack2 = receive();  // wait for acknowledgment |  | ||||||
|             System.out.println("got " + ack2); |  | ||||||
| 
 |  | ||||||
|             // Now that the barrel is drained, we can turn off water regulation. |  | ||||||
|             water.send(new WashingMessage(this, WATER_IDLE)); |  | ||||||
|             WashingMessage ack3 = receive();  // wait for acknowledgment |  | ||||||
|             System.out.println("got " + ack3); |  | ||||||
| 
 |  | ||||||
|             // Switch off spin. We expect an acknowledgment, to ensure |  | ||||||
|             // the hatch isn't opened while the barrel is spinning. |  | ||||||
|             spin.send(new WashingMessage(this, SPIN_OFF)); |  | ||||||
|             WashingMessage ack4 = receive();  // wait for acknowledgment |  | ||||||
|             System.out.println("got " + ack4); |  | ||||||
| 
 |  | ||||||
|             // Unlock hatch |  | ||||||
|             io.lock(false); |  | ||||||
|              |  | ||||||
|             System.out.println("WashingProgramStop Finished..."); |  | ||||||
|         } catch (InterruptedException e) { |  | ||||||
|             System.out.println("WashingProgramStop Interrupted..."); |  | ||||||
|             // If we end up here, it means the program was interrupt()'ed: |  | ||||||
|             // set all controllers to idle |  | ||||||
| 
 |  | ||||||
|             temp.send(new WashingMessage(this, TEMP_IDLE)); |  | ||||||
|             water.send(new WashingMessage(this, WATER_IDLE)); |  | ||||||
|             spin.send(new WashingMessage(this, SPIN_OFF)); |  | ||||||
|             System.out.println("washing stop program terminated"); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue