math - Android getOrientation Azimuth gets polluted when phone is tilted -


i'm having annoying problem ar view acting compass. when hold phone in portrait (so screen pointing face), call remapcoordinatesystem pitch 0 when holding portrait. azimuth (compass functionality) perfect, tilt phone azimuth gets ruined, if bend forward azimuth increases , if bend backwards decreases.

i use 2 sensors readings, sensor.type_magnetic_field , sensor.type_gravity.

i use lowpassfilter pretty basic, it's implemented alpha constant , used directly on read values sensors.

here code:

float[] rotationmatrix = new float[9]; sensormanager.getrotationmatrix(rotationmatrix, null, gravitymetervalues,     magnetometervalues);  float[] remappedrotationmatrix = new float[9];  sensormanager.remapcoordinatesystem(rotationmatrix, sensormanager.axis_x,     sensormanager.axis_z, remappedrotationmatrix);  float results[] = new float[3]; sensormanager.getorientation(remappedrotationmatrix, results);  float azimuth = (float) (results[0] * 180 / math.pi); if (azimuth < 0) {     azimuth += 360; }  float pitch = (float) (results[1] * 180 / math.pi); float roll = (float) (results[2] * 180 / math.pi); 

as see there no magic here. call piece of code when gravitymetervalues , magnetometervalues ready used.

my question how stop azimuth going crazy when tilt phone?

i checked free app on google play store, compass , hasn't solved problem, hope there solution.

i have 2 solutions in mind:

  1. make ar view work in constrainted pitch angles, right have pitch >= -5 && pitch <= 30. if isn't fullfilled user shown screen asks him/her rotate phone portrait.

  2. somehow use pitch suppress azimuth, seems pretty device-specific solution though, of course i'm open suggestions.

i can add i've been searching couple of hours decent solution , haven't found has given me better solutions 2) here.

thanks in advance!

for complete code see https://github.com/hoananguyen/dsensor
keep history , average out, not know correct interpretation of pitch , roll following code azimuth only.

class members

private list<float[]> mrothist = new arraylist<float[]>(); private int mrothistindex; // change value azimuth stable , fit requirement private int mhistorymaxlength = 40; float[] mgravity; float[] mmagnetic; float[] mrotationmatrix = new float[9]; // direction of camera, valid if device tilted // @ least 25 degrees. private float mfacing = float.nan;  public static final float twenty_five_degree_in_radian = 0.436332313f; public static final float one_fifty_five_degree_in_radian = 2.7052603f; 

onsensorchanged

@override public void onsensorchanged(sensorevent event) {      if (event.sensor.gettype() == sensor.type_gravity)      {          mgravity = event.values.clone();      }      else      {         mmagnetic = event.values.clone();      }       if (mgravity != null && mmagnetic != null)      {           if (sensormanager.getrotationmatrix(mrotationmatrix, null, mgravity, mmagnetic))           {               // inclination degree of tilt device independent of orientation (portrait or landscape)               // if less 25 or more 155 degrees device considered lying flat               float inclination = (float) math.acos(mrotationmatrix[8]);               if (inclination < twenty_five_degree_in_radian                        || inclination > one_fifty_five_degree_in_radian)               {                   // mfacing undefined, need clear history                   clearrothist();                   mfacing = float.nan;               }               else               {                   setrothist();                   // mfacing = azimuth in radian                   mfacing = findfacing();                }           }      } }  private void clearrothist() {     if (debug) {log.d(tag, "clearrothist()");}     mrothist.clear();     mrothistindex = 0; }  private void setrothist() {     if (debug) {log.d(tag, "setrothist()");}     float[] hist = mrotationmatrix.clone();     if (mrothist.size() == mhistorymaxlength)     {         mrothist.remove(mrothistindex);     }        mrothist.add(mrothistindex++, hist);     mrothistindex %= mhistorymaxlength; }  private float findfacing() {     if (debug) {log.d(tag, "findfacing()");}     float[] averagerothist = average(mrothist);     return (float) math.atan2(-averagerothist[2], -averagerothist[5]); }  public float[] average(list<float[]> values) {     float[] result = new float[9];     (float[] value : values)     {         (int = 0; < 9; i++)         {             result[i] += value[i];         }     }      (int = 0; < 9; i++)     {         result[i] = result[i] / values.size();     }      return result; } 

Comments

Popular posts from this blog

c++ - Creating new partition disk winapi -

Android Prevent Bluetooth Pairing Dialog -

VBA function to include CDATA -