Autore Topic: Stabilizzare i dati dei sensori TYPE_MAGNETIC_FIELD e TYPE_ACCELEROMETER  (Letto 1772 volte)

Offline tonnuns

  • Utente junior
  • **
  • Post: 81
  • Respect: +1
    • Mostra profilo
  • Sistema operativo:
    Windows
Sto provando un'applicazione su un cellulare che come sensori di movimento ha solo  TYPE_ORIENTATION, TYPE_MAGNETIC_FIELD e TYPE_ACCELEROMETER,
In origine questa applicazione usava il TYPE_ROTATION_VECTOR ma questo mer...a di cellulare non ce l'ha!
L'applicazione è un visualizzatore a 360° di immagini cubiche panoramiche (PanoramaGL per capirci) e devo usare dei sensori che facciano scorrere l'immagine in base alla direzione dove punto il cell in tutte le direzioni.

Per far questo in sostituzione al TYPE_ROTATION_VECTOR  ho usato il TYPE_MAGNETIC_FIELD e TYPE_ACCELEROMETER e funziona ma le immagini sono in continuo movimento fanno micro movimenti anche quando il cellulare è appoggiato sul tavolo, ho visto i dati che restituiscono i sensori e sono poco precisi e questa imprecisione causa il movimento convulso dell'immagine.

Sapete se c'è una classe o un metodo che mi consenta di applicare una sorta di stabilizzatore d'immagine ai dati dei sensori?
A qualcuno gli è mai capitato questo problema? e sapete se è fattibile?

Grazie

Offline undead

  • Utente senior
  • ****
  • Post: 666
  • Respect: +113
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Play Store ID:
    DrKappa
  • Sistema operativo:
    Windows 10 64-bit, Windows 8.1 64-bit
Re:Stabilizzare i dati dei sensori TYPE_MAGNETIC_FIELD e TYPE_ACCELEROMETER
« Risposta #1 il: 17 Gennaio 2013, 17:45:15 CET »
0
Puoi mettere un semplicissimo filtro in modo che il valore corrente dipenda fondamentalmente dal valore precedente.

Codice (Java): [Seleziona]
float myFilter = 0.85f;
accelerazioneTotaleX = (accelerazioneTotaleX * myFilter) + (accelerazioneCorrenteX * (1.0 - myFilter));

In questo caso il valore di accelerazione corrente pesa per il 15%. Quindi quando il telefono "da di matto" temporaneamente non hai salti. Allo stesso modo per una misura sufficientemente stabile il tuo filtro riporterà il valore corretto.

Ovviamente puoi aggiustare il myFilter nel modo che ritieni opportuno.

 ;-)

Offline tonnuns

  • Utente junior
  • **
  • Post: 81
  • Respect: +1
    • Mostra profilo
  • Sistema operativo:
    Windows
Re:Stabilizzare i dati dei sensori TYPE_MAGNETIC_FIELD e TYPE_ACCELEROMETER
« Risposta #2 il: 17 Gennaio 2013, 19:37:43 CET »
0
e il valore dell'accelerazioneTotaleX  da cosa dovrei calcolarla?

Offline undead

  • Utente senior
  • ****
  • Post: 666
  • Respect: +113
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Play Store ID:
    DrKappa
  • Sistema operativo:
    Windows 10 64-bit, Windows 8.1 64-bit
Re:Stabilizzare i dati dei sensori TYPE_MAGNETIC_FIELD e TYPE_ACCELEROMETER
« Risposta #3 il: 17 Gennaio 2013, 19:39:23 CET »
0
Da niente, lo dihiari nella classe e lo inizializzi a 0 prima di far partire il sensore.
L'accelerazione corrente invece viene dall'event del sensore.  ;-)

Offline tonnuns

  • Utente junior
  • **
  • Post: 81
  • Respect: +1
    • Mostra profilo
  • Sistema operativo:
    Windows
Re:Stabilizzare i dati dei sensori TYPE_MAGNETIC_FIELD e TYPE_ACCELEROMETER
« Risposta #4 il: 17 Gennaio 2013, 19:43:00 CET »
0
Cioè l'accelerazioneCorrenteX  è quella rilevata al momento ma quella totale? che deve essere la media da sempre rilevata?

Scusa ma io faccio questo nel metodo onSensorChanged

Codice (Java): [Seleziona]
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
{  
           valuesAccel = event.values.clone();    
}
               
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
{
                valuesMagnetic = event.values.clone();
}
if(valuesAccel == null || valuesMagnetic == null)
               
{
                       
      return;
               
}
               
               
SensorManager.getRotationMatrix(RR, I, valuesAccel, valuesMagnetic);
               
SensorManager.getOrientation(RR, orientation);
yaw = (float)Math.toDegrees(orientation[0]);

roll = (float)Math.toDegrees(orientation[2]);

dove dovrei mettere questo calcolo?
« Ultima modifica: 17 Gennaio 2013, 19:44:40 CET da tonnuns »

Offline undead

  • Utente senior
  • ****
  • Post: 666
  • Respect: +113
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Play Store ID:
    DrKappa
  • Sistema operativo:
    Windows 10 64-bit, Windows 8.1 64-bit
Re:Stabilizzare i dati dei sensori TYPE_MAGNETIC_FIELD e TYPE_ACCELEROMETER
« Risposta #5 il: 17 Gennaio 2013, 19:56:11 CET »
+1
Se stai usando quel sistema lì allora ti consiglio di non toccare l'accelerometro o il magnetometro!!!

ll filtro lo applichi direttamente a yaw, pitch e roll.
Prendo per esempio yaw.
Tu dichiari yaw fuori dal metodo, lo metti nella classe.
Poi nel costruttore, prima di far partre il sensore fai yaw = 0;

E infine sostituisci  a:

yaw = (float)Math.toDegrees(orientation[0]);

questo qua:

yaw = (yaw*myfilter)+(((float)Math.toDegrees(orientation[0]))*(1.0f-myfilter));

Poi fai lo stesso per pitch e roll.

In questo modo stabilizzi il tutto.

Offline tonnuns

  • Utente junior
  • **
  • Post: 81
  • Respect: +1
    • Mostra profilo
  • Sistema operativo:
    Windows
Re:Stabilizzare i dati dei sensori TYPE_MAGNETIC_FIELD e TYPE_ACCELEROMETER
« Risposta #6 il: 17 Gennaio 2013, 20:31:43 CET »
0
purtroppo in questo modo si ha una rotazione inferiore ai 360 gradi perchè ne tagli una parte

Arrivato ad una certa angolazione da di matto.
Penso che dia un risultato errato quando orientation[0] è al punto 0
« Ultima modifica: 17 Gennaio 2013, 20:40:01 CET da tonnuns »

Offline undead

  • Utente senior
  • ****
  • Post: 666
  • Respect: +113
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Play Store ID:
    DrKappa
  • Sistema operativo:
    Windows 10 64-bit, Windows 8.1 64-bit
Re:Stabilizzare i dati dei sensori TYPE_MAGNETIC_FIELD e TYPE_ACCELEROMETER
« Risposta #7 il: 17 Gennaio 2013, 21:48:54 CET »
0
Questo non è un problema del filtro in quanto tale, ma dei parametri di igresso.

Poichè il sensore non è precisissimo ti ritrovi con una orientation che evidentemente ti oscilla tra 359 gradi e 1 grado.
Il filtro cerca di adattarsi. Prima non lo notavi perchè settavi il valore all'istante.

Numericamente la via più breve se ci pensi non è andare da 0 a 359 ma da 0 a -1.... (o da 360 a 359  :-P )

La soluzione dipende molto da quello che vuoi ottenere e quali valori ti servono... ma in lnea di principio l'idea è quella di manipolare il tutto PRIMA di trasformarlo in gradi.

In una app ho fatto una cosa del genere perchè volevo tutti numeri tra 0 e 359:
1- prima elimino i valori negativi in ingresso sommandoci 2*PI.
2- successivamente se la distanza tra un valore e l'altro è maggiore di PI (quindi sto prendendo la strada più lunga) prendo il più piccolo e gli aggiungo 2PI (così da prendere la strada più corta).
3- passo il filtro e poi mi riscalo il valore tra 0 e 2PI.

 ;-)

Offline tonnuns

  • Utente junior
  • **
  • Post: 81
  • Respect: +1
    • Mostra profilo
  • Sistema operativo:
    Windows
Re:Stabilizzare i dati dei sensori TYPE_MAGNETIC_FIELD e TYPE_ACCELEROMETER
« Risposta #8 il: 19 Gennaio 2013, 18:54:22 CET »
0
Diciamo che lo calma ma in verticale ho un'escursione minima , tu conosci l'uso di un kalman filter?

Offline tonnuns

  • Utente junior
  • **
  • Post: 81
  • Respect: +1
    • Mostra profilo
  • Sistema operativo:
    Windows
Re:Stabilizzare i dati dei sensori TYPE_MAGNETIC_FIELD e TYPE_ACCELEROMETER
« Risposta #9 il: 19 Gennaio 2013, 19:40:23 CET »
0
Guarda il tuo calcolo va quasi bene solo che quando arrivo a 179 gradi e dovrebbe passare a 180 e subito dopo a -180 invece mi parte per la tangente e sembra che dia un valore che pare essere intorno all'80 come mai? tu sai come ovviare a questo problema e perchè da un valore così sballato in quel punto?

Offline tonnuns

  • Utente junior
  • **
  • Post: 81
  • Respect: +1
    • Mostra profilo
  • Sistema operativo:
    Windows
Re:Stabilizzare i dati dei sensori TYPE_MAGNETIC_FIELD e TYPE_ACCELEROMETER
« Risposta #10 il: 19 Gennaio 2013, 22:00:31 CET »
0
Ho risolto Grazie mille undead sei stato utilissimo, ho un risultato accettabile, certo non come il rotation vector ma penso utilizzabile

Offline undead

  • Utente senior
  • ****
  • Post: 666
  • Respect: +113
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Play Store ID:
    DrKappa
  • Sistema operativo:
    Windows 10 64-bit, Windows 8.1 64-bit
Re:Stabilizzare i dati dei sensori TYPE_MAGNETIC_FIELD e TYPE_ACCELEROMETER
« Risposta #11 il: 20 Gennaio 2013, 11:53:20 CET »
0
Figurati.  :-)

Per quanto riguarda filtri più avanzati puoi cercare online "sensor fusion". Se non mi ricordo male avevo letto qualcosa al riguardo sul blog "building windows 8". Hai 3 parametri in ingresso: accelerometro, giroscopio e magnetometro. Poi applichi dei filtri e combini alcuni output riapplicando altri filtri.

Col semplice filtro che ti ho descritto mi ci sono trovato bene, anche se onestamente non ci ho fatto niente di particolare.

Credo che quel tipo di pecisione (sensors fusion) sia richiesta per applicazioni avanzate. Per applicazioni avanzate intendo calcolare la posizioni in ambienti al chiuso tipo un museo, un centro commerciale, etc.

Certo una app che ti potesse guidare al chiuso (magari in un centro commerciale) sarebbe una gran cosa pe persone che magari hanno deficit visivi importanti.  :-)

Altra applicazione importante può essere un contapassi che sia preciso per davvero...