Updated CompassSensor to compensate for geomag declination

Change-Id: I82b421fc5d62fafa1bf6634430f76966025d6b46
Signed-off-by: Ricky Barrette <rickbarrette@gmail.com>
This commit is contained in:
2012-03-11 23:45:55 -04:00
parent 86d34b501f
commit 24d820cada

View File

@@ -6,17 +6,19 @@
*/ */
package com.TwentyCodes.android.location; package com.TwentyCodes.android.location;
import com.TwentyCodes.android.debug.Debug;
import android.content.Context; import android.content.Context;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.hardware.GeomagneticField;
import android.hardware.Sensor; import android.hardware.Sensor;
import android.hardware.SensorEvent; import android.hardware.SensorEvent;
import android.hardware.SensorEventListener; import android.hardware.SensorEventListener;
import android.hardware.SensorManager; import android.hardware.SensorManager;
import android.location.Location;
import android.os.Handler; import android.os.Handler;
import android.os.Message; import android.os.Message;
import com.TwentyCodes.android.debug.Debug;
/** /**
* A simple convince class that accesses the compass sensor on another thread * A simple convince class that accesses the compass sensor on another thread
* @author ricky barrette * @author ricky barrette
@@ -28,18 +30,20 @@ public class CompassSensor{
private CompassListener mListener; private CompassListener mListener;
private final Handler mHandler; private final Handler mHandler;
private Context mContext; private Context mContext;
private float mDelination = 0;
private final SensorEventListener mCallBack = new SensorEventListener() { private final SensorEventListener mCallBack = new SensorEventListener() {
private float[] inR = new float[16]; private float[] mR = new float[16];
private float[] I = new float[16]; private float[] mI = new float[16];
private float[] gravity = new float[3]; private float[] mGravity = new float[3];
private float[] geomag = new float[3]; private float[] mGeomag = new float[3];
private float[] orientVals = new float[3]; private float[] mOrientVals = new float[3];
private double azimuth = 0; private double mAzimuth = 0;
double pitch = 0; double mPitch = 0;
double roll = 0; double mRoll = 0;
private float mInclination;
public void onSensorChanged(SensorEvent sensorEvent) { public void onSensorChanged(SensorEvent sensorEvent) {
// If the sensor data is unreliable return // If the sensor data is unreliable return
@@ -49,44 +53,56 @@ public class CompassSensor{
// Gets the value of the sensor that has been changed // Gets the value of the sensor that has been changed
switch (sensorEvent.sensor.getType()) { switch (sensorEvent.sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER: case Sensor.TYPE_ACCELEROMETER:
gravity = sensorEvent.values.clone(); mGravity = sensorEvent.values.clone();
break; break;
case Sensor.TYPE_MAGNETIC_FIELD: case Sensor.TYPE_MAGNETIC_FIELD:
geomag = sensorEvent.values.clone(); mGeomag = sensorEvent.values.clone();
break; break;
} }
// If gravity and geomag have values then find rotation matrix // If gravity and geomag have values then find rotation matrix
if (gravity != null && geomag != null) { if (mGravity != null && mGeomag != null) {
// checks that the rotation matrix is found // checks that the rotation matrix is found
boolean success = SensorManager.getRotationMatrix(inR, I, gravity, geomag); boolean success = SensorManager.getRotationMatrix(mR, mI, mGravity, mGeomag);
if (success) { if (success) {
SensorManager.getOrientation(inR, orientVals);
azimuth = Math.toDegrees(orientVals[0]);
pitch = Math.toDegrees(orientVals[1]);
roll = Math.toDegrees(orientVals[2]);
/** /*
* TODO remap cords due to Display.getRotation()
*/
// SensorManager.remapCoordinateSystem(mR, SensorManager.AXIS_MINUS_Y, SensorManager.AXIS_X, mR);
SensorManager.getOrientation(mR, mOrientVals);
mInclination = SensorManager.getInclination(mI);
mAzimuth = Math.toDegrees(mOrientVals[0]);
mPitch = Math.toDegrees(mOrientVals[1]);
mRoll = Math.toDegrees(mOrientVals[2]);
/*
* compensate for magentic delination
*/
mAzimuth += mDelination;
/*
* this will compenstate for device rotations * this will compenstate for device rotations
* TODO compensate for inversed portrait
*/ */
if (mContext.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { if (mContext.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
boolean isNormal = false; boolean isNormal = false;
if (roll <= -25) if (mRoll <= -25)
isNormal = false; isNormal = false;
if (roll >= 25) if (mRoll >= 25)
isNormal = true; isNormal = true;
if (isNormal) if (isNormal)
azimuth = azimuth - 90; mAzimuth = mAzimuth - 90;
else else
azimuth = azimuth + 90; mAzimuth = mAzimuth + 90;
} }
} }
} }
mHandler.sendMessage(mHandler.obtainMessage(BEARING, (float) azimuth)); mHandler.sendMessage(mHandler.obtainMessage(BEARING, (float) mAzimuth));
} }
@Override @Override
@@ -103,7 +119,6 @@ public class CompassSensor{
mHandler = new Handler(){ mHandler = new Handler(){
@Override @Override
public void handleMessage(Message msg){ public void handleMessage(Message msg){
// System.out.print((Float) msg.obj);
if(mListener != null) if(mListener != null)
if(msg.what == BEARING) if(msg.what == BEARING)
mListener.onCompassUpdate((Float) msg.obj); mListener.onCompassUpdate((Float) msg.obj);
@@ -142,4 +157,22 @@ public class CompassSensor{
}).start(); }).start();
} }
} }
/**
* Updates the Geomagnetic Field Declination based off of the provided location
* @param location last known (lat,lon,altitude), null will reset
* @author ricky barrette
*/
public void setDeclination(Location location){
if (location != null) {
GeomagneticField geomagneticField;
geomagneticField = new GeomagneticField(new Double(location.getLatitude()).floatValue(),
new Double(location.getLongitude()).floatValue(),
new Double(location.getAltitude()).floatValue(),
System.currentTimeMillis());
mDelination = geomagneticField.getDeclination();
} else {
mDelination = 0;
}
}
} }