Autore Topic: Air mouse  (Letto 1964 volte)

Offline Joker91

  • Nuovo arrivato
  • *
  • Post: 9
  • Respect: 0
    • Mostra profilo
Air mouse
« il: 09 Luglio 2014, 17:57:36 CEST »
0
Salve, sto cercando di realizzare un semplice air mouse, cioè una app che permetta di usare l'orientamento dello smartphone come puntatore per un desktop. In sostanza quello che si fa in questo video: https://www.youtube.com/watch?v=C7JQ7Rpwn2k&feature=youtu.be&t=37m5s
Visto che nel video si parla di sensor fusion ho provato a realizzarlo utilizzando il rotation vector, il problema è che mi risulta molto inaccurato rispetto a quello del video che sembra veramente preciso! Vi posto un codice per darvi un'idea di cosa sto facendo per usare i dati del sensore:

Codice (Java): [Seleziona]
//get values from Rotation Vector sensor
SensorManager.getRotationMatrixFromVector(rotationMatrix, sensorValues);
SensorManager.getAngleChange(orientationValues, rotationMatrix, prevMatrix);
prevMatrix = rotationMatrix;
azimuth += orientationValues[0];
pitch += orientationValues[1];

//getAngleChange returns radians so I multiply by 100
float dX = (azimuth - lastX)*100.f;
float dY = (pitch - lastY)*100.f;
pixel.x += dX;
pixel.y += dY;

// store values
lastX = azimuth;
lastY = pitch;
prevMatrix = rotationMatrix;

Cosa sto sbagliando? Sto usando un sensore non adatto oppure è qualcosa inerente all'algoritmo?

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:Air mouse
« Risposta #1 il: 09 Luglio 2014, 18:06:39 CEST »
+1
Secondo me le uscite dei sensori allo stato solido (come quelli nei cellulari) sono molto rumorose, per cui c'è bisogno di un bel filtraggio prima di poter essere usate.

Prova a far acquisire la traccia dei sensori per qualche secondo mentre muovi il cellulare, salvando tutti i dati in un file di testo, poi traccia l'andamento su un foglio elettronico.
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

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:Air mouse
« Risposta #2 il: 09 Luglio 2014, 18:17:35 CEST »
+1

Offline Joker91

  • Nuovo arrivato
  • *
  • Post: 9
  • Respect: 0
    • Mostra profilo
Re:Air mouse
« Risposta #3 il: 09 Luglio 2014, 18:21:46 CEST »
0
Secondo me le uscite dei sensori allo stato solido (come quelli nei cellulari) sono molto rumorose, per cui c'è bisogno di un bel filtraggio prima di poter essere usate.

Prova a far acquisire la traccia dei sensori per qualche secondo mentre muovi il cellulare, salvando tutti i dati in un file di testo, poi traccia l'andamento su un foglio elettronico.
In realtà avevo fatto una prova con le varie app che fanno il grafico sui dati dei sensori e noto anomalie... Il pitch va molto bene, il problema è l'azimuth (che nel mio caso sarebbe l'asse x) che si muove anche quando sto "pitchando" e "rollando" lo smartphone... Da come ne parlava il tipo nel video pensavo bastasse prendere i dati e mapparli, tu invece mi dici che è solamente un problema di filtrare i risultati e non del sensore? Un po' è quello che sospettavo, ma il rotation vector non dovrebbe essere già filtrato?

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:Air mouse
« Risposta #4 il: 09 Luglio 2014, 18:39:28 CEST »
0
Per questo tipo di elaborazione servono dei filtri sui dati provenienti dai sensori molto sofisticati, l'utilizzo di filtri riconducibili a un filtro passa basso non risolve il problema. Guardando il video molto probabilmente è stato usato un filtro molto più complesso che permette di ridurre il rumore e stimare la posizione corretta. Di solito si parte con il filtro di kalman (o altri):

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

non è semplice capirlo, realizzarlo e utilizzarlo nel codice.

Inviato dal mio Nexus 5

adb logcat | tee /tmp/logcat | grep TAG

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:Air mouse
« Risposta #5 il: 09 Luglio 2014, 18:42:51 CEST »
0
Kalman filter - Wikipedia, the free encyclopedia

non è semplice capirlo, realizzarlo e utilizzarlo nel codice.

Si ok, l'ideale sarebbe studiare il fenomeno e dimensionare al meglio un filtro del genere.  :-)  Ma anche fare qualche prova con l'IIR a un polo proposto da undead potrebbe migliorare quanto basta la situazione. A quel punto può decidere se andare oltre, oppure accontentarsi.  :-P
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline Joker91

  • Nuovo arrivato
  • *
  • Post: 9
  • Respect: 0
    • Mostra profilo
Re:Air mouse
« Risposta #6 il: 09 Luglio 2014, 18:44:15 CEST »
0
Grazie mille, mi avete aiutato perlomeno a capire dov'è il problema: già con la soluzione di undead ho avuto un netto miglioramento dell'accuratezza! Ora perlomeno ho una base su cui dove cominciare ^^

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:Air mouse
« Risposta #7 il: 10 Luglio 2014, 08:16:24 CEST »
0
Mi fa piacere che almeno ti sia servito come base.

Beh hanno ragione iceweasel e bradipao, d'altra parte il filtro nel link sono si e no due righe di codice... più di tanto non si può pretendere. Sempre meglio dei dati non filtrati.. eheheh   :D

Offline arlabs

  • Utente normale
  • ***
  • Post: 430
  • Respect: +49
    • Mostra profilo
  • Dispositivo Android:
    GalaxyS6, Nexus5
  • Play Store ID:
    AR Labs
  • Sistema operativo:
    Windows 10
Re:Air mouse
« Risposta #8 il: 10 Luglio 2014, 10:05:54 CEST »
+1
Io ho fatto un po' di lavoro e prove con i sensori.

Innanzitutto al filtro di undead aggiungo questo:

Codice (Java): [Seleziona]
        float alpha = (float) Math.exp(-tick / T);
        filteredValue = filteredValue * alpha + input*(1-alpha);

Per dare un significato più "fisico" alla coefficiente di filtraggio
tick è il tempo che intercorre fra due campionamenti
T è la costante di tempo di campionamento, dove la frequenza di taglio è Ft = 1/(2*pi*T).
Il segnale si considera dimenticato in 3*T.

Seconda cosa ti consiglio un bel libro:
"Professional Android sensor programming"

Terzo ti riassumo 2 cose che ho trovato nel libro.

Il sensore magnetico è poco preciso (molto rumoroso). E' bene filtrarlo passa-basso pesantemente ma così perdi i movimenti rapidi.
Il giroscopio è preciso, ma misura la velocità, integrando si ottiene una componente continua che porta alla deriva del valore.
Il video che hai postato è di Invensense. Hanno brevettato e integrato (credo nei driver) un sistema di fusione dei sensori (magnetico e giroscopico).
Per cui (l'ho provato) su tutti i device con i loro sensori, il "ROTATION_VECTOR" funziona molto meglio che sugli altri device.
Alcuni dispositivi che hanno i loro sensori sono Nexus 7, Nexus 5, Galaxy S5 (l'S4 no).

Non l'ho ancora fatto, ma a breve voglio fare una cosa. Verificare il produttore del sensore, se è Invesense, usare il rotation vector, altrimenti leggermi indipendentemente sensore magnetico e giroscopio e combinare la componente in bassa frequenza del primo con quella in alta frequenza del secondo (ovviamente integrata). Dovrebbe essere un buon compromesso. Non capisco perché Google non abbia integrato qualcosa di simile nel ROTATION_VECTOR.


Ciao.
« Ultima modifica: 10 Luglio 2014, 10:08:53 CEST da arlabs »

Offline Joker91

  • Nuovo arrivato
  • *
  • Post: 9
  • Respect: 0
    • Mostra profilo
Re:Air mouse
« Risposta #9 il: 12 Luglio 2014, 20:07:08 CEST »
0
Secondo voi può avere senso usare un filtro come quello di undead combinato con un filtro simple moving average (un buffer circolare)? O è meglio usare solo uno dei due? Chiedo questo sia perché mi piace il modo in cui risponde un filtro weighted smoothing sia perché la mia applicazione deve inviare dati in tempo reale con UDP e facendo una media potrei ridurre il traffico dei pacchetti. Darei comunque più peso al primo filtro. Che ne pensate?

Avevo lo studio dubbio anche sull'applicare un filtro low pass e sequenzialmente uno high, avrebbe senso?
« Ultima modifica: 12 Luglio 2014, 20:10:34 CEST da Joker91 »

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:Air mouse
« Risposta #10 il: 12 Luglio 2014, 20:25:43 CEST »
0
Combinare più filtri bassa passo ottieni sempre un filtro bassa basso. Un moving average filter è sempre riconducibile a un filtro FIR bassa basso. Se combini un filtro bassa basso con un filtro bassa alto ottieni un filtro elimina banda, se la banda è molto stretta prende il nome di notch.

Inviato dal mio Nexus 5

adb logcat | tee /tmp/logcat | grep TAG

Offline arlabs

  • Utente normale
  • ***
  • Post: 430
  • Respect: +49
    • Mostra profilo
  • Dispositivo Android:
    GalaxyS6, Nexus5
  • Play Store ID:
    AR Labs
  • Sistema operativo:
    Windows 10
Re:Air mouse
« Risposta #11 il: 14 Luglio 2014, 09:45:38 CEST »
0
Applicando i due filtri sequenzialmente ottieni un "passa-banda".

Cmq, se sul RotationVector fai un passa alto, ti perde la componente continua che è la direzione effettiva (nel momento in cui sei fermo).
Quindi ha senso in casi specifici, nel caso di un air-mouse... direi di no.

Ciao.
« Ultima modifica: 14 Luglio 2014, 09:49:08 CEST da arlabs »

Offline Joker91

  • Nuovo arrivato
  • *
  • Post: 9
  • Respect: 0
    • Mostra profilo
Re:Air mouse
« Risposta #12 il: 14 Luglio 2014, 14:54:46 CEST »
0
Purtroppo con questi filtri semplici non riesco ad ottenere dati decenti, specialmente per l'azimuth che continua a essere molto sporco quando muovo in pitch. Mi sa che lascio perdere, probabilmente è impossibile avere un puntatore decente per una app "casereccia" :D Quello che mi chiedo io è come sia possibile che le app commerciali siano così precise e allo stesso tempo abbiano tempi di risposta praticamente immediati? Io penso che qualunque tipo di filtro debba introdurre un minimo di latenza, no? Giusto per curiosità, oramai penso d'aver capito che mi sarà impossibile raggiungere risultati lontanamente paragonabili ^^"

Offline arlabs

  • Utente normale
  • ***
  • Post: 430
  • Respect: +49
    • Mostra profilo
  • Dispositivo Android:
    GalaxyS6, Nexus5
  • Play Store ID:
    AR Labs
  • Sistema operativo:
    Windows 10
Re:Air mouse
« Risposta #13 il: 14 Luglio 2014, 15:16:22 CEST »
0
Ovviamente un filtraggio così fatto introduce un ritardo, ma se giustamente dosato quasi impercettibile...

Quali sono le App commerciali che reputi così precise?
E, per curiosità, che dispositivo stai usando per fare le prove?

Infine: continua a risultare impreciso anche dopo aver fatto ampi movimenti di taratura?
Te lo chiedo perché io ho notato delle incertezze iniziale, che vanno via via riducendosi.

Ciao

Offline Joker91

  • Nuovo arrivato
  • *
  • Post: 9
  • Respect: 0
    • Mostra profilo
Re:Air mouse
« Risposta #14 il: 14 Luglio 2014, 15:40:20 CEST »
0
Ovviamente un filtraggio così fatto introduce un ritardo, ma se giustamente dosato quasi impercettibile...

Quali sono le App commerciali che reputi così precise?
E, per curiosità, che dispositivo stai usando per fare le prove?

Infine: continua a risultare impreciso anche dopo aver fatto ampi movimenti di taratura?
Te lo chiedo perché io ho notato delle incertezze iniziale, che vanno via via riducendosi.

Ciao
Le app che ho provato sono Mouse Lite, Remote Mouse, Sensor Mouse e Unified Remote. Con il mio Galaxy S2 sono tutte molto precise e utilizzabili ma soprattutto sono così reattive che sembra non abbiano filtri!

Cosa intendi per ampi movimenti di taratura? Se intendi calibrazione a tempo d'esecuzione non ho fatto niente...  Ho usato solo i filtri classici e ho anche provato a sistemare i valori empiricamente.