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
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -39,42 +41,46 @@ import filter.Filter;
|
||||
// Singleton
|
||||
public class WiimoteWiigee {
|
||||
|
||||
protected static String version = "1.3.1 alpha";
|
||||
protected static String releasedate = "20081215";
|
||||
|
||||
protected static String version = "1.5 alpha";
|
||||
protected static String releasedate = "20090524";
|
||||
protected static WiimoteWiigee instance;
|
||||
private static Object lock = new Object();
|
||||
private Vector<Wiimote> devices;
|
||||
|
||||
private WiimoteWiigee() throws IOException {
|
||||
Log.write("This is wiigee version "+version+" ("+releasedate+")");
|
||||
this.devices=this.discoverWiimotes();
|
||||
for(int i=0; i<this.devices.size(); i++) {
|
||||
this.devices.elementAt(i).setLED(i+1);
|
||||
}
|
||||
}
|
||||
private WiimoteWiigee() {
|
||||
String stack;
|
||||
String stackVersion;
|
||||
String l2capFeature;
|
||||
String bluecoveVersion;
|
||||
|
||||
private WiimoteWiigee(String btaddr) throws IOException {
|
||||
Log.write("This is wiigee version "+version+" ("+releasedate+")");
|
||||
this.devices = new Vector<Wiimote>();
|
||||
this.devices.add(new Wiimote(btaddr));
|
||||
for(int i=0; i<this.devices.size(); i++) {
|
||||
this.devices.elementAt(i).setLED(i+1);
|
||||
}
|
||||
}
|
||||
Log.write("This is wiigee version " + version + " (" + releasedate + ")");
|
||||
|
||||
public static WiimoteWiigee getInstance() throws IOException {
|
||||
if(instance==null) {
|
||||
instance=new WiimoteWiigee();
|
||||
return instance;
|
||||
// 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 {
|
||||
return instance;
|
||||
Log.write("No Bluecove Library detected - trying anyway...");
|
||||
}
|
||||
}
|
||||
|
||||
public static WiimoteWiigee getInstance(String btaddr) throws IOException {
|
||||
if(instance==null) {
|
||||
instance=new WiimoteWiigee(btaddr);
|
||||
public static WiimoteWiigee getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new WiimoteWiigee();
|
||||
return instance;
|
||||
} else {
|
||||
return instance;
|
||||
@@ -87,9 +93,13 @@ public class WiimoteWiigee {
|
||||
* @return Array of discovered wiimotes or null if
|
||||
* none discoverd.
|
||||
*/
|
||||
public Wiimote[] getDevices() {
|
||||
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++) {
|
||||
for (int i = 0; i < this.devices.size(); i++) {
|
||||
out[i] = this.devices.elementAt(i);
|
||||
}
|
||||
return out;
|
||||
@@ -104,16 +114,15 @@ public class WiimoteWiigee {
|
||||
private Vector<Wiimote> 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("Your Computers Bluetooth MAC: " + localDevice.getBluetoothAddress());
|
||||
|
||||
Log.write("Starting device inquiry...");
|
||||
DiscoveryAgent discoveryAgent = localDevice.getDiscoveryAgent();
|
||||
discoveryAgent.startInquiry(DiscoveryAgent.GIAC, deviceDiscovery);
|
||||
|
||||
|
||||
try {
|
||||
synchronized(lock){
|
||||
synchronized (lock) {
|
||||
lock.wait();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
@@ -140,7 +149,7 @@ public class WiimoteWiigee {
|
||||
* @param b Button encoding, see static Wiimote values
|
||||
*/
|
||||
public void setTrainButton(int b) {
|
||||
for(int i=0; i<this.devices.size(); i++) {
|
||||
for (int i = 0; i < this.devices.size(); i++) {
|
||||
this.devices.elementAt(i).setTrainButton(b);
|
||||
}
|
||||
}
|
||||
@@ -151,7 +160,7 @@ public class WiimoteWiigee {
|
||||
* @param b Button encoding, see static Wiimote values
|
||||
*/
|
||||
public void setRecognitionButton(int b) {
|
||||
for(int i=0; i<this.devices.size(); i++) {
|
||||
for (int i = 0; i < this.devices.size(); i++) {
|
||||
this.devices.elementAt(i).setRecognitionButton(b);
|
||||
}
|
||||
}
|
||||
@@ -162,27 +171,26 @@ public class WiimoteWiigee {
|
||||
* @param b Button encoding, see static Wiimote values
|
||||
*/
|
||||
public void setCloseGestureButton(int b) {
|
||||
for(int i=0; i<this.devices.size(); i++) {
|
||||
for (int i = 0; i < this.devices.size(); i++) {
|
||||
this.devices.elementAt(i).setCloseGestureButton(b);
|
||||
}
|
||||
}
|
||||
|
||||
public void addDeviceListener(DeviceListener listener) {
|
||||
if(this.devices.size()>0) {
|
||||
this.devices.elementAt(0).addDeviceListener(listener);
|
||||
for (int i = 0; i < this.devices.size(); i++) {
|
||||
this.devices.elementAt(i).addDeviceListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
public void addGestureListener(GestureListener listener) {
|
||||
if(this.devices.size()>0) {
|
||||
this.devices.elementAt(0).addGestureListener(listener);
|
||||
for (int i = 0; i < this.devices.size(); i++) {
|
||||
this.devices.elementAt(i).addGestureListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
public void addFilter(Filter filter) {
|
||||
if(this.devices.size()>0) {
|
||||
this.devices.elementAt(0).addFilter(filter);
|
||||
for (int i = 0; i < this.devices.size(); i++) {
|
||||
this.devices.elementAt(i).addFilter(filter);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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> devicelistener = new Vector<DeviceListener>();
|
||||
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() {
|
||||
@@ -142,6 +141,14 @@ public class Device {
|
||||
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
|
||||
|
||||
/** Fires an acceleration event.
|
||||
|
||||
@@ -97,6 +97,10 @@ public class Classifier {
|
||||
return this.gesturemodel;
|
||||
}
|
||||
|
||||
public int getCountOfGestures() {
|
||||
return this.gesturemodel.size();
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.gesturemodel = new Vector<GestureModel>();
|
||||
}
|
||||
|
||||
@@ -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,21 +138,12 @@ 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;
|
||||
}
|
||||
|
||||
@@ -21,11 +21,9 @@ public abstract class ProcessingUnit implements DeviceListener {
|
||||
// Listener
|
||||
private Vector<GestureListener> listen = new Vector<GestureListener>();
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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<numObservations; i++) {
|
||||
String s[] = line.split(", ");
|
||||
@@ -186,14 +176,14 @@ public class FileIO {
|
||||
line = in.ready() ? in.readLine() : "";
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
case 5:
|
||||
pi = new double[numStates];
|
||||
String pi_row[] = line.split(", ");
|
||||
for(int i=0; i<numStates; i++) {
|
||||
pi[i] = Double.parseDouble(pi_row[i]);
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
case 6:
|
||||
a = new double[numStates][numStates];
|
||||
for(int i=0; i<numStates; i++) {
|
||||
String a_row[] = line.split(", ");
|
||||
@@ -203,7 +193,7 @@ public class FileIO {
|
||||
line = in.ready() ? in.readLine() : "";
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
case 7:
|
||||
b = new double[numStates][numObservations];
|
||||
for(int i=0; i<numStates; i++) {
|
||||
String b_row[] = line.split(", ");
|
||||
@@ -220,7 +210,7 @@ public class FileIO {
|
||||
}
|
||||
}
|
||||
|
||||
GestureModel ret = new GestureModel(id);
|
||||
GestureModel ret = new GestureModel();
|
||||
ret.setDefaultProbability(defaultprobability);
|
||||
|
||||
Quantizer quantizer = new Quantizer(numStates);
|
||||
|
||||
Reference in New Issue
Block a user