package Code.customClasses.DancingFinch; import edu.cmu.ri.createlab.terk.robot.finch.Finch; import java.awt.Color; import java.util.Random; /** * The DancingFinch is a controller for the finch which allows the finch to move to * a certain beat. It uses a simple state machine which stores the last motion, and * based on whether the finch is moving clockwise or counterclockwise, determines its * next motion. The finch also changes to a random color after every motion. * * The DancingFinch provides methods to check if the finch has been tapped sharply, * and a method which reverses the direction of the finch. * * @author Celestine Lau * */ public class DancingFinch { /** The current state of motion of the finch */ private int state; /** The Finch object to control */ private Finch finch; /** The direction the finch will "dance" in */ private boolean clockwise; /** The distance the finch moves on every step, this is related to how often it * has to move */ private double distance; /** The current color of the finch */ private int color; private static Random rng = new Random(); /* Constants defining the state of the motion */ private static final int STOP = 0; private static final int STRAIGHT = 1; private static final int TURN_LEFT = 2; private static final int TURN_RIGHT = 3; private static final int BACK = 4; // Calibrates to gravity private double gravityOffset; /** The next direction to move, if the finch is moving clockwise */ private static final int[] clockwiseTransition = new int[] { STRAIGHT, TURN_RIGHT, BACK, STRAIGHT, TURN_RIGHT }; /** The next direction to move, if the finch is moving counterclockwise */ private static final int[] counterclockwiseTransition = new int[] { BACK, TURN_LEFT, STRAIGHT, BACK, TURN_LEFT }; /** The array of random colors that the finch can take on */ private Color[] nextColor = new Color[] { Color.red, Color.green, Color.blue, Color.cyan, Color.magenta, Color.yellow, Color.pink, Color.white }; /** * Creates a new DancingFinch object * @param finch The finch object * @throws NullPointerException if finch is null */ public DancingFinch (Finch finch){ this.finch = finch; state = STOP; clockwise = true; distance = 15; color = 0; gravityOffset = finch.getZAcceleration(); } /** * Causes the dancingFinch to execute its next move * */ public void nextMove() { if (clockwise) state = clockwiseTransition[state]; else state = counterclockwiseTransition[state]; changeColor(); execute(state); } /** * Causes the dancingFinch to change to a different random color * within the nextColor array */ private void changeColor(){ color += rng.nextInt(nextColor.length - 1) + 1; if (color >= nextColor.length) color -= nextColor.length; finch.setLED(nextColor[color]); } /** * Executes the next motion of the finch, based on the state * @param state The motion to execute. This can be one of STRAIGHT, TURN_LEFT, * TURN_RIGHT or BACK */ private void execute(int state) { switch (state) { case STRAIGHT: finch.setWheelVelocities(200,200); break; case TURN_LEFT: finch.setWheelVelocities(-100, 100); break; case TURN_RIGHT: finch.setWheelVelocities(100, -100); break; case BACK: finch.setWheelVelocities(-200, -200); default: break; } } /** * Sets the array of random colors that the finch can change to * @param colors The array of colors from which random colors are drawn */ public void setColors(Color[] colors){ if (colors == null || colors.length == 0) { throw new IllegalArgumentException ("At least one color must be specified."); } this.nextColor = (Color[]) colors.clone(); color = 0; } /** * Sets the direction of the DancingFinch * @param clockwise Set to true to make the finch go clockwise, false to make it go * counterclockwise */ public void setClockwise(boolean clockwise) { this.clockwise = clockwise; } /** * Sets the time interval (in ms) between every motion. The distance the finch will move * will be determined from this value * @param interval The time between each successive call of nextMove(), in milliseconds */ public void setInterval(int interval) { distance = 0.0075 * interval; } /** * Reverses the direction of the DancingFinch * */ public void reverse() { clockwise = !clockwise; } /** * Check the z-accelerometers to determine if the user has tapped the finch * @return true if the Finch has been tapped, false otherwise */ public boolean isTapped() { double value = ((finch.getZAcceleration()-gravityOffset)); return value < -0.3; } }