/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package madsdf.shimmer.glview;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
import madsdf.shimmer.gui.AccelGyro;
import madsdf.shimmer.filter.ComplementaryFilter;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Observable;
import java.util.Observer;
import javax.swing.JTextArea;
import madsdf.shimmer.event.Globals;
/**
* Class that receive Shimmer samples, filter them to extract angle and dispatch
* angles to various components for display
* @author julien
*/
public class ShimmerAngleConverter {
public static class AngleEvent {
// Angles in degrees
public final float roll, pitch, yaw;
public AngleEvent(float roll, float pitch, float yaw) {
this.roll = roll;
this.pitch = pitch;
this.yaw = yaw;
}
}
private ComplementaryFilter cf = new ComplementaryFilter();
private JTextArea logArea;
private DecimalFormat fmt = new DecimalFormat("#.##");
private EventBus ebus;
public ShimmerAngleConverter(EventBus ebus, JTextArea logArea) {
this.logArea = logArea;
this.ebus = ebus;
}
@Subscribe
public void onSample(AccelGyro.CalibratedSample sample) {
cf.update(sample);
float roll = (float) Math.toDegrees(cf.angles[0]);
float pitch = (float) Math.toDegrees(cf.angles[1]);
float yaw = (float) Math.toDegrees(cf.angles[2]);
// When pitch becomes too big, roll estimation becomes wrong. So
// simply force the angles
// TODO: Not sure this is the best way to do it... the filter might
// be a bit too steep
if (pitch < -70 || pitch > 70) {
roll = 0;
pitch = pitch < -70 ? -70 : 70;
}
String txt = "roll :" + fmt.format(roll) + "\n"
+ "pitch :" + fmt.format(pitch) + "\n"
+ "yaw :" + fmt.format(yaw) + "\n";
//txt = detectMovements(txt, roll, pitch, yaw);
ebus.post(new AngleEvent(roll, pitch, yaw));
logArea.setText(txt);
}
// Detect movementif v is inside [sign*lower, sign*upper]
// Divide the detection interval in three to get three movements level
private String detectIf(String movementName, float v, int sign, float lower, float upper) {
// Define 3 thresholds
final float interval = Math.abs((upper - lower) / 2.0f);
final float thresh = interval / 3.0f;
String log = "";
if (sign > 0) { // positive case
if (v > lower && v < upper) {
log += movementName + " ";
if (v > upper - thresh) { log += " 3 "; }
else if (v > upper - 2*thresh) { log += " 2 "; }
else { log += " 1 "; }
}
} else { // negative case
if (v < lower && v > upper) {
log += movementName + " ";
if (v < upper + thresh) { log += " 3 "; }
else if (v < upper + 2*thresh) { log += " 2 "; }
else { log += " 1 "; }
}
}
return log;
}
// Quick hack to detect movements and print them in log
private String detectMovements(String log, float roll, float pitch, float yaw) {
/*if (pitch > -60 && pitch < -20) {
log += "LEFT";
}
if (pitch < 60 && pitch > 20) {
log += "RIGHT\n";
}
if (roll > -60 && roll < -20) {
log += "FORWARD\n";
}
if (roll < 60 && roll > 20) {
log += "BACKWARD\n";
}*/
log += detectIf("LEFT", pitch, -1, -20, -60);
log += detectIf("RIGHT", pitch, 1, 20, 60);
log += detectIf("FORWARD", roll, -1, -20, -60);
log += detectIf("BACKWARD", roll, 1, 20, 60);
return log;
}
}