Cardboard Talk02 Accelerometer

Source: Internet
Author: User
Tags cos sin

Operating system: Windows8.1

Graphics: Nivida gtx965m

Development tools: Android Studio 3.0.0 | Cardboard 1.0

Before discussing the implementation in depth, it is necessary to understand the relationship between the IMU sensor and the coordinate system of the Android system and the relationship transformation, so that the coordinate system can not be mixed in the implementation and application. In this loan opportunity to translate Nvdia an article Tegra Android Accelerometer whitepaper , if the content is inappropriate please advise.

Introduction

Mobile portable devices can be rotated in multiple directions. In many scenarios, applications need to consider ways to influence them, such as landscape landscape mode when customizing the user's UI or portriat portrait mode, or when interpreting the original sensor data. Applications that use the accelerometer accelerometer to get raw data must be specially processed, in other words, to gain a good user experience and to incorporate device and operating system considerations.

Although accelerometer accelerometer is an important input device for many software applications, some developers are using the wrong way to manipulate the accelerometer's data. More importantly, these applications do not take into account the direction of the device, which leads directly to a bad user experience. Handling the correct direction of the accelerometer is a simple and easy task that we will discuss in the next section.

coordinate Space Glossary

The Android system will escalate the value of the accelerometer in the form of absolute values. The initial reported value is always the data of the physical sensor, adjusted to the canonical specification format so that all devices can report and process data in the same form. Android does not convert the accelerometer data based on device orientation. The application must perform its own conversion process.

To illustrate the conversion process, this document defines the concept of the coordinate space and the transformation relationship between each coordinate space.

Space Description
Device coordinate space Accelerometer devices can output acceleration values in a variety of ways and are not subject to any standard restrictions.
Canonical coordinate space

To standardize the coordinate data output for each frame of the device, Android requires that device Raw Mapping be re-mapped. So, as the device moves towards the right, the positive x-axis increases and the positive y-axis increases as the device moves upwards, and the positive z-axis increases as the device moves toward the screen, and vice versa.

For the layout structure of each axis of the Canonical Accelerometer, see Accelerometer Canonical Axes .

Screen coordinate space The Android Form Manager's screen coordinate system origin is in the upper-left corner, with the maximum coordinates in the lower-right corner, that is, increasing x is to the right, and y is down. The display Manager of Android will change the screen orientation based on the data read by the sensor. The screen coordinate system is always relative to the current rotation angle.
World Coordinate space

This coordinate space is specific to the opengles application. The application developer may need to modify the code to accommodate the assumptions in this document, by default using the right-hand coordinate system, and up can be any vector.

It is important to note that many applications require additional transformations to display their models. Applications that use a left-handed coordinate system may also require additional coordinate inversion operations.

The following table shows the conversion relationships that need to be done and defines a glossary for this article. OpenGL applications typically use Canontoworld . Applications based on the Android form system will use Canontoscreen. Mixed-development applications, such as Android-based forms systems and the application of OpenGL-rendered content, will need both.

It is important to note that the accelerometer device driver handles Canonical Space, which is the process of Devicetocanon conversion. This document focuses on canontoscreen and canontoworld transformations.

Destination
Canonical Screen World
Source Device Raw Devicetocanon
Canonical Canontoscreen Canontoworld

Accelerometer Canonical Axes

Shows the change in the accelerometer value based on the given device and direction. They include a native device based on a vertical portrait portrait Layout, a portriat portrait device that rotates to the landscape, and a horizontal landscape Landscape Layout native device, normalized Canonical x/y/z Accelerometer axis/value.

Mobile Device Native portrait mode Orientation 0

Mobile Device Native portrait mode Orientation

Mobile native landscape mode Orientation 0

working with Acclerometer Data

The value of the accelerometer must be rotated according to the direction returned by the display object before it can get the desired result on the screen. Android Gets the screen rotation toward the API getorientation () or getrotation () , they all return the same results, but the former is not recommended to continue using.

The values returned by these functions correspond to integers and constants with Rotation_ prefixes in the Android.view.Surface class. The following is an example of calling one of the functions. Where This represents the Activity type Object.

WindowManager windowmgr =     (WindowManager) This.getsystemservice (window_service); int rotationindex = Windowmgr.getdefaultdisplay (). Getrotation ();

The return constants are:

Constant Name Index/value
Rotation_0 0
Rotation_90 1
rotation_180 2
rotation_270 3

The application can build a transformation matrix with rotational values that will convert the Android Canonical Accelerometer data to other coordinate system spaces. In order to convert the standard Canonical acceleration Count value to a value in the screen or world coordinate system. A canonaccel vector based on the Rotationindex index needs to be rotated in increments of 90 degrees, where rotation_0 means no rotation is required.

To perform a canontoscreen conversion, define the rotation equation as:

Screenaccel [0] = canonaccel[0] * cos? - Canonaccel[1] * sin?
Screenaccel [1] =-canonaccel[0] * sin? - Canonaccel[1] * cos?
Screenaccel [2] = Canonaccel[2]

which

A canontoscreen conversion function is implemented as follows:

static void Canonicaltoscreen (int     displayrotation,                              float[] Canvec,                              float[] screenvec) {     struct Axisswap     {          signed char Negatex;          Signed Char Negatey;          Signed Char xsrc;          Signed char ysrc;     };     static const Axisswap axisswap[] = {          {1,-1, 0, 1},   //Rotation_0          {-1,-1, 1, 0},   //Rotation_90
   {-1,  1, 0, 1},   //rotation_180          {1,  1, 1, 0}};//rotation_270     const axisswap& as = Axi Sswap[displayrotation];     Screenvec[0] = (float) As.negatex * canvec[AS.XSRC];     SCREENVEC[1] = (float) as.negatey * canvec[AS.YSRC];     SCREENVEC[2] = canvec[2]; }

For Canontoworld conversions, the rotation follows the following formula:

Screenaccel [0] = canonaccel[0] * cos? - Canonaccel[1] * sin?
Screenaccel [1] = Canonaccel[0] * sin? + Canonaccel[1] * cos?
Screenaccel [2] = Canonaccel[2]

Axis symmetry conversion related data can be preset in a static array, such as the following function Canonicaltoworld (), the standard space acceleration vector converted to OpenGL-style world space vector, using a simple integer lookup array to avoid expensive trigonometric function calculation cost.

static void Canonicaltoworld (int           displayrotation,                              const float*  canvec,                              float*        worldvec) {     struct Axisswap     {          signed char Negatex;          Signed Char Negatey;          Signed Char xsrc;          Signed char ysrc;     };     static const Axisswap axisswap[] = {          {1,  1, 0, 1},   //Rotation_0          {-1,  1, 1, 0},   //Rotati On_90          {-1,-1, 0, 1},   //rotation_180          {1,-1, 1, 0}};//rotation_270     const axisswap& as = Axi Sswap[displayrotation];     Worldvec[0] = (float) As.negatex * canvec[AS.XSRC];     WORLDVEC[1] = (float) as.negatey * canvec[AS.YSRC];     WORLDVEC[2] = canvec[2];}

The next function calculates the rotation angle based on the corresponding axis, which refers to the direction Localup of the accelerometer. The function returns the rotation axis rotaxis and the corresponding rotational angle angles in the form of a vector, which can be used to create a transformation matrix and a four-dollar number for world space.

void Computeaxisangle (const float* localup, const float* Worldvec,                      float* rotaxis, float* ang) {     const vec3& l Up  =  * (vec3*) Localup;     VEC3 Ntarget     =  Normalize (* (vec3*) worldvec);     *rotaxis         = Cross  (Lup, ntarget);     *rotaxis         =  normalize (*rotaxis);     *ang             =-ACOSF (dot (Lup, ntarget));}

Power Conservation

To conserve device power, the application should choose a low-level accelerometer update frequency. The update frequency levels that you can select are defined in Android.hardware.sensormanager , and the following table shows the update frequency levels for accelerometers in descending order.

Constant Name Relative speed
Sensor_delay_fastest Fastest
Sensor_delay_game Faster
Sensor_delay_normal Slower
sensor_delay_ui Slowest

An example of setting a sensor update frequency is as follows:

if (Msensormanager = = null)    Msensormanager = (sensormanager) getsystemservice (Sensor_service); if (Msensormanager!) = null)    Msensormanager.registerlistener (This         ,         msensormanager.getdefaultsensor (sensor.type_ ACCELEROMETER),         sensor_delay_game);

It is important to note that the delay value is abstract and that the value is related to the specific device. As a result, the same level of update will vary across mobile phones. The only way to ensure device update frequency is to measure the rate of return at run time.

supporting older OS Versions

To support older Android systems such as froyo/v2.2. You may need to use the older API feature Getorientation (). The following shows an example of dynamic binding, and it is important to note that getorientation () may disappear in future versions of Android.

windowmanager wm; Method GETROTATION;WM = (windowmanager) this.getsystemservice (Window_service); class<display> C = (class<display>) wm.getdefaultdisplay (). GetClass (); Method[] methods = C.getdeclaredmethods ();     String rotfnname = new String ("Getrotation"), for (Method method:methods) {LOG.D ("Methods", Method.getname ());         if (Method.getname (). Equals (Rotfnname)) {getrotation = method;     Break }}int Orientation;display Display = Wm.getdefaultdisplay (), if (getrotation! = null) {try {Integer i = (i         Nteger) Getrotation.invoke (d);     Orientation = I.intvalue (); } catch (Exception e) {}}else{orientation = Display.getorientation ();} 

What needs to be added is that the NDK does not directly capture the Display , but can indirectly pass the Context object through reflection to get WindowManager and Display object, which calls getorientation () or getrotation () . However, the performance of this method is rather worrying, after all, the use of reflection. Another way is to pass the value of getorientation () or getrotation () from the upper layer to the native tier.

Cardboard Talk02 Accelerometer

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.