0

I am doing a project about video stabilization. Now, I am trying to get the accurate Orientation first. I already read about the sensors event. I know that I can't only use the SensorManager.getOrientation() to get the accurate orientation. Also, I know using accelerometer and integrate of gyroscope can get the correct pitch and roll.

Now,I want to know how can I get the correct yaw too?

Thank you for your time!

wwwgoodhh
  • 1
  • 1

1 Answers1

0

With this code you get a accurate orientation by using the accelerometer and the magnetic field sensor. (What is the alternative to android orientation sensor?)

public class OrientationTestActivity extends Activity implements SensorEventListener
{
    private SensorManager mSensorManager;
    private Sensor mAccelerometer;
    private Sensor mMagnetometer;

    private float[] mLastAccelerometer = new float[3];
    private float[] mLastMagnetometer = new float[3];
    private boolean mLastAccelerometerSet = false;
    private boolean mLastMagnetometerSet = false;

    private float[] mR = new float[9];
    private float[] mOrientation = new float[3];

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
        mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        mMagnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
    }

    protected void onResume() {
        super.onResume();
        mLastAccelerometerSet = false;
        mLastMagnetometerSet = false;
        mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
        mSensorManager.registerListener(this, mMagnetometer, SensorManager.SENSOR_DELAY_NORMAL);
    }

    protected void onPause() {
        super.onPause();
        mSensorManager.unregisterListener(this);
    }

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

    public void onSensorChanged(SensorEvent event) {
        if (event.sensor == mAccelerometer) {
            System.arraycopy(event.values, 0, mLastAccelerometer, 0, event.values.length);
            mLastAccelerometerSet = true;
        } else if (event.sensor == mMagnetometer) {
            System.arraycopy(event.values, 0, mLastMagnetometer, 0, event.values.length);
            mLastMagnetometerSet = true;
        }
        if (mLastAccelerometerSet && mLastMagnetometerSet) {
            SensorManager.getRotationMatrix(mR, null, mLastAccelerometer, mLastMagnetometer);
            SensorManager.getOrientation(mR, mOrientation);
            Log.i("OrientationTestActivity", String.format("Orientation: %f, %f, %f",
                                                           mOrientation[0], mOrientation[1], mOrientation[2]));
        }
    }
}

With this you get mOrientation which contains azimuth, pitch and roll.

As explained here https://math.stackexchange.com/questions/296799/azimuth-vs-yaw yaw is the change in azimuth.

Community
  • 1
  • 1
Someone
  • 560
  • 9
  • 21
  • Thank you for your help! I found some post talking about the problem of using the accelerometer and the magnetometer. https://stackoverflow.com/questions/24242972/how-can-i-get-device-tilt He mentions that "As long as you use the accelerometer and the magnetometer but not the gyroscopes, your method will fail when the device goes through rapid acceleration / deceleration." Is that means sudden movement will make the sensor inaccurate? I am so confusing with these sensor T.T Thank you for your time again! – wwwgoodhh Apr 09 '16 at 09:20
  • Also, I want to know why people talking abut the accelerometer and gyroscope will the complementary filter. What's the pros and cons of the accelerometer and gyroscope verse the accelerometer and the magnetometer. – wwwgoodhh Apr 09 '16 at 09:27
  • Thats interesting, for my cases it worked just fine. But i didn't need rapid acceleration/decelleration. For what do you need the rapid stuff? I would like to take a look at it later. – Someone Apr 09 '16 at 09:31
  • Maybe don't need the rapid LoL. The code works. You save my day. Thanks a lot. BTW, what is the unit of azimuth, pitch and roll? I found that the range is around -3 to +3. Can I turn it to degrees? Moreover, it is great when I use the phone vertical. But if I take picture with the phone horizontally. The roll will become pitch, the azimuth become roll and the pitch become yaw. In fact, what I misunderstand the word "orientation". What I really want is how my phone rotate with the angles LOL. Or it is the same>.< Thank you for your patience. You really help me a lot! – wwwgoodhh Apr 09 '16 at 16:57
  • You should take a look at the android documentation about the sensorManager: https://developer.android.com/reference/android/hardware/SensorManager.html#getOrientation(float[],%20float[]) . As you can see: "All three angles above are in radians and positive in the counter-clockwise direction. Range of output is: azimuth from -π to π, pitch from -π/2 to π/2 and roll from -π to π" so you can calculate the degrees pretty easy. I don't really understand what you mean with how the phone rotates with the angles, could you elaborate? – Someone Apr 09 '16 at 17:12
  • OIC~ Thank you for the information. You are the best! Forget the above question. Just my stupid >. – wwwgoodhh Apr 09 '16 at 17:45