TRACKING APP: use magnetic field and accelerometer for heading

This commit is contained in:
Lukas Zielinski committed 2014-12-08 16:50:32 +01:00
1 parent 5f022d3b21
commit 7392d38e9e
8 files changed
+197 -8

No files matched your search

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.sap.sailing.android.tracking.app.test"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="14" />
<instrumentation
android:name="android.test.InstrumentationTestRunner"
android:targetPackage="com.sap.sailing.android.tracking.app" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<uses-library android:name="android.test.runner" />
</application>
</manifest>
@@ -7,4 +7,9 @@
<string name="preference_energy_saving_is_disabled">Aus</string>
<string name="prefrence_energy_saving_summary_is_enabled">GPS Updates werden alle 30 Sekunden verschickt.</string>
<string name="prefrence_energy_saving_summary_is_disabled">GPS Updates werden alle 3 Sekunden verschickt.</string>
<string name="preference_heading_from_magnetic_key_is_enabled">magn.</string>
<string name="preference_heading_from_magnetic_key_is_disabled">GPS</string>
<string name="preference_heading_from_magnetic_key_summary_is_enabled">Angezeigte Richtung stammt vom Magnetkompass</string>
<string name="preference_heading_from_magnetic_key_summary_is_disabled">Angezeigte Richtung stammt vom GPS</string>
<string name="preference_heading_from_magnetic_enabled">Richtung</string>
</resources>
@@ -10,6 +10,7 @@
<string name="preference_server_url_default">http://95.85.58.11:8000</string>
<string name="preference_energy_saving_enabled_key">preferenceEnergySavingEnabled</string>
<string name="preference_heading_from_magnetic_key">preferenceHeadingFromMagneticKey</string>
<string name="settings_category_energy_saving">Battery Saving</string>
<string name="energy_saving_enabled">Save Energy</string>
@@ -26,4 +27,10 @@
<string name="preference_tracking_timer_started">trackingTimerStarted</string>
<string name="preference_tracker_is_tracking">trackerIsTracking</string>
<string name="preference_tracker_is_tracking_event_id">trackerIsTrackingEventId</string>
<string name="preference_heading_from_magnetic_key_is_enabled">magn.</string>
<string name="preference_heading_from_magnetic_key_is_disabled">GPS</string>
<string name="preference_heading_from_magnetic_key_summary_is_enabled">Reported heading from magnetic compass</string>
<string name="preference_heading_from_magnetic_key_summary_is_disabled">Reported heading from GPS</string>
<string name="preference_heading_from_magnetic_enabled">Heading</string>
</resources>
@@ -20,6 +20,16 @@
android:key="@string/preference_device_identifier_key"
android:summary="@string/empty"
android:title="@string/device_identifier" android:selectable="false"/>
<SwitchPreference
android:defaultValue="false"
android:key="@string/preference_heading_from_magnetic_key"
android:switchTextOn="@string/preference_heading_from_magnetic_key_is_enabled"
android:switchTextOff="@string/preference_heading_from_magnetic_key_is_disabled"
android:summaryOn="@string/preference_heading_from_magnetic_key_summary_is_enabled"
android:summaryOff="@string/preference_heading_from_magnetic_key_summary_is_disabled"
android:title="@string/preference_heading_from_magnetic_enabled" />
</PreferenceCategory>
</PreferenceScreen>
@@ -0,0 +1,102 @@
package com.sap.sailing.android.tracking.app.sensors;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
public class CompassManager implements SensorEventListener {
//private final static String TAG = CompassManager.class.getName();
private static CompassManager mInstance;
private Context mContext;
private SensorManager sensorManager;
private Sensor gsensor;
private Sensor msensor;
private float[] mGravity = new float[3];
private float[] mGeomagnetic = new float[3];
private float azimuth = 0f;
private MagneticHeadingListener listener;
public static synchronized CompassManager getInstance(Context context) {
if (mInstance == null) {
mInstance = new CompassManager(context);
}
return mInstance;
}
private CompassManager(Context context) {
mContext = context;
sensorManager = (SensorManager) mContext
.getSystemService(Context.SENSOR_SERVICE);
gsensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
msensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
}
public void registerListener(MagneticHeadingListener listener)
{
this.listener = listener;
start();
}
public void unregisterListener()
{
stop();
this.listener = null;
}
public void start() {
sensorManager.registerListener(this, gsensor, SensorManager.SENSOR_DELAY_GAME);
sensorManager.registerListener(this, msensor, SensorManager.SENSOR_DELAY_GAME);
}
public void stop() {
sensorManager.unregisterListener(this);
}
@Override
public void onSensorChanged(SensorEvent event) {
final float alpha = 0.97f;
if (listener == null) {
return;
}
synchronized (this) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
mGravity[0] = alpha * mGravity[0] + (1 - alpha) * event.values[0];
mGravity[1] = alpha * mGravity[1] + (1 - alpha) * event.values[1];
mGravity[2] = alpha * mGravity[2] + (1 - alpha) * event.values[2];
}
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
mGeomagnetic[0] = alpha * mGeomagnetic[0] + (1 - alpha) * event.values[0];
mGeomagnetic[1] = alpha * mGeomagnetic[1] + (1 - alpha) * event.values[1];
mGeomagnetic[2] = alpha * mGeomagnetic[2] + (1 - alpha) * event.values[2];
}
float R[] = new float[9];
float I[] = new float[9];
boolean success = SensorManager.getRotationMatrix(R, I, mGravity, mGeomagnetic);
if (success) {
float orientation[] = new float[3];
SensorManager.getOrientation(R, orientation);
azimuth = (float) Math.toDegrees(orientation[0]); // orientation
azimuth = (azimuth + 360) % 360;
listener.magneticHeadingUpdated(azimuth);
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
public interface MagneticHeadingListener {
public void magneticHeadingUpdated(float heading);
}
}
@@ -11,6 +11,8 @@ import android.support.v7.widget.Toolbar;
import com.sap.sailing.android.shared.logging.ExLog;
import com.sap.sailing.android.tracking.app.BuildConfig;
import com.sap.sailing.android.tracking.app.R;
import com.sap.sailing.android.tracking.app.sensors.CompassManager;
import com.sap.sailing.android.tracking.app.sensors.CompassManager.MagneticHeadingListener;
import com.sap.sailing.android.tracking.app.services.TrackingService;
import com.sap.sailing.android.tracking.app.services.TrackingService.GPSQuality;
import com.sap.sailing.android.tracking.app.services.TrackingService.GPSQualityListener;
@@ -21,10 +23,11 @@ import com.sap.sailing.android.tracking.app.services.TransmittingService.APIConn
import com.sap.sailing.android.tracking.app.services.TransmittingService.TransmittingBinder;
import com.sap.sailing.android.tracking.app.ui.fragments.HudFragment;
import com.sap.sailing.android.tracking.app.ui.fragments.TrackingFragment;
import com.sap.sailing.android.tracking.app.utils.AppPreferences;
import com.sap.sailing.android.tracking.app.utils.DatabaseHelper;
import com.sap.sailing.android.tracking.app.valueobjects.EventInfo;
public class TrackingActivity extends BaseActivity implements GPSQualityListener, APIConnectivityListener {
public class TrackingActivity extends BaseActivity implements GPSQualityListener, APIConnectivityListener, MagneticHeadingListener {
TrackingService trackingService;
boolean trackingServiceBound;
@@ -37,10 +40,14 @@ public class TrackingActivity extends BaseActivity implements GPSQualityListener
private String eventId;
private AppPreferences prefs;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
prefs = new AppPreferences(this);
Intent intent = getIntent();
eventId = intent.getExtras().getString(getString(R.string.tracking_activity_event_id_parameter));
@@ -96,8 +103,7 @@ public class TrackingActivity extends BaseActivity implements GPSQualityListener
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
TrackingFragment fragment = (TrackingFragment)getSupportFragmentManager()
.findFragmentById(R.id.content_frame);
TrackingFragment fragment = (TrackingFragment)getSupportFragmentManager().findFragmentById(R.id.content_frame);
getSupportFragmentManager().putFragment(outState, SIS_FRAGMENT, fragment);
}
@@ -138,7 +144,21 @@ public class TrackingActivity extends BaseActivity implements GPSQualityListener
}
}
@Override
protected void onPause() {
super.onPause();
CompassManager.getInstance(this).unregisterListener();
}
@Override
protected void onResume() {
super.onResume();
if (prefs.getHeadingFromMagneticSensorPreferred()) {
CompassManager.getInstance(this).registerListener(this);
}
}
@Override
public void gpsQualityAndAccurracyUpdated(GPSQuality quality, float gpsAccurracy, float bearing, float speed) {
TrackingFragment trackingFragment = (TrackingFragment) getSupportFragmentManager().findFragmentById(R.id.content_frame);
@@ -146,7 +166,11 @@ public class TrackingActivity extends BaseActivity implements GPSQualityListener
HudFragment hudFragment = (HudFragment) getSupportFragmentManager().findFragmentById(R.id.hud_content_frame);
hudFragment.setSpeedOverGround(speed);
hudFragment.setHeading(bearing);
if (!prefs.getHeadingFromMagneticSensorPreferred())
{
hudFragment.setHeading(bearing);
}
}
@Override
@@ -231,4 +255,21 @@ public class TrackingActivity extends BaseActivity implements GPSQualityListener
trackingServiceBound = false;
}
};
@Override
public void magneticHeadingUpdated(float heading) {
HudFragment hudFragment = (HudFragment) getSupportFragmentManager().findFragmentById(R.id.hud_content_frame);
if (prefs.getHeadingFromMagneticSensorPreferred())
{
hudFragment.setHeading(heading);
}
else
{
if (BuildConfig.DEBUG)
{
ExLog.i(this, TAG, "Received magnet compass update, even though prefs say get from GPS. Unregistering listener." );
}
CompassManager.getInstance(this).unregisterListener();
}
}
}
@@ -36,13 +36,14 @@ public class HudFragment extends BaseFragment {
public void setHeading(float heading)
{
TextView headingLabel = (TextView)getActivity().findViewById(R.id.hud_hdg_label);
headingLabel.setText(getString(R.string.hud_heading_prefix) + String.valueOf(heading) + "°");
headingLabel.setText(getString(R.string.hud_heading_prefix) + String.valueOf(Math.round(heading)) + "°");
}
public void setSpeedOverGround(float speed)
public void setSpeedOverGround(float speedInMetersPerSeconds)
{
float speedInKnots = speedInMetersPerSeconds * 1.9438444924574f;
TextView speedLabel = (TextView)getActivity().findViewById(R.id.hud_speed_label);
speedLabel.setText(getString(R.string.hud_speed_over_ground_prefix) + String.valueOf(speed) + "kn");
speedLabel.setText(getString(R.string.hud_speed_over_ground_prefix) + String.valueOf(speedInKnots) + "kn");
}
/**
@@ -104,6 +104,10 @@ public class AppPreferences {
return preferences.getBoolean(context.getString(R.string.preference_energy_saving_enabled_key), false);
}
public boolean getHeadingFromMagneticSensorPreferred() {
return preferences.getBoolean(context.getString(R.string.preference_heading_from_magnetic_key), false);
}
public void setTrackingTimerStarted(long milliseconds)
{
preferences.edit().putLong(context.getString(R.string.preference_tracking_timer_started), milliseconds).commit();