It's been like 2 weeks trying different ways to calculate the azimuth of the phone, but I've found basically two problems:
My problems
- A 360º turn is not always 360º. If I do my turn quickly, I get done my 360º before the end of the turn, if I go slowly, I get done my 360º after the end of the turn.
- The azimuth gets moved randomly when I put it laying on the table. Or even holding in the same position, for any tick, I get a +- 3 degrees, so if I stay with 200º and I wait, I could be 197º. And then if I keep waiting, it could reach 194º, but I'm staying.
What am I looking for?
For the problem 1.-, I'm looking for a precise movement on the X axis (azimuth). A good example can be found in the HelloPanoramaGL project sample. It moves smoothly and you can get the sensation you're moving a real panorama.
For the problem 2.-, This project based in a Panorama for iOS does both 1.- and 2.-. When you do a turn, it gets the same position.
What I've tried
Well, after 2 weeks I dare to say I've done everything I found on Internet, for example:
- Trying to set the
Sensor.TYPE_ORIENTATION
which is deprecated, but it's the one that has provided me best results. - Trying a combination of
Sensor.TYPE_ACCELEROMETER
andSensor.TYPE_MAGNETIC_FIELD
. Also adding a Low Pass Filter to the Sensors. - Using the rest of the sensors like
Sensor.TYPE_ROTATION_VECTOR
to wait for any hope to make it work.
But I got my problems not solved.
This is my current code now:
Declaring all sensors:
private SensorManager sensorManager;
private Sensor magnetic_field;
private Sensor accelerometer;
private Sensor orientation;
initializing onCreate():
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
orientation = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
magnetic_field = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
registering the listener onResume():
sensorManager.registerListener(this, magnetic_field, SensorManager.SENSOR_DELAY_FASTEST);
sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_FASTEST);
sensorManager.registerListener(this, orientation, SensorManager.SENSOR_DELAY_FASTEST);
// tried with SENSOR_DELAY_FASTEST, SENSOR_DELAY_UI and SENSOR_DELAY_GAME
and getting the results:
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ORIENTATION) {
float azimuth1 = event.values[0];
return;
}
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
mGravity = event.values;
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
mGeomagnetic = event.values;
if (mGravity != null && mGeomagnetic != null) {
float R_[] = new float[9];
float I_[] = new float[9];
boolean success = SensorManager.getRotationMatrix(R_, I_, mGravity, mGeomagnetic);
if (success) {
float orientation[] = new float[3];
SensorManager.getOrientation(R_, orientation);
azimut = orientation[0]; // orientation contains: azimut, pitch and roll
}
}
}
If you could help me with that it would be great.
Thank you very much.
Regards.
Rafael.