diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 966f121..e62697e 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -23,6 +23,10 @@
+
+
diff --git a/assets/about/de/index.html b/assets/about/de/index.html
new file mode 100644
index 0000000..acfb90e
--- /dev/null
+++ b/assets/about/de/index.html
@@ -0,0 +1,57 @@
+
+
+
+
+ Diese App wurde von Alexander Pacha am Human Interface Technology
+ Laboratory New Zealand entwickelt und demonstriert die
+ Leistungsfähigkeit von verschiedenen Sensoren und Sensorfusionen.
+ Messungen von dem Gyroskop, Akzelerometer und Kompass werden in
+ verschiedenen Weisen kombiniert und das Ergebnis wird als Würfel
+ visualisiert, der durch rotieren des Gerätes gedreht werden kann.
+
+
+ Die große Neuheit in dieser Applikation ist die Fusion von zwei
+ virtuellen Sensoren: Improved Orientation Sensor 1 und Improved
+ Orientation Sensor 2 nutzt den Android Rotation Vector mit dem
+ kalibrierten Gyroskopsensor mit einer nie zuvor dagewesenen Präzision
+ und Reaktionsfähigkeit.
+
+
+ Neben diesen beiden Sensorfusionen gibt es noch weitere Sensoren
+ zum Vergleich:
+
+ - Improved Orientation Sensor 1 (Sensorfusion des Android
+ Rotation Vector und des kalibrierten Gyroskops - weniger stabil,
+ dafür genauer)
+ - Improved Orientation Sensor 2 (Sensorfusion des Android
+ Rotation Vector und des kalibrierten Gyroskops - stabiler, dafür
+ ungenauer)
+ - Android Rotation Vector (Kalmanfilterfusion von Akzelerometer
+ + Gyroskop + Kompass) - die bisher beste verfügbare Fusion!
+ - Kalibriertes Gyroskop (Weiteres Ergebnis der
+ Kalmanfilterfusion von Akzelerometer + Gyroskop + Kompass). Liefert
+ nur relative Rotation, kann daher von den anderen Sensoren abweichen.
+ - Gravitation + Kompass
+ - Akzelerometer + Kompass
+
+
+
+ Die Anwendung wurde entwickelt um die im Rahmer der Masterarbeit "Sensor
+ fusion for robust outdoor Augmented Reality tracking on mobile devices"
+ (download)
+ entwickelte Sensorfusion zu demonstrieren. Die App wurde am Human Interface Technology
+ Laboratory New Zealand entwickelt.
+
+
+ Lange auf den Würfel gedrückt halten, um kurzfristig in den Raummodus zu wechseln.
+
+
+ Der Quellcode ist öffentlich verfügbar auf Bitbucket
+ unter der MIT Lizenz.
+
+
+
\ No newline at end of file
diff --git a/assets/about/en/index.html b/assets/about/en/index.html
new file mode 100644
index 0000000..eef4c42
--- /dev/null
+++ b/assets/about/en/index.html
@@ -0,0 +1,52 @@
+
+
+
+ This application was developed by Alexander Pacha at the Human Interface
+ Technology Laboratory New Zealand to demonstrate the
+ capabilities of various sensors and sensor fusion approaches. 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.
+
+ The major novelty in this application is the fusion of virtual
+ sensors: Improved Orientation Sensor 1 and Improved
+ Orientation Sensor 2 fuse the Android Rotation Vector with the
+ virtual Gyroscope sensor to achieve a pose estimation with a
+ previously unknown stability and precision.
+
+
+ Apart from these two sensors, the following sensors are
+ available for comparison:
+
+ - 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)
+ - 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
+
+
+
+ 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"
+ (download) at the Human Interface
+ Technology Laboratory New Zealand
+
+
+ Long-click on a cube to temporarily change into the space-mode for this fusion.
+
+
+ The source-code is publicly available at Bitbucket
+ and licensed under the MIT license.
+
+
+
\ No newline at end of file
diff --git a/res/layout/activity_about.xml b/res/layout/activity_about.xml
new file mode 100644
index 0000000..1e879bb
--- /dev/null
+++ b/res/layout/activity_about.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
new file mode 100644
index 0000000..a2b870f
--- /dev/null
+++ b/res/values-de/strings.xml
@@ -0,0 +1,16 @@
+
+
+
+ Sensorfusions Demo
+ Über
+ Sensorfusions Demo
+ Improved Orientation Sensor 1
+ Improved Orientation Sensor 2
+ Android Rotation Vector
+ Kalibriertes Gyroskop
+ Gravitation und Kompass
+ Akzelerometer und Kompass
+ Sensorfusions Demo
+ Über
+
+
diff --git a/res/values/strings.xml b/res/values/strings.xml
index ff106de..a4042c0 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -11,5 +11,6 @@
Gravity and Compass
Accelerometer and Compass
Sensor fusion demo
+ About
diff --git a/src/org/hitlabnz/sensor_fusion_demo/AboutActivity.java b/src/org/hitlabnz/sensor_fusion_demo/AboutActivity.java
new file mode 100644
index 0000000..07beeb1
--- /dev/null
+++ b/src/org/hitlabnz/sensor_fusion_demo/AboutActivity.java
@@ -0,0 +1,43 @@
+package org.hitlabnz.sensor_fusion_demo;
+
+import java.util.Locale;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.MenuItem;
+import android.webkit.WebView;
+
+/**
+ * Activity, that displays a single WebView with the text shown under the section About in the settings
+ *
+ * @author Alexander Pacha
+ *
+ */
+public class AboutActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_about);
+
+ // Get the locale substring to access the localised assets
+ String localPrefix = Locale.getDefault().getLanguage().substring(0, 2).toLowerCase(Locale.US);
+
+ // Load the website as the only action for this activity
+ WebView webView = (WebView) findViewById(R.id.webViewAbout);
+ webView.loadUrl("file:///android_asset/about/" + localPrefix + "/index.html");
+
+ // Enable the logo in the top left corner to bring the user back to another activity.
+ getActionBar().setDisplayHomeAsUpEnabled(true);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ finish();
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+}
diff --git a/src/org/hitlabnz/sensor_fusion_demo/CubeRenderer.java b/src/org/hitlabnz/sensor_fusion_demo/CubeRenderer.java
index 632e2b9..c8b03fc 100644
--- a/src/org/hitlabnz/sensor_fusion_demo/CubeRenderer.java
+++ b/src/org/hitlabnz/sensor_fusion_demo/CubeRenderer.java
@@ -56,18 +56,49 @@ public class CubeRenderer implements GLSurfaceView.Renderer {
// set-up modelview matrix
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
- gl.glTranslatef(0, 0, -3.0f);
- if (orientationProvider != null) {
- // All Orientation providers deliver Quaternion as well as rotation matrix.
- // Use your favourite representation:
+ if (showCubeInsideOut) {
+ float dist = 3;
+ gl.glTranslatef(0, 0, -dist);
- // Get the rotation from the current orientationProvider as rotation matrix
- //gl.glMultMatrixf(orientationProvider.getRotationMatrix().getMatrix(), 0);
+ if (orientationProvider != null) {
+ // All Orientation providers deliver Quaternion as well as rotation matrix.
+ // Use your favourite representation:
- // 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());
+ // 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());
+ }
+
+ // draw our object
+ gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
+ gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
+
+ mCube.draw(gl);
+ } else {
+
+ if (orientationProvider != null) {
+ // 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());
+ }
+
+ float dist = 3;
+ drawTranslatedCube(gl, 0, 0, -dist);
+ drawTranslatedCube(gl, 0, 0, dist);
+ drawTranslatedCube(gl, 0, -dist, 0);
+ drawTranslatedCube(gl, 0, dist, 0);
+ drawTranslatedCube(gl, -dist, 0, 0);
+ drawTranslatedCube(gl, dist, 0, 0);
}
// draw our object
@@ -77,6 +108,26 @@ public class CubeRenderer implements GLSurfaceView.Renderer {
mCube.draw(gl);
}
+ /**
+ * Draws a translated cube
+ *
+ * @param gl the surface
+ * @param translateX x-translation
+ * @param translateY y-translation
+ * @param translateZ z-translation
+ */
+ private void drawTranslatedCube(GL10 gl, float translateX, float translateY, float translateZ) {
+ gl.glPushMatrix();
+ gl.glTranslatef(translateX, translateY, translateZ);
+
+ // draw our object
+ gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
+ gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
+
+ mCube.draw(gl);
+ gl.glPopMatrix();
+ }
+
/**
* Update view-port with the new surface
*
@@ -101,4 +152,16 @@ public class CubeRenderer implements GLSurfaceView.Renderer {
// clear screen in black
gl.glClearColor(0, 0, 0, 1);
}
+
+ /**
+ * Flag indicating whether you want to view inside out, or outside in
+ */
+ private boolean showCubeInsideOut = true;
+
+ /**
+ * Toggles whether the cube will be shown inside-out or outside in.
+ */
+ public void toggleShowCubeInsideOut() {
+ this.showCubeInsideOut = !showCubeInsideOut;
+ }
}
diff --git a/src/org/hitlabnz/sensor_fusion_demo/SensorSelectionActivity.java b/src/org/hitlabnz/sensor_fusion_demo/SensorSelectionActivity.java
index 3aca89c..68e0efe 100644
--- a/src/org/hitlabnz/sensor_fusion_demo/SensorSelectionActivity.java
+++ b/src/org/hitlabnz/sensor_fusion_demo/SensorSelectionActivity.java
@@ -10,6 +10,7 @@ import org.hitlabnz.sensor_fusion_demo.orientationProvider.ImprovedOrientationSe
import org.hitlabnz.sensor_fusion_demo.orientationProvider.OrientationProvider;
import org.hitlabnz.sensor_fusion_demo.orientationProvider.RotationVectorProvider;
+import android.content.Intent;
import android.hardware.SensorManager;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
@@ -20,7 +21,9 @@ import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.Menu;
+import android.view.MenuItem;
import android.view.View;
+import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
/**
@@ -67,6 +70,18 @@ public class SensorSelectionActivity extends FragmentActivity {
return true;
}
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ // Handle item selection
+ switch (item.getItemId()) {
+ case R.id.action_about:
+ Intent intent = new Intent(this, AboutActivity.class);
+ startActivity(intent);
+ return true;
+ }
+ return false;
+ }
+
/**
* A {@link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
@@ -200,6 +215,15 @@ public class SensorSelectionActivity extends FragmentActivity {
mGLSurfaceView = new GLSurfaceView(getActivity());
mGLSurfaceView.setRenderer(mRenderer);
+ mGLSurfaceView.setOnLongClickListener(new OnLongClickListener() {
+
+ @Override
+ public boolean onLongClick(View v) {
+ mRenderer.toggleShowCubeInsideOut();
+ return true;
+ }
+ });
+
return mGLSurfaceView;
}
}