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:

+ + +

+ 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:

+ + +

+ 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; } }