diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..567609b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+build/
diff --git a/BSD_License_for_WPILib_code.txt b/BSD_License_for_WPILib_code.txt
new file mode 100644
index 0000000..f7ee350
--- /dev/null
+++ b/BSD_License_for_WPILib_code.txt
@@ -0,0 +1,24 @@
+* Copyright (c) 2009 FIRST
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+* * Neither the name of the FIRST nor the
+* names of its contributors may be used to endorse or promote products
+* derived from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY FIRST AND CONTRIBUTORS``AS IS'' AND ANY
+* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY NONINFRINGEMENT AND FITNESS FOR A PARTICULAR
+* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL FIRST OR CONTRIBUTORS BE LIABLE FOR
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..8cede3a
--- /dev/null
+++ b/README.md
@@ -0,0 +1,13 @@
+GRT Framework v6
+================
+
+GRTFramework is an asynchronous, event-driven framework built on top of [WPILibJ](http://firstforge.wpi.edu/sf/projects/wpilib), which is provided by FIRST and includes a host of useful low-level hardware classes.
+
+The purpose of GRTFramework is:
+* To provide a framework for rapid FRC robot development
+* An asynchronous design and a focus on quality code design
+* Coder happiness :)
+
+Please feel free to email any of the developers if you have questions about the code.
+
+-FRC Team 192: Gunn Robotics Team (A.K.A "GRT")
diff --git a/build.properties b/build.properties
new file mode 100644
index 0000000..4ea99c3
--- /dev/null
+++ b/build.properties
@@ -0,0 +1,10 @@
+# Properties file for a Sun Spot Application
+#
+# build.properties
+#
+# This file is the default location for user properties that over-ride the
+# defaults in ${sunspot.home}/default.properties. See that file for a full
+# listing of the properties that may be set. This file is minimal and contains
+# only those properties that a user would generally need to set right away.
+#
+user.classpath=${wpilibj.home}/src
diff --git a/build.xml b/build.xml
new file mode 100644
index 0000000..a8f5392
--- /dev/null
+++ b/build.xml
@@ -0,0 +1,93 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/nbproject/project.xml b/nbproject/project.xml
new file mode 100644
index 0000000..f6b0258
--- /dev/null
+++ b/nbproject/project.xml
@@ -0,0 +1,93 @@
+
+
+
+ org.netbeans.modules.ant.freeform
+
+
+ grtframeworkv6
+
+ ${user.home}/.sunspotfrc.properties
+ build.properties
+ ${sunspot.home}/default.properties
+
+
+
+
+ java
+ src
+
+
+
+
+ jar-app
+
+
+ clean
+
+
+ deploy
+ run
+
+
+ clean
+ jar-app
+
+
+ deploy
+ debug-run
+
+
+ javadoc
+
+
+
+ folder
+ build
+ jar-app
+
+
+
+
+
+ src
+
+
+ build.xml
+
+
+
+
+
+
+
+
+
+
+
+ deploy
+
+
+
+ jar-deploy
+
+
+
+
+
+
+
+
+ src
+ ${sunspot.bootclasspath}
+ /home/gerberduffy/sunspotfrcsdk/lib/WPILibJ/classes.jar
+ build
+ 1.4
+
+
+
+
diff --git a/resources/META-INF/MANIFEST.MF b/resources/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..a9b02ac
--- /dev/null
+++ b/resources/META-INF/MANIFEST.MF
@@ -0,0 +1,6 @@
+MIDlet-Name: Base2012-redesign
+MIDlet-Version: 1.0.0
+MIDlet-Vendor: FIRST
+MIDlet-1: MainRobot, , deploy.MainRobot
+MicroEdition-Profile: IMP-1.0
+MicroEdition-Configuration: CLDC-1.1
diff --git a/src/actuator/GRTLed.java b/src/actuator/GRTLed.java
new file mode 100644
index 0000000..754e647
--- /dev/null
+++ b/src/actuator/GRTLed.java
@@ -0,0 +1,73 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package actuator;
+
+import core.Actuator;
+import edu.wpi.first.wpilibj.PWM;
+
+/**
+ * Abstraction of a standard LED
+ * @author gerberduffy
+ */
+public class GRTLed extends Actuator {
+
+ private static final int DEFAULT_BRIGHTNESS = 255;
+ private static final int HIGHEST_BRIGHTNESS = 255;
+ private static final int OFF_BRIGHTNESS = 0;
+
+
+ private final PWM led; //The PWM input controlling the LED
+ private int brightness;
+
+ public GRTLed(int channel, String id){
+ this(channel, DEFAULT_BRIGHTNESS, id);
+ }
+
+ public GRTLed(int channel, int brightness, String id){
+ super(id);
+
+ this.brightness = brightness;
+
+ led = new PWM(channel);
+ led.setRaw(brightness);
+ }
+
+ public void setToBrightness(int bright){
+ if (bright > HIGHEST_BRIGHTNESS){
+ bright = HIGHEST_BRIGHTNESS;
+ } else if (bright < OFF_BRIGHTNESS){
+ bright = OFF_BRIGHTNESS;
+ }
+
+ led.setRaw(bright);
+
+ this.brightness = bright;
+ }
+
+ public void toggleState(){
+ if (isOn()){
+ led.setRaw(OFF_BRIGHTNESS);
+ brightness = OFF_BRIGHTNESS;
+
+ } else {
+ led.setRaw(HIGHEST_BRIGHTNESS);
+ brightness = HIGHEST_BRIGHTNESS;
+ }
+ }
+
+ public int getBrightness(){
+ return this.brightness;
+ }
+
+ public boolean isOn(){
+ return this.brightness > OFF_BRIGHTNESS;
+ }
+
+ public void executeCommand(double command) {
+ led.setRaw((int) command);
+ brightness = (int) command;
+ }
+
+}
diff --git a/src/actuator/GRTRelay.java b/src/actuator/GRTRelay.java
new file mode 100644
index 0000000..22dd609
--- /dev/null
+++ b/src/actuator/GRTRelay.java
@@ -0,0 +1,53 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package actuator;
+
+import edu.wpi.first.wpilibj.Relay;
+import core.Actuator;
+
+/**
+ *
+ * @author calvin
+ */
+public class GRTRelay extends Actuator{
+ private Relay relay;
+
+ private static final double FORWARD = 1.0;
+ private static final double REVERSE = -1.0;
+ private static final double OFF = 0.0;
+
+ public GRTRelay(int channel, String name){
+ super(name);
+ relay = new Relay(channel);
+ }
+
+ /**
+ * Sends command to relay. If the value of the command is -1.0 the relay is in reverse,
+ * 1.0 is forward, and 0.0 is off.
+ * @param c
+ */
+ public void executeCommand(double command) {
+ if (command == OFF) {
+ relay.set(Relay.Value.kOff);
+ } else if(command == FORWARD) {
+ relay.set(Relay.Value.kForward);
+ } else if(command == REVERSE) {
+ relay.set(Relay.Value.kReverse);
+ }
+ }
+/**
+ * SEts the state of the relay to off
+ */
+ public void halt() {
+ relay.set(Relay.Value.kOff);
+ }
+/**
+ * Returns String
+ * @return
+ */
+ public String toString() {
+ return "Relay";
+ }
+}
diff --git a/src/actuator/GRTSolenoid.java b/src/actuator/GRTSolenoid.java
new file mode 100644
index 0000000..343ce6a
--- /dev/null
+++ b/src/actuator/GRTSolenoid.java
@@ -0,0 +1,46 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package actuator;
+
+import core.Actuator;
+import edu.wpi.first.wpilibj.Solenoid;
+
+/**
+ *
+ * @author gerberduffy
+ */
+public class GRTSolenoid extends Actuator {
+
+ private Solenoid sol;
+
+ public static final double ON = 1.0;
+ public static final double OFF = 0.0;
+
+ public GRTSolenoid(int slot, int channel, String id) {
+ super(id);
+
+ sol = new Solenoid(slot, channel);
+ }
+
+ /*
+ * Engage or disengage the solenoid
+ */
+ public void executeCommand(double command) {
+ if (command == ON) {
+ sol.set(true);
+ } else if (command == OFF) {
+ sol.set(false);
+ }
+ }
+
+
+// @Override
+ public void halt() {
+ sol.set(false);
+
+ super.halt();
+
+ }
+}
diff --git a/src/actuator/GRTVictor.java b/src/actuator/GRTVictor.java
new file mode 100644
index 0000000..35d7be2
--- /dev/null
+++ b/src/actuator/GRTVictor.java
@@ -0,0 +1,39 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package actuator;
+
+import core.Actuator;
+import edu.wpi.first.wpilibj.Victor;
+
+/**
+ *
+ * @author ajc
+ */
+public class GRTVictor extends Actuator implements IMotor {
+
+ Victor victor;
+
+ public GRTVictor(int id, String name) {
+ super(name);
+ victor = new Victor(id);
+ }
+
+ public void executeCommand(double command) {
+ if (enabled) {
+ victor.set(command);
+ }
+ }
+
+ /*
+ * Set the Victor's speed
+ * @param speed the new speed to set
+ */
+ public void setSpeed(double speed){
+ if(enabled){
+ victor.set(speed);
+// log(speed);
+ }
+ }
+}
diff --git a/src/actuator/IMotor.java b/src/actuator/IMotor.java
new file mode 100644
index 0000000..6020262
--- /dev/null
+++ b/src/actuator/IMotor.java
@@ -0,0 +1,21 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package actuator;
+
+import core.IProcess;
+
+/**
+ *
+ * @author ajc
+ */
+public interface IMotor extends IProcess{
+
+ /**
+ *
+ * @param speed
+ */
+ public void setSpeed(double speed);
+
+}
diff --git a/src/balancer/BalanceController.java b/src/balancer/BalanceController.java
new file mode 100644
index 0000000..c2696f2
--- /dev/null
+++ b/src/balancer/BalanceController.java
@@ -0,0 +1,63 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package balancer;
+import balancer.RobotTiltGyro;
+import core.EventController;
+import event.RobotTiltListener;
+import event.RobotTiltEvent;
+import mechanism.GRTRobotBase;
+
+
+/**
+ *
+ * @author calvin
+ */
+public class BalanceController extends EventController implements RobotTiltListener{
+
+ private double previousAngle;
+ private double currentAngle;
+ private double deltaAngle;
+ private double P_CONSTANT = .024;
+ private double D_CONSTANT = 0;
+ private final RobotTiltGyro robotTilt;
+ private final GRTRobotBase base;
+ private double DRIVE_THRESHOLD = .01;
+
+ public BalanceController(GRTRobotBase base, RobotTiltGyro robotTilt, String name){
+ super(name);
+ this.base = base;
+ this.robotTilt = robotTilt;
+ }
+
+ public void startBalancing(){
+ startListening();
+ }
+
+ public void stopBalancing(){
+ stopListening();
+ }
+
+ protected void startListening() {
+ robotTilt.addRobotTiltListeners(this);
+ }
+
+ protected void stopListening() {
+ robotTilt.removeRobotTiltListeners(this);
+ }
+
+ public void RobotTiltChange(RobotTiltEvent e) {
+ currentAngle = e.getTilt();
+ deltaAngle = currentAngle - previousAngle;
+ double drivePower = P_CONSTANT * currentAngle - D_CONSTANT * deltaAngle;
+ if(Math.abs(drivePower) >= DRIVE_THRESHOLD)
+ base.tankDrive(drivePower, drivePower);
+ else
+ base.tankDrive(0, 0);
+ System.out.println(drivePower);
+ }
+
+
+
+}
diff --git a/src/balancer/RobotTiltAccel.java b/src/balancer/RobotTiltAccel.java
new file mode 100644
index 0000000..cfbe3e5
--- /dev/null
+++ b/src/balancer/RobotTiltAccel.java
@@ -0,0 +1,91 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+//DO NOT USE--use robotTiltGyro instead
+package balancer;
+
+import com.sun.squawk.util.MathUtils;
+import core.Sensor;
+import event.ADXL345Event;
+import event.ADXL345Listener;
+import event.RobotTiltEvent;
+import event.RobotTiltListener;
+import java.util.Vector;
+import sensor.GRTADXL345;
+
+/**
+ *
+ * @author calvin
+ */
+public class RobotTiltAccel extends Sensor implements ADXL345Listener {
+
+ private Vector robotTiltListeners;
+ private static final int NUM_DATA = 1;//TODO change
+ public static final int KEY_ANGLE = 0;
+ private double angle;
+ private double xAccel;
+ private double yAccel;
+ private double zAccel;
+ private final GRTADXL345 accelerometer;
+
+ public RobotTiltAccel(GRTADXL345 accelerometer, String name) {
+ super(name);
+ this.accelerometer = accelerometer;
+ robotTiltListeners = new Vector();
+ }
+
+// protected void notifyListeners(int id, double oldDatum, double newDatum) {
+// RobotTiltEvent e = new RobotTiltEvent(this, id, newDatum);
+// for (int i = 0; i < robotTiltListeners.size(); i++) {
+// ((RobotTiltListener) robotTiltListeners.elementAt(i)).RobotTiltChange(e);
+// }
+// }
+
+ private void updateAngle() {
+ //magnitude of vector sum of x, y accelerations
+ double normalDeviation = Math.sqrt(((xAccel) * (xAccel))
+ + ((yAccel) * (yAccel)));
+// double oldAngle = angle;
+ angle = MathUtils.atan(normalDeviation / zAccel);
+ //angle is angle between acceleration vector and z axis
+ notifyStateChange(KEY_ANGLE, angle);
+ }
+
+ public double getTilt() {
+ return angle;
+ }
+
+ public void addRobotTiltListeners(RobotTiltListener l) {
+ robotTiltListeners.addElement(l);
+ }
+
+ public void removeRobotTiltListeners(RobotTiltListener l) {
+ robotTiltListeners.removeElement(l);
+ }
+
+ //@Override
+ protected void startListening() {
+ accelerometer.addADXL345Listener(this);
+ }
+
+ protected void stopListening() {
+ accelerometer.removeADXL345Listener(this);
+ }
+
+ public void XAccelChange(ADXL345Event e) {
+ xAccel = e.getAcceleration();
+ updateAngle();
+ }
+
+ public void YAccelChange(ADXL345Event e) {
+ yAccel = e.getAcceleration();
+ updateAngle();
+ }
+
+ public void ZAccelChange(ADXL345Event e) {
+ zAccel = e.getAcceleration();
+ updateAngle();
+ }
+}
\ No newline at end of file
diff --git a/src/balancer/RobotTiltGyro.java b/src/balancer/RobotTiltGyro.java
new file mode 100644
index 0000000..e8a8f2b
--- /dev/null
+++ b/src/balancer/RobotTiltGyro.java
@@ -0,0 +1,68 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package balancer;
+import core.Sensor;
+import sensor.GRTGyro;
+import event.GyroEvent;
+import event.GyroListener;
+import java.util.Vector;
+import event.RobotTiltEvent;
+import event.RobotTiltListener;
+
+/**
+ *
+ * @author calvin
+ */
+
+
+public class RobotTiltGyro extends Sensor implements GyroListener{
+ private Vector robotTiltListeners;
+ private double angle;
+ private double previousAngle;
+ private GRTGyro g;
+
+ public RobotTiltGyro(GRTGyro g, String name){
+ super(name);
+ this.g = g;
+ robotTiltListeners = new Vector();
+ angle = 0;
+ previousAngle = 0;
+ }
+ public void angleChanged(GyroEvent e) {
+ updateAngle();
+ }
+
+ private void updateAngle(){
+ angle += g.getAngle() - previousAngle;
+ previousAngle = g.getAngle();
+ notifyStateChange(0, angle);
+ notifyListeners(0, angle);
+ }
+
+ protected void notifyListeners(int id, double newDatum) {
+ RobotTiltEvent e = new RobotTiltEvent(this, id, newDatum);
+ for (int i = 0; i < robotTiltListeners.size(); i++) {
+ ((RobotTiltListener) robotTiltListeners.elementAt(i)).RobotTiltChange(e);
+ }
+
+
+ }
+
+ public void addRobotTiltListeners(RobotTiltListener l) {
+ robotTiltListeners.addElement(l);
+ }
+
+ public void removeRobotTiltListeners(RobotTiltListener l) {
+ robotTiltListeners.removeElement(l);
+ }
+
+ protected void startListening() {
+ g.addListener(this);
+ }
+
+ protected void stopListening() {
+ g.removeListener(this);
+ }
+}
diff --git a/src/balancer/balancePD.java b/src/balancer/balancePD.java
new file mode 100644
index 0000000..46de57d
--- /dev/null
+++ b/src/balancer/balancePD.java
@@ -0,0 +1,58 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package balancer;
+import balancer.RobotTiltAccel;
+import core.EventController;
+import event.RobotTiltListener;
+import event.RobotTiltEvent;
+import mechanism.GRTRobotBase;
+
+
+/**
+ *
+ * @author calvin
+ */
+public class balancePD extends EventController implements RobotTiltListener{
+
+ private double previousAngle;
+ private double currentAngle;
+ private double deltaAngle;
+ private double P_CONSTANT = 1;
+ private double D_CONSTANT = 0;
+ private final RobotTiltAccel robotTilt;
+ private final GRTRobotBase base;
+
+ public balancePD(GRTRobotBase base, RobotTiltAccel robotTilt, String name){
+ super(name);
+ this.base = base;
+ this.robotTilt = robotTilt;
+ }
+
+// public void startBalancing(){
+// startListening();
+// }
+//
+// public void stopBalancing(){
+// stopListening();
+// }
+
+ protected void startListening() {
+ robotTilt.addRobotTiltListeners(this);
+ }
+
+ protected void stopListening() {
+ robotTilt.removeRobotTiltListeners(this);
+ }
+
+ public void RobotTiltChange(RobotTiltEvent e) {
+ currentAngle = e.getTilt();
+ deltaAngle = currentAngle - previousAngle;
+ double drivePower = P_CONSTANT * currentAngle - D_CONSTANT * deltaAngle;
+ base.tankDrive(drivePower, drivePower);
+ }
+
+
+
+}
diff --git a/src/controller/PrimaryDriver.java b/src/controller/PrimaryDriver.java
new file mode 100644
index 0000000..5d93b49
--- /dev/null
+++ b/src/controller/PrimaryDriver.java
@@ -0,0 +1,74 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package controller;
+
+import core.EventController;
+import edu.wpi.first.wpilibj.DriverStation;
+import event.DrivingEvent;
+import event.DrivingListener;
+import event.DrivingProfileEvent;
+import event.DrivingProfileListener;
+import event.XboxJoystickEvent;
+import event.XboxJoystickListener;
+import mechanism.GRTDriveTrain;
+import sensor.base.GRTXboxDriverStation;
+import mechanism.GRTRobotBase;
+import sensor.base.IDriverProfile;
+import sensor.base.LinearDrive;
+import sensor.GRTXBoxJoystick;
+import sensor.base.GRTDriverStation;
+
+/**
+ * Robot base driving.
+ *
+ * Operates for any DriverStation
+ *
+ * @author ajc
+ */
+public class PrimaryDriver extends EventController implements DrivingListener, DrivingProfileListener {
+
+ //sensor
+ private final GRTDriverStation ds;
+ //actuator
+ private final GRTRobotBase dt;
+ //drive curve
+ private IDriverProfile driveProfile;
+ //state
+ private double leftVelocity;
+ private double rightVelocity;
+
+ public PrimaryDriver(GRTRobotBase dt, GRTDriverStation ds, IDriverProfile driveProfile, String name) {
+ super(name);
+ this.dt = dt;
+ this.ds = ds;
+ this.driveProfile = driveProfile;
+ }
+
+ protected void startListening() {
+ ds.addDrivingListener(this);
+ ds.addDrivingProfileListener(this);
+ }
+
+ protected void stopListening() {
+ ds.removeDrivingListener(this);
+ ds.removeDrivingProfileListener(this);
+ }
+
+ public void driverLeftSpeed(DrivingEvent e) {
+ leftVelocity = e.getPercentSpeed();
+
+ dt.tankDrive(driveProfile.driveSpeed(leftVelocity), driveProfile.driveSpeed(rightVelocity));
+ }
+
+ public void driverRightSpeed(DrivingEvent e) {
+ rightVelocity = e.getPercentSpeed();
+
+ dt.tankDrive(driveProfile.driveSpeed(leftVelocity), driveProfile.driveSpeed(rightVelocity));
+ }
+
+ public void drivingProfileChanged(DrivingProfileEvent e) {
+ driveProfile = e.getProfile();
+ }
+}
diff --git a/src/core/Actuator.java b/src/core/Actuator.java
new file mode 100644
index 0000000..7010c78
--- /dev/null
+++ b/src/core/Actuator.java
@@ -0,0 +1,25 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package core;
+
+/**
+ * An actuator is a driver for low level hardware that directly influences the
+ * physical world. Actuators can perform actions.
+ * @author ajc
+ */
+public abstract class Actuator extends GRTLoggedProcess {
+
+
+ public Actuator(String name){
+ super(name);
+ }
+
+ /**
+ * Performs an action. Actuator must be enabled for this to succeed.
+ * @param command
+ */
+ public abstract void executeCommand(double command);
+
+}
diff --git a/src/core/EventController.java b/src/core/EventController.java
new file mode 100644
index 0000000..1eae9ab
--- /dev/null
+++ b/src/core/EventController.java
@@ -0,0 +1,39 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package core;
+
+/**
+ * An EventController describes behavior based on received events.
+ * @author ajc
+ */
+public abstract class EventController extends GRTLoggedProcess {
+
+ public EventController(String name) {
+ super(name);
+ running = true; //TODO does this belong
+ }
+
+ /**
+ * Adds listeners.
+ */
+ protected abstract void startListening();
+
+ /**
+ * Removes listeners
+ */
+ protected abstract void stopListening();
+
+
+ public void enable() {
+ //enable() always works because an EventController is always running
+ super.enable();
+ startListening();
+ }
+
+ public void disable() {
+ super.disable();
+ stopListening();
+ }
+}
diff --git a/src/core/GRTLoggedProcess.java b/src/core/GRTLoggedProcess.java
new file mode 100644
index 0000000..3c1cb5b
--- /dev/null
+++ b/src/core/GRTLoggedProcess.java
@@ -0,0 +1,93 @@
+package core;
+
+/**
+ * A GRTLoggedProcess is a controllable process. It can be initiated/terminated.
+ *
+ * When a GRTLoggedProcess is constructed, it is immediately run, but not enabled.
+ *
+ * @author ajc
+ *
+ */
+public abstract class GRTLoggedProcess extends Thread implements IProcess {
+
+ protected final String name;
+ protected boolean enabled = false;
+ protected boolean running = true;
+
+ public GRTLoggedProcess(String name) {
+ this.name = name;
+ }
+
+ /**
+ *
+ * @param message
+ */
+ protected void log(String message) {
+ System.out.println(toString() + "\t" + message);
+ }
+
+ /**
+ * Logs in format: "[[ClassName:Id]] @name message
+ * @param name
+ * @param message
+ */
+ protected void log(String name, String message) {
+ System.out.println(toString() + "\t" + name + "\t" + message);
+ }
+
+ /**
+ *
+ * @param data
+ */
+ protected void log(double data) {
+ System.out.println(toString() + "\t" + data);
+
+ }
+
+ /**
+ *
+ * @param name
+ * @param data
+ */
+ protected void log(String name, double data) {
+ System.out.println(toString() + "\t" + name + "\t" + data);
+ }
+
+ public void enable() {
+ enabled = true;
+ }
+
+ public void disable() {
+ enabled = false;
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public void halt() {
+ running = false;
+ disable();
+ }
+
+ public boolean isRunning() {
+ return running;
+ }
+
+ /**
+ * Name
+ *
+ * @return
+ */
+ public String getID() {
+ return name;
+ }
+
+ /*
+ * To string method, returns loggable string in the formate
+ * [[ClassName:Id]]
+ */
+ public String toString(){
+ return "[[" + getClass().getName() + ":" + getID();
+ }
+}
diff --git a/src/core/IProcess.java b/src/core/IProcess.java
new file mode 100644
index 0000000..b38d8b4
--- /dev/null
+++ b/src/core/IProcess.java
@@ -0,0 +1,41 @@
+package core;
+
+/**
+ * An IProcess is a component that produces a certain behavior.
+ * This behavior can be enabled or disabled for a temporary pausing, or halted.
+ * Halting stops the behavior from ever being re-enabled again.
+ *
+ * @author ajc
+ *
+ */
+public interface IProcess {
+
+ /**
+ * Enables process behavior
+ */
+ public void enable();
+
+ /**
+ * Disables process behavior
+ */
+ public void disable();
+
+ /**
+ *
+ * @return true if behavior is active
+ */
+ public boolean isEnabled();
+
+ /**
+ * Terminates the behavior forever
+ */
+ public void halt();
+
+ /**
+ *
+ * @return true if the process can be enabled
+ */
+ public boolean isRunning();
+
+
+}
diff --git a/src/core/PollingSensor.java b/src/core/PollingSensor.java
new file mode 100644
index 0000000..969d98a
--- /dev/null
+++ b/src/core/PollingSensor.java
@@ -0,0 +1,98 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package core;
+
+/**
+ * A PollingSensor directly obtains data through the poll() method, as opposed
+ * to generic sensors that could receive events.
+ *
+ * It additionally stores the state of variables, and automatically performs
+ * state change checks.
+ *
+ *
+ * @author ajc
+ */
+public abstract class PollingSensor extends Sensor {
+
+ private double[] data;
+ private final int sleepTime;
+
+ /**
+ * Construct a polling sensor.
+ * Subclasses need to start themselves-- make a call to start();
+ * @param name name of the sensor
+ * @param sleepTime time between polls [ms]
+ * @param numData number of pieces of data
+ */
+ public PollingSensor(String name, int sleepTime, int numData) {
+ super(name);
+ this.sleepTime = sleepTime;
+ data = new double[numData];
+ }
+
+ /**
+ * Called to poll sensor.
+ */
+ protected abstract void poll();
+
+ public void run() {
+ running = true;
+ while (running) {
+
+ //only poll, and thus only send events, if enabled
+ if (enabled) {
+ poll();
+ }
+
+ try {
+ Thread.sleep(sleepTime);
+ } catch (InterruptedException ex) {
+ ex.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * Stores a datum, and notifies listeners if the state of it has changed.
+ *
+ * @param id key of the data
+ * @param datum fresh datum
+ */
+ protected void setState(int id, double datum) {
+ double previous = data[id];
+ //notify self and state change listeners if the datum has changed
+ if (previous != datum) {
+ notifyListeners(id, previous, datum);
+ notifyStateChange(id, datum);
+ }
+ data[id] = datum;
+ }
+
+ /**
+ * Retrieves sensor data
+ * @param id
+ * @return
+ */
+ public double getState(int id) {
+ return data[id];
+ }
+
+ /**
+ * Calls the listener events based on what has changed
+ * @param id the key of the data that changed
+ * @param oldDatum the datum's previous value
+ * @param newDatum the datum's new value
+ */
+ protected abstract void notifyListeners(int id, double oldDatum, double newDatum);
+
+ /*
+ * Polling sensors do not listen to things, necesserily
+ */
+ protected void startListening() {
+ }
+
+ protected void stopListening() {
+ }
+}
diff --git a/src/core/Sensor.java b/src/core/Sensor.java
new file mode 100644
index 0000000..cc75c08
--- /dev/null
+++ b/src/core/Sensor.java
@@ -0,0 +1,67 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package core;
+
+import event.SensorChangeListener;
+import event.SensorEvent;
+import java.util.Vector;
+
+/**
+ * A sensor sends sensor event data. They only send data when running.
+ *
+ * @author ajc
+ */
+public abstract class Sensor extends GRTLoggedProcess {
+
+ //Constants
+ public static final double TRUE = 1.0;
+ public static final double FALSE = 0.0;
+ public static final double ERROR = -999;
+
+ //Instance variables
+ private Vector listeners; //Collection of things that listen to this sensor
+
+ public Sensor(String name) {
+ super(name);
+ listeners = new Vector();
+ running = true;
+ }
+
+ /**
+ * Adds listeners.
+ */
+ protected abstract void startListening();
+
+ /**
+ * Removes listeners
+ */
+ protected abstract void stopListening();
+
+ public void enable() {
+ //enable() always works because a Sensor is always running
+ super.enable();
+ startListening();
+ }
+
+ public void disable() {
+ super.disable();
+ stopListening();
+ }
+
+ protected void notifyStateChange(int id, double data) {
+ SensorEvent e = new SensorEvent(this, id, data);
+ for (int i = 0; i < listeners.size(); i++) {
+ ((SensorChangeListener) listeners.elementAt(i)).sensorStateChanged(e);
+ }
+ }
+
+ public void addSensorStateChangeListener(SensorChangeListener l) {
+ listeners.addElement(l);
+ }
+
+ public void removeSensorStateChangeListener(SensorChangeListener l) {
+ listeners.removeElement(l);
+ }
+}
diff --git a/src/deploy/GRTRobot.java b/src/deploy/GRTRobot.java
new file mode 100644
index 0000000..810f06d
--- /dev/null
+++ b/src/deploy/GRTRobot.java
@@ -0,0 +1,69 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2008. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+package deploy;
+
+import core.EventController;
+import edu.wpi.first.wpilibj.SimpleRobot;
+import java.util.Vector;
+
+/**
+ *
+ * GRTRobot is the entry point.
+ *
+ * The VM is configured to automatically run this class, and to call the
+ * functions corresponding to each mode, as described in the SimpleRobot
+ * documentation. If you change the name of this class or the package after
+ * creating this project, you must also update the manifest file in the resource
+ * directory.
+ */
+public abstract class GRTRobot extends SimpleRobot {
+
+ private Vector autoControllers;
+ private Vector teleopControllers;
+
+ public GRTRobot() {
+ autoControllers = new Vector();
+ teleopControllers = new Vector();
+
+ }
+
+ /**
+ * This function is called once each time the robot enters autonomous mode.
+ * All Autonomous controllers are started/resumed, and all teleop controllers are paused.
+ */
+ public void autonomous() {
+ for (int i = 0; i < teleopControllers.size(); i++) {
+ ((EventController) teleopControllers.elementAt(i)).disable();
+ }
+ for (int i = 0; i < autoControllers.size(); i++) {
+ ((EventController) autoControllers.elementAt(i)).enable();
+ }
+
+ }
+
+ /**
+ * This function is called once each time the robot enters operator control.
+ * All Teleop controllers are started/resumed, and all autonomous controllers are paused.
+ */
+ public void operatorControl() {
+ for (int i = 0; i < autoControllers.size(); i++) {
+ ((EventController) autoControllers.elementAt(i)).disable();
+ }
+ for (int i = 0; i < teleopControllers.size(); i++) {
+ ((EventController) teleopControllers.elementAt(i)).enable();
+ }
+
+ }
+
+ public void addAutonomousController(EventController c) {
+ autoControllers.addElement(c);
+ }
+
+ public void addTeleopController(EventController c) {
+ teleopControllers.addElement(c);
+ }
+}
diff --git a/src/deploy/MainRobot.java b/src/deploy/MainRobot.java
new file mode 100644
index 0000000..8d6c2c9
--- /dev/null
+++ b/src/deploy/MainRobot.java
@@ -0,0 +1,136 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package deploy;
+
+import actuator.GRTVictor;
+import balancer.RobotTiltAccel;
+import controller.PrimaryDriver;
+import mechanism.GRTDriveTrain;
+import sensor.base.GRTXboxDriverStation;
+import mechanism.GRTRobotBase;
+import sensor.base.LinearDrive;
+import sensor.base.SquareDrive;
+import sensor.base.IDriverProfile;
+import rpc.connection.NetworkRPC;
+import rpc.telemetry.SensorLogger;
+import sensor.ADXL345DigitalAccelerometer;
+import sensor.GRTADXL345;
+import sensor.GRTAttack3Joystick;
+import sensor.GRTBatterySensor;
+import sensor.GRTEncoder;
+import sensor.GRTGyro;
+import sensor.GRTSwitch;
+import sensor.GRTXBoxJoystick;
+import sensor.base.*;
+
+/**
+ *
+ * @author ajc
+ */
+public class MainRobot extends GRTRobot {
+
+ /**
+ * Buttons which refer to enumerated driver curve profiles.
+ * First index refers to Linear drive
+ * Second index refers to Square drive
+ */
+ public static final int[] DRIVER_PROFILE_KEYS = new int[] {1,2};
+ public static final IDriverProfile[] DRIVER_PROFILES = new IDriverProfile[] {new LinearDrive(), new SquareDrive()};
+
+
+
+ //Global Controllers
+ private SensorLogger batteryLogger;
+ //Teleop Controllers
+ private PrimaryDriver driveControl;
+ private GRTDriverStation driverStation;
+ private GRTRobotBase robotBase;
+ private GRTADXL345 adxl;
+// private final ADXL345DigitalAccelerometer primaryADXL;
+// private final RobotTiltAccel tiltSensor;
+// private final SensorLogger tiltLogger;
+
+
+ public MainRobot() {
+
+ System.out.println("Running grtframeworkv6");
+
+ //RPC Connection
+ NetworkRPC rpcConn = new NetworkRPC(180);
+
+ //Driver station components
+ GRTAttack3Joystick primary = new GRTAttack3Joystick(1, 12, "primary");
+ GRTAttack3Joystick secondary = new GRTAttack3Joystick(2, 12, "secondary");
+ primary.start();
+ secondary.start();
+ primary.enable();
+ secondary.enable();
+ System.out.println("Joysticks initialized");
+
+ //Battery Sensor
+ GRTBatterySensor batterySensor = new GRTBatterySensor(10, "battery");
+ batterySensor.start();
+ batterySensor.enable();
+
+ // PWM outputs
+ GRTVictor leftDT1 = new GRTVictor(2, "leftDT1");
+ GRTVictor leftDT2 = new GRTVictor(3, "leftDT2");
+ GRTVictor rightDT1 = new GRTVictor(8, "rightDT1");
+ GRTVictor rightDT2 = new GRTVictor(9, "rightDT2");
+ leftDT1.enable();
+ leftDT2.enable();
+ rightDT1.enable();
+ rightDT2.enable();
+ System.out.println("Motors initialized");
+
+ //Mechanisms
+ GRTDriveTrain dt = new GRTDriveTrain(leftDT1, leftDT2, rightDT1, rightDT2);
+ robotBase = new GRTRobotBase(dt, batterySensor);
+ driverStation = new GRTAttack3DriverStation(primary, secondary, DRIVER_PROFILE_KEYS, DRIVER_PROFILES,
+ "driverStation");
+ driverStation.enable();
+ System.out.println("Mechanisms initialized");
+
+ //Controllers
+ driveControl = new PrimaryDriver(robotBase, driverStation, new LinearDrive(), "driveControl");
+ batteryLogger = new SensorLogger(batterySensor, rpcConn, new int[]{23}, "batterylogger");
+ System.out.println("Controllers Initialized");
+
+// adxl = new GRTADXL345(1, 25, "ADXL345");
+// adxl.enable();
+// adxl.start();
+
+
+// GRTGyro gyro = new GRTGyro(1, 10, "Gyro");
+// gyro.enable();
+// gyro.start();
+
+// tiltSensor = new RobotTiltAccel(adxl, "TiltSensor");
+// tiltLogger = new SensorLogger(tiltSensor, rpcConn, new int[]{210}, "tiltLogger");
+
+ // Start/prepare controllers
+// primaryADXL.enable();
+// batteryLogger.enable();
+// tiltSensor.enable();
+
+ addTeleopController(driveControl);
+// addAutonomousController(tiltLogger);
+
+ GRTEncoder encoder1 = new GRTEncoder(2, 1, 4.0, 10, "EncoderLeft");
+
+ GRTEncoder encoder2 = new GRTEncoder(3, 4, 4.0, 10, "EncoderRight");
+
+
+ encoder1.start(); encoder1.enable();
+ encoder2.start(); encoder2.enable();
+
+ SensorLogger encoderLogger1 = new SensorLogger(encoder1, rpcConn, new int[]{81, 82, 83}, null);
+ SensorLogger encoderLogger2 = new SensorLogger(encoder2, rpcConn, new int[]{84,85,86}, null);
+
+
+ encoderLogger1.enable();
+ encoderLogger2.enable();
+ }
+}
diff --git a/src/event/ADXL345Event.java b/src/event/ADXL345Event.java
new file mode 100644
index 0000000..2e13e1d
--- /dev/null
+++ b/src/event/ADXL345Event.java
@@ -0,0 +1,39 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package event;
+import sensor.GRTADXL345;
+
+/**
+ *
+ * @author calvin
+ */
+public class ADXL345Event {
+ public static final int KEY_X = 0;
+ public static final int KEY_Y = 1;
+ public static final int KEY_Z = 2;
+
+ private GRTADXL345 source;
+ private int id;
+ private double acceleration;
+
+ public ADXL345Event(GRTADXL345 source, int id, double acceleration) {
+ this.source = source;
+ this.id = id;
+ this.acceleration = acceleration;
+ }
+
+ //TODO what units
+ public double getAcceleration() {
+ return acceleration;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public GRTADXL345 getSource() {
+ return source;
+ }
+}
diff --git a/src/event/ADXL345Listener.java b/src/event/ADXL345Listener.java
new file mode 100644
index 0000000..c06f406
--- /dev/null
+++ b/src/event/ADXL345Listener.java
@@ -0,0 +1,18 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package event;
+
+/**
+ *
+ * @author calvin
+ */
+public interface ADXL345Listener {
+
+ public void XAccelChange(ADXL345Event e);
+
+ public void YAccelChange(ADXL345Event e);
+
+ public void ZAccelChange(ADXL345Event e);
+}
diff --git a/src/event/Attack3JoystickEvent.java b/src/event/Attack3JoystickEvent.java
new file mode 100644
index 0000000..f0feb5f
--- /dev/null
+++ b/src/event/Attack3JoystickEvent.java
@@ -0,0 +1,31 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package event;
+import sensor.GRTAttack3Joystick;
+/**
+ *
+ * @author dan
+ */
+public class Attack3JoystickEvent {
+ public static final int DEFAULT = 0;
+ private int id;
+ private double value;
+ private GRTAttack3Joystick source;
+
+ public Attack3JoystickEvent(GRTAttack3Joystick source, int id, double value){
+ this.source = source;
+ this.id = id;
+ this.value = value;
+ }
+ public int getId() {
+ return id;
+ }
+ public GRTAttack3Joystick getSource(){
+ return source;
+ }
+ public double getValue() {
+ return value;
+ }
+}
diff --git a/src/event/Attack3JoystickListener.java b/src/event/Attack3JoystickListener.java
new file mode 100644
index 0000000..7648796
--- /dev/null
+++ b/src/event/Attack3JoystickListener.java
@@ -0,0 +1,15 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package event;
+
+/**
+ *
+ * @author dan
+ */
+public interface Attack3JoystickListener {
+ public void XAxisMoved(Attack3JoystickEvent e);
+ public void YAxisMoved(Attack3JoystickEvent e);
+ public void AngleChanged(Attack3JoystickEvent e);
+}
diff --git a/src/event/BatteryVoltageEvent.java b/src/event/BatteryVoltageEvent.java
new file mode 100644
index 0000000..f815ccd
--- /dev/null
+++ b/src/event/BatteryVoltageEvent.java
@@ -0,0 +1,32 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package event;
+
+import sensor.GRTBatterySensor;
+
+
+/**
+ *
+ * @author ajc
+ */
+public class BatteryVoltageEvent {
+ private final GRTBatterySensor sensor;
+ private final double voltage;
+
+ public BatteryVoltageEvent(GRTBatterySensor sensor, double voltage){
+ this.sensor = sensor;
+ this.voltage = voltage;
+ }
+
+ public GRTBatterySensor getSource(){
+ return sensor;
+ }
+
+ public double getVoltage(){
+ return voltage;
+ }
+
+}
diff --git a/src/event/BatteryVoltageListener.java b/src/event/BatteryVoltageListener.java
new file mode 100644
index 0000000..87da8e3
--- /dev/null
+++ b/src/event/BatteryVoltageListener.java
@@ -0,0 +1,16 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package event;
+
+/**
+ *
+ * @author ajc
+ */
+public interface BatteryVoltageListener {
+
+ public void batteryVoltageChanged(BatteryVoltageEvent ev);
+
+}
diff --git a/src/event/ButtonEvent.java b/src/event/ButtonEvent.java
new file mode 100644
index 0000000..1155d43
--- /dev/null
+++ b/src/event/ButtonEvent.java
@@ -0,0 +1,40 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package event;
+
+import core.Sensor;
+
+/**
+ *
+ * @author ajc
+ */
+public class ButtonEvent {
+ private final Sensor source;
+ private final int id;
+ private final boolean pressed;
+
+ public ButtonEvent(Sensor source, int id, boolean pressed){
+ this.source = source;
+ this.id = id;
+ this.pressed = pressed;
+ }
+
+ public Sensor getSource(){
+ return source;
+ }
+
+ public int getButtonID(){
+ return id;
+ }
+
+ public boolean isPressed(){
+ return pressed;
+ }
+
+ public boolean isReleased(){
+ return !pressed;
+ }
+
+}
diff --git a/src/event/ButtonListener.java b/src/event/ButtonListener.java
new file mode 100644
index 0000000..63eafb1
--- /dev/null
+++ b/src/event/ButtonListener.java
@@ -0,0 +1,18 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package event;
+
+
+/**
+ *
+ * @author anand
+ */
+public interface ButtonListener {
+
+ public void buttonPressed(ButtonEvent e);
+
+ public void buttonReleased(ButtonEvent e);
+}
diff --git a/src/event/DrivingEvent.java b/src/event/DrivingEvent.java
new file mode 100644
index 0000000..7a6a157
--- /dev/null
+++ b/src/event/DrivingEvent.java
@@ -0,0 +1,38 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package event;
+
+import sensor.base.GRTDriverStation;
+
+/**
+ *
+ * @author ajc
+ */
+public class DrivingEvent {
+
+ public static final int SIDE_LEFT = 0;
+ public static final int SIDE_RIGHT = 1;
+ private final GRTDriverStation source;
+ private final int sideID;
+ private final double value;
+
+ public DrivingEvent(GRTDriverStation source, int sideID, double value) {
+ this.source = source;
+ this.sideID = sideID;
+ this.value = value;
+ }
+
+ public int getSide() {
+ return sideID;
+ }
+
+ public double getPercentSpeed() {
+ return value;
+ }
+
+ public GRTDriverStation getSource() {
+ return source;
+ }
+}
diff --git a/src/event/DrivingListener.java b/src/event/DrivingListener.java
new file mode 100644
index 0000000..b392773
--- /dev/null
+++ b/src/event/DrivingListener.java
@@ -0,0 +1,25 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package event;
+
+/**
+ * A high level interface for robot driving
+ * @author ajc
+ */
+public interface DrivingListener {
+
+ /**
+ * Called to set speed of left drivetrain
+ * @param e
+ */
+ public void driverLeftSpeed(DrivingEvent e);
+
+ /**
+ * Called to set speed of right drivetrain
+ * @param e
+ */
+ public void driverRightSpeed(DrivingEvent e);
+
+}
diff --git a/src/event/DrivingProfileEvent.java b/src/event/DrivingProfileEvent.java
new file mode 100644
index 0000000..fb4b79f
--- /dev/null
+++ b/src/event/DrivingProfileEvent.java
@@ -0,0 +1,32 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package event;
+
+import sensor.base.GRTDriverStation;
+import sensor.base.IDriverProfile;
+
+/**
+ *
+ * @author ajc
+ */
+public class DrivingProfileEvent {
+
+ private final GRTDriverStation source;
+ private final IDriverProfile profile;
+
+ public DrivingProfileEvent(GRTDriverStation source, IDriverProfile profile) {
+ this.source = source;
+ this.profile = profile;
+
+ }
+
+ public IDriverProfile getProfile() {
+ return profile;
+ }
+
+ public GRTDriverStation getSource() {
+ return source;
+ }
+}
diff --git a/src/event/DrivingProfileListener.java b/src/event/DrivingProfileListener.java
new file mode 100644
index 0000000..3e7e1a6
--- /dev/null
+++ b/src/event/DrivingProfileListener.java
@@ -0,0 +1,14 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package event;
+
+/**
+ *
+ * @author ajc
+ */
+public interface DrivingProfileListener {
+
+ public void drivingProfileChanged(DrivingProfileEvent e);
+}
diff --git a/src/event/EncoderEvent.java b/src/event/EncoderEvent.java
new file mode 100644
index 0000000..a144079
--- /dev/null
+++ b/src/event/EncoderEvent.java
@@ -0,0 +1,23 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package event;
+
+import sensor.GRTEncoder;
+
+/**
+ *
+ * @author gerberduffy
+ */
+public class EncoderEvent {
+
+ public static final int ROTATION_STARTED = 0;
+ public static final int ROTATION_STOPPED = 1;
+ public static final int DEGREE_CHANGE = 2;
+
+ public EncoderEvent(GRTEncoder source){
+
+ }
+
+}
diff --git a/src/event/EncoderListener.java b/src/event/EncoderListener.java
new file mode 100644
index 0000000..20d98da
--- /dev/null
+++ b/src/event/EncoderListener.java
@@ -0,0 +1,19 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package event;
+
+/**
+ *
+ * @author gerberduffy
+ */
+public interface EncoderListener {
+
+ public void rotationStarted(EncoderEvent e);
+
+ public void degreeChanged(EncoderEvent e);
+
+ public void rotationStopped(EncoderEvent e);
+
+}
diff --git a/src/event/GyroEvent.java b/src/event/GyroEvent.java
new file mode 100644
index 0000000..4583ae8
--- /dev/null
+++ b/src/event/GyroEvent.java
@@ -0,0 +1,29 @@
+/** To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package event;
+
+import sensor.GRTGyro;
+
+/**
+ *
+ * @author calvin
+ */
+public class GyroEvent {
+
+ private GRTGyro source;
+ private double rotation;
+
+ public GyroEvent(GRTGyro source, double rotation) {
+ this.source = source;
+ this.rotation = rotation;
+ }
+
+ public double getAngle() {
+ return rotation;
+ }
+
+ public GRTGyro getSource() {
+ return source;
+ }
+}
diff --git a/src/event/GyroListener.java b/src/event/GyroListener.java
new file mode 100644
index 0000000..59bc691
--- /dev/null
+++ b/src/event/GyroListener.java
@@ -0,0 +1,14 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package event;
+
+/**
+ *
+ * @author calvin
+ */
+public interface GyroListener {
+
+ public void angleChanged(GyroEvent e);
+}
diff --git a/src/event/PotentiometerEvent.java b/src/event/PotentiometerEvent.java
new file mode 100644
index 0000000..bb57a7b
--- /dev/null
+++ b/src/event/PotentiometerEvent.java
@@ -0,0 +1,31 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package event;
+
+import sensor.Potentiometer;
+
+/**
+ *
+ * @author calvin
+ */
+public class PotentiometerEvent {
+
+ private Potentiometer source;
+ private double value;
+
+ public PotentiometerEvent(Potentiometer source, double value) {
+ this.source = source;
+ this.value = value;
+ }
+
+ public double getAngle() {
+ return value;
+ }
+
+ public Potentiometer getSource() {
+ return source;
+ }
+
+}
diff --git a/src/event/PotentiometerListener.java b/src/event/PotentiometerListener.java
new file mode 100644
index 0000000..0c7f49a
--- /dev/null
+++ b/src/event/PotentiometerListener.java
@@ -0,0 +1,13 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package event;
+
+/**
+ *
+ * @author calvin
+ */
+public interface PotentiometerListener {
+ public void valueChanged();
+}
diff --git a/src/event/RobotTiltEvent.java b/src/event/RobotTiltEvent.java
new file mode 100644
index 0000000..4e0f779
--- /dev/null
+++ b/src/event/RobotTiltEvent.java
@@ -0,0 +1,34 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package event;
+import balancer.RobotTiltGyro;
+
+/**
+ *
+ * @author calvin
+ */
+public class RobotTiltEvent {
+ private RobotTiltGyro source;
+ private int id;
+ private double tilt;
+
+ public RobotTiltEvent(RobotTiltGyro source, int id, double tilt) {
+ this.source = source;
+ this.id = id;
+ this.tilt = tilt;
+ }
+
+ public double getTilt() {
+ return tilt;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public RobotTiltGyro getSource() {
+ return source;
+ }
+}
diff --git a/src/event/RobotTiltListener.java b/src/event/RobotTiltListener.java
new file mode 100644
index 0000000..c443658
--- /dev/null
+++ b/src/event/RobotTiltListener.java
@@ -0,0 +1,13 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package event;
+
+/**
+ *
+ * @author calvin
+ */
+public interface RobotTiltListener {
+ public void RobotTiltChange(RobotTiltEvent e);
+}
diff --git a/src/event/SensorChangeListener.java b/src/event/SensorChangeListener.java
new file mode 100644
index 0000000..1ae5550
--- /dev/null
+++ b/src/event/SensorChangeListener.java
@@ -0,0 +1,11 @@
+
+package event;
+
+/**
+ *
+ * @author anand, ajc
+ */
+public interface SensorChangeListener {
+
+ public void sensorStateChanged(SensorEvent e);
+}
diff --git a/src/event/SensorEvent.java b/src/event/SensorEvent.java
new file mode 100644
index 0000000..08563dc
--- /dev/null
+++ b/src/event/SensorEvent.java
@@ -0,0 +1,34 @@
+package event;
+
+import core.Sensor;
+import java.util.Hashtable;
+
+/**
+ *
+ * @author anand, ajc
+ */
+public class SensorEvent {
+
+ private Sensor source;
+ private int id;
+ private double data;
+
+ public SensorEvent(Sensor source, int id, double data) {
+ this.source = source;
+ this.id = id;
+ this.data = data;
+ }
+
+ public double getData() {
+ return data;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public Sensor getSource() {
+ return source;
+ }
+
+}
diff --git a/src/event/SwitchEvent.java b/src/event/SwitchEvent.java
new file mode 100644
index 0000000..d00f730
--- /dev/null
+++ b/src/event/SwitchEvent.java
@@ -0,0 +1,31 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package event;
+
+import core.PollingSensor;
+import sensor.GRTSwitch;
+
+/**
+ *
+ * @author gerberduffy
+ */
+public class SwitchEvent {
+
+ private boolean state;
+ private GRTSwitch sw;
+
+ public SwitchEvent(GRTSwitch sw, double newState){
+ state = newState == PollingSensor.TRUE;
+ this.sw = sw;
+ }
+
+ public GRTSwitch getSource(){
+ return this.sw;
+ }
+
+ public boolean getState(){
+ return this.state;
+ }
+}
diff --git a/src/event/SwitchListener.java b/src/event/SwitchListener.java
new file mode 100644
index 0000000..3606e1b
--- /dev/null
+++ b/src/event/SwitchListener.java
@@ -0,0 +1,15 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package event;
+
+/**
+ *
+ * @author gerberduffy
+ */
+public interface SwitchListener {
+
+ public void switchStateChanged(event.SwitchEvent e);
+
+}
diff --git a/src/event/XboxJoystickEvent.java b/src/event/XboxJoystickEvent.java
new file mode 100644
index 0000000..677bd19
--- /dev/null
+++ b/src/event/XboxJoystickEvent.java
@@ -0,0 +1,37 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package event;
+
+import sensor.GRTXBoxJoystick;
+
+/**
+ *
+ * @author student
+ */
+public class XboxJoystickEvent {
+
+ public static final int DEFAULT = 0;
+ private GRTXBoxJoystick source;
+ private int id;
+ private double value;
+
+ public XboxJoystickEvent(GRTXBoxJoystick source, int id, double value) {
+ this.source = source;
+ this.id = id;
+ this.value = value;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public GRTXBoxJoystick getSource() {
+ return source;
+ }
+
+ public double getValue() {
+ return value;
+ }
+}
\ No newline at end of file
diff --git a/src/event/XboxJoystickListener.java b/src/event/XboxJoystickListener.java
new file mode 100644
index 0000000..5483c71
--- /dev/null
+++ b/src/event/XboxJoystickListener.java
@@ -0,0 +1,23 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package event;
+
+/**
+ *
+ * @author student
+ */
+public interface XboxJoystickListener {
+ public void leftXAxisMoved(XboxJoystickEvent e);
+ public void leftYAxisMoved(XboxJoystickEvent e);
+ public void leftAngleChanged(XboxJoystickEvent e);
+
+ public void rightXAxisMoved(XboxJoystickEvent e);
+ public void rightYAxisMoved(XboxJoystickEvent e);
+
+ public void padMoved(XboxJoystickEvent e);
+
+ public void triggerMoved(XboxJoystickEvent e);
+}
\ No newline at end of file
diff --git a/src/mechanism/GRTDriveTrain.java b/src/mechanism/GRTDriveTrain.java
new file mode 100644
index 0000000..bef8fd6
--- /dev/null
+++ b/src/mechanism/GRTDriveTrain.java
@@ -0,0 +1,47 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package mechanism;
+
+import actuator.IMotor;
+
+/**
+ * Standard 4 motor drivetrain.
+ * @author ajc
+ */
+public class GRTDriveTrain {
+
+ private final IMotor leftFront;
+ private final IMotor leftBack;
+ private final IMotor rightFront;
+ private final IMotor rightBack;
+
+ /**
+ *
+ * @param leftFront left front motor
+ * @param leftBack left back motor
+ * @param rightFront right front motor
+ * @param rightBack right back motor
+ */
+ public GRTDriveTrain(IMotor leftFront, IMotor leftBack,
+ IMotor rightFront, IMotor rightBack) {
+
+ this.leftFront = leftFront;
+ this.leftBack = leftBack;
+ this.rightFront = rightFront;
+ this.rightBack = rightBack;
+ }
+
+ /**
+ * TankDrive uses differential steering.
+ * @param leftVelocity
+ * @param rightVelocity
+ */
+ public void tankDrive(double leftVelocity, double rightVelocity) {
+ leftFront.setSpeed(-leftVelocity);
+ leftBack.setSpeed(-leftVelocity);
+ rightFront.setSpeed(-rightVelocity);
+ rightBack.setSpeed(-rightVelocity);
+ }
+}
diff --git a/src/mechanism/GRTRobotBase.java b/src/mechanism/GRTRobotBase.java
new file mode 100644
index 0000000..c6c7a72
--- /dev/null
+++ b/src/mechanism/GRTRobotBase.java
@@ -0,0 +1,35 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package mechanism;
+
+import sensor.GRTBatterySensor;
+
+/**
+ * Encapsulates all components on the robot base.
+ *
+ * @author ajc
+ */
+public class GRTRobotBase {
+
+ private final GRTDriveTrain dt;
+ private final GRTBatterySensor s;
+
+ public GRTRobotBase(GRTDriveTrain dt, GRTBatterySensor s) {
+ this.dt = dt;
+ this.s = s;
+ }
+
+ public GRTDriveTrain getDriveTrain() {
+ return dt;
+ }
+
+ public GRTBatterySensor getBatterySensor(){
+ return s;
+ }
+
+ public void tankDrive(double leftVelocity, double rightVelocity){
+ dt.tankDrive(leftVelocity, rightVelocity);
+ }
+}
diff --git a/src/networking/GRTClientSocket.java b/src/networking/GRTClientSocket.java
new file mode 100644
index 0000000..775c689
--- /dev/null
+++ b/src/networking/GRTClientSocket.java
@@ -0,0 +1,156 @@
+package networking;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.util.Vector;
+
+import javax.microedition.io.Connector;
+
+import com.sun.squawk.io.BufferedReader;
+import javax.microedition.io.SocketConnection;
+
+public class GRTClientSocket extends Thread implements GRTSocket {
+ public static final int POLL_TIME = 50;
+
+ private String host;
+ private int port;
+ private boolean connected;
+
+ private boolean running;
+ private Vector socketListeners;
+ private SocketConnection connection;
+ private BufferedReader in;
+ private OutputStreamWriter out;
+ private String lastData;
+
+ public GRTClientSocket(String host, int port) {
+ this.host = host;
+ this.port = port;
+ running = connected = false;
+ socketListeners = new Vector();
+ try {
+ connection = ((SocketConnection) (Connector.open("socket://" + host
+ + ":" + port)));
+ } catch (IOException e) {
+ e.printStackTrace();
+ connection = null;
+ }
+ }
+
+ public void run() {
+ running = true;
+ while (running) {
+ poll();
+ try {
+ Thread.sleep(POLL_TIME);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public synchronized void sendData(String data) {
+ if (connected) {
+ try {
+ out.write(data);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ protected void poll() {
+ if (!connected) {
+ connect();
+ }
+ try {
+ String latest = in.readLine();
+ if (latest != null && !latest.equals("")){
+ lastData = latest;
+ notifyListeners();
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ disconnect();
+ }
+ }
+
+ public void connect() {
+ try {
+ in = new BufferedReader(new InputStreamReader(connection
+ .openInputStream()));
+ out = new OutputStreamWriter(connection.openOutputStream());
+ connected = true;
+ notifyConnected();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public String getHost() {
+ return host;
+ }
+
+ public int getPort() {
+ return port;
+ }
+
+ public boolean isConnected() {
+ return connected;
+ }
+
+ public void stop() {
+ disconnect();
+ this.running = false;
+ }
+
+ public void disconnect() {
+ if (connected) {
+ try {
+ connected = false;
+ in.close();
+ out.close();
+ notifyDisconnected();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public String getLastData() {
+ return lastData;
+ }
+
+ private void notifyListeners() {
+ for (int i = 0; i < socketListeners.size(); i++) {
+ ((SocketListener) socketListeners.elementAt(i))
+ .dataRecieved(new SocketEvent(this, SocketEvent.ON_DATA,
+ lastData));
+ }
+ }
+
+ private void notifyConnected() {
+ for (int i = 0; i < socketListeners.size(); i++) {
+ ((SocketListener) socketListeners.elementAt(i))
+ .dataRecieved(new SocketEvent(this, SocketEvent.ON_CONNECT,
+ null));
+ }
+ }
+
+ private void notifyDisconnected() {
+ for (int i = 0; i < socketListeners.size(); i++) {
+ ((SocketListener) socketListeners.elementAt(i))
+ .dataRecieved(new SocketEvent(this, SocketEvent.ON_DISCONNECT,
+ null));
+ }
+ }
+
+ public void addSocketListener(SocketListener s) {
+ socketListeners.addElement(s);
+ }
+
+ public void removeSocketListener(SocketListener s) {
+ socketListeners.removeElement(s);
+ }
+}
diff --git a/src/networking/GRTServer.java b/src/networking/GRTServer.java
new file mode 100644
index 0000000..b5da4eb
--- /dev/null
+++ b/src/networking/GRTServer.java
@@ -0,0 +1,226 @@
+package networking;
+
+import com.sun.squawk.io.BufferedReader;
+//import com.sun.squawk.microedition.io.ServerSocketConnection;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.util.Vector;
+import javax.microedition.io.Connector;
+import javax.microedition.io.ServerSocketConnection;
+import javax.microedition.io.StreamConnection;
+
+/**
+ * A event driven daemon which makes multiple single client connections
+ * @author data, ajc
+ */
+public class GRTServer extends Thread implements GRTSocket {
+
+ /**
+ * A single client connection to the server.
+ */
+ private class GRTSingleConnect extends Thread implements GRTSocket {
+
+ private StreamConnection client;
+ private OutputStreamWriter osw;
+ private BufferedReader in;
+// private DataInputStream in;
+ InputStreamReader isr;
+ private OutputStreamWriter out;
+ private boolean running;
+ private boolean connected = true;
+ Vector serverSocketListeners;
+
+ public GRTSingleConnect(StreamConnection client) {
+ try {
+ this.client = client;
+// GRTRobot.getInstance().getLogger().write("GRTServer", client.toString());
+ serverSocketListeners = new Vector();
+// isr = new InputStreamReader(client.openInputStream());
+// isr.read
+ in = new BufferedReader(new InputStreamReader(client.openInputStream()),1);
+
+// client.openDataInputStream().readUT
+// in = client.openDataInputStream();
+ out = new OutputStreamWriter(client.openOutputStream());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void run() {
+ running = true;
+ while (running) {
+ try {
+// System.out.println("Waiting for input...");
+ String text = in.readLine();
+// String text = in.readUTF();
+ notifyMyListeners(text);
+ } catch (Exception e) {
+ this.disconnect();
+ e.printStackTrace();
+ }
+
+ }
+ }
+
+ public void stop() {
+ running = false;
+ }
+
+ public void sendData(String data) {
+ try {
+ out.write(data + "\n");
+ } catch (IOException e) {
+ //GRTRobot.getInstance().getLogger().write("GRTServer", "disconnected from client");
+ this.disconnect();
+ } catch (Exception e) {
+ e.printStackTrace();
+
+ }
+
+ }
+
+ public boolean isConnected() {
+ return connected;
+ }
+
+ public void connect() {
+ connected = true;
+ }
+
+ public void disconnect() {
+ try {
+ in.close();
+ out.close();
+ client.close();
+ clients.removeElement(this);
+ running = false;
+ notifyMyDisconnect();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void addSocketListener(SocketListener s) {
+ serverSocketListeners.addElement(s);
+ }
+
+ public void removeSocketListener(SocketListener s) {
+ serverSocketListeners.removeElement(s);
+ }
+
+ private void notifyMyListeners(String text) {
+ if (text == null) {
+ return;
+ }
+ for (int i = 0; i < serverSocketListeners.size(); i++) {
+ SocketListener s = (SocketListener) serverSocketListeners.elementAt(i);
+ s.dataRecieved(new SocketEvent(this, SocketEvent.ON_DATA, text));
+ }
+ notifyListeners(text, this);
+ }
+
+ private void notifyMyDisconnect() {
+ for (int i = 0; i < serverSocketListeners.size(); i++) {
+ SocketListener s = (SocketListener) serverSocketListeners.elementAt(i);
+ s.onDisconnect(new SocketEvent(this, SocketEvent.ON_DISCONNECT, null));
+ }
+ notifyDisconnect(this);
+ }
+ }
+
+ public GRTServer(int port) {
+ server = null;
+ while (server == null) {
+ try {
+// Connector.
+ server = (ServerSocketConnection) Connector.open("socket://:" + port);
+ } catch (IOException e) {
+ e.printStackTrace();
+ System.out.println("Failed to open socket!!!!!!!!");
+ server = null;
+ }
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ serverSocketListeners = new Vector();
+ clients = new Vector();
+
+ }
+ private ServerSocketConnection server;
+ private Vector clients;
+ private boolean running;
+ private Vector serverSocketListeners;
+
+ public void sendData(String data) {
+ for (int i = 0; i < clients.size(); i++) {
+ GRTSingleConnect c = (GRTSingleConnect) clients.elementAt(i);
+ c.sendData(data);
+ }
+ }
+
+ public boolean isConnected() {
+ return clients.size() > 0;
+ }
+
+ public void connect() {
+ try {
+ StreamConnection client = server.acceptAndOpen();
+ GRTSingleConnect c = new GRTSingleConnect(client);
+ c.start();
+ clients.addElement(c);
+ notifyConnect(c);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ public void run() {
+ running = true;
+ while (running) {
+ connect();
+ }
+ }
+
+ public void disconnect() {
+ for (int i = 0; i < clients.size(); i++) {
+ ((GRTSingleConnect) clients.elementAt(i)).stop();
+ }
+ }
+
+ public void addSocketListener(SocketListener s) {
+ serverSocketListeners.addElement(s);
+ }
+
+ public void removeSocketListener(SocketListener s) {
+ serverSocketListeners.removeElement(s);
+ }
+
+ private void notifyListeners(String text, GRTSocket source) {
+ for (int i = 0; i < serverSocketListeners.size(); i++) {
+ SocketListener s = (SocketListener) serverSocketListeners.elementAt(i);
+ s.dataRecieved(new SocketEvent(source, SocketEvent.ON_DATA, text));
+ }
+ }
+
+ private void notifyDisconnect(GRTSocket source) {
+ for (int i = 0; i < serverSocketListeners.size(); i++) {
+ SocketListener s = (SocketListener) serverSocketListeners.elementAt(i);
+ s.onDisconnect(new SocketEvent(source, SocketEvent.ON_DISCONNECT, null));
+ }
+ }
+
+ private void notifyConnect(GRTSocket source) {
+ for (int i = 0; i < serverSocketListeners.size(); i++) {
+ SocketListener s = (SocketListener) serverSocketListeners.elementAt(i);
+ s.onConnect(new SocketEvent(source, SocketEvent.ON_CONNECT, null));
+ }
+ }
+}
diff --git a/src/networking/GRTSingleClientServer.java b/src/networking/GRTSingleClientServer.java
new file mode 100644
index 0000000..28f519e
--- /dev/null
+++ b/src/networking/GRTSingleClientServer.java
@@ -0,0 +1,149 @@
+package networking;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.util.Vector;
+
+import javax.microedition.io.Connector;
+import javax.microedition.io.StreamConnection;
+
+import com.sun.squawk.io.BufferedReader;
+import javax.microedition.io.ServerSocketConnection;
+
+public class GRTSingleClientServer extends Thread implements GRTSocket {
+ public static final int POLL_TIME = 50;
+
+ private ServerSocketConnection server;
+ private StreamConnection client;
+ private BufferedReader in;
+ private OutputStreamWriter out;
+ private boolean connected;
+ private Vector serverSocketListeners;
+ private String lastData;
+
+ private boolean running;
+
+ public GRTSingleClientServer(int port) {
+ try {
+ server = (ServerSocketConnection) Connector.open("socket://:"
+ + port);
+ } catch (IOException e) {
+ e.printStackTrace();
+ server = null;
+ }
+ connected = false;
+ serverSocketListeners = new Vector();
+ running = false;
+ }
+
+ public void run() {
+ running = true;
+ while (running) {
+ poll();
+ }
+ }
+
+ public synchronized void sendData(String data) {
+ if (connected) {
+ try {
+ out.write(data+"\n");
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public void connect() {
+ try {
+ client = server.acceptAndOpen();
+ in = new BufferedReader(new InputStreamReader(client
+ .openInputStream()));
+ out = new OutputStreamWriter(client.openOutputStream());
+ connected = true;
+ notifyConnected();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ protected void poll() {
+ if (!connected) {
+ connect();
+ }
+ try {
+ String latest = in.readLine();
+ if (latest != null && !latest.equals("")){
+ lastData = latest;
+ notifyListeners();
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ disconnect();
+ }
+ }
+
+ private void notifyListeners() {
+ for (int i = 0; i < serverSocketListeners.size(); i++) {
+ ((SocketListener) serverSocketListeners.elementAt(i))
+ .dataRecieved(new SocketEvent(this, SocketEvent.ON_DATA,
+ lastData));
+ }
+ }
+
+ private void notifyConnected() {
+ for (int i = 0; i < serverSocketListeners.size(); i++) {
+ ((SocketListener) serverSocketListeners.elementAt(i))
+ .dataRecieved(new SocketEvent(this, SocketEvent.ON_CONNECT,
+ null));
+ }
+ }
+
+ private void notifyDisconnected() {
+ for (int i = 0; i < serverSocketListeners.size(); i++) {
+ ((SocketListener) serverSocketListeners.elementAt(i))
+ .dataRecieved(new SocketEvent(this, SocketEvent.ON_DISCONNECT,
+ null));
+ }
+ }
+
+ public boolean isConnected() {
+ return connected;
+ }
+
+ public String getLastData() {
+ return lastData;
+ }
+
+ public boolean isRunning() {
+ return running;
+ }
+
+ public void stop() {
+ disconnect();
+ this.running = false;
+ }
+
+ public void disconnect() {
+ if (connected) {
+ try {
+ connected = false;
+ in.close();
+ out.close();
+ client.close();
+ notifyDisconnected();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public void addSocketListener(SocketListener s) {
+ serverSocketListeners.addElement(s);
+ }
+
+ public void removeSocketListener(SocketListener s) {
+ serverSocketListeners.removeElement(s);
+ }
+
+}
diff --git a/src/networking/GRTSocket.java b/src/networking/GRTSocket.java
new file mode 100644
index 0000000..6334d0e
--- /dev/null
+++ b/src/networking/GRTSocket.java
@@ -0,0 +1,15 @@
+package networking;
+
+public interface GRTSocket {
+ public void sendData(String data);
+
+ public boolean isConnected();
+
+ public void connect();
+
+ public void disconnect();
+
+ public void addSocketListener(SocketListener s);
+
+ public void removeSocketListener(SocketListener s);
+}
diff --git a/src/networking/SocketEvent.java b/src/networking/SocketEvent.java
new file mode 100644
index 0000000..fa8b7e6
--- /dev/null
+++ b/src/networking/SocketEvent.java
@@ -0,0 +1,28 @@
+package networking;
+
+public class SocketEvent {
+ public static final int ON_DATA = 0;
+ public static final int ON_CONNECT = 1;
+ public static final int ON_DISCONNECT = 2;
+ private GRTSocket source;
+ private int id;
+ private String data;
+
+ public SocketEvent(GRTSocket source, int id, String data) {
+ super();
+ this.source = source;
+ this.id = id;
+ this.data = data;
+ }
+ public GRTSocket getSource() {
+ return source;
+ }
+ public int getId() {
+ return id;
+ }
+ public String getData() {
+ return data;
+ }
+
+
+}
diff --git a/src/networking/SocketListener.java b/src/networking/SocketListener.java
new file mode 100644
index 0000000..d8f7206
--- /dev/null
+++ b/src/networking/SocketListener.java
@@ -0,0 +1,8 @@
+package networking;
+
+public interface SocketListener {
+
+ public void onConnect(SocketEvent e);
+ public void onDisconnect(SocketEvent e);
+ public void dataRecieved(SocketEvent e);
+}
diff --git a/src/rpc/RPCConnection.java b/src/rpc/RPCConnection.java
new file mode 100644
index 0000000..ce429b7
--- /dev/null
+++ b/src/rpc/RPCConnection.java
@@ -0,0 +1,11 @@
+package rpc;
+
+public interface RPCConnection {
+
+ public void send(RPCMessage message);
+
+ public void addMessageListener(RPCMessageListener l);
+
+ public void removeMessageListener(RPCMessageListener l);
+
+}
diff --git a/src/rpc/RPCMessage.java b/src/rpc/RPCMessage.java
new file mode 100644
index 0000000..2f1f1ad
--- /dev/null
+++ b/src/rpc/RPCMessage.java
@@ -0,0 +1,25 @@
+package rpc;
+
+public class RPCMessage {
+
+ private final int key;
+ private final double data;
+
+ public RPCMessage(int key, double data) {
+ this.key = key;
+ this.data = data;
+ }
+
+ public int getKey() {
+ return key;
+ }
+
+ public double getData() {
+ return data;
+ }
+
+ public String toString() {
+ return "RPCMessage:" + key + ":" + data;
+ }
+
+}
diff --git a/src/rpc/RPCMessageListener.java b/src/rpc/RPCMessageListener.java
new file mode 100644
index 0000000..6540d21
--- /dev/null
+++ b/src/rpc/RPCMessageListener.java
@@ -0,0 +1,11 @@
+package rpc;
+
+/**
+ *
+ * @author ajc
+ *
+ */
+public interface RPCMessageListener {
+
+ public void messageReceived(RPCMessage message);
+}
diff --git a/src/rpc/connection/NetworkRPC.java b/src/rpc/connection/NetworkRPC.java
new file mode 100644
index 0000000..f6eeba2
--- /dev/null
+++ b/src/rpc/connection/NetworkRPC.java
@@ -0,0 +1,101 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package rpc.connection;
+
+import networking.GRTServer;
+import networking.SocketEvent;
+import networking.SocketListener;
+import java.util.Enumeration;
+import java.util.Vector;
+import rpc.RPCConnection;
+import rpc.RPCMessage;
+import rpc.RPCMessageListener;
+
+/**
+ * NetworkRPC provides an Internet RPC connection. It currently receives
+ * messages from any connecting host, and sends messages to all connected hosts
+ *
+ * @author ajc
+ */
+public class NetworkRPC implements RPCConnection, SocketListener {
+
+ private GRTServer connection;
+ private Vector listeners = new Vector();
+
+ /**
+ * Opens a new Network RPC connection and starts it.
+ * @param port
+ */
+ public NetworkRPC(int port) {
+ connection = new GRTServer(port);
+ start();
+ }
+
+
+ private void start(){
+ connection.addSocketListener(this);
+ connection.start();
+ }
+
+ //TODO enable sending to a single host
+ public void send(RPCMessage message) {
+ connection.sendData(encode(message));
+ }
+
+ public void addMessageListener(RPCMessageListener l) {
+ listeners.addElement(l);
+ }
+
+ public void removeMessageListener(RPCMessageListener l) {
+ listeners.removeElement(l);
+ }
+
+ private void notifyListeners(String received) {
+ if (isTelemetryLine(received)) {
+ // RPCMessage message = new RPCMessage(getKey(received),
+ // getData(received));
+ RPCMessage message = decode(received);
+// System.out.println(message);
+ // TODO only notify specific 'keyed' listeners
+ for (Enumeration e = listeners.elements(); e.hasMoreElements();) {
+ ((RPCMessageListener) e.nextElement()).messageReceived(message);
+ }
+
+ }
+ }
+
+ private static String encode(RPCMessage m) {
+ // newline to flush all buffers
+ return ("USB" + m.getKey() + ":" + m.getData() + "\n");
+ }
+
+ private static RPCMessage decode(String received) {
+ return new RPCMessage(getKey(received), getData(received));
+ }
+
+ private static boolean isTelemetryLine(String line) {
+ return line.length() > 3 && line.substring(0, 3).equals("USB");// TODO
+ // MAGICNUMBERS
+ }
+
+ private static int getKey(String line) {
+ return Integer.parseInt(line.substring(3, line.indexOf(':')));
+ }
+
+ private static double getData(String line) {
+ return Double.parseDouble((line.substring(line.indexOf(':') + 1)));
+ }
+
+ public void onConnect(SocketEvent e) { //TODO
+ }
+
+ public void onDisconnect(SocketEvent e) { //TODO
+ }
+
+ public void dataRecieved(SocketEvent e) {
+// System.out.println("Data received: " + e.getData());
+ notifyListeners(e.getData());
+ }
+}
diff --git a/src/rpc/connection/StreamedRPC.java b/src/rpc/connection/StreamedRPC.java
new file mode 100644
index 0000000..fffe211
--- /dev/null
+++ b/src/rpc/connection/StreamedRPC.java
@@ -0,0 +1,122 @@
+package rpc.connection;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import rpc.RPCConnection;
+import rpc.RPCMessage;
+import rpc.RPCMessageListener;
+
+/**
+ * Reads lines from an input stream
+ *
+ * @author ajc
+ *
+ */
+public class StreamedRPC extends Thread implements RPCConnection {
+
+ private static final int MAX_STRING_LENGTH = 1024;
+ // stores byteform of string until newline
+ private byte[] buffer = new byte[MAX_STRING_LENGTH];
+ private final InputStream in;
+ private final OutputStream out;
+ private boolean running; // TODO grtobject type thing
+ private Vector listeners = new Vector();
+
+ public StreamedRPC(InputStream in, OutputStream out) {
+ this.in = in;
+ this.out = out;
+ }
+
+ public void run() {
+ running = true;
+ while (running) {
+ poll();
+ try {
+ Thread.sleep(1);// TODO sleeping
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+
+ private void poll() {
+ int data;
+ try {
+ int len = 0;
+ while ((data = in.read()) > -1) {
+ if (data == '\n') {
+ break;
+ }
+ buffer[len++] = (byte) data;
+ }
+ // System.out.println("READ:\t" + new String(buffer, 0, len));//
+ // TODO
+ // selected
+ // debug:
+ // prints
+ notifyListeners(new String(buffer, 0, len));
+ } catch (IOException e) {
+ e.printStackTrace();
+ System.exit(-1);
+ }
+ }
+
+ private static boolean isTelemetryLine(String line) {
+ return line.length() > 3 && line.substring(0, 3).equals("USB");// TODO
+ // MAGICNUMBERS
+ }
+
+ private static int getKey(String line) {
+ return Integer.parseInt(line.substring(3, line.indexOf(':')));
+ }
+
+ private static double getData(String line) {
+ return Double.parseDouble((line.substring(line.indexOf(':') + 1)));
+ }
+
+ public void addMessageListener(RPCMessageListener listener) {
+ listeners.addElement(listener);
+ }
+
+ public void removeMessageListener(RPCMessageListener listener) {
+ listeners.removeElement(listener);
+ }
+
+ private void notifyListeners(String received) {
+ if (isTelemetryLine(received)) {
+ // RPCMessage message = new RPCMessage(getKey(received),
+ // getData(received));
+ RPCMessage message = decode(received);
+ // System.out.println(message);
+ // TODO only notify specific 'keyed' listeners
+ for (Enumeration e = listeners.elements(); e.hasMoreElements();) {
+ ((RPCMessageListener) e.nextElement()).messageReceived(message);
+ }
+
+ }
+ }
+
+ public void send(RPCMessage message) {
+ try {
+ out.write(encode(message));
+ out.flush();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ private static byte[] encode(RPCMessage m) {
+ // newline to flush all buffers
+ return ("USB" + m.getKey() + ":" + m.getData() + "\n").getBytes();
+ }
+
+ private static RPCMessage decode(String received) {
+ return new RPCMessage(getKey(received), getData(received));
+ }
+}
diff --git a/src/rpc/telemetry/SensorLogger.java b/src/rpc/telemetry/SensorLogger.java
new file mode 100644
index 0000000..a555625
--- /dev/null
+++ b/src/rpc/telemetry/SensorLogger.java
@@ -0,0 +1,49 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package rpc.telemetry;
+
+import core.EventController;
+import core.Sensor;
+import event.SensorChangeListener;
+import event.SensorEvent;
+import rpc.RPCConnection;
+import rpc.RPCMessage;
+
+/**
+ * Automatically sends all data from any sensor.
+ * @author ajc
+ */
+public class SensorLogger extends EventController implements SensorChangeListener {
+
+ private final Sensor s;
+ private final RPCConnection conn;
+ private final int[] rpcKeys;
+
+ /**
+ *
+ * @param s sensor to read from
+ * @param conn connection to send data with
+ * @param rpcKeys rpc keys to send data with for each index of sensor
+ * @param name name of process
+ */
+ public SensorLogger(Sensor s, RPCConnection conn, int[] rpcKeys, String name) {
+ super(name);
+ this.s = s;
+ this.conn = conn;
+ this.rpcKeys = rpcKeys;
+ }
+
+ protected void startListening() {
+ s.addSensorStateChangeListener(this);
+ }
+
+ protected void stopListening() {
+ s.removeSensorStateChangeListener(this);
+ }
+
+ public void sensorStateChanged(SensorEvent e) {
+ conn.send(new RPCMessage(rpcKeys[e.getId()], e.getData()));
+ }
+}
diff --git a/src/sensor/ADXL345DigitalAccelerometer.java b/src/sensor/ADXL345DigitalAccelerometer.java
new file mode 100644
index 0000000..e9f68b7
--- /dev/null
+++ b/src/sensor/ADXL345DigitalAccelerometer.java
@@ -0,0 +1,175 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2008. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+package sensor;
+
+import edu.wpi.first.wpilibj.DigitalModule;
+import edu.wpi.first.wpilibj.I2C;
+import edu.wpi.first.wpilibj.SensorBase;
+
+
+
+/**
+ *
+ * digital accelerometer from the 2010 KOP
+ *
+ * this implementation just gets the 3 axis values and allows setting the range
+ *
+ * Possible enhancements:
+ * Add access to other features of the chip
+ * Add measurement of error during intialization and set channel offsets
+ */
+public class ADXL345DigitalAccelerometer extends SensorBase {
+ private I2C i2c;
+ // default address
+ private static final byte kAddress = 0x3A;
+ // register map from datasheet
+ private static final byte OFSX = 0x1E;
+ private static final byte OFSY = 0x1F;
+ private static final byte OFSZ = 0x20;
+ private static final byte BW_RATE = 0x2C;
+ private static final byte POWER_CTL = 0x2D;
+ private static final byte DATA_FORMAT = 0x31;
+ private static final byte DATAX0 = 0x32;
+ private static final byte DATAY0 = 0x34;
+ private static final byte DATAZ0 = 0x36;
+ private static final byte FIFO_CTL = 0x38;
+ private static final byte FIFO_STATUS = 0x39;
+
+
+
+
+ // would use enums here if we had them
+ // BW_RATE 0x2C
+ private static final byte BW_RATE_R3200B1600 = 0x0F;
+ private static final byte BW_RATE_R1600B0800 = 0x0E;
+ private static final byte BW_RATE_R0800B0400 = 0x0D;
+ private static final byte BW_RATE_R0400B0200 = 0x0C;
+ private static final byte BW_RATE_R0200B0100 = 0x0B;
+ private static final byte BW_RATE_R0100B0050 = 0x0A;
+ private static final byte BW_RATE_R0050B0025 = 0x09;
+ private static final byte BW_RATE_R0025B0012 = 0x08;
+ private static final byte BW_RATE_R0012B0006 = 0x07;
+ private static final byte BW_RATE_R0006B0003 = 0x06;
+
+ private static final byte BW_RATE_LOW_POWER = 0x10;
+
+ // POWER_CTL 0x2D
+ private static final byte POWER_CTL_LINK = 0x20;
+ private static final byte POWER_CTL_AUTO_SLEEP = 0x10;
+ private static final byte POWER_CTL_MEASURE = 0x08;
+ private static final byte POWER_CTL_SLEEP = 0x04;
+ private static final byte POWER_CTL_WAKEUP8 = 0x00;
+ private static final byte POWER_CTL_WAKEUP4 = 0x01;
+ private static final byte POWER_CTL_WAKEUP2 = 0x02;
+ private static final byte POWER_CTL_WAKEUP1 = 0x03;
+
+ // DATA_FORMAT
+ public static final byte DATA_FORMAT_02G = 0x00;
+ public static final byte DATA_FORMAT_04G = 0x01;
+ public static final byte DATA_FORMAT_08G = 0x02;
+ public static final byte DATA_FORMAT_16G = 0x03;
+
+ // store the current
+ private byte range = DATA_FORMAT_02G;
+
+ public class ADXL345Exception extends RuntimeException {
+
+ /**
+ * Create a new exception with the given message
+ * @param message the message to pass with the exception
+ */
+ public ADXL345Exception(String message) {
+ super(message);
+ }
+
+ }
+
+ //
+ // constuctior with slot number parameter
+ //
+ public ADXL345DigitalAccelerometer(int slot) {
+
+ i2c = new I2C( DigitalModule.getInstance(1), kAddress );
+ }
+
+ // initialize the sensor
+ public void initialize()
+ {
+ // set BW_RATE
+ i2c.write(BW_RATE, BW_RATE_R0100B0050);
+ // set POWER_CTL
+ i2c.write(POWER_CTL, POWER_CTL_MEASURE);
+ }
+
+ // set he range (default is =/- 2g
+ public void setRange( byte rangeParam )
+ {
+ if ( !( rangeParam == DATA_FORMAT_02G ||
+ rangeParam == DATA_FORMAT_04G ||
+ rangeParam == DATA_FORMAT_08G ||
+ rangeParam == DATA_FORMAT_16G ) )
+ {
+ throw new ADXL345Exception("Invalid range!");
+ }
+
+
+ range = rangeParam;
+
+ i2c.write(DATA_FORMAT, range);
+ }
+
+ // get acceleration routines
+ public double getXAxis()
+ {
+ return getAxis( DATAX0 );
+ }
+
+ public double getYAxis()
+ {
+ return getAxis( DATAY0 );
+ }
+
+ public double getZAxis()
+ {
+ return getAxis( DATAZ0 );
+ }
+
+ protected double getAxis( byte registerParam )
+ {
+ // setup array for our data
+ byte[] data = new byte[2];
+ // read consecutive registers
+ this.i2c.read( registerParam, (byte) data.length, data);
+
+ // convert to 2s complement integer
+ // [0] has low byte [1] has the high byte
+ // jave does not have unsigned so we have to do it this way
+ int intResult = ( data[0] & 0xFF ) | ( data[1] << 8 );
+
+ // convert to double based on 10 bit result
+ double returnValue = (double)intResult / 512.0 ;
+
+ // now scale based upon our range
+ switch( range )
+ {
+ case DATA_FORMAT_02G:
+ returnValue *= 2.0;
+ break;
+ case DATA_FORMAT_04G:
+ returnValue *= 4.0;
+ break;
+ case DATA_FORMAT_08G:
+ returnValue *= 8.0;
+ break;
+ case DATA_FORMAT_16G:
+ returnValue *= 16.0;
+ break;
+ }
+ return returnValue;
+ }
+}
diff --git a/src/sensor/GRTADXL345.java b/src/sensor/GRTADXL345.java
new file mode 100644
index 0000000..04e5513
--- /dev/null
+++ b/src/sensor/GRTADXL345.java
@@ -0,0 +1,78 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package sensor;
+
+import core.PollingSensor;
+import edu.wpi.first.wpilibj.ADXL345_I2C;
+import event.ADXL345Event;
+import event.ADXL345Listener;
+import java.util.Vector;
+/**
+ *
+ * @author gerberduffy
+ */
+public class GRTADXL345 extends PollingSensor{
+
+ private ADXL345_I2C i2c;
+
+ private static final int X_AXIS = 0;
+ private static final int Y_AXIS = 1;
+ private static final int Z_AXIS = 2;
+ private static final int NUM_DATA = 3;
+
+
+
+ private Vector listeners;
+
+ private ADXL345_I2C.AllAxes accelerations;
+
+ public GRTADXL345(int slot, int pollTime, String id){
+ super (id, pollTime, NUM_DATA);
+ i2c = new ADXL345_I2C(slot, ADXL345_I2C.DataFormat_Range.k2G);
+
+ listeners = new Vector();
+ }
+
+ protected void poll() {
+ setState(X_AXIS, i2c.getAcceleration(ADXL345_I2C.Axes.kX));
+ setState(Y_AXIS, i2c.getAcceleration(ADXL345_I2C.Axes.kY));
+ setState(Z_AXIS, i2c.getAcceleration(ADXL345_I2C.Axes.kZ));
+
+ System.out.println("ADXL345:\t" + getState(X_AXIS) + "\t" + getState(Y_AXIS) + "\t" + getState(Z_AXIS));
+ }
+
+ public void addADXL345Listener(ADXL345Listener l){
+ listeners.addElement(l);
+ }
+
+ public void removeADXL345Listener(ADXL345Listener l){
+ listeners.removeElement(l);
+ }
+
+ protected void notifyListeners(int id, double oldDatum, double newDatum) {
+ ADXL345Event e = new ADXL345Event(this, id, newDatum);
+
+ switch (id){
+ case X_AXIS: {
+ for (int i=0; i < listeners.size(); i++){
+ ((ADXL345Listener)listeners.elementAt(i)).XAccelChange(e);
+ }
+ }
+
+ case Y_AXIS: {
+ for (int i=0; i < listeners.size(); i++){
+ ((ADXL345Listener)listeners.elementAt(i)).YAccelChange(e);
+ }
+ }
+
+ case Z_AXIS: {
+ for (int i=0; i < listeners.size(); i++){
+ ((ADXL345Listener)listeners.elementAt(i)).ZAccelChange(e);
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/sensor/GRTAttack3Joystick.java b/src/sensor/GRTAttack3Joystick.java
new file mode 100644
index 0000000..b9c4760
--- /dev/null
+++ b/src/sensor/GRTAttack3Joystick.java
@@ -0,0 +1,107 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package sensor;
+
+import core.PollingSensor;
+import edu.wpi.first.wpilibj.Joystick;
+import event.*;
+import java.util.Vector;
+
+/**
+ *
+ * @author dan
+ */
+public class GRTAttack3Joystick extends PollingSensor {
+ private final Vector joystickListeners;
+ private final Vector buttonListeners;
+ private final Joystick joystick;
+ public static final int KEY_BUTTON_0 = 0;
+ public static final int KEY_BUTTON_1 = 1;
+ public static final int KEY_BUTTON_2 = 2;
+ public static final int KEY_BUTTON_3 = 3;
+ public static final int KEY_BUTTON_4 = 4;
+ public static final int KEY_BUTTON_5 = 5;
+ public static final int KEY_BUTTON_6 = 6;
+ public static final int KEY_BUTTON_7 = 7;
+ public static final int KEY_BUTTON_8 = 8;
+ public static final int KEY_BUTTON_9 = 9;
+ public static final int KEY_X = 10;
+ public static final int KEY_Y = 11;
+ public static final int KEY_JOYSTICK_ANGLE = 12;
+ private final static int NUM_OF_BUTTONS=10;
+ private final static int NUM_DATA=13;
+ public static final double PRESSED = TRUE;
+ public static final double RELEASED = FALSE;
+
+ public GRTAttack3Joystick(int channel, int pollTime, String name){
+ super(name, pollTime, NUM_DATA);
+ joystick = new Joystick(channel);
+ joystickListeners = new Vector();
+ buttonListeners = new Vector();
+
+ }
+
+ protected void poll() {
+ for (int i = 0; i < NUM_OF_BUTTONS; ++i){
+ setState(i, joystick.getRawButton(i)?PRESSED:RELEASED);
+ }
+ setState(KEY_X, joystick.getX());
+ setState(KEY_Y, joystick.getY());
+ setState(KEY_JOYSTICK_ANGLE, joystick.getDirectionRadians());
+ }
+
+ protected void notifyListeners(int id, double oldDatum, double newDatum) {
+ if (id < NUM_OF_BUTTONS) {
+ //ID maps directly to button ID
+ ButtonEvent e = new ButtonEvent(this, id, newDatum == PRESSED);
+ if (newDatum == PRESSED) { //true
+ for (int i = 0; i < buttonListeners.size(); i++) {
+ ((ButtonListener) buttonListeners.elementAt(i)).buttonPressed(e);
+ }
+ } else {
+ for (int i = 0; i < buttonListeners.size(); i++) {
+ ((ButtonListener) buttonListeners.elementAt(i)).buttonReleased(e);
+ }
+ }
+
+ } else { //we are now a joystick
+ //only reach here if not a button
+ Attack3JoystickEvent e = new Attack3JoystickEvent(this, id, newDatum);
+ switch (id){
+ case (KEY_X):
+ for (int i = 0; i < joystickListeners.size(); i++) {
+ ((Attack3JoystickListener)joystickListeners.elementAt(i)).XAxisMoved(e);
+ }
+ break;
+ case (KEY_Y):
+ for (int i = 0; i < joystickListeners.size(); i++) {
+ ((Attack3JoystickListener)joystickListeners.elementAt(i)).YAxisMoved(e);
+ }
+ break;
+ case (KEY_JOYSTICK_ANGLE):
+ for (int i = 0; i < joystickListeners.size(); i++) {
+ ((Attack3JoystickListener)joystickListeners.elementAt(i)).AngleChanged(e);
+ }
+ break;
+ }
+ }
+ }
+ public void addButtonListener(ButtonListener b) {
+ buttonListeners.addElement(b);
+ }
+
+ public void removeButtonListener(ButtonListener b) {
+ buttonListeners.removeElement(b);
+ }
+
+ public void addJoystickListener(Attack3JoystickListener l) {
+ joystickListeners.addElement(l);
+ }
+
+ public void removeJoystickListener(Attack3JoystickListener l) {
+ joystickListeners.removeElement(l);
+ }
+
+}
diff --git a/src/sensor/GRTBatterySensor.java b/src/sensor/GRTBatterySensor.java
new file mode 100644
index 0000000..ed7d327
--- /dev/null
+++ b/src/sensor/GRTBatterySensor.java
@@ -0,0 +1,50 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package sensor;
+
+import core.PollingSensor;
+import edu.wpi.first.wpilibj.DriverStation;
+import event.BatteryVoltageEvent;
+import event.BatteryVoltageListener;
+import java.util.Vector;
+
+/**
+ * A battery sensor that retrieves main battery voltage from the analog sidecar
+ * @author ajc
+ */
+public class GRTBatterySensor extends PollingSensor {
+
+ public static final int KEY_BATTERY_VOLTAGE = 0;
+
+ private final DriverStation ds;
+ private final Vector listeners;
+
+ public GRTBatterySensor(int pollTime, String name) {
+ super(name, pollTime, 1);
+ ds = DriverStation.getInstance();
+ listeners = new Vector();
+ }
+
+ protected void poll() {
+ setState(KEY_BATTERY_VOLTAGE, ds.getBatteryVoltage());
+ }
+
+ protected void notifyListeners(int id, double oldDatum, double newDatum) {
+
+ BatteryVoltageEvent e = new BatteryVoltageEvent(this, newDatum);
+
+ for (int i = 0; i < listeners.size(); i++) {
+ ((BatteryVoltageListener) listeners.elementAt(i)).batteryVoltageChanged(e);
+ }
+ }
+
+ public void addBatteryVoltageListener(BatteryVoltageListener l) {
+ listeners.addElement(l);
+ }
+
+ public void removeBatteryVoltageListener(BatteryVoltageListener l) {
+ listeners.removeElement(l);
+ }
+}
diff --git a/src/sensor/GRTEncoder.java b/src/sensor/GRTEncoder.java
new file mode 100644
index 0000000..468d569
--- /dev/null
+++ b/src/sensor/GRTEncoder.java
@@ -0,0 +1,45 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package sensor;
+
+import core.PollingSensor;
+import edu.wpi.first.wpilibj.Encoder;
+import edu.wpi.first.wpilibj.PIDSource;
+/**
+ *
+ * @author gerberduffy
+ */
+public class GRTEncoder extends PollingSensor {
+
+ private Encoder rotaryEncoder;
+ private double distancePerPulse;
+
+ public static final int DISTANCE = 0;
+ public static final int DEGREES = 1;
+ public static final int DIRECTION = 2;
+
+ public static final int NUM_DATA = 3;
+
+ public GRTEncoder(int channelA, int channelB, double pulseDistance, int pollTime, String id){
+ super(id, pollTime, NUM_DATA);
+ rotaryEncoder = new Encoder(channelA, channelB);
+ rotaryEncoder.start();
+
+ distancePerPulse = pulseDistance;
+ }
+
+
+ protected void poll() {
+ setState(DISTANCE, rotaryEncoder.getDistance());
+ setState(DEGREES, rotaryEncoder.getDistance()/distancePerPulse);
+ setState(DIRECTION, rotaryEncoder.getDirection() ? TRUE : FALSE);
+
+ System.out.println(getState(DISTANCE) + "\t" + getState(DEGREES) + "\t" + getState(DIRECTION));
+ }
+
+ protected void notifyListeners(int id, double oldDatum, double newDatum) {
+ }
+
+}
diff --git a/src/sensor/GRTGyro.java b/src/sensor/GRTGyro.java
new file mode 100644
index 0000000..d4661f2
--- /dev/null
+++ b/src/sensor/GRTGyro.java
@@ -0,0 +1,57 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package sensor;
+
+import core.PollingSensor;
+import edu.wpi.first.wpilibj.AnalogModule;
+import edu.wpi.first.wpilibj.Gyro;
+import java.util.Vector;
+import event.GyroEvent;
+import event.GyroListener;
+
+/**
+ * Provides angular position along a single axis through an analog sensor
+ * @author calvin
+ */
+public class GRTGyro extends PollingSensor {
+
+ public static final int KEY_ANGLE = 0;
+ public static final int NUM_DATA = 1;
+ private Gyro gyro;
+ private Vector gyroListeners;
+
+ public GRTGyro(int channel, int pollTime, String name) {
+ super(name, pollTime, NUM_DATA);
+ gyro = new Gyro(AnalogModule.getDefaultAnalogModule(), channel);
+ gyroListeners = new Vector();
+ }
+
+ public double getAngle(){
+ return gyro.getAngle();
+ }
+
+ protected void poll() {
+ setState(KEY_ANGLE, gyro.getAngle());
+
+ System.out.println("Gyro: \t" + getState(KEY_ANGLE));
+ }
+
+ protected void notifyListeners(int id, double oldDatum, double newDatum) {
+ if (id == KEY_ANGLE) {
+ GyroEvent e = new GyroEvent(this, newDatum);
+ for (int i = 0; i < gyroListeners.size(); i++) {
+ ((GyroListener) gyroListeners.elementAt(i)).angleChanged(e);
+ }
+ }
+ }
+
+ public void addListener(GyroListener l) {
+ gyroListeners.addElement(l);
+ }
+
+ public void removeListener(GyroListener l) {
+ gyroListeners.removeElement(l);
+ }
+}
diff --git a/src/sensor/GRTSwitch.java b/src/sensor/GRTSwitch.java
new file mode 100644
index 0000000..6d9b9f0
--- /dev/null
+++ b/src/sensor/GRTSwitch.java
@@ -0,0 +1,54 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package sensor;
+
+import core.PollingSensor;
+import edu.wpi.first.wpilibj.DigitalInput;
+import event.SwitchEvent;
+import event.SwitchListener;
+import java.util.Vector;
+
+/**
+ *
+ * @author gerberduffy
+ */
+public class GRTSwitch extends PollingSensor {
+
+ private DigitalInput in;
+
+ private static final int STATE = 0;
+ private static final int NUM_DATA = 1;
+
+ private Vector listeners;
+
+ public GRTSwitch(int slot, int polltime, String id){
+
+ super(id, polltime, NUM_DATA);
+
+ in = new DigitalInput(slot);
+
+ listeners = new Vector();
+ }
+
+ public boolean isOn(){
+ return in.get();
+ }
+
+ protected void poll() {
+ setState(STATE, isOn() ? TRUE : FALSE);
+ System.out.println(getState(STATE));
+ }
+
+ protected void notifyListeners(int id, double oldDatum, double newDatum) {
+
+ SwitchEvent e = new SwitchEvent(this, newDatum);
+
+ for (int i=0; i < listeners.size(); i++){
+ ((SwitchListener)listeners.elementAt(i)).switchStateChanged(e);
+ }
+ }
+
+
+}
diff --git a/src/sensor/GRTXBoxJoystick.java b/src/sensor/GRTXBoxJoystick.java
new file mode 100644
index 0000000..907b291
--- /dev/null
+++ b/src/sensor/GRTXBoxJoystick.java
@@ -0,0 +1,161 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package sensor;
+
+import core.PollingSensor;
+import edu.wpi.first.wpilibj.Joystick;
+import event.ButtonEvent;
+import event.ButtonListener;
+import event.XboxJoystickEvent;
+import event.XboxJoystickListener;
+import java.util.Vector;
+
+/**
+ *
+ * @author ajc
+ */
+public class GRTXBoxJoystick extends PollingSensor {
+
+ /**
+ * Keys of data
+ */
+ public static final int KEY_BUTTON_0 = 0;
+ public static final int KEY_BUTTON_1 = 1;
+ public static final int KEY_BUTTON_2 = 2;
+ public static final int KEY_BUTTON_3 = 3;
+ public static final int KEY_BUTTON_4 = 4;
+ public static final int KEY_BUTTON_5 = 5;
+ public static final int KEY_BUTTON_6 = 6;
+ public static final int KEY_BUTTON_7 = 7;
+ public static final int KEY_BUTTON_8 = 8;
+ public static final int KEY_BUTTON_9 = 9;
+ public static final int KEY_LEFT_X = 10;
+ public static final int KEY_LEFT_Y = 11;
+ public static final int KEY_RIGHT_X = 12;
+ public static final int KEY_RIGHT_Y = 13;
+ public static final int KEY_JOYSTICK_ANGLE = 14;
+ public static final int KEY_TRIGGER = 15;
+ public static final int KEY_PAD = 16;
+
+ private static final int NUM_DATA = 17;
+ private static final int NUM_OF_BUTTONS = 10;
+
+ /**
+ * State definitions
+ */
+ public static final double PRESSED = TRUE;
+ public static final double RELEASED = FALSE;
+
+ private final Joystick joystick;
+ private final Vector buttonListeners;
+ private final Vector joystickListeners;
+
+ public GRTXBoxJoystick(int channel, int pollTime, String name) {
+ super(name, pollTime, NUM_DATA);
+ joystick = new Joystick(channel);
+
+ buttonListeners = new Vector();
+ joystickListeners = new Vector();
+ }
+
+ protected void poll() {
+ for (int i = 0; i < NUM_OF_BUTTONS; i++) {
+ //if we measure true, this indicates pressed state
+ setState(i, joystick.getRawButton(i) ? PRESSED : RELEASED);
+ }
+ setState(KEY_LEFT_X, joystick.getX());
+ setState(KEY_LEFT_Y, joystick.getY());
+ setState(KEY_RIGHT_X, joystick.getRawAxis(4));
+ setState(KEY_RIGHT_Y, joystick.getRawAxis(5));
+ setState(KEY_JOYSTICK_ANGLE, joystick.getDirectionRadians());
+ setState(KEY_TRIGGER, joystick.getZ());
+ setState(KEY_PAD, joystick.getRawAxis(6));
+ }
+
+ protected void notifyListeners(int id, double oldDatum, double newDatum) {
+ if (id < NUM_OF_BUTTONS) {
+ //ID maps directly to button ID
+ ButtonEvent e = new ButtonEvent(this, id, newDatum == PRESSED);
+ if (newDatum == PRESSED) { //true
+ for (int i = 0; i < buttonListeners.size(); i++) {
+ ((ButtonListener) buttonListeners.elementAt(i)).buttonPressed(e);
+ }
+ } else {
+ for (int i = 0; i < buttonListeners.size(); i++) {
+ ((ButtonListener) buttonListeners.elementAt(i)).buttonReleased(e);
+ }
+ }
+
+ } else { //we are now a joystick
+ //only reach here if not a button
+ XboxJoystickEvent e = new XboxJoystickEvent(this, id, newDatum);
+
+ //call various events based on which datum we are
+ switch (id) {
+ case KEY_LEFT_X: {
+ for (int i = 0; i < joystickListeners.size(); i++) {
+ ((XboxJoystickListener) joystickListeners.elementAt(i)).leftXAxisMoved(e);
+ }
+
+ }
+ case KEY_LEFT_Y: {
+ for (int i = 0; i < joystickListeners.size(); i++) {
+ ((XboxJoystickListener) joystickListeners.elementAt(i)).leftYAxisMoved(e);
+ }
+ break;
+ }
+ case KEY_RIGHT_X: {
+ for (int i = 0; i < joystickListeners.size(); i++) {
+ ((XboxJoystickListener) joystickListeners.elementAt(i)).rightXAxisMoved(e);
+ }
+ break;
+ }
+ case KEY_RIGHT_Y: {
+ for (int i = 0; i < joystickListeners.size(); i++) {
+ ((XboxJoystickListener) joystickListeners.elementAt(i)).rightYAxisMoved(e);
+ }
+ break;
+ }
+ case KEY_JOYSTICK_ANGLE: {
+ for (int i = 0; i < joystickListeners.size(); i++) {
+ ((XboxJoystickListener) joystickListeners.elementAt(i)).leftAngleChanged(e);
+ }
+ break;
+ }
+ case KEY_TRIGGER: {
+ for (int i = 0; i < joystickListeners.size(); i++) {
+ ((XboxJoystickListener) joystickListeners.elementAt(i)).triggerMoved(e);
+ }
+ break;
+ }
+ case KEY_PAD: {
+ for (int i = 0; i < joystickListeners.size(); i++) {
+ ((XboxJoystickListener) joystickListeners.elementAt(i)).padMoved(e);
+ }
+ break;
+ }
+
+ }
+ }
+
+
+ }
+
+ public void addButtonListener(ButtonListener b) {
+ buttonListeners.addElement(b);
+ }
+
+ public void removeButtonListener(ButtonListener b) {
+ buttonListeners.removeElement(b);
+ }
+
+ public void addJoystickListener(XboxJoystickListener l) {
+ joystickListeners.addElement(l);
+ }
+
+ public void removeJoystickListener(XboxJoystickListener l) {
+ joystickListeners.removeElement(l);
+ }
+}
diff --git a/src/sensor/Potentiometer.java b/src/sensor/Potentiometer.java
new file mode 100644
index 0000000..08dc037
--- /dev/null
+++ b/src/sensor/Potentiometer.java
@@ -0,0 +1,53 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package sensor;
+
+import edu.wpi.first.wpilibj.AnalogChannel;
+import core.PollingSensor;
+import event.PotentiometerEvent;
+import event.PotentiometerListener;
+import java.util.Vector;
+
+/**
+ *
+ * @author calvin
+ */
+public class Potentiometer extends PollingSensor{
+ public static final int KEY_VALUE = 0;
+ public static final int NUM_DATA = 1;
+
+ private int potentiometerType;
+ private AnalogChannel channel;
+ public static final int LINEAR = 0;
+ public static final int LOGARITHMIC = 1;
+
+ public Potentiometer(AnalogChannel channel, int type, int pollTime, String name){
+ super(name, pollTime, NUM_DATA);
+ potentiometerType = type;
+ this.channel = channel;
+ }
+
+ protected void poll() {
+ setState(KEY_VALUE, updateScaledValue());
+ }
+
+ private double updateScaledValue(){
+ double rawValue = channel.getVoltage();
+ double scaledValue;
+ switch(potentiometerType){
+ case LINEAR:
+ scaledValue = rawValue / 5;
+ break;
+ default:
+ scaledValue = rawValue / 5;
+ System.out.println("log is broken as of right now");
+ }
+
+ return scaledValue;
+ }
+
+ protected void notifyListeners(int id, double oldDatum, double newDatum) {
+ }
+}
diff --git a/src/sensor/base/GRTAttack3DriverStation.java b/src/sensor/base/GRTAttack3DriverStation.java
new file mode 100644
index 0000000..a1f0ad0
--- /dev/null
+++ b/src/sensor/base/GRTAttack3DriverStation.java
@@ -0,0 +1,78 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package sensor.base;
+
+import event.Attack3JoystickEvent;
+import event.Attack3JoystickListener;
+import event.ButtonEvent;
+import event.ButtonListener;
+import sensor.GRTAttack3Joystick;
+
+/**
+ * Driver station using 2 Logitech Attack 3 Joysticks
+ * @author dan
+ */
+public class GRTAttack3DriverStation extends GRTDriverStation implements Attack3JoystickListener, ButtonListener{
+ private final GRTAttack3Joystick left;
+ private final GRTAttack3Joystick right;
+
+ public GRTAttack3DriverStation(GRTAttack3Joystick left, GRTAttack3Joystick right,
+ int[] profileButtons, IDriverProfile[] curves, String name){
+ super(profileButtons, curves, name);
+ this.left= left;
+ this.right = right;
+ }
+
+ protected void startListening() {
+ left.addJoystickListener(this);
+ left.addButtonListener(this);
+ right.addJoystickListener(this);
+ right.addButtonListener(this);
+ }
+
+ protected void stopListening() {
+ left.removeJoystickListener(this);
+ left.removeButtonListener(this);
+ right.removeJoystickListener(this);
+ right.removeButtonListener(this);
+ }
+
+ public void XAxisMoved(Attack3JoystickEvent e) {
+ }
+
+ public void YAxisMoved(Attack3JoystickEvent e) {
+ if (e.getSource()==left){
+ notifyLeftDriveSpeed(e.getValue());
+ notifyStateChange(KEY_LEFT_VELOCITY, e.getValue());
+ }
+ else if (e.getSource() ==right){
+ notifyRightDriveSpeed(e.getValue());
+ notifyStateChange(KEY_RIGHT_VELOCITY, e.getValue());
+ }
+ }
+
+ public void AngleChanged(Attack3JoystickEvent e) {
+ }
+
+ public void buttonPressed(ButtonEvent e) {
+ }
+
+ public void buttonReleased(ButtonEvent e) {
+ int profileID = getIndex(profileButtons, e.getButtonID());
+ if (profileID != -1) {//meaning it exists, see #getIndex(int[], int)
+ notifyProfileChange(profileID);
+ notifyStateChange(KEY_PROFILE_ID, profileID);
+ }
+ }
+ private static int getIndex(int[] array, int value) {
+ for (int i = 0; i < array.length; i++) {
+ if (value == array[i]) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+}
diff --git a/src/sensor/base/GRTDriverStation.java b/src/sensor/base/GRTDriverStation.java
new file mode 100644
index 0000000..c76f89c
--- /dev/null
+++ b/src/sensor/base/GRTDriverStation.java
@@ -0,0 +1,93 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package sensor.base;
+
+import core.Sensor;
+import event.DrivingEvent;
+import event.DrivingListener;
+import event.DrivingProfileEvent;
+import event.DrivingProfileListener;
+import java.util.Vector;
+
+/**
+ * Superclass for all DriverStations.
+ *
+ * Handles driver profiles.s
+ * @author ajc
+ */
+public abstract class GRTDriverStation extends Sensor {
+
+ /*
+ * State Keys
+ */
+ public static final int KEY_LEFT_VELOCITY = 0;
+ public static final int KEY_RIGHT_VELOCITY = 1;
+ public static final int KEY_PROFILE_ID = 2;
+
+ //profiles
+ protected IDriverProfile[] curves;
+ /*
+ * maps the profile index to the button that should register it
+ * so {3 4} means button 3 will register PROFILE_LINEAR,
+ * while button 4 will register PROFILE_SQUARED.
+ */
+ protected final int[] profileButtons;
+ //listeners
+ private final Vector drivingListeners;
+ private final Vector profileListeners;
+
+ /**
+ *
+ * @param profileButtons
+ * @param curves
+ * @param name
+ */
+ public GRTDriverStation(int[] profileButtons, IDriverProfile[] curves, String name) {
+ super(name);
+ this.profileButtons = profileButtons;
+ this.curves = curves;
+
+ drivingListeners = new Vector();
+ profileListeners = new Vector();
+ }
+
+ public void addDrivingListener(DrivingListener l) {
+ drivingListeners.addElement(l);
+ }
+
+ public void removeDrivingListener(DrivingListener l) {
+ drivingListeners.removeElement(l);
+ }
+
+ public void addDrivingProfileListener(DrivingProfileListener l) {
+ profileListeners.addElement(l);
+ }
+
+ public void removeDrivingProfileListener(DrivingProfileListener l) {
+ profileListeners.removeElement(l);
+ }
+
+ protected void notifyLeftDriveSpeed(double speed) {
+ DrivingEvent ev = new DrivingEvent(this, DrivingEvent.SIDE_LEFT, speed);
+ for (int i = 0; i < drivingListeners.size(); i++) {
+ ((DrivingListener) drivingListeners.elementAt(i)).driverLeftSpeed(ev);
+ }
+ }
+
+ protected void notifyRightDriveSpeed(double speed) {
+ DrivingEvent ev = new DrivingEvent(this, DrivingEvent.SIDE_RIGHT, speed);
+ for (int i = 0; i < drivingListeners.size(); i++) {
+ ((DrivingListener) drivingListeners.elementAt(i)).driverRightSpeed(ev);
+ }
+ }
+
+ protected void notifyProfileChange(int profileID) {
+ DrivingProfileEvent e = new DrivingProfileEvent(this, curves[profileID]);
+ for (int i = 0; i < profileListeners.size(); i++) {
+ ((DrivingProfileListener) profileListeners.elementAt(i)).drivingProfileChanged(e);
+
+ }
+ }
+}
diff --git a/src/sensor/base/GRTXboxDriverStation.java b/src/sensor/base/GRTXboxDriverStation.java
new file mode 100644
index 0000000..d5b3ed8
--- /dev/null
+++ b/src/sensor/base/GRTXboxDriverStation.java
@@ -0,0 +1,113 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package sensor.base;
+
+import event.ButtonEvent;
+import event.ButtonListener;
+import event.XboxJoystickEvent;
+import event.XboxJoystickListener;
+import sensor.GRTXBoxJoystick;
+
+/**
+ * Driverstation using XBoxJoysticks
+ *
+ * @author ajc
+ */
+public class GRTXboxDriverStation extends GRTDriverStation implements XboxJoystickListener, ButtonListener {
+
+ private final GRTXBoxJoystick primary;
+ private final GRTXBoxJoystick secondary;
+
+ /**
+ *
+ * @param primary
+ * @param secondary
+ * @param profileButtons
+ * @param curves
+ * @param name
+ */
+ public GRTXboxDriverStation(GRTXBoxJoystick primary, GRTXBoxJoystick secondary,
+ int[] profileButtons, IDriverProfile[] curves, String name) {
+ super(profileButtons, curves, name);
+ this.primary = primary;
+ this.secondary = secondary;
+
+ }
+
+ protected void startListening() {
+ primary.addJoystickListener(this);
+ primary.addButtonListener(this);
+ }
+
+ protected void stopListening() {
+ primary.removeJoystickListener(this);
+ primary.removeButtonListener(this);
+ }
+
+ /*
+ * JOYSTICK EVENTS
+ */
+ public void leftXAxisMoved(XboxJoystickEvent e) {
+ }
+
+ public void leftYAxisMoved(XboxJoystickEvent e) {
+ if (e.getSource() == primary) {
+ notifyLeftDriveSpeed(e.getValue());
+ notifyStateChange(KEY_LEFT_VELOCITY, e.getValue());
+ }
+ }
+
+ public void rightXAxisMoved(XboxJoystickEvent e) {
+ }
+
+ public void rightYAxisMoved(XboxJoystickEvent e) {
+ if (e.getSource() == primary) {
+ notifyRightDriveSpeed(e.getValue());
+ notifyStateChange(KEY_RIGHT_VELOCITY, e.getValue());
+ }
+ }
+
+ public void padMoved(XboxJoystickEvent e) {
+ }
+
+ public void triggerMoved(XboxJoystickEvent e) {
+ }
+
+ /*
+ * BUTTON EVENTS
+ */
+ public void buttonPressed(ButtonEvent e) {
+ }
+
+ public void buttonReleased(ButtonEvent e) {
+
+ //we receive the button.
+ //the button corresponds to an element in the profileButtons list
+ //we need to find the index from that array that the button ID is
+ int profileID = getIndex(profileButtons, e.getButtonID());
+ if (profileID != -1) {//meaning it exists, see #getIndex(int[], int)
+ notifyProfileChange(profileID);
+ notifyStateChange(KEY_PROFILE_ID, profileID);
+ }
+ }
+
+ /**
+ *
+ * @param array
+ * @param value
+ * @return
+ */
+ private static int getIndex(int[] array, int value) {
+ for (int i = 0; i < array.length; i++) {
+ if (value == array[i]) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public void leftAngleChanged(XboxJoystickEvent e) {
+ }
+}
diff --git a/src/sensor/base/IDriverProfile.java b/src/sensor/base/IDriverProfile.java
new file mode 100644
index 0000000..173509f
--- /dev/null
+++ b/src/sensor/base/IDriverProfile.java
@@ -0,0 +1,19 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package sensor.base;
+
+/**
+ *
+ * @author ajc
+ */
+public interface IDriverProfile {
+
+ /**
+ *
+ * @param joystickTiltPercent an input percent from [-1.0 - 1.0]
+ * @return an output from [-1.0 - 1.0]
+ */
+ public double driveSpeed(double joystickTiltPercent);
+}
diff --git a/src/sensor/base/LinearDrive.java b/src/sensor/base/LinearDrive.java
new file mode 100644
index 0000000..995cb24
--- /dev/null
+++ b/src/sensor/base/LinearDrive.java
@@ -0,0 +1,17 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package sensor.base;
+
+/**
+ *
+ * @author ajc
+ */
+public class LinearDrive implements IDriverProfile{
+
+ public double driveSpeed(double joystickTiltPercent) {
+ return joystickTiltPercent;
+ }
+
+}
diff --git a/src/sensor/base/SquareDrive.java b/src/sensor/base/SquareDrive.java
new file mode 100644
index 0000000..a33ae77
--- /dev/null
+++ b/src/sensor/base/SquareDrive.java
@@ -0,0 +1,19 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package sensor.base;
+
+/**
+ *
+ * @author ajc
+ */
+public class SquareDrive implements IDriverProfile {
+
+ public double driveSpeed(double joystickTiltPercent) {
+ //save the sign: becomes -1 if original was negative, +1 if positive
+ double sign = joystickTiltPercent > 0 ? +1.0 : -1.0;
+ //apply sign to square to enable reverse driving
+ return sign * joystickTiltPercent * joystickTiltPercent;
+ }
+}
diff --git a/src/sensor/base/TestSwitch.java b/src/sensor/base/TestSwitch.java
new file mode 100644
index 0000000..b3abe42
--- /dev/null
+++ b/src/sensor/base/TestSwitch.java
@@ -0,0 +1,22 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package sensor.base;
+
+import core.Sensor;
+
+/**
+ *
+ * @author gerberduffy
+ */
+public class TestSwitch {
+
+
+ protected void startListening() {
+ }
+
+ protected void stopListening() {
+ }
+
+}
diff --git a/src/sensor/base/VictorDriverProfile.java b/src/sensor/base/VictorDriverProfile.java
new file mode 100644
index 0000000..2e9f355
--- /dev/null
+++ b/src/sensor/base/VictorDriverProfile.java
@@ -0,0 +1,25 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package sensor.base;
+
+
+/**
+ *
+ * Driver profile that transaltes joystick values
+ * specifically calibrated for Victors
+ *
+ * @author gerberduffy
+ */
+public class VictorDriverProfile implements IDriverProfile {
+
+ public double driveSpeed(double joystickTiltPercent) {
+ //TODO: IMPLEMENT THE HECK OUT OF THIS.
+
+ return 0.0;
+ }
+
+
+
+}
diff --git a/suite/Base2012-redesign_1.0.0.jar b/suite/Base2012-redesign_1.0.0.jar
new file mode 100644
index 0000000..5c5bbd9
Binary files /dev/null and b/suite/Base2012-redesign_1.0.0.jar differ