3

I'm trying to make a compass app for a project I'm working on that will work while going over rough terrain. I've used the standard TYPE_ACCELEROMETER and TYPE_MAGNETIC_FIELD sensors and it seems to give reasonably accurate readings. However, when I tilt the phone around its y and z axes, the the Heading reading changes even though the phone is pointing in the same direction (constant z axes).

Does anyone know how to compensate for this? Example code would be appreciated.

Here is the code I'm currently using:

private void updateDirection() {
  float[] R = new float[16];
      float[] orientationValues = new float[3];

      if(SensorManager.getRotationMatrix (R, null, accelerometerValues, magneticValues)){

        SensorManager.getOrientation (R, orientationValues);

        orientationValues[0] = (float)Math.toDegrees (orientationValues[0]);
        orientationValues[1] = (float)Math.toDegrees (orientationValues[1]);
        orientationValues[2] = (float)Math.toDegrees (orientationValues[2]);

        if(orientationValues[0] < 0){
          orientationValues[0] = 360 + orientationValues[0];
        }

        final int trueNorthHeading = NavigationUtils.getTrueNorthBearing(currentLocation, orientationValues[0]);
        if(trueNorthHeading == currentHeading) {
      return;
    }

        int accuracy = 3;
        if(NavigationUtils.isSignificantHeadingChange(currentHeading, trueNorthHeading, accuracy, SIGNIFICANT_CHANGE_LIMIT)){

          int headingChangeDegrees = NavigationUtils.getStearageDegree(currentHeading, trueNorthHeading);
      currentHeading = trueNorthHeading;    

      navigationManager.headingUpdate(trueNorthHeading, Math.round(orientationValues[0]), headingChangeDegrees);

          Log.d("COMPASS", "North: values[0]: " + (int)orientationValues[0]);
        }
      }
}

Thanks for your help,

Adam

Fraser
  • 74,704
  • 20
  • 238
  • 215
Adam Davies
  • 2,742
  • 4
  • 33
  • 52
  • Do you mean that it is changing slightly while being held firm in place by some sort of a device while you are rotating it? Or is it much more noticeble than slight drifts? – Jay Snayder Apr 30 '13 at 18:21
  • When rotating around the y axes the values returned will very from 160* to 200* even though the phone is pointing in the same direction. Defo a bigger deal than a slight drift. – Adam Davies Apr 30 '13 at 18:32
  • Is the phone in lay flat or vertical? – Hoan Nguyen Apr 30 '13 at 19:59

2 Answers2

2

Use TYPE_GRAVITY instead or if not available filter your accelerometer using low pass filter or Kalman filter. TYPE_GRAVITY improve the accuracy over low pass filter up to 10 degrees.

Hoan Nguyen
  • 18,033
  • 3
  • 50
  • 54
  • Didn't work. In fact it made it even worse. You'd have thought the clever guys at Google would have done a simple API for doing this sort of stuff considering how much effort they are putting into augmented reality. – Adam Davies Apr 30 '13 at 20:50
  • I do not quite understand what exactly the question in your post. Is the error concerning the azimuth? And what is the position of your phone? – Hoan Nguyen Apr 30 '13 at 20:52
  • Position of the phone is flat on a table away from all magnetic interference. Say its orientation[0] is 150* when I rotate it around the the y axis, say by about 60* left or right the reading for orientation[0] changes by as much as 40* even though there has been no rotation around the z axis. – Adam Davies Apr 30 '13 at 21:07
  • When you say rotate about the y axis, you mean the phone is lift up with y axis unchanged? – Hoan Nguyen Apr 30 '13 at 21:11
  • Yes. So lay the phone flat with the top away from you (like you were reading a book) and tilt it from side to side. – Adam Davies Apr 30 '13 at 21:23
  • The value change because of the accelerometer value pass into getRotationMatrix is not approximately gravity when you rotate. You need to filter the accelerometer using low pass filter or Kalman filter. Instead of using accelerometer value, use TYPE_GRAVITY, it is accelerometer with filtered.. – Hoan Nguyen Apr 30 '13 at 21:41
  • Some improvement. Error down to 10*, guess I'll have to live with that. Thanks Hoan Nguyen – Adam Davies Apr 30 '13 at 22:59
0

Tried this Android getOrientation() method returns bad results and it seemed to work.

Applied the filter to both the orientation results as suggested, and also the raw accelerometer array.

Community
  • 1
  • 1
Adam Davies
  • 2,742
  • 4
  • 33
  • 52