9

Currently, I'm trying to rotate 3D Cube using orientation sensor values, using getRotation() method. Some unexpected behaviors are observed when the android device is rotated above some bounds. For instance, if I make the device 'stand up', the value of the 'roll' just becomes crazy.

Also I'm experiencing the phenomenon similar to so-called gimbal-lock. The only difference is I'm experiencing the very problem even before applying the sensor values to the 3D rotation. When I try to change the 'pitch' value by rotating the device around only 'pitch' axis, the 'yaw' value also changes according to the rotation of the pitch. It seems completely unreasonable to me.

Could somebody help me?? I'm stuck in this problem for a month.

Kyoung-Rok Jang
  • 327
  • 1
  • 4
  • 9

4 Answers4

18

This is a common problem with yaw, pitch and roll. You cannot get rid of it as long as you are using yaw, pitch and roll (Euler angles). This video explains why.

I use rotation matrices instead of Euler angles in my motion sensing application. For an introduction to rotation matrices I recommend:

Direction Cosine Matrix IMU: Theory

Rotation matrices work like a charm.

Quaternions are also very popular and said to be the most stable.

[This answer was copied from here.]

Community
  • 1
  • 1
Ali
  • 56,466
  • 29
  • 168
  • 265
  • Thank you for your answer :) Your solution sounds worth trying. Then can I use the rotation matrix gained from android API directly? Regretfully I have no knowledge how 3D works, so I can't figure out whether some manipulation is needed on 'pure' rotation matrix or not. – Kyoung-Rok Jang Apr 09 '11 at 04:26
  • 1
    It depends on how you do your rotation. I have never used Android. If you use OpenGL for rotation (and I guess you do), you may have to add a couple of zeros and one, see from 41:58 in the youtube video. But apart from that, the 'pure' rotation matrix is enough. Good luck! – Ali Apr 09 '11 at 11:14
  • Can you give an example of how you use rotation matrix without euler angles? I can't seem to figure it out ^^ – Adam Honoré May 18 '12 at 14:42
  • @AdamHonoré I am not sure I understand. Please give me a specific question then I can tell you how to do that with a rotation matrix. – Ali May 18 '12 at 16:02
  • @Ali - Can you help me, How to use Quaternions in calculation of yaw, pitch and roll to achieve more stable reading! Thanks in advance! Please! – sam Sep 07 '12 at 13:59
  • @Ali Dear sir, [link](http://stackoverflow.com/questions/12322797/use-quaternions-to-compute-yaw-pitch-and-roll-from-iphone) This link will guide you to my new question! Please answer it. Thank you! – sam Sep 07 '12 at 17:34
0

Using quaternions to compute YPR won't do much to solve any problem. The problem of gimbal lock (which near pitch of +/-90 can drive yaw and roll -- actually yaw-roll at the north pole -- to go crazy under slight changes/noise in the underlying quaternion).

However, if you use Yaw Pitch and Roll values to perform a rotation of a 3D object shouldn't exhibit any odd behavior near the gimbal lock position. It's just that an amibguity in yaw and roll arise and large variations in yaw and roll do not imply the actual orientation is going crazy -- just that the orientation is insensitive to large changes in yaw-roll near pitch of 90.

BUT, also note that phones and browsers for HTML5 do not properly implement yaw, pitch and roll per conventions for Android. Here is a good blog for reference:

http://www.sensorplatforms.com/understanding-orientation-conventions-mobile-platforms/

nak
  • 97
  • 2
  • to avoid gimbal lock, don't use axis angle math. euler rotations are just fine as long as you avoid axis angle implementations. – Tcll Jan 23 '17 at 16:15
0

Here is a basic example, this will return the vector of gravity. Note that you can change the sensor type and the speed of sampling, more details here

SensorManager sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

sensorManager.registerListener(new SensorEventListener() {
    @Override
    public void onSensorChanged(SensorEvent event) {

        float x = event.values[0];
        float y = event.values[1];
        float z = event.values[2];
        double total = Math.sqrt(x * x + y * y + z * z);

    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
    }

}, sensor, SensorManager.SENSOR_DELAY_FASTEST);
Kirill Kulakov
  • 10,035
  • 9
  • 50
  • 67
0

Well if you running on the phone.

Quaternions are the best, and you should use it

For rotation matrix and euler angle, you can easily came across such term called gimbal lock. It happens frequently with user violent action.

Gimbal lock is the loss of one degree of freedom in a three-dimensional, three-gimbal mechanism that occurs when the axes of two of the three gimbals are driven into a parallel configuration, "locking" the system into rotation in a degenerate two-dimensional space. enter image description here

Rotation matrix and euler angle are good for slow moving robot action.

For details on quaternions concatnations and convert point to new system, you can refer to wiki link

https://en.wikipedia.org/wiki/Quaternion

Dr Yuan Shenghai
  • 1,849
  • 1
  • 6
  • 19