Implemented Sensor-Selection with Swipe-gesture in new Activity.
This commit is contained in:
@@ -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" />
|
||||
|
||||
12
README.md
12
README.md
@@ -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).
|
||||
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
9
res/menu/sensor_selection.xml
Normal file
9
res/menu/sensor_selection.xml
Normal 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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
207
src/org/hitlabnz/sensor_fusion_demo/SensorSelectionActivity.java
Normal file
207
src/org/hitlabnz/sensor_fusion_demo/SensorSelectionActivity.java
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user