From 2f76a8432181ff2bee4fd373343978c77b84a468 Mon Sep 17 00:00:00 2001 From: bepo23 Date: Sun, 24 May 2009 10:45:15 +0000 Subject: [PATCH] The GestureModel doesn't contain an ID anymore since this is now managed by the Classifier dynamically. Gesture Saving therefore would become more flexible with the next release containing GestureSets with exchangeable Gestures. To any who already use the save/load function of wiigee: Please remove the first two lines within the saved gesture files (that's the id). Then it should work properly. git-svn-id: svn://svn.code.sf.net/p/wiigee/code/trunk@69 c7eff9ee-dd40-0410-8832-91a4d88773cf --- src/control/WiimoteWiigee.java | 298 +++++++++++++------------ src/device/Device.java | 19 +- src/logic/Classifier.java | 4 + src/logic/GestureModel.java | 17 +- src/logic/ProcessingUnit.java | 8 +- src/logic/TriggeredProcessingUnit.java | 13 +- src/util/FileIO.java | 26 +-- 7 files changed, 189 insertions(+), 196 deletions(-) diff --git a/src/control/WiimoteWiigee.java b/src/control/WiimoteWiigee.java index e562feb..c56901f 100755 --- a/src/control/WiimoteWiigee.java +++ b/src/control/WiimoteWiigee.java @@ -21,12 +21,14 @@ * 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 java.util.logging.Level; +import java.util.logging.Logger; +import javax.bluetooth.BluetoothStateException; import javax.bluetooth.DiscoveryAgent; import javax.bluetooth.LocalDevice; @@ -38,151 +40,157 @@ 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(); - } + protected static String version = "1.5 alpha"; + protected static String releasedate = "20090524"; + protected static WiimoteWiigee instance; + private static Object lock = new Object(); + private Vector devices; - 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); - } - } + private WiimoteWiigee() { + String stack; + String stackVersion; + String l2capFeature; + String bluecoveVersion; + Log.write("This is wiigee version " + version + " (" + releasedate + ")"); + + // Bluecove + bluecoveVersion = LocalDevice.getProperty("bluecove"); + if(!bluecoveVersion.equals("")) { + + stack = LocalDevice.getProperty("bluecove.stack"); + stackVersion = LocalDevice.getProperty("bluecove.stack.version"); + Log.write("You are using the "+stack+" Bluetooth stack (Version "+stackVersion+")"); + + l2capFeature = LocalDevice.getProperty("bluecove.feature.l2cap"); + Log.write("L2CAP supported: "+l2capFeature); + + if(l2capFeature.equals("true")) { + Log.write("wiigee: found a supported stack!"); + + // set min id for Bluecove + Log.write(Log.DEBUG, "JSR82 PSM Minimum Restriction -- OFF", null); + System.setProperty("bluecove.jsr82.psm_minimum_off", "true"); + } + } else { + Log.write("No Bluecove Library detected - trying anyway..."); + } + } + + public static WiimoteWiigee getInstance() { + if (instance == null) { + instance = new WiimoteWiigee(); + return instance; + } else { + return instance; + } + } + + /** + * Returns an array of discovered wiimotes. + * + * @return Array of discovered wiimotes or null if + * none discoverd. + */ + public Wiimote[] getDevices() throws IOException { + this.devices = this.discoverWiimotes(); + for (int i = 0; i < this.devices.size(); i++) { + this.devices.elementAt(i).setLED(i + 1); + } + Wiimote[] out = new Wiimote[this.devices.size()]; + for (int i = 0; i < this.devices.size(); i++) { + out[i] = this.devices.elementAt(i); + } + return out; + } + + /** + * Discover the wiimotes around the bluetooth host and + * make them available public via getWiimotes method. + * + * @return Array of discovered wiimotes. + */ + private Vector discoverWiimotes() throws IOException { + WiimoteDeviceDiscovery deviceDiscovery = new WiimoteDeviceDiscovery(lock); + LocalDevice localDevice = LocalDevice.getLocalDevice(); + Log.write("Your Computers Bluetooth MAC: " + localDevice.getBluetoothAddress()); + + Log.write("Starting device inquiry..."); + DiscoveryAgent discoveryAgent = localDevice.getDiscoveryAgent(); + 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; i < this.devices.size(); i++) { + this.devices.elementAt(i).setTrainButton(b); + } + } + + /** + * Sets the Recognitionbutton for all wiimotes; + * + * @param b Button encoding, see static Wiimote values + */ + public void setRecognitionButton(int b) { + for (int i = 0; i < this.devices.size(); i++) { + this.devices.elementAt(i).setRecognitionButton(b); + } + } + + /** + * Sets the CloseGesturebutton for all wiimotes; + * + * @param b Button encoding, see static Wiimote values + */ + public void setCloseGestureButton(int b) { + for (int i = 0; i < this.devices.size(); i++) { + this.devices.elementAt(i).setCloseGestureButton(b); + } + } + + public void addDeviceListener(DeviceListener listener) { + for (int i = 0; i < this.devices.size(); i++) { + this.devices.elementAt(i).addDeviceListener(listener); + } + } + + public void addGestureListener(GestureListener listener) { + for (int i = 0; i < this.devices.size(); i++) { + this.devices.elementAt(i).addGestureListener(listener); + } + } + + public void addFilter(Filter filter) { + for (int i = 0; i < this.devices.size(); i++) { + this.devices.elementAt(i).addFilter(filter); + } + } } diff --git a/src/device/Device.java b/src/device/Device.java index defd31a..575d52e 100644 --- a/src/device/Device.java +++ b/src/device/Device.java @@ -27,7 +27,6 @@ package device; import java.io.IOException; import java.util.Vector; -import logic.ProcessingUnit; import logic.*; import event.*; import filter.DirectionalEquivalenceFilter; @@ -53,13 +52,13 @@ public class Device { // Listeners, receive generated events protected Vector devicelistener = new Vector(); - protected ProcessingUnit analyzer = new TriggeredProcessingUnit(); + protected ProcessingUnit processingunit = new TriggeredProcessingUnit(); public Device() { this.addFilter(new IdleStateFilter()); this.addFilter(new MotionDetectFilter(this)); this.addFilter(new DirectionalEquivalenceFilter()); - this.addDeviceListener(this.analyzer); + this.addDeviceListener(this.processingunit); } /** @@ -98,7 +97,7 @@ public class Device { * this gesture. */ public void addGestureListener(GestureListener listener) { - this.analyzer.addGestureListener(listener); + this.processingunit.addGestureListener(listener); System.out.println("GestureListener added..."); } @@ -126,8 +125,8 @@ public class Device { this.closegesturebutton=b; } - public ProcessingUnit getAccelerationStreamAnalyzer() { - return this.analyzer; + public ProcessingUnit getProcessingUnit() { + return this.processingunit; } public boolean accelerationEnabled() { @@ -141,6 +140,14 @@ public class Device { public void disableAccelerationSensors() throws IOException { this.accelerationenabled=false; } + + public void loadGesture(String filename) { + this.processingunit.loadGesture(filename); + } + + public void saveGesture(int id, String filename) { + this.processingunit.saveGesture(id, filename); + } // ###### Event-Methoden diff --git a/src/logic/Classifier.java b/src/logic/Classifier.java index c3c015f..9b32558 100644 --- a/src/logic/Classifier.java +++ b/src/logic/Classifier.java @@ -96,6 +96,10 @@ public class Classifier { public Vector getGestureModels() { return this.gesturemodel; } + + public int getCountOfGestures() { + return this.gesturemodel.size(); + } public void clear() { this.gesturemodel = new Vector(); diff --git a/src/logic/GestureModel.java b/src/logic/GestureModel.java index 7b57b41..5150886 100755 --- a/src/logic/GestureModel.java +++ b/src/logic/GestureModel.java @@ -42,9 +42,6 @@ public class GestureModel { /** The number of observations for the hmm and k-mean */ private int numObservations; - /** The id representation of this model */ - private int id; - /** The quantization component */ private Quantizer quantizer; @@ -61,8 +58,7 @@ public class GestureModel { * @param id * int representation of a gesture "name"/class. */ - public GestureModel(int id) { - this.id=id; + public GestureModel() { this.numStates=8; // n=8 states empirical value this.numObservations=14; // k=14 observations empirical value this.markovmodell = new HMM(numStates, numObservations); // init model @@ -133,7 +129,7 @@ public class GestureModel { * For debug purposes or very technical interested people. :) */ public void printMap() { - System.out.println("Gesture "+this.id+" Quantizer-Map:"); + System.out.println("Gesture Quantizer-Map:"); this.quantizer.printMap(); } @@ -142,20 +138,11 @@ public class GestureModel { * @return */ public void print() { - System.out.println("Debug Output for Gesture "+this.id); System.out.println("HMM-Print:"); this.markovmodell.print(); System.out.println("Quanzizer-Print:"); this.quantizer.printMap(); } - - public int getId() { - return this.id; - } - - public void setId(int id) { - this.id=id; - } public int getNumStates() { return this.numStates; diff --git a/src/logic/ProcessingUnit.java b/src/logic/ProcessingUnit.java index 5b666e1..210c3b0 100644 --- a/src/logic/ProcessingUnit.java +++ b/src/logic/ProcessingUnit.java @@ -21,11 +21,9 @@ public abstract class ProcessingUnit implements DeviceListener { // Listener private Vector listen = new Vector(); - protected int gesturecount; public ProcessingUnit() { this.classifier = new Classifier(); - this.gesturecount=0; } /** @@ -69,7 +67,7 @@ public abstract class ProcessingUnit implements DeviceListener { * to the system. */ public void reset() { - if(this.gesturecount>0) { + if(this.classifier.getCountOfGestures()>0) { this.classifier.clear(); System.out.println("### Model reset ###"); } else { @@ -78,8 +76,8 @@ public abstract class ProcessingUnit implements DeviceListener { } // File IO - public abstract void loadGesture(String name); + public abstract void loadGesture(String filename); - public abstract void saveGesture(int id, String name); + public abstract void saveGesture(int id, String filename); } diff --git a/src/logic/TriggeredProcessingUnit.java b/src/logic/TriggeredProcessingUnit.java index 950cb09..89c53bf 100644 --- a/src/logic/TriggeredProcessingUnit.java +++ b/src/logic/TriggeredProcessingUnit.java @@ -122,7 +122,7 @@ public class TriggeredProcessingUnit extends ProcessingUnit { this.fireStateEvent(1); this.learning=true; - GestureModel m = new GestureModel(this.gesturecount++); + GestureModel m = new GestureModel(); m.train(this.trainsequence); m.print(); this.classifier.addGestureModel(m); @@ -154,7 +154,7 @@ public class TriggeredProcessingUnit extends ProcessingUnit { else if(this.analyzing) { // button release and state=analyzing, stops analyzing if(this.current.getCountOfData()>0) { System.out.println("Finished recording (recognition)..."); - System.out.println("Compare gesture with "+this.gesturecount+" other gestures."); + System.out.println("Compare gesture with "+this.classifier.getCountOfGestures()+" other gestures."); Gesture gesture = new Gesture(this.current); int recognized = this.classifier.classifyGesture(gesture); @@ -182,15 +182,14 @@ public class TriggeredProcessingUnit extends ProcessingUnit { } @Override - public void loadGesture(String name) { - this.gesturecount++; - GestureModel g = util.FileIO.readFromFile(name); + public void loadGesture(String filename) { + GestureModel g = util.FileIO.readFromFile(filename); this.classifier.addGestureModel(g); } @Override - public void saveGesture(int id, String name) { - util.FileIO.writeToFile(this.classifier.getGestureModel(id), name); + public void saveGesture(int id, String filename) { + util.FileIO.writeToFile(this.classifier.getGestureModel(id), filename); } } diff --git a/src/util/FileIO.java b/src/util/FileIO.java index 815a5ce..56619b5 100644 --- a/src/util/FileIO.java +++ b/src/util/FileIO.java @@ -48,19 +48,12 @@ public class FileIO { try { // initialize file and get values BufferedWriter out = new BufferedWriter(new FileWriter(name+".txt")); - int id = m.getId(); int numStates = m.getNumStates(); int numObservations = m.getNumObservations(); double defaultProbability = m.getDefaultProbability(); Quantizer quantizer = m.getQuantizer(); HMM hmm = m.getHMM(); - // write to file - out.write("# ID:"); - out.newLine(); - out.write(Integer.toString(id)); - out.newLine(); - out.write("# numStates:"); out.newLine(); out.write(Integer.toString(numStates)); @@ -161,21 +154,18 @@ public class FileIO { if(!line.startsWith("#")) { // isn't a comment switch (position++) { case 0: - id = Integer.parseInt(line); - break; - case 1: numStates = Integer.parseInt(line); break; - case 2: + case 1: numObservations = Integer.parseInt(line); break; - case 3: + case 2: defaultprobability = Double.parseDouble(line); break; - case 4: + case 3: radius = Double.parseDouble(line); break; - case 5: + case 4: map = new double[numObservations][3]; for(int i=0; i