Autore Topic: Rotazione view sugli assi  (Letto 1744 volte)

Offline Fullydroid

  • Nuovo arrivato
  • *
  • Post: 34
  • Respect: +1
    • Mostra profilo
Rotazione view sugli assi
« il: 03 Settembre 2014, 15:17:26 CEST »
0
Ciao ragazzi!

Mi trovo a dover modificare il codice per poter sostituire l'ormai deprecato TYPE_ORIENTATION.

Passando ore sul web e avendo letto svariati tutorial ho riscritto parte del codice usando Sensor.TYPE_ACCELEROMETER & Sensor.TYPE_MAGNETIC_FIELD.

la rotazione funziona ma una cosa non funziona affatto ovvero  se prendo il valore dell' azimuth preso dalla matrice di orientamento ho notato che, dopo averlo trasformato in gradi arriva al massimo a 179..... e poi? poi si decrementa da solo girando nello stesso verso.... ma perchè?

Per essere piu' chiaro posto il fulcro del codice..

Codice: [Seleziona]
public void onSensorChanged(SensorEvent evt) {
         
         if (evt.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
            gravSensorVals = lowPass(evt.values.clone(), gravSensorVals);
            grav[0] = evt.values[0];
            grav[1] = evt.values[1];
            grav[2] = evt.values[2];

         }
         else if (evt.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
            magSensorVals = lowPass(evt.values.clone(), magSensorVals);
            mag[0] = evt.values[0];
            mag[1] = evt.values[1];
            mag[2] = evt.values[2];

         }
         boolean succes = false;
         if (gravSensorVals != null && magSensorVals != null) {
            succes =SensorManager.getRotationMatrix(RTmp, I, gravSensorVals, magSensorVals);


            if (succes) {
               /* Orientation has azimuth, pitch and roll */
               float orientation[] = new float[3];
               SensorManager.getOrientation(RTmp, orientation);
               double azim = (double) orientation[0];
               double roll = (double) orientation[2];
               double pitch = (double) orientation[1];
               valueSensor.setText("" + (azim)*360/(2*3.14159f));
               Circle.setRotation( (float)Math.toDegrees(azim));
             
  }
}


qualcuno mi puo illuminare??

Grazie ragazzi
« Ultima modifica: 03 Settembre 2014, 15:24:23 CEST da Fullydroid »

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:Rotazione view sugli assi
« Risposta #1 il: 03 Settembre 2014, 16:55:41 CEST »
0
Non usare mai il valore del pi-greco tronco, usa sempre le funzioni di libreria per le conversioni.

Quando si parla di rotazioni nello spazio 3D le cose si complicano parecchio e usare gli angoli di Eulero ci si imbatte nel Gimbal lock https://en.m.wikipedia.org/wiki/Gimbal_lock

Per avere dati sulle rotazioni che cambiano in modo continuo, senza salti o inversioni devi usare i quaternioni https://en.m.wikipedia.org/wiki/Quaternions_and_spatial_rotation

Non sono semplici, non sono intuitivi ma si evita il Gimbal lock.

API di Android gestisce i quaternioni:

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

Inviato dal mio Nexus 5 utilizzando Tapatalk

adb logcat | tee /tmp/logcat | grep TAG

Offline Fullydroid

  • Nuovo arrivato
  • *
  • Post: 34
  • Respect: +1
    • Mostra profilo
Re:Rotazione view sugli assi
« Risposta #2 il: 04 Settembre 2014, 09:24:08 CEST »
0
Non usare mai il valore del pi-greco tronco, usa sempre le funzioni di libreria per le conversioni.

Quando si parla di rotazioni nello spazio 3D le cose si complicano parecchio e usare gli angoli di Eulero ci si imbatte nel Gimbal lock https://en.m.wikipedia.org/wiki/Gimbal_lock

Per avere dati sulle rotazioni che cambiano in modo continuo, senza salti o inversioni devi usare i quaternioni https://en.m.wikipedia.org/wiki/Quaternions_and_spatial_rotation

Non sono semplici, non sono intuitivi ma si evita il Gimbal lock.

API di Android gestisce i quaternioni:

SensorManager | Android Developers[], float[])

Inviato dal mio Nexus 5 utilizzando Tapatalk

Ciao, grazie per la risposta!
Ho letto la documentazione android, ma non ho capito una cosa:
Usando i quaternioni ho attivato sensorManager.registerListener(listener,
            sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR),
            60000); perche ho letto che il metodo  SensorManager.getQuaternionFromVector prende come parametri il vettore di rotazione.

Il metodo in questione mi ritorna un float[4] e fin qui tutto ok... ma i valori all'interno cosa sono? radianti? gradi? quando ottengo l'array cosa devo farci sopra? applicare il getOrientation?

Grazie mille..

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:Rotazione view sugli assi
« Risposta #3 il: 04 Settembre 2014, 10:48:57 CEST »
0
La trattazione matematica non è semplice, esistono capitoli e anche libri interi di matematica che trattano l'argomento, ti posso solo dire che i quaternioni sono formati da una componente scalare (una dimensione) e da una componente vettoriale (3 dimensioni), in questo caso specifico sono unitari quindi rappresentano solo la rotazione e non anche un ridimensionamento.

Inviato dal mio Nexus 5 utilizzando Tapatalk

adb logcat | tee /tmp/logcat | grep TAG

Offline Fullydroid

  • Nuovo arrivato
  • *
  • Post: 34
  • Respect: +1
    • Mostra profilo
Re:Rotazione view sugli assi
« Risposta #4 il: 04 Settembre 2014, 11:03:06 CEST »
0
La trattazione matematica non è semplice, esistono capitoli e anche libri interi di matematica che trattano l'argomento, ti posso solo dire che i quaternioni sono formati da una componente scalare (una dimensione) e da una componente vettoriale (3 dimensioni), in questo caso specifico sono unitari quindi rappresentano solo la rotazione e non anche un ridimensionamento.

Inviato dal mio Nexus 5 utilizzando Tapatalk
Ma quindi non ci sono delle api che dal quaternione mi ricavano la rotazione su azimuth pitch e roll?

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:Rotazione view sugli assi
« Risposta #5 il: 04 Settembre 2014, 11:20:20 CEST »
0
Mi fugge cosa fuori fare, se vuoi usare gli angoli di Eulero non ti devi meravigliare di avere valori che cambiano in modo discontinuo.

Wikipedia ha le formule di conversione:
https://en.m.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles

Inviato dal mio Nexus 5 utilizzando Tapatalk

adb logcat | tee /tmp/logcat | grep TAG

Offline Fullydroid

  • Nuovo arrivato
  • *
  • Post: 34
  • Respect: +1
    • Mostra profilo
Re:Rotazione view sugli assi
« Risposta #6 il: 04 Settembre 2014, 11:43:11 CEST »
0
Mi fugge cosa fuori fare, se vuoi usare gli angoli di Eulero non ti devi meravigliare di avere valori che cambiano in modo discontinuo.

Wikipedia ha le formule di conversione:
https://en.m.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles

Inviato dal mio Nexus 5 utilizzando Tapatalk

Grazie per l'interesse, quello che io dovrei fare è far semplicemente ruotare una view usando i sensori. La view deve essere aggiornata con la rotazione su azimuth. Prima avevo implementato il tutto con il type_orientation e funzionava il tutto abbastanza bene...ma essendo deprecato ho deciso di reimplementare il tutto usando la soluzione che sostituisce l'API deprecata, ovvero unire il sensore magnetico e accelerometro. Il problema è che a un certo punto della rotazione i valori anzichè proseguire verso ad esempio i 360° iniziano a decrementarsi come se si invertisse il moto.

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:Rotazione view sugli assi
« Risposta #7 il: 04 Settembre 2014, 12:43:37 CEST »
0
Non serve citare ogni volta tutto.

Mi ripeto per ennesima volta: quando si vuole ruotare un oggetto 3D la cosa migliore per non avere problemi è usare i quaternioni. Rimando ai link precedenti e a Google per la documentazione più approfondita.

Inviato dal mio Nexus 5 utilizzando Tapatalk

adb logcat | tee /tmp/logcat | grep TAG