Implemented Sensor-Selection with Swipe-gesture in new Activity.

This commit is contained in:
Alexander Pacha
2013-12-15 23:44:00 +01:00
parent d97983288b
commit e2e4269176
16 changed files with 243 additions and 152 deletions

View File

@@ -14,8 +14,8 @@
android:label="@string/app_name" android:label="@string/app_name"
android:theme="@style/AppTheme" > android:theme="@style/AppTheme" >
<activity <activity
android:name="org.hitlabnz.sensor_fusion_demo.MainActivity" android:name="org.hitlabnz.sensor_fusion_demo.SensorSelectionActivity"
android:label="@string/title_main_activity" android:label="@string/title_activity_sensor_selection"
android:screenOrientation="nosensor" > android:screenOrientation="nosensor" >
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />

View File

@@ -1,4 +1,4 @@
# Sensor fusion Demo for Android # Sensor fusion demo for Android
This application demonstrates the capabilities of various sensors and sensor-fusions. Data from the Gyroscope, Accelerometer and compass are combined in different ways and the result is shown as a cube that can be rotated by rotating the device. This application demonstrates the capabilities of various sensors and sensor-fusions. Data from the Gyroscope, Accelerometer and compass are combined in different ways and the result is shown as a cube that can be rotated by rotating the device.
@@ -6,13 +6,13 @@ The major novelty in this application is the fusion of virtual sensors: **Improv
Apart from these two sensors, the following sensors are available for comparison: Apart from these two sensors, the following sensors are available for comparison:
- Accelerometer + Compass
- Gravity + Compass
- Android Rotation Vector (Kalman filter fusion of Accelerometer + Gyroscope + Compass)
- Calibrated Gyroscope (Separate result of Kalman filter fusion of Accelerometer + Gyroscope + Compass)
- Improved Orientation Sensor 1 (Sensor fusion of Android Rotation Vector and Calibrated Gyroscope - less stable but more accurate) - Improved Orientation Sensor 1 (Sensor fusion of Android Rotation Vector and Calibrated Gyroscope - less stable but more accurate)
- Improved Orientation Sensor 2 (Sensor fusion of Android Rotation Vector and Calibrated Gyroscope - more stable but less accurate) - Improved Orientation Sensor 2 (Sensor fusion of Android Rotation Vector and Calibrated Gyroscope - more stable but less accurate)
- Old Android Orientation Sensor (Complementary filter fusion of Accelerometer + Gyroscope + Compass) - Android Rotation Vector (Kalman filter fusion of Accelerometer + Gyroscope + Compass)
- Calibrated Gyroscope (Separate result of Kalman filter fusion of Accelerometer + Gyroscope + Compass)
- Gravity + Compass
- Accelerometer + Compass
- Deprecated Android Orientation Sensor (Complementary filter fusion of Accelerometer + Gyroscope + Compass)
This application was developed for demonstrating the sensor fusion approach developed for my [Master Thesis "Sensor fusion for robust outdoor Augmented Reality tracking on mobile devices"](http://my-it.at/media/MasterThesis-Pacha.pdf) at the [Human Interface Technology Laboratory New Zealand](http://www.hitlabnz.org). This application was developed for demonstrating the sensor fusion approach developed for my [Master Thesis "Sensor fusion for robust outdoor Augmented Reality tracking on mobile devices"](http://my-it.at/media/MasterThesis-Pacha.pdf) at the [Human Interface Technology Laboratory New Zealand](http://www.hitlabnz.org).

View File

@@ -1,8 +0,0 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity2"
tools:ignore="MergeRootFrame" />

View File

@@ -3,7 +3,7 @@
android:id="@+id/pager" android:id="@+id/pager"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".MainActivity" > tools:context=".SensorSelectionActivity" >
<!-- <!--
This title strip will display the currently visible page title, as well as the page This title strip will display the currently visible page title, as well as the page

View File

@@ -1,16 +0,0 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity2$DummySectionFragment" >
<TextView
android:id="@+id/section_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>

View File

@@ -1,16 +0,0 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity$DummySectionFragment" >
<TextView
android:id="@+id/section_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>

View File

@@ -1,9 +0,0 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:showAsAction="never"
android:title="@string/action_settings"/>
</menu>

View File

@@ -1,9 +0,0 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:showAsAction="never"
android:title="@string/action_settings"/>
</menu>

View File

@@ -0,0 +1,9 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/action_about"
android:orderInCategory="100"
android:showAsAction="always"
android:title="@string/action_about"/>
</menu>

View File

@@ -1,8 +1,15 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="app_name">Sensor fusion Demo</string> <string name="app_name">Sensor fusion demo</string>
<string name="action_settings">Settings</string> <string name="action_about">About</string>
<string name="title_main_activity">Sensor fusion Demo</string> <string name="title_main_activity">Sensor fusion demo</string>
<string name="title_section1">Improved Orientation Sensor 1</string>
<string name="title_section2">Improved Orientation Sensor 2</string>
<string name="title_section3">Android Rotation Vector</string>
<string name="title_section4">Calibrated Gyroscope</string>
<string name="title_section5">Gravity and Compass</string>
<string name="title_section6">Accelerometer and Compass</string>
<string name="title_activity_sensor_selection">Sensor fusion demo</string>
</resources> </resources>

View File

@@ -59,9 +59,13 @@ public class CubeRenderer implements GLSurfaceView.Renderer {
gl.glTranslatef(0, 0, -3.0f); gl.glTranslatef(0, 0, -3.0f);
if (orientationProvider != null) { if (orientationProvider != null) {
// Get the rotation from the current orientationProvider // All Orientation providers deliver Quaternion as well as rotation matrix.
// Use your favourite representation:
// Get the rotation from the current orientationProvider as rotation matrix
//gl.glMultMatrixf(orientationProvider.getRotationMatrix().getMatrix(), 0); //gl.glMultMatrixf(orientationProvider.getRotationMatrix().getMatrix(), 0);
// Get the rotation from the current orientationProvider as quaternion
Quaternion q = orientationProvider.getQuaternion(); Quaternion q = orientationProvider.getQuaternion();
gl.glRotatef((float) (2.0f * Math.acos(q.getW()) * 180.0f / Math.PI), q.getX(), q.getY(), q.getZ()); gl.glRotatef((float) (2.0f * Math.acos(q.getW()) * 180.0f / Math.PI), q.getX(), q.getY(), q.getZ());
} }

View File

@@ -1,78 +0,0 @@
/* Copyright (C) 2007 The Android Open Source Project
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License. */
package org.hitlabnz.sensor_fusion_demo;
import org.hitlabnz.sensor_fusion_demo.orientationProvider.ImprovedOrientationSensor2Provider;
import org.hitlabnz.sensor_fusion_demo.orientationProvider.OrientationProvider;
import android.app.Activity;
import android.hardware.SensorManager;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
/**
* Main controller activity for demo-application. Processes user-input and delegates calls to orientation providers.
*/
public class MainActivity extends Activity {
/**
* The surface that will be drawn upon
*/
private GLSurfaceView mGLSurfaceView;
/**
* The class that renders the cube
*/
private CubeRenderer mRenderer;
/**
* The current orientation provider that delivers device orientation.
*/
private OrientationProvider currentOrientationProvider;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Initialise the orientationProvider
//currentOrientationProvider = new RotationVectorProvider((SensorManager) getSystemService(SENSOR_SERVICE));
//currentOrientationProvider = new AccelerometerCompassProvider((SensorManager) getSystemService(SENSOR_SERVICE));
//currentOrientationProvider = new GravityCompassProvider((SensorManager) getSystemService(SENSOR_SERVICE));
//currentOrientationProvider = new CalibratedGyroscopeProvider((SensorManager) getSystemService(SENSOR_SERVICE));
// currentOrientationProvider = new ImprovedOrientationSensor1Provider(
// (SensorManager) getSystemService(SENSOR_SERVICE));
currentOrientationProvider = new ImprovedOrientationSensor2Provider(
(SensorManager) getSystemService(SENSOR_SERVICE));
// Create our Preview view and set it as the content of our Activity
mRenderer = new CubeRenderer();
mRenderer.setOrientationProvider(currentOrientationProvider);
mGLSurfaceView = new GLSurfaceView(this);
mGLSurfaceView.setRenderer(mRenderer);
setContentView(mGLSurfaceView);
}
@Override
protected void onResume() {
// Ideally a game should implement onResume() and onPause()
// to take appropriate action when the activity looses focus
super.onResume();
currentOrientationProvider.start();
mGLSurfaceView.onResume();
}
@Override
protected void onPause() {
// Ideally a game should implement onResume() and onPause()
// to take appropriate action when the activity looses focus
super.onPause();
currentOrientationProvider.stop();
mGLSurfaceView.onPause();
}
}

View File

@@ -0,0 +1,207 @@
package org.hitlabnz.sensor_fusion_demo;
import java.util.Locale;
import org.hitlabnz.sensor_fusion_demo.orientationProvider.AccelerometerCompassProvider;
import org.hitlabnz.sensor_fusion_demo.orientationProvider.CalibratedGyroscopeProvider;
import org.hitlabnz.sensor_fusion_demo.orientationProvider.GravityCompassProvider;
import org.hitlabnz.sensor_fusion_demo.orientationProvider.ImprovedOrientationSensor1Provider;
import org.hitlabnz.sensor_fusion_demo.orientationProvider.ImprovedOrientationSensor2Provider;
import org.hitlabnz.sensor_fusion_demo.orientationProvider.OrientationProvider;
import org.hitlabnz.sensor_fusion_demo.orientationProvider.RotationVectorProvider;
import android.hardware.SensorManager;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
/**
* The main activity where the user can select which sensor-fusion he wants to try out
*
* @author Alexander Pacha
*
*/
public class SensorSelectionActivity extends FragmentActivity {
/**
* The {@link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a {@link android.support.v4.app.FragmentPagerAdapter} derivative,
* which
* will keep every loaded fragment in memory. If this becomes too memory
* intensive, it may be best to switch to a {@link android.support.v4.app.FragmentStatePagerAdapter}.
*/
SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {@link ViewPager} that will host the section contents.
*/
ViewPager mViewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sensor_selection);
// Create the adapter that will return a fragment for each of the three
// primary sections of the app.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.sensor_selection, menu);
return true;
}
/**
* A {@link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
/**
* Initialises a new sectionPagerAdapter
*
* @param fm the fragment Manager
*/
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a DummySectionFragment (defined as a static inner class
// below) with the page number as its lone argument.
Fragment fragment = new OrientationVisualisationFragment();
Bundle args = new Bundle();
args.putInt(OrientationVisualisationFragment.ARG_SECTION_NUMBER, position + 1);
fragment.setArguments(args);
return fragment;
}
@Override
public int getCount() {
// Show 6 total pages.
return 6;
}
@Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return getString(R.string.title_section1).toUpperCase(l);
case 1:
return getString(R.string.title_section2).toUpperCase(l);
case 2:
return getString(R.string.title_section3).toUpperCase(l);
case 3:
return getString(R.string.title_section4).toUpperCase(l);
case 4:
return getString(R.string.title_section5).toUpperCase(l);
case 5:
return getString(R.string.title_section6).toUpperCase(l);
}
return null;
}
}
/**
* A fragment that contains the same visualisation for different orientation providers
*/
public static class OrientationVisualisationFragment extends Fragment {
/**
* The surface that will be drawn upon
*/
private GLSurfaceView mGLSurfaceView;
/**
* The class that renders the cube
*/
private CubeRenderer mRenderer;
/**
* The current orientation provider that delivers device orientation.
*/
private OrientationProvider currentOrientationProvider;
/**
* The fragment argument representing the section number for this
* fragment.
*/
public static final String ARG_SECTION_NUMBER = "section_number";
@Override
public void onResume() {
// Ideally a game should implement onResume() and onPause()
// to take appropriate action when the activity looses focus
super.onResume();
currentOrientationProvider.start();
mGLSurfaceView.onResume();
}
@Override
public void onPause() {
// Ideally a game should implement onResume() and onPause()
// to take appropriate action when the activity looses focus
super.onPause();
currentOrientationProvider.stop();
mGLSurfaceView.onPause();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Initialise the orientationProvider
switch (getArguments().getInt(ARG_SECTION_NUMBER)) {
case 1:
currentOrientationProvider = new ImprovedOrientationSensor1Provider((SensorManager) getActivity()
.getSystemService(SENSOR_SERVICE));
break;
case 2:
currentOrientationProvider = new ImprovedOrientationSensor2Provider((SensorManager) getActivity()
.getSystemService(SENSOR_SERVICE));
break;
case 3:
currentOrientationProvider = new RotationVectorProvider((SensorManager) getActivity().getSystemService(
SENSOR_SERVICE));
break;
case 4:
currentOrientationProvider = new CalibratedGyroscopeProvider((SensorManager) getActivity()
.getSystemService(SENSOR_SERVICE));
break;
case 5:
currentOrientationProvider = new GravityCompassProvider((SensorManager) getActivity().getSystemService(
SENSOR_SERVICE));
break;
case 6:
currentOrientationProvider = new AccelerometerCompassProvider((SensorManager) getActivity()
.getSystemService(SENSOR_SERVICE));
break;
default:
break;
}
// Create our Preview view and set it as the content of our Activity
mRenderer = new CubeRenderer();
mRenderer.setOrientationProvider(currentOrientationProvider);
mGLSurfaceView = new GLSurfaceView(getActivity());
mGLSurfaceView.setRenderer(mRenderer);
return mGLSurfaceView;
}
}
}

View File

@@ -55,7 +55,7 @@ public class CalibratedGyroscopeProvider extends OrientationProvider {
private double gyroscopeRotationVelocity = 0; private double gyroscopeRotationVelocity = 0;
/** /**
* Initialises a new GravityCompassProvider * Initialises a new CalibratedGyroscopeProvider
* *
* @param sensorManager The android sensor manager * @param sensorManager The android sensor manager
*/ */

View File

@@ -127,7 +127,7 @@ public class ImprovedOrientationSensor1Provider extends OrientationProvider {
private static final int PANIC_THRESHOLD = 60; private static final int PANIC_THRESHOLD = 60;
/** /**
* Initialises a new GravityCompassProvider * Initialises a new ImprovedOrientationSensor1Provider
* *
* @param sensorManager The android sensor manager * @param sensorManager The android sensor manager
*/ */

View File

@@ -127,7 +127,7 @@ public class ImprovedOrientationSensor2Provider extends OrientationProvider {
private static final int PANIC_THRESHOLD = 60; private static final int PANIC_THRESHOLD = 60;
/** /**
* Initialises a new GravityCompassProvider * Initialises a new ImprovedOrientationSensor2Provider
* *
* @param sensorManager The android sensor manager * @param sensorManager The android sensor manager
*/ */