Chciałbym mieć możliwość pobrania obrotu urządzenia w okół co najmniej dwóch osi, tzn. roll i pitch.
Pisząc prosty kod:

    @Override
    public void onSensorChanged(SensorEvent event) {
        switch (event.sensor.getType()) {
            case Sensor.TYPE_ACCELEROMETER:
                System.arraycopy(event.values, 0, valuesAccel, 0, 3);
                break;

            case Sensor.TYPE_MAGNETIC_FIELD:
                System.arraycopy(event.values, 0, valuesMagnet, 0, 3);
                break;
        }

        if (SensorManager.getRotationMatrix(rotationMatrixTemp, null, valuesAccel, valuesMagnet)) {
            SensorManager.getOrientation(rotationMatrixTemp, valuesOrientation);

            for (int i = 0; i < valuesOrientation.length; i++) {
                valuesOrientation[i] /= Math.PI;
                valuesOrientation[i] *= 100;
                valuesOrientation[i] = (int)valuesOrientation[i];
                valuesOrientation[i] /= 100;
            }

            updateOrientationBuffer(valuesOrientation);

            quadcopter.onEvent(new Event(Event.Codes.ORIENTATION_CHANGED, calculateSmoothedOrientation()));
        }
        else {
            Log.d("Quadcopter-SM", "Matrix rotate error");
        }
    }

Otrzymuję w valuesOrientation[] trzy wartości: yaw, pitch, roll.
yaw mnie na razie w ogóle nie interesuje.
roll otrzymuję z przedziałem od -Math.PI, przez 0, do Math.PI, czyli idealnie jak chce. 0 oznacza, że kamera telefonu jest skierowana w ziemię. Obrót telefonu wzdłuż niego samego powoduje oczekiwaną zmianę tej wartości, którą później zamieniam sobie na przedział od -1 do 1.

Problem jest natomiast z obrotem w osi pitch. Przyjmuje ona wartości od -Math.PI/2 do Math.PI/2. Podczas obrotu telefonu wzdłóż tej osi wykonywana jest następująca sekwencja:
0 (kamera do ziemi) --> PI/2 --> 0 (kamera patrzy w niebo) --> -PI/2 --> 0 (kamera znów do ziemi)

Czyli de facto telefon dla dwóch obrotów może przyporządkować 1 wartość. W osi roll wartość rośnie cały czas, gdy zaczynamy z kamerą patrzącą w ziemię (0), później patrzymy na ścianę - osiąga 0.5 pełnej wartości, a następnie jak patrzymy w niebo mamy pełną wartość, tj. 1.
A co do pitch, pierw patrzymy w ziemię (0), później wartość rośnie do momentu gdy patrzymy na ścianę (0.5), a gdy zaczynamy przechylać dalej w kierunku nieba, wartość spada z powrotem do 0.

Niestety, bardzo słabo się znam na tej części matematyki, trygonometrii itd. W Androidzie widzę jeszcze jakieś macierze obrotu, terminologia całkowicie mi obca.

Jest też dodatkowy warunek - docelowe urządzenie nie posiada żyroskopu (tylko te sensory z których tu korzystam).

Byłbym bardzo wdzięczny, gdyby był ktoś w stanie pomóc mi rozwiązać ten problem