Android getOrientation Azimuth gets polluted when phone is tilted
For complete code see https://github.com/hoananguyen/dsensor
Keep a history and average out, I do not know the correct interpretation of pitch and roll so the following code is for azimuth only.
Class members
private List<float[]> mRotHist = new ArrayList<float[]>();
private int mRotHistIndex;
// Change the value so that the azimuth is stable and fit your requirement
private int mHistoryMaxLength = 40;
float[] mGravity;
float[] mMagnetic;
float[] mRotationMatrix = new float[9];
// the direction of the back camera, only valid if the device is tilted up by
// at 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 is the degree of tilt by the device independent of orientation (portrait or landscape)
// if less than 25 or more than 155 degrees the device is 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 is undefined, so we need to clear the history
clearRotHist();
mFacing = Float.NaN;
}
else
{
setRotHist();
// mFacing = azimuth is 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];
for (float[] value : values)
{
for (int i = 0; i < 9; i++)
{
result[i] += value[i];
}
}
for (int i = 0; i < 9; i++)
{
result[i] = result[i] / values.size();
}
return result;
}
How to make azimuth and degree less shaky in Android
Solution is to apply (LPF) Low Pass Filter. It's smooth and working perfectly now.
I found the solution here: Low Pass Filter
How to get phone heading for augmented reality?
Both your code and the solution you found are wrong if by "phone facing" you means the opposite direction of the device z-coordinate. For augmented reality, you just call
remapCoordinateSystem(inR, AXIS_X, AXIS_Z, outR);
independent of the device orientation. Then the azimuth in the call to getOrientation() gives the direction of the phone facing with respect to Magnetic North.
These 2 calls amount to projection of the device z-coordinate to the XY plane of the world coordinates and then calculate the direction of the resulting vector.
Android Sensor Upright Rotation
From the code above the parameters gravity
and geomagnetic
in mSensorManager.getRotationMatrix(rotationMatrix, I, gravity, geomagnetic);
are probably zero array
and thus your accy
is always zero
Android trouble getting compass direction
You should use TYPE_GRAVITY instead of TYPE_ACCELEROMETER else you should low pass filter TYPE_ACCELEROMETER. Your problem lies mainly in
mGravity = sensorEvent.values;
and
mGeomagnetic = sensorEvent.values;
Since sensorEvent
is a local variable and either mGravity
or mGeomagnetic
points to this value, either of these can be anything by the next time onSensorChanged
is called. It should be
mGravity = sensorEvent.values.clone();
and
mGeomagnetic = sensorEvent.values.clone();
You can look at my answer at Android getOrientation Azimuth gets polluted when phone is tilted
Related Topics
Single Click and Double Click of a Button in Android
Limitation on Texture Size? Android Open Gl Es 2.0
How to Use Broadcast Receiver in Different Applications in Android
Displaying Contact Number and Contact Name in a Custom List View
Is Deprecated Word the Only Difference Between Fill_Parent and Match_Parent
Notifydatasetchanged Not Working on Recyclerview
Android Emulator Not Receiving Push Notifications
How to Find the Android Version Name Programmatically
Android - Margins Specified in Custom Style Not Taking Effect
Room - Livedata Observer Does Not Trigger When Database Is Updated
How to Configure Launcher Activity Programmatically in Android
Read Contents of a Url in Android
Java.Lang.Stackoverflow Error. Suspected Too Many Views
Android 'Debuggable' Default Value