Moja aplikacja rozszerzonej rzeczywistości wymaga widoku kompasu z widoku kamery, a jest wiele przykładów na uzyskanie wskazówki od sensormanager.Kierunek kompasu różni się w zależności od orientacji telefonu.
Jednak znajduję wynikową wartość różną w zależności od orientacji telefonu - krajobraz obrócony w prawo to około 10 stopni różny od krajobrazu obróconego w lewo (różnica między ROTATION_0 i ROTATION_180 jest mniejsza, ale wciąż inna). Ta różnica wystarczy, aby zepsuć efekt AR.
Czy ma to coś wspólnego z kalibracją? (Nie jestem przekonany, że poprawnie wykonuję figurę 8 razy - próbowałem różnych sposobów, które znalazłem na youtube).
Jakieś pomysły, dlaczego istnieje różnica? Czy zawiodłem na materiałach macierzy obrotowej? Mam możliwość ograniczenia aplikacji do pojedynczej orientacji, ale nadal mnie martwi, że odczyt kompasu nadal nie jest bardzo dokładny (choć po przefiltrowaniu jest dość stabilna)
public void onSensorChanged(SensorEvent event) {
if (event.accuracy == SensorManager.SENSOR_STATUS_UNRELIABLE) {
return;
}
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[] rotationMatrixA = mRotationMatrixA;
if (SensorManager.getRotationMatrix(rotationMatrixA, null, mGravity, mGeomagnetic)) {
float[] rotationMatrixB = mRotationMatrixB;
Display display = getWindowManager().getDefaultDisplay();
int deviceRot = display.getRotation();
switch (deviceRot)
{
// portrait - normal
case Surface.ROTATION_0: SensorManager.remapCoordinateSystem(rotationMatrixA,
SensorManager.AXIS_X, SensorManager.AXIS_Z,
rotationMatrixB);
break;
// rotated left (landscape - keys to bottom)
case Surface.ROTATION_90: SensorManager.remapCoordinateSystem(rotationMatrixA,
SensorManager.AXIS_Z, SensorManager.AXIS_MINUS_X,
rotationMatrixB);
break;
// upside down
case Surface.ROTATION_180: SensorManager.remapCoordinateSystem(rotationMatrixA,
SensorManager.AXIS_X, SensorManager.AXIS_Z,
rotationMatrixB);
break;
// rotated right
case Surface.ROTATION_270: SensorManager.remapCoordinateSystem(rotationMatrixA,
SensorManager.AXIS_MINUS_Z, SensorManager.AXIS_X,
rotationMatrixB);
break;
default: break;
}
float[] dv = new float[3];
SensorManager.getOrientation(rotationMatrixB, dv);
// add to smoothing filter
fd.AddLatest((double)dv[0]);
}
mDraw.invalidate();
}
}
Mężczyzna! Szukałem SO przez ponad 2 godziny i jest wiele NIEPRAWIDŁOWYCH odpowiedzi. Twój jest pierwszy, który działa właściwie dla mnie. Dzięki za to. – BoD
Skopiowałem i edytowałem wpis. Nie zdawałem sobie sprawy, że Mush miał mGravity = event.values, powinno to być event.values.clone(). To samo dla mGeomagnetycznego –
'SensorManager.remapCoordinateSystem' jest rozwiązaniem. Dzięki. –