package com.maciekjanusz.compassproject.sensor;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import static java.lang.Math.*;
public class Compass implements SensorEventListener {
private static final float FILTER_ALPHA = 0.97f;
private final CompassListener listener;
private final SensorManager sensorManager;
private final Sensor accelerometer;
private final Sensor magnetometer;
private final float[] accelerometerValues = new float[3];
private final float[] magnetometerValues = new float[3];
private final float[] orientation = new float[3];
private final float[] rotMatR = new float[9];
private final float[] rotMatI = new float[9];
public Compass(Context context, CompassListener listener) {
sensorManager = (SensorManager) context
.getSystemService(Context.SENSOR_SERVICE);
accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
magnetometer = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
this.listener = listener;
}
public void start() {
sensorManager.registerListener(this, accelerometer,
SensorManager.SENSOR_DELAY_FASTEST);
sensorManager.registerListener(this, magnetometer,
SensorManager.SENSOR_DELAY_FASTEST);
}
public void stop() {
sensorManager.unregisterListener(this);
}
@Override
public void onSensorChanged(SensorEvent event) {
synchronized (this) {
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
// magnetometer low-pass filtering
magnetometerValues[0] = FILTER_ALPHA * magnetometerValues[0]
+ (1 - FILTER_ALPHA) * event.values[0];
magnetometerValues[1] = FILTER_ALPHA * magnetometerValues[1]
+ (1 - FILTER_ALPHA) * event.values[1];
magnetometerValues[2] = FILTER_ALPHA * magnetometerValues[2]
+ (1 - FILTER_ALPHA) * event.values[2];
}
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
// accelerometer low-pass filtering
accelerometerValues[0] = FILTER_ALPHA * accelerometerValues[0]
+ (1 - FILTER_ALPHA) * event.values[0];
accelerometerValues[1] = FILTER_ALPHA * accelerometerValues[1]
+ (1 - FILTER_ALPHA) * event.values[1];
accelerometerValues[2] = FILTER_ALPHA * accelerometerValues[2]
+ (1 - FILTER_ALPHA) * event.values[2];
}
boolean success = SensorManager
.getRotationMatrix(rotMatR, rotMatI, accelerometerValues, magnetometerValues);
if (success) {
SensorManager.getOrientation(rotMatR, orientation);
float bearing = (float) toDegrees(orientation[0]);
float pitch = (float) toDegrees(orientation[1]);
float roll = (float) toDegrees(orientation[2]);
bearing = (bearing + 360f) % 360f;
listener.onCompassStateChanged(bearing, pitch, roll);
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
public interface CompassListener {
/**
* Called when obtained rotation values
* @param bearing bearing in 0:360 format
* @param pitch pitch in -90:90 format
* @param roll roll in -180:180 format
*/
void onCompassStateChanged(float bearing, float pitch, float roll);
}
}