Reputation: 374
Possible duplicate : Android getOrientation Azimuth gets polluted when phone is tilted
I am new to android development and I try to get the user facing.
After searching on the web I am pretty sure I need to use remapCoordinateSystem
, android documentation say it is good to use for an augmented reality app.
I try to use some existing code to be sure that is a good way.
(Finally I want to create an augmented reality application)
The following code should return the user facing in degree :
Sensor sensor = event.sensor;
if (sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
gravity = event.values.clone();
}else if (sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
geomagnetic = event.values.clone();
}
if (gravity != null && geomagnetic != null){
_rM = SensorManager.getRotationMatrix (R, null, gravity, geomagnetic);
if(_rM){
int mScreenRotation = activity.getWindowManager().getDefaultDisplay().getRotation(); // get user orientation mode
switch (mScreenRotation) { // Handle device rotation (landscape, portrait)
case Surface.ROTATION_0:
axisX = SensorManager.AXIS_X;
axisY = SensorManager.AXIS_Y;
break;
case Surface.ROTATION_90:
axisX = SensorManager.AXIS_Y;
axisY = SensorManager.AXIS_MINUS_X;
break;
case Surface.ROTATION_180: // not handled by my phone so I can't test
axisX = SensorManager.AXIS_MINUS_X;
axisY = SensorManager.AXIS_MINUS_Y;
break;
case Surface.ROTATION_270:
axisX = SensorManager.AXIS_MINUS_Y;
axisY = SensorManager.AXIS_X;
break;
default:
break;
}
SensorManager.remapCoordinateSystem (R, axisX, axisY, outR);
SensorManager.getOrientation (outR, gO);
}
}
userFacing = (float) Math.toDegrees(gO[0]); // Radian to degree
if(userFacing<0) { userFacing+=360; } // -180;180 to 0;360
return userFacing;
Actually I am able to get an accurate compass when the phone is facing down, but when I try to move the phone (as a user would do), the results are very inaccurate : when i tilt the device, direction can move of 40°...
I saw this link : https://stackoverflow.com/questions/17979238/android-getorientation-azimuth-gets-polluted-when-phone-is-tilted
But if i stay tilted, the results are inaccurate again (it's an average, so it's normal!) And i need the compass working anytime...
I think I will use TYPE_GYROSCOPE
, but not all devices have a gyroscope nowadays so i need another solution for all the other devices !
Hope you can understand my problem, and sorry for my bad english! (I'm French)
Ok so after adapting the application on iOS, I decided to check if the android methods were as good as I though. A month ago, I posted a solution and it was really wrong. I made a huge mistake on remapCoordinateSystem
: I used AXIS_X
and AXIS_Y
to get my matrice and I tried to correct my values with different values. As @HoanNguyen suggested, we just have to use AXIS_X
and AXIS_Z
and android handle the rest.
So here is the final code. Lot more shorter and easier:
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
gravity = lowPass(event.values.clone(), gravity);
}
else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
geomagnetic = lowPass(event.values.clone(), geomagnetic);
}
if (geomagnetic != null && gravity != null) {
if (SensorManager.getRotationMatrix (R_in, null, gravity, geomagnetic)) {
SensorManager.remapCoordinateSystem (R_in, SensorManager.AXIS_X, SensorManager.AXIS_Z, R_out);
SensorManager.getOrientation (R_out, gO);
}
}
And to get magnetic north, you just have to use gO[0]
like heading = gO[0];
(Caution, the returned values are in radians)
Hope it could here someone!
Upvotes: 2
Views: 2791
Reputation: 18151
Both your code and the solution you found are wrong if by "phone facing" you means the opposite direction of the device z-coordinate. For augmented reality, you just call
remapCoordinateSystem(inR, AXIS_X, AXIS_Z, outR);
independent of the device orientation. Then the azimuth in the call to getOrientation() gives the direction of the phone facing with respect to Magnetic North.
These 2 calls amount to projection of the device z-coordinate to the XY plane of the world coordinates and then calculate the direction of the resulting vector.
Upvotes: 3