diff --git a/src/control/WiimoteDeviceDiscovery.java b/src/control/WiimoteDeviceDiscovery.java new file mode 100755 index 0000000..d51ee03 --- /dev/null +++ b/src/control/WiimoteDeviceDiscovery.java @@ -0,0 +1,108 @@ +/* + * wiigee - accelerometerbased gesture recognition + * Copyright (C) 2007, 2008 Benjamin Poppinga + * + * Developed at University of Oldenburg + * Contact: benjamin.poppinga@informatik.uni-oldenburg.de + * + * This file is part of wiigee. + * + * wiigee is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package control; + +import java.io.IOException; +import java.util.Vector; + +import javax.bluetooth.DeviceClass; +import javax.bluetooth.DiscoveryListener; +import javax.bluetooth.RemoteDevice; +import javax.bluetooth.ServiceRecord; + +import util.Log; + +import device.Wiimote; + +public class WiimoteDeviceDiscovery implements DiscoveryListener { + + private Vector devices; + private boolean isInquiring; + private Object lock; + + public WiimoteDeviceDiscovery(Object lock) { + super(); + this.lock=lock; + this.devices = new Vector(); + //this.isInquiring=true; + } + + public void deviceDiscovered(RemoteDevice newdevice, DeviceClass devclass) { + Log.write("Device discovered: " + + newdevice.getBluetoothAddress() + " - "); + // add the device to the vector + if (!devices.contains(newdevice) + && devclass.getMajorDeviceClass() == 1280 + && devclass.getMinorDeviceClass() == 4) { + Log.write("Is a Wiimote!"); + devices.addElement(newdevice); + } else { + Log.write("Is NOT a Wiimote!"); + } + } + + public void inquiryCompleted(int discType) { + switch (discType) { + case WiimoteDeviceDiscovery.INQUIRY_COMPLETED: + Log.write("Inquiry completed."); + break; + + case WiimoteDeviceDiscovery.INQUIRY_ERROR: + Log.write("Inquiry error."); + break; + + case WiimoteDeviceDiscovery.INQUIRY_TERMINATED: + Log.write("Inquiry terminated."); + break; + } + synchronized(this.lock) { + this.lock.notify(); + } + //this.isInquiring=false; + } + + public void serviceSearchCompleted(int arg0, int arg1) { + // not necessary + } + + public void servicesDiscovered(int arg0, ServiceRecord[] arg1) { + // not necessary + } + + public boolean isInquirying() { + return this.isInquiring; + } + + public Vector getDiscoveredWiimotes() throws IOException { + Vector wiimotes = new Vector(); + + for (int i = 0; i < devices.size(); i++) { + wiimotes.add(new Wiimote(devices.elementAt(i).getBluetoothAddress())); + } + + return wiimotes; + } + +} diff --git a/src/control/WiimoteWiigee.java b/src/control/WiimoteWiigee.java new file mode 100755 index 0000000..e562feb --- /dev/null +++ b/src/control/WiimoteWiigee.java @@ -0,0 +1,188 @@ +/* + * wiigee - accelerometerbased gesture recognition + * Copyright (C) 2007, 2008 Benjamin Poppinga + * + * Developed at University of Oldenburg + * Contact: benjamin.poppinga@informatik.uni-oldenburg.de + * + * This file is part of wiigee. + * + * wiigee is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package control; + +import java.io.IOException; +import java.util.Vector; + +import javax.bluetooth.DiscoveryAgent; +import javax.bluetooth.LocalDevice; + +import util.Log; +import device.Wiimote; +import event.DeviceListener; +import event.GestureListener; +import filter.Filter; + +// Singleton +public class WiimoteWiigee { + + protected static String version = "1.3.1 alpha"; + protected static String releasedate = "20081215"; + + protected static WiimoteWiigee instance; + private static Object lock = new Object(); + private Vector devices; + + private WiimoteWiigee() throws IOException { + Log.write("This is wiigee version "+version+" ("+releasedate+")"); + this.devices=this.discoverWiimotes(); + for(int i=0; i(); + this.devices.add(new Wiimote(btaddr)); + for(int i=0; i discoverWiimotes() throws IOException { + WiimoteDeviceDiscovery deviceDiscovery = new WiimoteDeviceDiscovery(lock); + LocalDevice localDevice = LocalDevice.getLocalDevice(); + Log.write("Your Computers Bluetooth MAC: "+localDevice.getBluetoothAddress()); + + DiscoveryAgent discoveryAgent = localDevice.getDiscoveryAgent(); + + Log.write("Starting device inquiry..."); + discoveryAgent.startInquiry(DiscoveryAgent.GIAC, deviceDiscovery); + + + try { + synchronized(lock){ + lock.wait(); + } + } catch (InterruptedException e) { + Log.write("Problems during device discovery."); + e.printStackTrace(); + } + + Log.write("Device discovery completed!"); + return deviceDiscovery.getDiscoveredWiimotes(); + } + + /** + * Returns the number of wiimotes discovered. + * + * @return Number of wiimotes discovered. + */ + public int getNumberOfDevices() { + return this.devices.size(); + } + + /** + * Sets the Trainbutton for all wiimotes; + * + * @param b Button encoding, see static Wiimote values + */ + public void setTrainButton(int b) { + for(int i=0; i0) { + this.devices.elementAt(0).addDeviceListener(listener); + } + } + + public void addGestureListener(GestureListener listener) { + if(this.devices.size()>0) { + this.devices.elementAt(0).addGestureListener(listener); + } + } + + public void addFilter(Filter filter) { + if(this.devices.size()>0) { + this.devices.elementAt(0).addFilter(filter); + } + } + +} diff --git a/src/device/Device.java b/src/device/Device.java new file mode 100644 index 0000000..defd31a --- /dev/null +++ b/src/device/Device.java @@ -0,0 +1,220 @@ +/* + * wiigee - accelerometerbased gesture recognition + * Copyright (C) 2007, 2008 Benjamin Poppinga + * + * Developed at University of Oldenburg + * Contact: benjamin.poppinga@informatik.uni-oldenburg.de + * + * This file is part of wiigee. + * + * wiigee is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package device; + +import java.io.IOException; +import java.util.Vector; + +import logic.ProcessingUnit; +import logic.*; +import event.*; +import filter.DirectionalEquivalenceFilter; +import filter.Filter; +import filter.IdleStateFilter; +import filter.MotionDetectFilter; + +public class Device { + + // Fixed number values. + public static final int MOTION = 0; + + // Buttons for action coordination + protected int recognitionbutton; + protected int trainbutton; + protected int closegesturebutton; + + // Functional + protected boolean accelerationenabled; + + // Filters, can filter the data stream + protected Vector filters = new Vector(); + + // Listeners, receive generated events + protected Vector devicelistener = new Vector(); + protected ProcessingUnit analyzer = new TriggeredProcessingUnit(); + + public Device() { + this.addFilter(new IdleStateFilter()); + this.addFilter(new MotionDetectFilter(this)); + this.addFilter(new DirectionalEquivalenceFilter()); + this.addDeviceListener(this.analyzer); + } + + /** + * Adds a Filter for processing the acceleration values. + * @param filter The Filter instance. + */ + public void addFilter(Filter filter) { + this.filters.add(filter); + System.out.println("Filter added..."); + } + + /** + * Resets all the filters, which are resetable. + * Sometimes they have to be resettet if a new gesture starts. + */ + public void resetFilters() { + for(int i=0; i0) { + byte tmp = (byte)value; + this.ledencoding=(byte)(tmp<<4); + this.sendRaw(new byte[] {CMD_SET_REPORT, 0x11, this.ledencoding}); + } else { + // Random LED change :) + this.setLED(new Random().nextInt(16)); + } + } + + /** + * Initializes the calibration of the accerlarometer. This is done once + * per each controller in program lifetime. + * + * @throws IOException + */ + private void calibrateAccelerometer() throws IOException { + // calibration command + this.readEEPROM(new byte[] {0x00, 0x00, 0x20}, new byte[] {0x00, 0x07}); + this.calibrated=true; + } + + /** + * Activates the acceleration sensor. You have to call the + * streamData(true) method to react to this acceleration data. + * Otherwise the wiimote would send data the whole time and + * nothing else would happen. + * + */ + public void enableAccelerationSensors() throws IOException { + super.enableAccelerationSensors(); + if(!this.calibrated) { + this.calibrateAccelerometer(); + } + + // enable acceleration in continuous mode + this.sendRaw(new byte[] {CMD_SET_REPORT, 0x12, 0x04, 0x31}); + } + + /** + * Deactivates the acceleration sensors. + * + */ + public void disableAccelerationSensors() throws IOException { + super.disableAccelerationSensors(); + this.sendRaw(new byte[] {CMD_SET_REPORT, 0x12, 0x00, 0x30}); + } + + /** + * Enables the infrared camera in front of the wiimote to track + * IR sources in the field of view of the camera. This could be used + * to a lot of amazing stuff. Using this Mode could slow down the + * recognition of acceleration gestures during the increased data + * size transmitted. + */ + public void enableInfraredCamera() throws IOException { + this.accelerationenabled=true; + this.infraredenabled=true; + if(!this.calibrated) { + this.calibrateAccelerometer(); + } + + //write 0x04 to output 0x13 + this.sendRaw(new byte[] {CMD_SET_REPORT, 0x13, 0x04}); + + // write 0x04 to output 0x1a + this.sendRaw(new byte[] {CMD_SET_REPORT, 0x1a, 0x04}); + + // write 0x08 to reguster 0xb00030 + this.writeRegister(new byte[] {(byte)0xb0, 0x00, 0x30}, new byte[] {0x08}); + + // write sensivity block 1 to register 0xb00000 + this.writeRegister(new byte[] {(byte)0xb0, 0x00, 0x00}, new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte)0x90, 0x00, (byte)0xc0}); + + // write sensivity block 2 to register 0xb0001a + this.writeRegister(new byte[] {(byte)0xb0, 0x00, (byte)0x1a}, new byte[] {0x40, 0x00}); + + // write ir-mode to register 0xb00033 + this.writeRegister(new byte[] {(byte)0xb0, 0x00, 0x33}, new byte[] {0x03}); + + // enable continuous acceleration and IR cam on channel 33 + this.sendRaw(new byte[] {CMD_SET_REPORT, 0x12, 0x00, 0x33}); + + } + + + /** + * With this method you gain access over the vibrate function of + * the wiimote. You got to try which time in milliseconds would + * fit your requirements. + * + * @param milliseconds + * time the wiimote would vibrate + */ + public void vibrateForTime(long milliseconds) throws IOException { + try { + if(!vibrating) { + this.vibrating=true; + byte tmp = (byte)(this.ledencoding | 0x01); + this.sendRaw(new byte[] {CMD_SET_REPORT, 0x11, tmp}); + Thread.sleep(milliseconds); + this.sendRaw(new byte[] {CMD_SET_REPORT, 0x11, this.ledencoding}); + this.vibrating=false; + } + } catch (InterruptedException e) { + System.out.println("WiiMoteThread interrupted."); + } + } + + public boolean infraredEnabled() { + return this.infraredenabled; + } + + // ###### Hilfsmethoden + // TODO + private String removeChar(String s, char c) { + String r = ""; + for (int i = 0; i < s.length(); i ++) { + if (s.charAt(i) != c) r += s.charAt(i); + } + return r; + } + + /** + * Fires a infrared event + * + * @param coordinates + * @param size + */ + public void fireInfraredEvent(int[][] coordinates, int[] size) { + InfraredEvent w = new InfraredEvent(this, coordinates, size); + for(int i=0; ireference[0]+this.sensivity || + vector[1]reference[1]+this.sensivity || + vector[2]reference[2]+this.sensivity) { + this.reference=vector; + return vector; + } else { + return null; + } + } + + public void setSensivity(double sensivity) { + this.sensivity=sensivity; + } + + public double getSensivity() { + return this.sensivity; + } + +} diff --git a/src/filter/Filter.java b/src/filter/Filter.java new file mode 100755 index 0000000..f715caa --- /dev/null +++ b/src/filter/Filter.java @@ -0,0 +1,63 @@ +/* + * wiigee - accelerometerbased gesture recognition + * Copyright (C) 2007, 2008 Benjamin Poppinga + * + * Developed at University of Oldenburg + * Contact: benjamin.poppinga@informatik.uni-oldenburg.de + * + * This file is part of wiigee. + * + * wiigee is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package filter; + +public abstract class Filter { + + public Filter() { + // nothing, but should be called via SUPER. + } + + public void reset() { + // reset filter, if necessary. + } + + /*** + * The actual called method to filter anything. It checks if the vector is + * already set to NULL by another filter and won't process it anymore. If it's + * not NULL it would be forwarded to the actual implemented method - filterAlgorithm(). + * @param vector The acceleration vector, encoding: 0/x, 1/y, 2/z + * @return a new, filtered acceleration vector, encoded the same way + */ + public double[] filter(double[] vector) { + if(vector==null) { + return null; + } else { + return filterAlgorithm(vector); + } + } + + /*** + * A filter receives a triple of acceleration values within the variable 'vector'. + * It's encoded as vector[0]=x, vector[1]=y, vector[2]=z. This is not an object since the + * processing of the filter should be really fast, since every acceleration of the wiimote + * passes the filter. + * @param vector + * @param absvalue + * @return + */ + abstract public double[] filterAlgorithm(double[] vector); + +} diff --git a/src/filter/IdleStateFilter.java b/src/filter/IdleStateFilter.java new file mode 100755 index 0000000..8f40167 --- /dev/null +++ b/src/filter/IdleStateFilter.java @@ -0,0 +1,74 @@ +/* + * wiigee - accelerometerbased gesture recognition + * Copyright (C) 2007, 2008 Benjamin Poppinga + * + * Developed at University of Oldenburg + * Contact: benjamin.poppinga@informatik.uni-oldenburg.de + * + * This file is part of wiigee. + * + * wiigee is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package filter; + +public class IdleStateFilter extends Filter { + + private double sensivity; + + /** + * Since an acceleration sensor usually provides information even + * if it doesn't move, this filter removes the data if it's in the + * idle state. + */ + public IdleStateFilter() { + super(); + this.sensivity = 0.1; + } + + public double[] filterAlgorithm(double[] vector) { + // calculate values needed for filtering: + // absolute value + double absvalue = Math.sqrt((vector[0]*vector[0])+ + (vector[1]*vector[1])+(vector[2]*vector[2])); + + // filter formulaes and return values + if(absvalue > 1+this.sensivity || + absvalue < 1-this.sensivity) { + return vector; + } else { + return null; + } + } + + /** + * Defines the absolute value when the wiimote should react to acceleration. + * This is a parameter for the first of the two filters: idle state + * filter. For example: sensivity=0.2 makes the wiimote react to acceleration + * where the absolute value is equal or greater than 1.2g. The default value 0.1 + * should work well. Only change if you are sure what you're doing. + * + * @param sensivity + * acceleration data values smaller than this value wouldn't be detected. + */ + public void setSensivity(double sensivity) { + this.sensivity = sensivity; + } + + public double getSensivity() { + return this.sensivity; + } + +} diff --git a/src/filter/MotionDetectFilter.java b/src/filter/MotionDetectFilter.java new file mode 100755 index 0000000..2461fc6 --- /dev/null +++ b/src/filter/MotionDetectFilter.java @@ -0,0 +1,96 @@ +/* + * wiigee - accelerometerbased gesture recognition + * Copyright (C) 2007, 2008 Benjamin Poppinga + * + * Developed at University of Oldenburg + * Contact: benjamin.poppinga@informatik.uni-oldenburg.de + * + * This file is part of wiigee. + * + * wiigee is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package filter; + +import device.Device; + +public class MotionDetectFilter extends Filter { + + private int motionchangetime; + private boolean nowinmotion; + private long motionstartstamp; + private Device device; + + /*** + * Detects wheather the wiimote receives acceleration or not and + * raises an event, if the device starts or stops. This is actual a + * null filter, not manipulating anything. But looks pretty good in + * this datatype since it could be removed easily. + * + * @param wiimote The Wiimote object which is controlled by the filter. + */ + public MotionDetectFilter(Device device) { + super(); + this.device=device; + this.reset(); + } + + public void reset() { + super.reset(); + this.motionstartstamp=System.currentTimeMillis(); + this.nowinmotion=false; + this.motionchangetime=190; + } + + public double[] filter(double[] vector) { + + if(this.nowinmotion && + (System.currentTimeMillis()-this.motionstartstamp)>= + this.motionchangetime) { + this.nowinmotion=false; + this.device.fireMotionStopEvent(); + } // fi + + return filterAlgorithm(vector); + } + + public double[] filterAlgorithm(double[] vector) { + if(vector!=null) { + this.motionstartstamp=System.currentTimeMillis(); + if(!this.nowinmotion) { + this.nowinmotion=true; + this.motionstartstamp=System.currentTimeMillis(); + this.device.fireMotionStartEvent(); + } + } + + return vector; + } + + /** + * Defines the time the wiimote has to be in idle state before a new motion change + * event appears. The default value 500ms should work well, only change it if you are sure + * about what you're doing. + * @param time Time in ms + */ + public void setMotionChangeTime(int time) { + this.motionchangetime=time; + } + + public int getMotionChangeTime() { + return this.motionchangetime; + } + +} diff --git a/src/logic/Classifier.java b/src/logic/Classifier.java new file mode 100644 index 0000000..c3c015f --- /dev/null +++ b/src/logic/Classifier.java @@ -0,0 +1,105 @@ +/* + * wiigee - accelerometerbased gesture recognition + * Copyright (C) 2007, 2008 Benjamin Poppinga + * + * Developed at University of Oldenburg + * Contact: benjamin.poppinga@informatik.uni-oldenburg.de + * + * This file is part of wiigee. + * + * wiigee is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package logic; + +import java.util.Vector; + +public class Classifier { + + private Vector gesturemodel; // each gesturetype got its own + // gesturemodel in this vector + private double lastprob; + + public Classifier() { + this.gesturemodel=new Vector(); + this.lastprob=0.0; + } + + /** + * This method recognize a specific gesture, given to the procedure. + * For classification a bayes classification algorithm is used. + * + * @param g gesture to classify + */ + public int classifyGesture(Gesture g) { + //System.out.println("Recognizing gesture..."); + + // Wert im Nenner berechnen, nach Bayes + double sum = 0; + for(int i=0; irecogprob) { + probgesture=tmpgesture; + probmodel=tmpmodel; + recogprob=((tmpmodel*tmpgesture)/sum); + recognized=i; + } + } + + // a gesture could be recognized + if(recogprob>0 && probmodel>0 && probgesture>0 && sum>0) { + this.lastprob=recogprob; + return recognized; + } else { + // no gesture could be recognized + return -1; + } + + } + + public double getLastProbability() { + return this.lastprob; + } + + public void addGestureModel(GestureModel gm) { + this.gesturemodel.add(gm); + } + + public GestureModel getGestureModel(int id) { + return this.gesturemodel.elementAt(id); + } + + public Vector getGestureModels() { + return this.gesturemodel; + } + + public void clear() { + this.gesturemodel = new Vector(); + } + + +} diff --git a/src/logic/Gesture.java b/src/logic/Gesture.java new file mode 100755 index 0000000..51f520a --- /dev/null +++ b/src/logic/Gesture.java @@ -0,0 +1,155 @@ +/* + * wiigee - accelerometerbased gesture recognition + * Copyright (C) 2007, 2008 Benjamin Poppinga + * + * Developed at University of Oldenburg + * Contact: benjamin.poppinga@informatik.uni-oldenburg.de + * + * This file is part of wiigee. + * + * wiigee is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package logic; + +import java.util.Vector; +import event.AccelerationEvent; + +/** + * This class represents ONE movement trajectory in a + * concrete instance. + * + * @author Benjamin 'BePo' Poppinga + */ + +public class Gesture implements Cloneable { + + /** Min/MaxAcceleration setup manually? */ + private boolean minmaxmanual; + private double minacc; + private double maxacc; + + /** The complete trajectory as WiimoteAccelerationEvents + * as a vector. It's a vector because we don't want to + * loose the chronology of the stored events. + */ + private Vector data; + + /** + * Create an empty Gesture. + */ + public Gesture() { + this.data = new Vector(); + } + + /** + * Make a deep copy of another Gesture object. + * + * @param original Another Gesture object + */ + public Gesture(Gesture original) { + this.data = new Vector(); + Vector origin = original.getData(); + for (int i = 0; i < origin.size(); i++) { + this.add((AccelerationEvent) origin.get(i)); + } + } + + + /** + * Adds a new acceleration event to this gesture. + * + * @param event The WiimoteAccelerationEvent to add. + */ + public void add(AccelerationEvent event) { + this.data.add(event); + } + + /** + * Returns the last acceleration added to this gesture. + * + * @return the last acceleration event added. + */ + public AccelerationEvent getLastData() { + return (AccelerationEvent) this.data.get(this.data.size() - 1); + } + + /** + * Returns the whole chronological sequence of accelerations as + * a vector. + * + * @return chronological sequence of accelerations. + */ + public Vector getData() { + return this.data; + } + + /** + * Removes the first element of the acceleration queue of a gesture + */ + public void removeFirstData() { + this.data.remove(0); + } + + public int getCountOfData() { + return this.data.size(); + } + + public void setMaxAndMinAcceleration(double max, double min) { + this.maxacc = max; + this.minacc = min; + this.minmaxmanual = true; + } + + public double getMaxAcceleration() { + if(!this.minmaxmanual) { + double maxacc = Double.MIN_VALUE; + for(int i=0; i maxacc) { + maxacc=Math.abs(this.data.get(i).getX()); + } + if(Math.abs(this.data.get(i).getY()) > maxacc) { + maxacc=Math.abs(this.data.get(i).getY()); + } + if(Math.abs(this.data.get(i).getZ()) > maxacc) { + maxacc=Math.abs(this.data.get(i).getZ()); + } + } + return maxacc; + } else { + return this.maxacc; + } + } + + public double getMinAcceleration() { + if(!this.minmaxmanual) { + double minacc = Double.MAX_VALUE; + for(int i=0; i