0

i have an appli which display x, y, z orientation values calculated with accelerometer and magnetometer. But when i swap from portrait to landscape, i don't get the same X value. I tryed to implement with Rotation Vector, but my device doesn't have rotation vector sensor :s

Here's my code to calculate X, Y, Z value :

@Override
public void onSensorChanged(SensorEvent event) {
    // TODO Auto-generated method stub
    float x, y, z;
    String s1 = "stringX", s2 = "stringY", s3 = "stringZ";
    // Mettre à jour la valeur de l'accéléromètre et du champ magnétique
    if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
        acceleromterVector=event.values;
    } else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
        magneticVector=event.values;
    }
    // Demander au sensorManager la matrice de Rotation (resultMatrix)
    SensorManager.getRotationMatrix(resultMatrix, null, acceleromterVector, magneticVector);
    // Demander au SensorManager le vecteur d'orientation associé (values)
    SensorManager.getOrientation(resultMatrix, values);
    // l'azimuth
    x = (float) Math.toDegrees(values[0]);
    // le pitch
    y = (float) Math.toDegrees(values[1]);
    // le roll
    z = (float) Math.toDegrees(values[2]);


    s1 = "X :" + x;
    s2 = "Y :" + y;           
    s3 = "Z :" + z;

    tvx.setText(s1);
    tvy.setText(s2);
    tvz.setText(s3);

    updateOrientation(x);
}

Thank you guys.

Eydolol
  • 222
  • 1
  • 3
  • 16

1 Answers1

0

The sensor values are always relative to the default orientation, so you need to take account of the rotation away from the default orientation. To do this, use something like the following:

int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
float screen_adjustment = 0;
switch(rotation) {
    case Surface.ROTATION_0:   screen_adjustment =          0;         break;
    case Surface.ROTATION_90:  screen_adjustment =   (float)Math.PI/2; break;
    case Surface.ROTATION_180: screen_adjustment =   (float)Math.PI;   break;
    case Surface.ROTATION_270: screen_adjustment = 3*(float)Math.PI/2; break;
}

to adjust the azimith. For a fully working example, see the code that I posted in my answer here.

Community
  • 1
  • 1
Stochastically
  • 7,616
  • 5
  • 30
  • 58
  • your fully example looks very interesting but a bit hard. If i deal with this screen_adjustment, i have to do azimuth + screen adjustment to get a correct value of azimuth? – Eydolol May 22 '13 at 14:04
  • Indeed, I would expect azimuth + screen_adjustment to give you the right azimuth as long as your device is lying close to flat on a table. When the device is upright, azimuth from `SensorManager.getOrientation` starts misbehaving, which is what my example is about. – Stochastically May 22 '13 at 14:16
  • It's not logical for me Stochastically, i have a basic value of 85 for X, if i add 1.5 (which is PI/2) of adjustment, it won't change anything to my orientation which move from 0 -> 360°. I hope you understood me :x – Eydolol May 22 '13 at 14:29
  • The screen adjustment in my code is in [radians](http://en.wikipedia.org/wiki/Radian). For degrees, alter the 4 cases in my switch statement to 0, 90, 180, 270 instead of 0, pi/2, pi, and 3*pi/2 respectivly. – Stochastically May 22 '13 at 14:39
  • I looked to your code on your link, how can i make an adjustment of roll ? Thank you Stochastically. – Eydolol May 23 '13 at 08:50
  • I'm not sure what you mean. An *adjustment* could mean many things. I suggest you ask a new question and give a lot more details, and if you leave a comment here to point to your new question then I'll be able to find it and try and answer it :-). – Stochastically May 23 '13 at 10:19
  • Here's my new post Stochastically ! http://stackoverflow.com/questions/16717640/maths-trick-to-get-azimuth-value-from-one-unique-origin-point Thanks to you. – Eydolol May 23 '13 at 15:13