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:theme="@style/AppTheme" >
<activity
android:name="org.hitlabnz.sensor_fusion_demo.MainActivity"
android:label="@string/title_main_activity"
android:name="org.hitlabnz.sensor_fusion_demo.SensorSelectionActivity"
android:label="@string/title_activity_sensor_selection"
android:screenOrientation="nosensor" >
<intent-filter>
<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.
@@ -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:
- 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 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).

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:layout_width="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

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"?>
<resources>
<string name="app_name">Sensor fusion Demo</string>
<string name="action_settings">Settings</string>
<string name="title_main_activity">Sensor fusion Demo</string>
<string name="app_name">Sensor fusion demo</string>
<string name="action_about">About</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>

View File

@@ -59,9 +59,13 @@ public class CubeRenderer implements GLSurfaceView.Renderer {
gl.glTranslatef(0, 0, -3.0f);
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);
// Get the rotation from the current orientationProvider as quaternion
Quaternion q = orientationProvider.getQuaternion();
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;
/**
* Initialises a new GravityCompassProvider
* Initialises a new CalibratedGyroscopeProvider
*
* @param sensorManager The android sensor manager
*/

View File

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

View File

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