SensorManager.getRotationMatrix strange behavior

北慕城南 提交于 2019-12-11 08:16:41

问题


I am implementing a compass, getting readings from SensorManager.getRotationMatrix (see code below).

I have an imageView that rotates using RotateAnimation. The compass and animation works fine except for one issue:

Through the SensorManager.getOrientation I get an array of three values - Azimuth, Pitch and Roll. I only use the array[0] which holds the Azimuth Value

If I hold the phone flat and turn it around on the Z axis (azimuth) - it works perfectly. But, the minute I tilt the phone on the X or Y axis (Pitch or Roll) - the compass goes off the correct measurement. In other words - when tilting Pitch or Roll - it seriously effects the readings from the Azimuth.

So, to sum up my question - How would I block interference from the Pitch/Roll readings (although I do NOT address them in the code at all) - Or, am I doing something wrong?

Thanks in advance!

Here is most of my code:

public class MainActivity extends Activity implements SensorEventListener {

    private SensorManager mSensorManager;
    private Sensor accelerometer;
    private Sensor magnetometer;
    private float[] mGravity;
    private float[] mGeomagnetic;
    float avgRead[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };

    private TextView tvCurrAzim;
    private ImageView ivCompass;
    private float currentDegree = 0f;
    private float azimuth;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        tvCurrAzim = (TextView) findViewById(R.id.tvaz);

        ivCompass = (ImageView) findViewById(R.id.imageView1);

        mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        accelerometer = mSensorManager
                .getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        magnetometer = mSensorManager
                .getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);

    }

    // Compass Sensor Methods:

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onSensorChanged(SensorEvent event) {

        // TODO Auto-generated method stub
        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);


                //Creating a running smooth average of readings
                avgRead[0] = avgRead[1];
                avgRead[1] = avgRead[2];
                avgRead[2] = avgRead[3];
                avgRead[3] = avgRead[4];
                avgRead[4] = avgRead[5];
                avgRead[5] = avgRead[6];
                avgRead[6] = avgRead[7];
                avgRead[7] = avgRead[8];
                avgRead[8] = orientation[0]; // orientation contains: azimuth, pitch and roll
                azimuth = (avgRead[0] + avgRead[1] + avgRead[2] + avgRead[3]
                        + avgRead[4] + avgRead[5] + avgRead[6] + avgRead[7] + avgRead[8]) / 9;


                azimuth = Math.round(azimuth * 360 / (2 * 3.14159f));
                if (azimuth < 0 && azimuth > -180)
                    azimuth += 360;
            }

        }

        tvCurrAzim.setText(Float.toString(azimuth));

        // get the angle around the z-axis rotated

        // create a rotation animation (reverse turn degree degrees)
        if (-azimuth - currentDegree > 180)
            azimuth = azimuth - 360;

        RotateAnimation ra = new RotateAnimation(currentDegree, -azimuth,
                Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
                0.5f);

        // how long the animation will take place
        ra.setDuration(50);

        // set the animation after the end of the reservation status
        ra.setFillAfter(true);

        // Start the animation
        ivCompass.startAnimation(ra);
        currentDegree = -azimuth;

    }

    @Override
    protected void onPause() {

        super.onPause();
        mSensorManager.unregisterListener(this);

    }

    @Override
    protected void onResume() {
        super.onResume();
        mSensorManager.registerListener(this, accelerometer,
                SensorManager.SENSOR_DELAY_UI);
        mSensorManager.registerListener(this, magnetometer,
                SensorManager.SENSOR_DELAY_UI);

    }

}

来源:https://stackoverflow.com/questions/22792048/sensormanager-getrotationmatrix-strange-behavior

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!