I am trying to take the pitch and roll of a device when in portrait orientation. With the axes looking like this, it would be about the x and z axis respectively. Right now I'm using the SensorManager API to get the pitch, roll, and yaw of the device sitting flat, as is default.
When I try and translate the rotational values from the flat device to the vertical orientation I experience what other SO users have called gimbal lock, which is a problem inherent in the way Euler angles work. Problem is I've tried implementing a rotational matrix, as other users have to solve a similar problem, but even still I'm having the same gimbal lock problem. I've included my onSensorChanged method and hopefully someone out there could help find out what's going wrong.
public void onSensorChanged(SensorEvent se) {
float degPitch = 0;
float degRoll = 0;
float degYaw = 0;
float radPitch = 0;
float radRoll = 0;
float radYaw = 0;
if (se.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
mAccelerometerResult = se.values;
Log.d("onSensorChanged", "Accelerometer: " + mAccelerometerResult.length);
}
if (se.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
mMagneticFieldResult = se.values;
Log.d("onSensorChanged", "Magnetic Field: " + mMagneticFieldResult.length);
}
if (mAccelerometerResult != null && mMagneticFieldResult != null) {
float[] rotation = new float[9];
float[] inclination = new float[9];
boolean rotationMatrixCheck = mSensorManager.getRotationMatrix(rotation, inclination, mAccelerometerResult, mMagneticFieldResult);
if (rotationMatrixCheck) {
float[] orientation = new float[3];
mSensorManager.getOrientation(rotation, orientation);
radYaw = orientation[0]; //Yaw = Z axis
radPitch = orientation[1]; //Pitch = X axis
radRoll = orientation[2]; //Roll = Y axis
degYaw = round((float) Math.toDegrees(radYaw), 2);
degPitch = round((float)Math.toDegrees(radPitch), 2);
degRoll = round((float)Math.toDegrees(radRoll), 2);
if ((counter % 10) == 0) {
//mYawTextView.setText(degYaw + "°");
mPitchTextView.setText(degPitch + "°");
mRollTextView.setText(degRoll + "°");
counter = 0;
} else {
counter++;
}
}
}
Further, I'm not even sure that I understand what rotational value I'm looking for if I can get good rotation about the portrait axes. If I want the roll of the device in portrait (about z axis from my original image), would that still be the roll of the device laying flat(about y from the flat axes image)?
Any insight that can be shared here would be appreciated.