Autore Topic: Rotazioni con cambio sistema di riferimento  (Letto 2074 volte)

Offline bpaolo

  • Nuovo arrivato
  • *
  • Post: 4
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    S3
  • Sistema operativo:
    mac os
Rotazioni con cambio sistema di riferimento
« il: 17 Febbraio 2015, 14:38:05 CET »
0
Salve a tutti,
sto implementando una app che visualizza gli angoli di inclinazione del telefono.
Pur essendo deprecato l'uso del SENSOR_ORIENTATION spiegherò il problema anche perché il problema si presenta anche con TYPE_ACCELEROMETER + TYPE_MAGNETIC_FIELD.
Spiego il caso più evidente: partendo dal telefono appoggiato sul tavolo con lo schermo verso l'alto metto il telefono verticale e la rotazione dell'asse x risulta 90°, se inclino il telefono a sinistra mi aspetterei di mantenere costante l'angolo intorno all'asse x ed aumentare l'angolo di rotazione attorno a y, invece noto l'angolo attorno a x da 90° decresce (strano) ed aumenta in modo fluido l'angolo attorno a y fino a circa 36° (ok) ma poi quando salta di più 30 gradi fino a circa 90°.......ma cosa succede??
In varie posizioni le rotazioni attorno all'asse x e y scattano in modo anomalo.
Sapreste darmi indicazioni?

Offline arlabs

  • Utente normale
  • ***
  • Post: 434
  • Respect: +49
    • Mostra profilo
  • Dispositivo Android:
    GalaxyS7
  • Play Store ID:
    AR Labs
  • Sistema operativo:
    Windows 10
Re:Rotazioni con cambio sistema di riferimento
« Risposta #1 il: 17 Febbraio 2015, 16:08:57 CET »
0
Innanzitutto per MagneticField finché non "calibri" il sensore ruotando il dispositivo su se stesso più volte (il famoso 8 che molte applicazioni chiedono di fare) dà risultati quasi casuali.

Anche dopo calibrato i valori non sono comunque il massimo, è d'obbligo un passabasso che però limita i tempi di reazione.

Cmq, per gli orientamenti il sensore più adatto è il TYPE_ROTATION_VECTOR (o TYPE_GAME_ROTATION_VECTOR se non ti interessa avere riferimento al nord reale). Fonde i risultati di Accelerometro, magnetometro e giroscopio (se presente). Attenzione che anche con questa soluzione per avere i risultati riferiti al nord reale serve calibrare ruotando il dispositivo.
Cmq, ritorna un quaternione che si può trasformare in matrice agevolmente. Dalla matrice puoi estrarre gli angoli che ti servono.

Per ottenere gli angoli dipende cosa vuoi fare. Una rotazione ha 3 gradi di libertà e può essere rappresentata in diversi modi, tutti i metodi con 3 valori (come gli angoli di Eulero) soffrono del GimbalLock.
Cmq, con gli angoli di Eulero rotazioni molto simili possono essere rappresentate da valori molto diversi, in particolare in prossimità dei 90°.

Ciao.

Offline bpaolo

  • Nuovo arrivato
  • *
  • Post: 4
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    S3
  • Sistema operativo:
    mac os
Re:Rotazioni con cambio sistema di riferimento
« Risposta #2 il: 23 Febbraio 2015, 13:02:09 CET »
0
ciao grazie della spiegazione.
sto leggendo a destra e manca per capire come estrarre i valori dalla matrice di rotazione.....
praticamente uso TYPE_ROTATION_VECTOR, nel onSensorChange estraggo i valori con getRotationMatrixFromVector,
dopodiché ho una matrice 9x9 e qui mi sono bloccato.
Ora dovrei combinare tali valori per determinare gli angoli di rotazione in gradi attorno agli assi x, y, z.....però senza ricadere nel GimbalLock, per esempio se faccio un getOrientation e trasformo in gradi mi si ripresenta l'errore iniziale, come se utilizzassi Type_orientation....
....mi sai aiutare magari indicandomi qualche link?

Offline iceweasel

  • Moderatore globale
  • Utente senior
  • *****
  • Post: 878
  • Respect: +147
    • Mostra profilo
  • Dispositivo Android:
    LGE P990 - Google Nexus 5
  • Sistema operativo:
    Linux Debian Sid
Re:Rotazioni con cambio sistema di riferimento
« Risposta #3 il: 23 Febbraio 2015, 17:11:57 CET »
0
Conosci l'algebra lineare e soprattutto i quaternioni?

Inviato dal mio Nexus 5 utilizzando Tapatalk

adb logcat | tee /tmp/logcat | grep TAG

Offline bpaolo

  • Nuovo arrivato
  • *
  • Post: 4
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    S3
  • Sistema operativo:
    mac os
Re:Rotazioni con cambio sistema di riferimento
« Risposta #4 il: 23 Febbraio 2015, 20:57:58 CET »
0
Beh per quanto riguarda i quaternioni mi sto informando e l'algebra lineare lo mastico abbastanza  :D

Offline iceweasel

  • Moderatore globale
  • Utente senior
  • *****
  • Post: 878
  • Respect: +147
    • Mostra profilo
  • Dispositivo Android:
    LGE P990 - Google Nexus 5
  • Sistema operativo:
    Linux Debian Sid
Re:Rotazioni con cambio sistema di riferimento
« Risposta #5 il: 23 Febbraio 2015, 22:21:36 CET »
0
API di Android ha il supporto per la conversione in quaternioni:

http://developer.android.com/reference/android/hardware/SensorManager.html#getQuaternionFromVector(float[], float[])

Qui spiega come effettuare i calcoli delle rotazioni con i quaternioni:

http://en.m.wikipedia.org/wiki/Quaternions_and_spatial_rotation

Inviato dal mio Nexus 5 utilizzando Tapatalk

adb logcat | tee /tmp/logcat | grep TAG

Offline bpaolo

  • Nuovo arrivato
  • *
  • Post: 4
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    S3
  • Sistema operativo:
    mac os
Re:Rotazioni con cambio sistema di riferimento
« Risposta #6 il: 23 Febbraio 2015, 22:57:19 CET »
0
Grazie tanto domani leggo tutto

Offline arlabs

  • Utente normale
  • ***
  • Post: 434
  • Respect: +49
    • Mostra profilo
  • Dispositivo Android:
    GalaxyS7
  • Play Store ID:
    AR Labs
  • Sistema operativo:
    Windows 10
Re:Rotazioni con cambio sistema di riferimento
« Risposta #7 il: 24 Febbraio 2015, 10:49:35 CET »
0
Scusa, a mio parere puoi lavorare tranquillamente con le matrici. Personalmente le trovo più intuitive e facili da usare.
Cmq, quello che ti ritorna il sensore TYPE_ROTATION_VECTOR è già fondamentalmente un quaternione (su dispositivi vecchi torna solo 3 valori di un quaternione, da cui puoi ricavare il quarto).

Con getMatrixFromVector ottieni la matrice di rotazione.
Se vuoi ottenere gli angoli di Eulero penso trovi come si fa su qualche libro o anche su Stackoverflow (http://stackoverflow.com/questions/1996957/conversion-euler-to-matrix-and-matrix-to-euler)

Quello che non ho capito è se sono proprio quelli che stai cercando.
Se invece semplicemente ti interessa l'angolo di un asse del telefono rispetto ad un asse del mondo, ti basta usare le proiezioni degli assi del sistema di riferimento telefono sugli assi del sistema di riferimento mondo... (hai 9 possibili combinazioni, che guarda caso sono le componenti della matrice di rotazione )

Ti incollo un esempio che io uso che calcolare il bearing dell'asse Z uscente dal telefono:

Codice (Java): [Seleziona]
        public float getBearing()
        {
/*        Types.Vec3 rotzAxe = new Types.Vec3( mRotationMatrix[8], mRotationMatrix[9], mRotationMatrix[10] );
        Types.Vec3 xAxe = new Types.Vec3( 1, 0, 0 );
        Types.Vec3 yAxe = new Types.Vec3( 0, 1, 0 );
        float zxProj = Types.Vec3.dot( rotzAxe, xAxe );
        float zyProj = Types.Vec3.dot( rotzAxe, yAxe );*/

            float zxProj = mRotationMatrix[8];
            float zyProj = mRotationMatrix[9];

            return (float) Math.toDegrees( Math.atan2( -zxProj, -zyProj ) );
        }

Nego i valori delle proiezioni perché mi interessa l'asse uscente dal retro del telefono.

Ciao.