1 package org.kde.kstars.rotation; 2 3 import android.hardware.Sensor; 4 import android.hardware.SensorEvent; 5 import android.hardware.SensorEventListener; 6 import android.hardware.SensorManager; 7 8 /** 9 * Magnetometer / Accelerometer sensor fusion Smoothed by means of simple high 10 * pass filter 11 * 12 * When it receives an event it will notify the constructor-specified delegate. 13 * 14 * @author Adam 15 * 16 */ 17 public class MagAccelListener implements SensorEventListener { 18 private float[] mRotationM = new float[16]; 19 // smoothing factor - tune to taste 20 private final float mFilterFactor = 0.1f; 21 private final float mFilterFactorInv = 1.0f - mFilterFactor; 22 private boolean mIsReady = false; 23 // smoothed accelerometer values 24 private float[] mAccelVals = new float[] { 0f, 0f, 9.8f }; 25 // smoothed magnetometer values 26 private float[] mMagVals = new float[] { 0.5f, 0f, 0f }; 27 private RotationUpdateDelegate mRotationUpdateDelegate; 28 MagAccelListener(RotationUpdateDelegate rotationUpdateDelegate)29 public MagAccelListener(RotationUpdateDelegate rotationUpdateDelegate) { 30 mRotationUpdateDelegate = rotationUpdateDelegate; 31 } 32 33 @Override onSensorChanged(SensorEvent event)34 public void onSensorChanged(SensorEvent event) { 35 switch (event.sensor.getType()) { 36 case Sensor.TYPE_ACCELEROMETER: 37 smooth(event.values, mAccelVals, mAccelVals); 38 break; 39 case Sensor.TYPE_MAGNETIC_FIELD: 40 smooth(event.values, mMagVals, mMagVals); 41 mIsReady = true; 42 break; 43 default: 44 break; 45 } 46 // wait until we have both a new accelerometer and magnetometer sample 47 if (mIsReady) { 48 mIsReady = false; 49 fuseValues(); 50 } 51 } 52 fuseValues()53 private void fuseValues() { 54 SensorManager.getRotationMatrix(mRotationM, null, mAccelVals, mMagVals); 55 mRotationUpdateDelegate.onRotationUpdate(mRotationM); 56 } 57 smooth(float[] inv, float prevv[], float outv[])58 private void smooth(float[] inv, float prevv[], float outv[]) { 59 outv[0] = inv[0] * mFilterFactor + prevv[0] * (mFilterFactorInv); 60 outv[1] = inv[1] * mFilterFactor + prevv[1] * (mFilterFactorInv); 61 outv[2] = inv[2] * mFilterFactor + prevv[2] * (mFilterFactorInv); 62 } 63 64 @Override onAccuracyChanged(Sensor sensor, int accuracy)65 public void onAccuracyChanged(Sensor sensor, int accuracy) { 66 } 67 }