13

Sto cercando di appianare i dati che ottengo dall'API DeviceOrientation per creare un'applicazione Google Cardboard nel browser.Implementare un filtro Kalman per uniformare i dati dall'API deviceOrientation

Sto collegando i dati dell'accelerometro direttamente alla rotazione della fotocamera ThreeJs, ma stiamo ricevendo un sacco di rumore sul segnale che sta causando la vista di Judder.

Qualcuno ha suggerito un filtro di Kalman come il modo migliore per affrontare lisciatura rumore di elaborazione del segnale e ho trovato questa semplice libreria Javascript su GitHub

https://github.com/itamarwe/kalman

Tuttavia la sua davvero la luce sulla documentazione.

Capisco che ho bisogno di creare un modello di Kalman fornendo un vettore e 3 matrici come argomenti e quindi aggiornare il modello, di nuovo con un vettore e matrici come argomenti su un periodo di tempo.

Capisco anche che un'equazione di filtro di Kalman ha diverse parti distinte: la posizione stimata corrente, il valore di guadagno di Kalman, la lettura corrente dall'API di orientamento e la posizione stimata precedente.

Vedo che un punto nello spazio 3D può essere descritto come un vettore, quindi qualsiasi valore di posizione, come una posizione stimata o la lettura corrente può essere un vettore.

Quello che non capisco è come queste parti possano essere tradotte in Matrici per formare gli argomenti per la libreria Javascript.

+0

Sì, per essere onesti, la biblioteca è completamente aborrita e documentata. Questo non sarebbe accettabile se lavorasse per me! Francamente, proverei a contattare l'autore e, in caso negativo, usare qualcos'altro. –

+0

Ho aggiunto un problema al repository github nella speranza che possa avere pietà di me. Suppongo che se l'elaborazione del segnale è la tua cosa, questo è probabilmente ovvio ma sono un po 'perso per le Matrici. Mi chiedo se Matrix rappresenti la traduzione tra stati temporali. Quindi, invece di rappresentare la posizione corrente come un vettore, si rappresenta la posizione corrente come una traduzione tra la lettura effettiva e la lettura eseguita nell'ultimo stato temporale? –

risposta

11

Bene, ho scritto la biblioteca aborramente documentata un paio di anni fa. Se c'è interesse, sono decisamente disposto ad aggiornarlo, migliorare la documentazione e scrivere test.

Permettetemi brevemente spiegare quali sono tutte le diverse matrici e vettori e come devono essere derivati:

x - questo è il vettore che si tenta di stimare. Nel tuo caso, probabilmente sono le 3 accelerazioni angolari.

P - è la matrice di covarianza della stima, ovvero l'incertezza della stima. Viene inoltre stimato in ogni fase del filtro di Kalman insieme a x.

F - descrive come si sviluppa X in base al modello. Generalmente, il modello è x[k] = Fx[k-1]+w[k]. Nel tuo caso, F potrebbe essere la matrice identità, se ti aspetti che l'accelerazione angolare sia relativamente liscia o la matrice zero, se ti aspetti che l'accelerazione angolare sia completamente imprevedibile. In ogni caso, w rappresenterebbe quanto ci si aspetta che l'accelerazione cambi da un passo all'altro.

w - descrive il rumore di processo, ovvero quanto il modello si discosta dal modello "perfetto". È definita come distribuzione normale multivariata media zero con matrice di covarianza Q.

Tutte le variabili precedenti definiscono il modello, ovvero ciò che si sta tentando di stimare. Nella parte successiva, parliamo del modello di dell'osservazione - che cosa misurate per stimare il vostro modello.

z - questo è ciò che si misura. Nel tuo caso, dal momento che stai usando gli accelerometri, stai misurando ciò che stai anche stimando. Saranno le accelerazioni angolari.

H - descrive la relazione tra il modello e l'osservazione. z[k]=H[k]x[k]+v[k]. Nel tuo caso, è la matrice di identità.

v - è il rumore di misurazione e si presume che sia un rumore bianco gaussiano medio con covarianza R [k]. Qui è necessario misurare la rumorosità degli accelerometri e calcolare la matrice di covarianza del rumore.

In sintesi, la procedura per utilizzare il filtro di Kalman:

  1. Determinare x[0] e P[0] - lo stato iniziale del modello, e la stima iniziale di quanto accuratamente si sa x[0].
  2. Determina F in base al modello e al modo in cui si sviluppa da un passaggio all'altro.
  3. Determinare Q in base alla natura stocastica del modello.
  4. Determinare H in base alla relazione tra ciò che si misura e ciò che si desidera stimare (tra il modello e la misurazione).
  5. Determinare R in base al rumore di misurazione. Quanto rumorosa è la tua misura.

Poi, con ogni nuova osservazione, è possibile aggiornare la stima modello di stato utilizzando il filtro di Kalman, e hanno una stima ottimale dello stato del modello (x[k]), e l'esattezza di tale stima (P[k]) .

+0

Grazie per aver dedicato del tempo. Lo apprezzo molto, anche grazie per aver creato la libreria in primo luogo –

2
var acc = { 
x:0, 
y:0, 
z:0 
}; 

var count = 0; 

if (window.DeviceOrientationEvent) { 
    window.addEventListener('deviceorientation', getDeviceRotation, false); 
}else{ 
    $(".accelerometer").html("NOT SUPPORTED") 
} 

var x_0 = $V([acc.x, acc.y, acc.z]); //vector. Initial accelerometer values 

//P prior knowledge of state 
var P_0 = $M([ 
       [1,0,0], 
       [0,1,0], 
       [0,0,1] 
      ]); //identity matrix. Initial covariance. Set to 1 
var F_k = $M([ 
       [1,0,0], 
       [0,1,0], 
       [0,0,1] 
      ]); //identity matrix. How change to model is applied. Set to 1 
var Q_k = $M([ 
       [0,0,0], 
       [0,0,0], 
       [0,0,0] 
      ]); //empty matrix. Noise in system is zero 

var KM = new KalmanModel(x_0,P_0,F_k,Q_k); 

var z_k = $V([acc.x, acc.y, acc.z]); //Updated accelerometer values 
var H_k = $M([ 
       [1,0,0], 
       [0,1,0], 
       [0,0,1] 
      ]); //identity matrix. Describes relationship between model and observation 
var R_k = $M([ 
       [2,0,0], 
       [0,2,0], 
       [0,0,2] 
      ]); //2x Scalar matrix. Describes noise from sensor. Set to 2 to begin 
var KO = new KalmanObservation(z_k,H_k,R_k); 

//each 1/10th second take new reading from accelerometer to update 
var getNewPos = window.setInterval(function(){ 

    KO.z_k = $V([acc.x, acc.y, acc.z]); //vector to be new reading from x, y, z 
    KM.update(KO); 

    $(".kalman-result").html(" x:" +KM.x_k.elements[0]+", y:" +KM.x_k.elements[1]+", z:" +KM.x_k.elements[2]); 
    $(".difference").html(" x:" +(acc.x-KM.x_k.elements[0])+", y:" +(acc.y-KM.x_k.elements[1])+", z:" +(acc.z-KM.x_k.elements[2])) 


}, 100); 

//read event data from device 
function getDeviceRotation(evt){ 

    // gamma is the left-to-right tilt in degrees, where right is positive 
    // beta is the front-to-back tilt in degrees, where front is positive 
    // alpha is the compass direction the device is facing in degrees 
    acc.x = evt.alpha; 
    acc.y = evt.beta; 
    acc.z = evt.gamma; 
    $(".accelerometer").html(" x:" +acc.x+", y:" +acc.y+", z:" +acc.z); 
} 

Ecco una pagina di prova che mostra i miei risultati

http://cardboard-hand.herokuapp.com/kalman.html

ho impostato rumore del sensore ad una matrice 2 scalare per ora per vedere se il Kalman stava facendo la sua cosa, ma abbiamo notato il sensore ha una maggiore variazione nell'asse x quando il telefono è appoggiato sul tavolo. Pensiamo che questo potrebbe essere un problema con il blocco Gimbal. Non abbiamo testato ma è possibile che le variazioni di varianza in ciascun asse dipendano dall'orientamento del dispositivo.

+0

Il tuo sistema è statico? Se è così, allora va bene che 'Q' è 0. Ma se il tuo sistema si muove, devi avere un' Q' diverso da zero che rappresenti la covarianza delle variazioni di accelerazione da un passo all'altro. Inoltre, inizializzerei 'x' con la prima misurazione dell'accelerometro, poiché questa è la migliore ipotesi che hai e accelererà la convergenza del filtro. – Ita

Problemi correlati