Skip to content

Commit

Permalink
SensorHandler updated to develop
Browse files Browse the repository at this point in the history
  • Loading branch information
avihric committed Aug 8, 2015
1 parent ac2ec48 commit 05662dd
Showing 1 changed file with 164 additions and 57 deletions.
221 changes: 164 additions & 57 deletions catroid/src/org/catrobat/catroid/formulaeditor/SensorHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,32 +37,55 @@
import org.catrobat.catroid.facedetection.FaceDetectionHandler;

public final class SensorHandler implements SensorEventListener, SensorCustomEventListener {
public static final float RADIAN_TO_DEGREE_CONST = 180f / (float) Math.PI;
private static final String TAG = SensorHandler.class.getSimpleName();
private static SensorHandler instance = null;
private static BluetoothDeviceService btService = ServiceProvider.getService(CatroidService.BLUETOOTH_DEVICE_SERVICE);
private SensorManagerInterface sensorManager = null;
private Sensor linearAccelerationSensor = null;
private Sensor accelerometerSensor = null;
private Sensor magneticFieldSensor = null;
private Sensor rotationVectorSensor = null;
private float[] rotationMatrix = new float[16];
private float[] rotationVector = new float[3];
public static final float RADIAN_TO_DEGREE_CONST = 180f / (float) Math.PI;

private float linearAcceleartionX = 0f;
private float linearAcceleartionY = 0f;
private float linearAcceleartionZ = 0f;

private float[] accelerationXYZ = new float[3];
private float signAccelerationZ = 0f;
private float[] gravity = new float[] { 0f, 0f, 0f };
private boolean useLinearAccelerationFallback = false;
private boolean useRotationVectorFallback = false;
private float linearAccelerationX = 0f;
private float linearAccelerationY = 0f;
private float linearAccelerationZ = 0f;
private float loudness = 0f;
private float faceDetected = 0f;
private float faceSize = 0f;
private float facePositionX = 0f;
private float facePositionY = 0f;

private static BluetoothDeviceService btService = ServiceProvider.getService(CatroidService.BLUETOOTH_DEVICE_SERVICE);

private SensorHandler(Context context) {
sensorManager = new SensorManager(
(android.hardware.SensorManager) context.getSystemService(Context.SENSOR_SERVICE));
accelerometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION);
linearAccelerationSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION);
if (linearAccelerationSensor == null) {
useLinearAccelerationFallback = true;
}

rotationVectorSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
if (rotationVectorSensor == null) {
useRotationVectorFallback = true;
}

if (useRotationVectorFallback) {
accelerometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
magneticFieldSensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
} else if (useLinearAccelerationFallback) {
accelerometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
}

Log.d(TAG, "*** LINEAR_ACCELERATION SENSOR: " + linearAccelerationSensor);
Log.d(TAG, "*** ACCELEROMETER SENSOR: " + accelerometerSensor);
Log.d(TAG, "*** ROTATION_VECTOR SENSOR: " + rotationVectorSensor);
Log.d(TAG, "*** MAGNETIC_FIELD SENSOR: " + magneticFieldSensor);
}

public static void startSensorListener(Context context) {
Expand All @@ -72,10 +95,9 @@ public static void startSensorListener(Context context) {
}
instance.sensorManager.unregisterListener((SensorEventListener) instance);
instance.sensorManager.unregisterListener((SensorCustomEventListener) instance);
instance.sensorManager.registerListener(instance, instance.accelerometerSensor,
android.hardware.SensorManager.SENSOR_DELAY_NORMAL);
instance.sensorManager.registerListener(instance, instance.rotationVectorSensor,
android.hardware.SensorManager.SENSOR_DELAY_NORMAL);

instance.registerListener(instance);

instance.sensorManager.registerListener(instance, Sensors.LOUDNESS);
FaceDetectionHandler.registerOnFaceDetectedListener(instance);
FaceDetectionHandler.registerOnFaceDetectionStatusListener(instance);
Expand All @@ -85,10 +107,26 @@ public static void registerListener(SensorEventListener listener) {
if (instance == null) {
return;
}
instance.sensorManager.registerListener(listener, instance.accelerometerSensor,
android.hardware.SensorManager.SENSOR_DELAY_NORMAL);
instance.sensorManager.registerListener(listener, instance.rotationVectorSensor,
android.hardware.SensorManager.SENSOR_DELAY_NORMAL);

if (!instance.useLinearAccelerationFallback) {
instance.sensorManager.registerListener(listener, instance.linearAccelerationSensor,
android.hardware.SensorManager.SENSOR_DELAY_GAME);
}

if (!instance.useRotationVectorFallback) {
instance.sensorManager.registerListener(listener, instance.rotationVectorSensor,
android.hardware.SensorManager.SENSOR_DELAY_GAME);
}

if (instance.useLinearAccelerationFallback || instance.useRotationVectorFallback) {
instance.sensorManager.registerListener(listener, instance.accelerometerSensor,
android.hardware.SensorManager.SENSOR_DELAY_GAME);
}

if (instance.useRotationVectorFallback && instance.magneticFieldSensor != null) {
instance.sensorManager.registerListener(listener, instance.magneticFieldSensor,
android.hardware.SensorManager.SENSOR_DELAY_GAME);
}
}

public static void unregisterListener(SensorEventListener listener) {
Expand Down Expand Up @@ -117,50 +155,89 @@ public static Double getSensorValue(Sensors sensor) {
switch (sensor) {

case X_ACCELERATION:
return (double) instance.linearAcceleartionX;
return (double) instance.linearAccelerationX;

case Y_ACCELERATION:
return (double) instance.linearAcceleartionY;
return (double) instance.linearAccelerationY;

case Z_ACCELERATION:
return (double) instance.linearAcceleartionZ;
return (double) instance.linearAccelerationZ;

case COMPASS_DIRECTION:
float[] orientations = new float[3];
android.hardware.SensorManager.getRotationMatrixFromVector(instance.rotationMatrix,
instance.rotationVector);
if (!instance.useRotationVectorFallback) {
android.hardware.SensorManager.getRotationMatrixFromVector(instance.rotationMatrix,
instance.rotationVector);
}
android.hardware.SensorManager.getOrientation(instance.rotationMatrix, orientations);
sensorValue = (double) orientations[0];
return sensorValue * RADIAN_TO_DEGREE_CONST * -1f;

case X_INCLINATION:

orientations = new float[3];
android.hardware.SensorManager.getRotationMatrixFromVector(instance.rotationMatrix,
instance.rotationVector);
android.hardware.SensorManager.getOrientation(instance.rotationMatrix, orientations);
sensorValue = (double) orientations[2];
return sensorValue * RADIAN_TO_DEGREE_CONST * -1f;

if (instance.useRotationVectorFallback) {
float rawInclinationX = RADIAN_TO_DEGREE_CONST * (float) (Math.acos(instance.accelerationXYZ[0]));
float correctedInclinationX = 0;

if (rawInclinationX >= 90 && rawInclinationX <= 180) {
if (instance.signAccelerationZ > 0) {
correctedInclinationX = -(rawInclinationX - 90);
} else {
correctedInclinationX = -(180 + (90 - rawInclinationX));
}
} else if (rawInclinationX >= 0 && rawInclinationX < 90) {
if (instance.signAccelerationZ > 0) {
correctedInclinationX = (90 - rawInclinationX);
} else {
correctedInclinationX = (90 + rawInclinationX);
}
}
return (double) correctedInclinationX;
} else {
orientations = new float[3];
android.hardware.SensorManager.getRotationMatrixFromVector(instance.rotationMatrix,
instance.rotationVector);
android.hardware.SensorManager.getOrientation(instance.rotationMatrix, orientations);
sensorValue = (double) orientations[2];
return sensorValue * RADIAN_TO_DEGREE_CONST * -1f;
}
case Y_INCLINATION:
orientations = new float[3];
android.hardware.SensorManager.getRotationMatrixFromVector(instance.rotationMatrix,
instance.rotationVector);
android.hardware.SensorManager.getOrientation(instance.rotationMatrix, orientations);

float xInclinationUsedToExtendRangeOfRoll = orientations[2] * RADIAN_TO_DEGREE_CONST * -1f;
if (instance.useRotationVectorFallback) {
float rawInclinationY = RADIAN_TO_DEGREE_CONST * (float) (Math.acos(instance.accelerationXYZ[1]));
float correctedInclinationY = 0;
if (rawInclinationY >= 90 && rawInclinationY <= 180) {
if (instance.signAccelerationZ > 0) {
correctedInclinationY = -(rawInclinationY - 90);
} else {
correctedInclinationY = -(180 + (90 - rawInclinationY));
}
} else if (rawInclinationY >= 0 && rawInclinationY < 90) {
if (instance.signAccelerationZ > 0) {
correctedInclinationY = (90 - rawInclinationY);
} else {
correctedInclinationY = (90 + rawInclinationY);
}
}
return (double) correctedInclinationY;
} else {
orientations = new float[3];
android.hardware.SensorManager.getRotationMatrixFromVector(instance.rotationMatrix,
instance.rotationVector);
android.hardware.SensorManager.getOrientation(instance.rotationMatrix, orientations);

sensorValue = (double) orientations[1];
float xInclinationUsedToExtendRangeOfRoll = orientations[2] * RADIAN_TO_DEGREE_CONST * -1f;

if (Math.abs(xInclinationUsedToExtendRangeOfRoll) <= 90f) {
return sensorValue * RADIAN_TO_DEGREE_CONST * -1f;
} else {
float uncorrectedYInclination = sensorValue.floatValue() * RADIAN_TO_DEGREE_CONST * -1f;
sensorValue = (double) orientations[1];

if (uncorrectedYInclination > 0f) {
return (double) 180f - uncorrectedYInclination;
if (Math.abs(xInclinationUsedToExtendRangeOfRoll) <= 90f) {
return sensorValue * RADIAN_TO_DEGREE_CONST * -1f;
} else {
return (double) -180f - uncorrectedYInclination;
float uncorrectedYInclination = sensorValue.floatValue() * RADIAN_TO_DEGREE_CONST * -1f;

if (uncorrectedYInclination > 0f) {
return (double) 180f - uncorrectedYInclination;
} else {
return (double) -180f - uncorrectedYInclination;
}
}
}
case FACE_DETECTED:
Expand Down Expand Up @@ -201,17 +278,45 @@ public static Double getSensorValue(Sensors sensor) {
return 0d;
}

public static void clearFaceDetectionValues() {
if (instance != null) {
instance.faceDetected = 0f;
instance.faceSize = 0f;
instance.facePositionX = 0f;
instance.facePositionY = 0f;
}
}

@Override
public void onAccuracyChanged(Sensor arg0, int arg1) {
}

@Override
public void onSensorChanged(SensorEvent event) {
switch (event.sensor.getType()) {
case Sensor.TYPE_MAGNETIC_FIELD:
float[] tempMagneticFieldXYZ = event.values.clone();
float[] tempInclinationMatrix = new float[9];
android.hardware.SensorManager.getRotationMatrix(rotationMatrix, tempInclinationMatrix, accelerationXYZ,
tempMagneticFieldXYZ); //http://goo.gl/wo6QK5
break;
case Sensor.TYPE_ACCELEROMETER:
accelerationXYZ = event.values.clone();
if (useLinearAccelerationFallback) {
determinePseudoLinearAcceleration(accelerationXYZ.clone());
}
double normOfG = Math.sqrt(accelerationXYZ[0] * accelerationXYZ[0]
+ accelerationXYZ[1] * accelerationXYZ[1]
+ accelerationXYZ[2] * accelerationXYZ[2]);
accelerationXYZ[0] = (float) (accelerationXYZ[0] / normOfG);
accelerationXYZ[1] = (float) (accelerationXYZ[1] / normOfG);
accelerationXYZ[2] = (float) (accelerationXYZ[2] / normOfG);
signAccelerationZ = Math.signum(event.values[2]);
break;
case Sensor.TYPE_LINEAR_ACCELERATION:
linearAcceleartionX = event.values[0];
linearAcceleartionY = event.values[1];
linearAcceleartionZ = event.values[2];
linearAccelerationX = event.values[0];
linearAccelerationY = event.values[1];
linearAccelerationZ = event.values[2];
break;
case Sensor.TYPE_ROTATION_VECTOR:
rotationVector[0] = event.values[0];
Expand All @@ -223,6 +328,18 @@ public void onSensorChanged(SensorEvent event) {
}
}

private void determinePseudoLinearAcceleration(float[] input) {
float alpha = 0.8f;

gravity[0] = alpha * gravity[0] + ((1 - alpha) * input[0]);
gravity[1] = alpha * gravity[1] + ((1 - alpha) * input[1]);
gravity[2] = alpha * gravity[2] + ((1 - alpha) * input[2]);

linearAccelerationX = -1f * (input[0] - gravity[0]);
linearAccelerationY = -1f * (input[1] - gravity[1]);
linearAccelerationZ = -1f * (input[2] - gravity[2]);
}

@Override
public void onCustomSensorChanged(SensorCustomEvent event) {
switch (event.sensor) {
Expand All @@ -245,14 +362,4 @@ public void onCustomSensorChanged(SensorCustomEvent event) {
Log.v(TAG, "Unhandled sensor: " + event.sensor);
}
}

public static void clearFaceDetectionValues() {
if (instance != null) {
instance.faceDetected = 0f;
instance.faceSize = 0f;
instance.facePositionX = 0f;
instance.facePositionY = 0f;
}
}

}

0 comments on commit 05662dd

Please sign in to comment.