How to Measure the Tilt of the Phone in Xy Plane Using Accelerometer in Android

How to measure the tilt of the phone in XY plane using accelerometer in Android

Essentially, there is 2 cases here: the device is laying flat and not flat. Flat here means the angle between the surface of the device screen and the world xy plane (I call it the inclination) is less than 25 degree or larger than 155 degree. Think of the phone lying flat or tilt up just a little bit from a table.

First you need to normalize the accelerometer vector.

That is if g is the vector returns by the accelerometer sensor event values. In code

float[] g = new float[3]; 
g = event.values.clone();

double norm_Of_g = Math.sqrt(g[0] * g[0] + g[1] * g[1] + g[2] * g[2]);

// Normalize the accelerometer vector
g[0] = g[0] / norm_Of_g
g[1] = g[1] / norm_Of_g
g[2] = g[2] / norm_Of_g

Then the inclination can be calculated as

int inclination = (int) Math.round(Math.toDegrees(Math.acos(g[2])));

Thus

if (inclination < 25 || inclination > 155)
{
// device is flat
}
else
{
// device is not flat
}

For the case of laying flat, you have to use a compass to see how much the device is rotating from the starting position.

For the case of not flat, the rotation (tilt) is calculated as follow

int rotation = (int) Math.round(Math.toDegrees(Math.atan2(g[0], g[1])));

Now rotation = 0 means the device is in normal position. That is portrait without any tilt for most phone and probably landscape for tablet. So if you hold a phone as in your picture above and start rotating, the rotation will change and when the phone is in landscape the rotation will be 90 or -90 depends on the direction of rotation.

How to accurately detect when phone has been tilted back and forth in Android

You cannot use the z-value to detect the titling since the accelerometer value is given in term of device coordinate. You should use the change of inclinations instead (see How to measure the tilt of the phone in XY plane using accelerometer in Android)

How do I get the angle/degree of the phone with sensor/s?

I don't know if i understand your question ,but i think you want your app to calculate the angel of tilt only if the phone is in portrait ,first you need to take the value of mSensorEvent.values[0] and in this case if the phone in stand state in will return 0 , tilt to right will be negative values from 1 to 9 ,and the left positive .

then you have to do all this just in case of mSensorEvent.values[1] values between 9 and 7 for example (9 is perfect stand) . to ensure the the device in portrait position .

and if you need the degree angle values you can multiply the float value of mSensorEvent.values by 10.

i hope this help you

UPDATE***

you can try this :

    private boolean isLandscape;

@Override
public void onSensorChanged(SensorEvent mSensorEvent) {
float X_Axis = mSensorEvent.values[0];
float Y_Axis = mSensorEvent.values[1];

if((X_Axis <= 6 && X_Axis >= -6) && Y_Axis > 5){
isLandscape = false;
}
else if(X_Axis >= 6 || X_Axis <= -6){
isLandscape = true;
}

}

Head tracking angle using accelerometer

Measure just gravity orientation. there are two approaches I know of

1.use smooth (FIR) filter to filter out quick changes

  • for example remember last N measurements
  • and output their average
  • this is easy and continuous but not precise

2.check for acceleration vector size

  • and ignore all measurements where it does not match the gravity

    a=sqrt( ax^2 + ay^2 + az^2 )
    if (fabs(a*scale-9.81)>0.1) ignore...
  • where a is size of acceleration vector

  • (ax,ay,az) is measured acceleration vector (local to your device)
  • scale is scale of your accelerometer to convert a value to actual units like [m/s^2] or [N/kg]
  • device accelerometers are usualy already in [g] so the scale is 9.81
  • 9.81 is the gravity in the area of measurement
  • 0.1 is accuracy of acceleration size check (change it to your needs)
  • this approach is a bit slower
  • and not continuous because during acceleration will not measure the output (can use last valid output)
  • but it is much more precise

Now the formulas should work, from what I read your axises are

  • x - up,down
  • y - left,right
  • z - forward,backward
  • do not know the orientation so just negate output angle if i hit it the wrong way

axises

  • green is the gravity
  • blue is measured values
  • red is your pitch angle (ang)

    ang=asin(az*scale/9.81)
  • do not forget to avoid using asin with parameter out of range < -1.0 , +1.0 > !!!



Related Topics



Leave a reply



Submit