Coming from a iOS background, I am starting to see some of the more interesting parts of Android like device support for sensors and even OpenGL calls.
I have been using the Sensor.TYPE_ROTATION_VECTOR in Android to rotate a object in 3D space based on the device. Works great on a Nexus 7 (2012) with no issues. However, any other device (Nexus 5, HTC sensation, Terga Note) it jumps around like its on speed.
This was the same result I got when I just used the Sensor.TYPE_ACCELEROMETER
Does anyone have any advice, code or anything about getting a smooth (on majority of devices) sensor value.
Override
public void onSensorChanged(SensorEvent event) {
int type = event.sensor.getType();
//Log.i("TAG", "Sensor " + type);
// It is good practice to check that we received the proper sensor event
if (event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) {
//lowPass( event.values.clone(), MagneticFieldValues_last );
// Convert the rotation-vector to a 4x4 matrix.
SensorManager.getRotationMatrixFromVector(mRotationMatrix,
event.values);
SensorManager.remapCoordinateSystem(mRotationMatrix, SensorManager.AXIS_Y, SensorManager.AXIS_MINUS_X, mRotationMatrix);
SensorManager.getOrientation(mRotationMatrix, orientationVals);
Matrix.multiplyMV(orientationVector, 0, mRotationMatrix, 0, sZVector, 0);
orientation = (float) (-Math.atan2(orientationVector[0], orientationVector[1]) * RADIANS_TO_DEGREES);
Matrix.invertM(mRotationMatrix_inv, 0, mRotationMatrix, 0);
Matrix.multiplyMV(azimuthVector, 0, mRotationMatrix_inv, 0, sZVector, 0);
azimuth = (float) (180 + Math.atan2(azimuthVector[0], azimuthVector[1]) * RADIANS_TO_DEGREES);
// Optionally convert the result from radians to degrees
orientationVals[0] = (float) Math.toDegrees(orientationVals[0]);
orientationVals[1] = (float) Math.toDegrees(orientationVals[1]);
orientationVals[2] = (float) Math.toDegrees(orientationVals[2]);
}
if (type == Sensor.TYPE_MAGNETIC_FIELD) {
pitch = event.values[2] * axisSwapper;
}
}
I was using a low pass filter however it was not required on the Nexus 7 and did not seem to work well.
// protected float[] lowPass( float[] input, float[] output ) {
// if ( output == null ) return input;
//
// for ( int i=0; i<input.length; i++ ) {
// output[i] = output[i] + ALPHA * (input[i] - output[i]);
// }
// return output;
// }
I found moving to Google Cardboard for head tracking made things just work! really easy to implement. Copied