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 }