title: SensorManager.getRotationMatrix strange behavior
body: <p>I am implementing a compass, getting readings from <code>SensorManager.getRotationMatrix</code> (see code below).</p>
  
  <p>I have an <code>imageView</code> that rotates using <code>RotateAnimation</code>.
  The compass and animation works fine except for one issue:</p>
  
  <p>Through the <code>SensorManager.getOrientation</code> I get an array of three values - Azimuth, Pitch and Roll. I only use the <code>array[0]</code> which holds the Azimuth Value</p>
  
  <p>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.</p>
  
  <p>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?</p>
  
  <p>Thanks in advance!</p>
  
  <p>Here is most of my code:</p>
  
  <pre><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 &amp;&amp; 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 &lt; 0 &amp;&amp; azimuth &gt; -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 &gt; 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);
  
      }
  
  }
  </code></pre>