aboutsummaryrefslogtreecommitdiff
path: root/PunchingBag/src
diff options
context:
space:
mode:
Diffstat (limited to 'PunchingBag/src')
-rw-r--r--PunchingBag/src/uk/ac/open/punchingbag/PunchingBag.java252
-rw-r--r--PunchingBag/src/uk/ac/open/punchingbag/PunchingBagGUI.java14
-rw-r--r--PunchingBag/src/uk/ac/open/punchingbag/examples/SimpleKeyboard.java14
3 files changed, 206 insertions, 74 deletions
diff --git a/PunchingBag/src/uk/ac/open/punchingbag/PunchingBag.java b/PunchingBag/src/uk/ac/open/punchingbag/PunchingBag.java
index 5ef8006..265cbdc 100644
--- a/PunchingBag/src/uk/ac/open/punchingbag/PunchingBag.java
+++ b/PunchingBag/src/uk/ac/open/punchingbag/PunchingBag.java
@@ -4,6 +4,7 @@ import gnu.io.CommPortIdentifier;
import javax.swing.event.EventListenerList;
+import java.awt.Color;
import java.awt.Rectangle;
import java.awt.geom.Area;
@@ -17,55 +18,151 @@ import java.util.Iterator;
// TODO: Loads of threads in this class, make sure everything is thread safe.
+/**
+ * This class represents the punching bag, reads and sends data to and from the arduino's (using the Arduino class),
+ * controlling the led's and reading the state of the accelerometers and buttons.
+ *
+ * @author Christopher Baines <cbaines8@gmail.com>
+ * @author Adam Martindale
+ */
+/**
+ * @author cb24367
+ *
+ */
+/**
+ * @author cb24367
+ *
+ */
+/**
+ * @author cb24367
+ *
+ */
public class PunchingBag implements Runnable {
- boolean ledsChanged = false;
+ /**
+ * Used by the run method to decide if to call the LEDListeners
+ */
+ private boolean ledsChanged = false;
+ /**
+ * The number of rows of leds
+ */
final public int ledHeight = 20;
+ /**
+ * The number of columns of leds
+ */
final public int ledWidth = 9;
+ /**
+ * The byte array that is passed to the led drivers
+ */
private byte[] rawLeds = new byte[6 * 8];
- private Colour[][] leds = new Colour[ledWidth][ledHeight]; // NEVER ACCESS
- // DIRECTLY (Use
- // SetLedInternal)
+ /**
+ * The colour objects for each led, do not access directly as this does not properly set ledsChanged
+ */
+ private Color[][] leds = new Color[ledWidth][ledHeight];
+
+ /**
+ * NOT USED YET, this should be sent to the arduino, but is not
+ */
private byte[] ledGridIntensities = new byte[6];
+ /**
+ * The number of rows of buttons
+ */
final public int buttonHeight = 19;
+ /**
+ * The number of columns of buttons
+ */
final public int buttonWidth = 8;
+ /**
+ * Contains the state of all the buttons as of the last loop in run
+ */
private boolean[][] buttons = new boolean[buttonWidth][buttonHeight];
+ /**
+ * Used by the run method to decide if to call the ButtonListeners
+ */
boolean buttonsChanged = false;
+ /**
+ * Bottom accelerometer X value
+ */
int bottomAccelX = 0;
+ /**
+ * Bottom accelerometer Y value
+ */
int bottomAccelY = 0;
+ /**
+ * Top accelerometer X value
+ */
int topAccelX = 0;
+ /**
+ * Top accelerometer Y value
+ */
int topAccelY = 0;
+ /**
+ * Used to decide if to call the AccelListerners
+ */
boolean acccelChanged = false;
+ /**
+ * The system time of the last run loop
+ */
private long lastRefresh = 0;
+ /**
+ * Contains all running effects
+ */
private ArrayList<Effect> runningEffects = new ArrayList<Effect>();
+ /**
+ * Arduino managing the buttons and accelerometers
+ */
Arduino buttonArduino = new Arduino();
+ /**
+ * The Arduino managing the led drivers
+ */
Arduino ledArduino = new Arduino();
+ /**
+ * Turn on to activate the command line messages regarding the run loop timing stuff
+ */
boolean debugTimings = false;
+ /**
+ * Turn on to activate the command line messages regarding the serial stuff
+ */
boolean debugSerial = false;
+ /**
+ * The only instance of this class, represents the PunchingBag
+ */
static private PunchingBag bag = new PunchingBag();
+ /**
+ * Use this to get a local pointer to the PunchingBag instance
+ *
+ * @return The PunchingBag instance
+ */
public static PunchingBag getBag() {
return bag;
}
- public enum Colour {
- None, Red, Yellow, Green
- };
-
public enum Direction {
Right, Left, Up, Down
};
- // Is there a better class for this? One that it is not a swing class.
+ /**
+ * Is there a better class for this? One that it is not a swing class.
+ */
private EventListenerList buttonListenerList = new EventListenerList();
+ /**
+ * Is there a better class for this? One that it is not a swing class.
+ */
private EventListenerList ledListenerList = new EventListenerList();
+ /**
+ * Is there a better class for this? One that it is not a swing class.
+ */
private EventListenerList accelListenerList = new EventListenerList();
+ /**
+ * Private constructor, starts the run method.
+ */
private PunchingBag() {
Thread bagControlThread = new Thread(this);
bagControlThread.setPriority(Thread.MAX_PRIORITY);
@@ -73,33 +170,72 @@ public class PunchingBag implements Runnable {
}
/**
- * Adds an <code>ActionListener</code> to the button.
+ * Adds an <code>ButtonListener</code> to the bag.
*
* @param l
- * the <code>ActionListener</code> to be added
+ * the <code>ButtonListener</code> to be added
*/
public void addButtonListener(ButtonListener l) {
buttonListenerList.add(ButtonListener.class, l);
}
+ /**
+ * Adds an <code>LEDChangeListener</code> to the bag.
+ *
+ * @param l
+ * the <code>LEDChangeListener</code> to be added
+ */
public void addLEDChangeListener(LEDListener l) {
ledListenerList.add(LEDListener.class, l);
}
+ /**
+ * Adds an <code>AccelChangeListener</code> to the bag.
+ *
+ * @param l
+ * the <code>AccelChangeListener</code> to be added
+ */
public void addAccelChangeListener(AccelListener l) {
accelListenerList.add(AccelListener.class, l);
}
- public Colour getLED(int x, int y) {
+ /**
+ * Gets the <code>Color</code> of the led given by its x and y, it will be one of: <code>Color.red</code>
+ * <code>Color.yellow</code> <code>Color.green</code> <code>Color.white</code>
+ *
+ * @param x
+ * The x coordinate of the led
+ * @param y
+ * The y coordinate of the led
+ * @return
+ */
+ public Color getLED(int x, int y) {
return leds[x][y];
}
- private boolean setLEDInternal(int x, int y, Colour colour) {
+ /**
+ * Used by methods in the PunchingBag class to change the led's array. To simplify things it will accept any Color object,
+ * but if it's not one of the supported (red,green,yellow), then it will just set it to white (the none colour).
+ *
+ * @param x The x coordinate of the led
+ * @param y The y coordinate of the led
+ * @param colour The desired colour of the led, as either Color.red, Color.yellow, Color.green or Color,white.
+ * @return true if something was changed, false if not
+ */
+ private boolean setLEDInternal(int x, int y, Color colour) {
if (x >= 0 && x < ledWidth && y >= 0 && y < ledHeight) {
if (leds[x][y] != colour) {
- leds[x][y] = colour;
- ledsChanged = true;
-
+ if (colour != Color.red || colour != Color.green || colour != Color.yellow) {
+ if (leds[x][y] != Color.white) {
+ leds[x][y] = Color.white;
+ ledsChanged = true;
+ }
+ } else {
+ if (leds[x][y] != colour) {
+ leds[x][y] = colour;
+ ledsChanged = true;
+ }
+ }
}
return true;
} else {
@@ -107,7 +243,7 @@ public class PunchingBag implements Runnable {
}
}
- public void setLED(int x, int y, Colour colour) {
+ public void setLED(int x, int y, Color colour) {
runningEffects.add(new Point(x, y, colour));
}
@@ -115,15 +251,15 @@ public class PunchingBag implements Runnable {
runningEffects.add(new CircleExpand(x, y, 100));
}
- void squareExpand(int x, int y, int intensity, Colour colour) {
+ void squareExpand(int x, int y, int intensity, Color colour) {
runningEffects.add(new SquareExpand(x, y, intensity, colour));
}
- public void fillRect(int x, int y, int width, int height, Colour colour, long time) {
+ public void fillRect(int x, int y, int width, int height, Color colour, long time) {
runningEffects.add(new FillRect(x, y, width, height, colour, time));
}
- void rect(int x, int y, int width, int height, Colour colour) {
+ void rect(int x, int y, int width, int height, Color colour) {
runningEffects.add(new Rect(x, y, width, height, colour));
}
@@ -147,9 +283,9 @@ public class PunchingBag implements Runnable {
class Point extends Effect {
final int x;
final int y;
- final Colour colour;
+ final Color colour;
- public Point(int x, int y, Colour colour) {
+ public Point(int x, int y, Color colour) {
this.x = x;
this.y = y;
this.colour = colour;
@@ -165,10 +301,10 @@ public class PunchingBag implements Runnable {
final int y;
final int width;
final int height;
- final Colour colour;
+ final Color colour;
final long time;
- public FillRect(int x, int y, int width, int height, Colour colour, long time) {
+ public FillRect(int x, int y, int width, int height, Color colour, long time) {
this.x = x;
this.y = y;
this.width = width;
@@ -190,9 +326,9 @@ public class PunchingBag implements Runnable {
final int y;
final int width;
final int height;
- final Colour colour;
+ final Color colour;
- public Rect(int x, int y, int width, int height, Colour colour) {
+ public Rect(int x, int y, int width, int height, Color colour) {
this.x = x;
this.y = y;
this.width = width;
@@ -240,14 +376,14 @@ public class PunchingBag implements Runnable {
}
public void draw() {
- Colour colour;
+ Color colour;
if (intensity >= 10) {
- colour = Colour.Red;
+ colour = Color.red;
} else if (intensity >= 5) {
- colour = Colour.Yellow;
+ colour = Color.yellow;
} else {
- colour = Colour.Green;
+ colour = Color.green;
}
intensity -= 5;
@@ -266,13 +402,13 @@ public class PunchingBag implements Runnable {
class SquareExpand extends Effect {
final int x;
final int y;
- final Colour colour;
+ final Color colour;
int intensity;
boolean drawnSomething = true;
int heightWidth = 2;
- public SquareExpand(int x, int y, int intensity, Colour colour) {
+ public SquareExpand(int x, int y, int intensity, Color colour) {
this.x = x;
this.y = y;
this.intensity = intensity;
@@ -305,13 +441,13 @@ public class PunchingBag implements Runnable {
for (int x = area.x; x < (area.x + area.width); x++) {
double random = Math.random();
if (random < 0.25) {
- setLEDInternal(x, y, Colour.Red);
+ setLEDInternal(x, y, Color.red);
} else if (random < 0.5) {
- setLEDInternal(x, y, Colour.Yellow);
+ setLEDInternal(x, y, Color.yellow);
} else if (random < 0.75) {
- setLEDInternal(x, y, Colour.Green);
+ setLEDInternal(x, y, Color.green);
} else {
- setLEDInternal(x, y, Colour.None);
+ setLEDInternal(x, y, Color.white);
}
}
}
@@ -321,7 +457,7 @@ public class PunchingBag implements Runnable {
}
}
- public boolean drawRectCenter(int x, int y, int height, int width, Colour colour) {
+ public boolean drawRectCenter(int x, int y, int height, int width, Color colour) {
if (height < 0) {
height = 0;
}
@@ -361,7 +497,7 @@ public class PunchingBag implements Runnable {
return doneSomething;
}
- public boolean drawRectInternal(int x, int y, int width, int height, Colour colour) {
+ public boolean drawRectInternal(int x, int y, int width, int height, Color colour) {
if (height < 0) {
height = 0;
}
@@ -402,7 +538,7 @@ public class PunchingBag implements Runnable {
return doneSomething;
}
- public boolean drawEllipse(int x, int y, int radx, int rady, Colour colour) {
+ public boolean drawEllipse(int x, int y, int radx, int rady, Color colour) {
if (radx == 0 && rady == 0) {
return setLEDInternal(x, y, colour);
}
@@ -449,7 +585,7 @@ public class PunchingBag implements Runnable {
return doneSomething;
}
- public boolean drawCircle(double x, double y, double radius, Colour colour) {
+ public boolean drawCircle(double x, double y, double radius, Color colour) {
boolean drawnSomething = false;
int px;
int py;
@@ -466,7 +602,7 @@ public class PunchingBag implements Runnable {
return drawnSomething;
}
- public boolean fillRectInternal(int x, int y, int height, int width, Colour colour) {
+ public boolean fillRectInternal(int x, int y, int height, int width, Color colour) {
boolean doneSomething = false;
for (int px = x; px < (x + height); px++) {
@@ -489,11 +625,11 @@ public class PunchingBag implements Runnable {
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
if ((y % 2) == 0) {
- if (leds[1 + x][(grid * 4) + (y / 2)] == Colour.Green || leds[1 + x][(grid * 4) + (y / 2)] == Colour.Yellow) {
+ if (leds[1 + x][(grid * 4) + (y / 2)] == Color.green || leds[1 + x][(grid * 4) + (y / 2)] == Color.yellow) {
rawLeds[(grid * 8) + x] = (byte) (rawLeds[(grid * 8) + x] | (1 << (7 - y)));
}
} else {
- if (leds[1 + x][(grid * 4) + (y / 2)] == Colour.Red || leds[1 + x][(grid * 4) + (y / 2)] == Colour.Yellow) {
+ if (leds[1 + x][(grid * 4) + (y / 2)] == Color.red || leds[1 + x][(grid * 4) + (y / 2)] == Color.yellow) {
rawLeds[(grid * 8) + x] = (byte) (rawLeds[(grid * 8) + x] | (1 << (7 - y)));
}
}
@@ -502,23 +638,17 @@ public class PunchingBag implements Runnable {
}
/*
- * for (int y = 0; y <= 18; y++) { for (int x = 0; x <= 6; x++) { if ((y
- * % 2) == 0) { if (leds[x][y] == Colour.Green || leds[x][y] ==
- * Colour.Yellow) { rawLeds[(int) Math.floor(y / 4)] = (byte)
- * (rawLeds[(int) Math .floor(y / 4)] | (1 << (7 - x))); } } else { if
- * (leds[x][y] == Colour.Red || leds[x][y] == Colour.Yellow) {
- * rawLeds[(int) Math.floor(y / 4)] = (byte) (rawLeds[(int) Math
- * .floor(y / 4)] | (1 << (7 - x))); } } } }
+ * for (int y = 0; y <= 18; y++) { for (int x = 0; x <= 6; x++) { if ((y % 2) == 0) { if (leds[x][y] == Colour.Green
+ * || leds[x][y] == Colour.Yellow) { rawLeds[(int) Math.floor(y / 4)] = (byte) (rawLeds[(int) Math .floor(y / 4)] |
+ * (1 << (7 - x))); } } else { if (leds[x][y] == Colour.Red || leds[x][y] == Colour.Yellow) { rawLeds[(int)
+ * Math.floor(y / 4)] = (byte) (rawLeds[(int) Math .floor(y / 4)] | (1 << (7 - x))); } } } }
*/
/*
- * int x = 7; // TODO: Complete and test, or rethink the following? for
- * (int startY = 0; startY <= 4; startY++) { for (int y = 0; y <= 3;
- * y++) { if (leds[x][startY + (y * 4)] == Colour.Red || leds[x][startY
- * + (y * 4)] == Colour.Yellow) { rawLeds[(5 * 8) + startY] = (byte)
- * (rawLeds[(int) Math .floor(y / 4)] | (1 << (7 - x))); } if
- * (leds[x][y] == Colour.Green || leds[x][y] == Colour.Yellow) {
- * rawLeds[(int) Math.floor(y / 4)] = (byte) (rawLeds[(int) Math
- * .floor(y / 4)] | (1 << (7 - x))); } } }
+ * int x = 7; // TODO: Complete and test, or rethink the following? for (int startY = 0; startY <= 4; startY++) { for
+ * (int y = 0; y <= 3; y++) { if (leds[x][startY + (y * 4)] == Colour.Red || leds[x][startY + (y * 4)] ==
+ * Colour.Yellow) { rawLeds[(5 * 8) + startY] = (byte) (rawLeds[(int) Math .floor(y / 4)] | (1 << (7 - x))); } if
+ * (leds[x][y] == Colour.Green || leds[x][y] == Colour.Yellow) { rawLeds[(int) Math.floor(y / 4)] = (byte)
+ * (rawLeds[(int) Math .floor(y / 4)] | (1 << (7 - x))); } } }
*/
}
@@ -526,7 +656,7 @@ public class PunchingBag implements Runnable {
private void clearLEDGrid() {
for (int x = 0; x < ledWidth; x++) {
for (int y = 0; y < ledHeight; y++) {
- leds[x][y] = Colour.None;
+ leds[x][y] = Color.white;
}
}
}
@@ -629,8 +759,8 @@ public class PunchingBag implements Runnable {
int num = Integer.valueOf(data.replaceAll("[^0-9]", ""));
int x = ((num - 1) % 8);
int y = (num - 1) / 8;
- // System.out.println("X: " + x + " Y: " + y);
- if (x > 0 && x < buttonWidth && y > 0 && y < buttonHeight) {
+ System.out.println("X: " + x + " Y: " + y);
+ if (x >= 0 && x < buttonWidth && y >= 0 && y < buttonHeight) {
buttons[x][y] = true;
buttonsChanged = true;
}
diff --git a/PunchingBag/src/uk/ac/open/punchingbag/PunchingBagGUI.java b/PunchingBag/src/uk/ac/open/punchingbag/PunchingBagGUI.java
index 32ca78a..5eb57c6 100644
--- a/PunchingBag/src/uk/ac/open/punchingbag/PunchingBagGUI.java
+++ b/PunchingBag/src/uk/ac/open/punchingbag/PunchingBagGUI.java
@@ -291,13 +291,13 @@ public class PunchingBagGUI implements MouseListener, MouseMotionListener,
if (a.getActionCommand() == "C") {
bag.clearLEDs();
} else {
- PunchingBag.Colour colour = PunchingBag.Colour.None;
+ Color colour = Color.white;
if (((JComboBox) a.getSource()).getSelectedIndex() == 1) {
- colour = PunchingBag.Colour.Red;
+ colour = Color.red;
} else if (((JComboBox) a.getSource()).getSelectedIndex() == 2) {
- colour = PunchingBag.Colour.Yellow;
+ colour = Color.yellow;
} else if (((JComboBox) a.getSource()).getSelectedIndex() == 3) {
- colour = PunchingBag.Colour.Green;
+ colour = Color.green;
}
System.out.println("Setting "
+ a.getActionCommand().split(",")[0] + " "
@@ -426,11 +426,11 @@ public class PunchingBagGUI implements MouseListener, MouseMotionListener,
}
public void paintComponent(Graphics g) {
- if (bag.getLED(x, y) == PunchingBag.Colour.Red) {
+ if (bag.getLED(x, y) == Color.red) {
g.setColor(Color.red);
- } else if (bag.getLED(x, y) == PunchingBag.Colour.Green) {
+ } else if (bag.getLED(x, y) == Color.green) {
g.setColor(Color.green);
- } else if (bag.getLED(x, y) == PunchingBag.Colour.Yellow) {
+ } else if (bag.getLED(x, y) == Color.yellow) {
g.setColor(Color.yellow);
} else {
g.setColor(Color.white);
diff --git a/PunchingBag/src/uk/ac/open/punchingbag/examples/SimpleKeyboard.java b/PunchingBag/src/uk/ac/open/punchingbag/examples/SimpleKeyboard.java
index 188b262..7ba2200 100644
--- a/PunchingBag/src/uk/ac/open/punchingbag/examples/SimpleKeyboard.java
+++ b/PunchingBag/src/uk/ac/open/punchingbag/examples/SimpleKeyboard.java
@@ -1,5 +1,6 @@
package uk.ac.open.punchingbag.examples;
+import java.awt.Color;
import java.io.File;
import java.io.IOException;
@@ -36,23 +37,24 @@ public class SimpleKeyboard implements ButtonListener {
}
public void buttonPressed(int x, int y) {
+ System.out.println("Button Pressed: " + x + " " + y);
if (y < 3) {
- bag.fillRect(0, 0, 9, 4, PunchingBag.Colour.Red, 500);
+ bag.fillRect(0, 0, 9, 4, Color.red, 500);
playKey(5);
} else if (y < 6) {
- bag.fillRect(0, 3, 9, 4, PunchingBag.Colour.Red, 500);
+ bag.fillRect(0, 3, 9, 4, Color.red, 500);
playKey(4);
} else if (y < 9) {
- bag.fillRect(0, 6, 9, 4, PunchingBag.Colour.Red, 500);
+ bag.fillRect(0, 6, 9, 4, Color.red, 500);
playKey(3);
} else if (y < 12) {
- bag.fillRect(0, 9, 9, 4, PunchingBag.Colour.Red, 500);
+ bag.fillRect(0, 9, 9, 4, Color.red, 500);
playKey(2);
} else if (y < 15) {
- bag.fillRect(0, 12, 9, 4, PunchingBag.Colour.Red, 500);
+ bag.fillRect(0, 12, 9, 4, Color.red, 500);
playKey(1);
} else {
- bag.fillRect(0, 15, 9, 4, PunchingBag.Colour.Red, 500);
+ bag.fillRect(0, 15, 9, 4, Color.red, 500);
playKey(0);
}
}