2009-05-11 12 views
1

Ich frage sie bei 50Hz/50 mal pro Sekunde für Daten. Wenn ich das Gerät plötzlich auf der x-Achse um 90 Grad kippte, während das Gerät flach auf einem Tisch mit dem Display nach oben war, bewegen sich die Werte ziemlich langsam auf den "Ziel" -Wert für diese Position.Warum reagieren meine Beschleunigungssensoren so langsam?

Jetzt ist das Seltsame: Wenn ich die Messrate erhöhe, bewegt sich der Wert schneller auf diesen neuen Wert, wenn das Gerät plötzlich um 90 Grad gedreht wird. Aber wenn ich nur einmal pro Sekunde nach dem neuen Wert frage, dauert es sehr lange, bis der Wert das Ziel erreicht. Was kann der Grund dafür sein?

Ich mache keine Art von Datenaggregation und akkumulieren nichts. Ich mache einfach eine einfache Filterung, um den Lärm loszuwerden. Meine Methode sieht wie folgt aus:

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration { 
    // Use a basic low-pass filter to only keep the gravity in the accelerometer values for the X and Y axes 
    // accelerationX is an instance variable 
    accelerationX = acceleration.x * 0.05 + accelerationX * (1.0 - 0.05); 

    // round 
    int i = accelerationX * 100; 
    float clippedAccelerationValue = i; 
    clippedAccelerationValue /= 100; 

    [self moveViews:clippedAccelerationValue]; 
} 

später, in meinem -moveViews: Methode, ich dies tun:

-(IBAction)moveSceneForPseudo3D:(float)accelerationValue { 
    if(fabs(lastAccelerationValue - accelerationValue) > 0.02) { // some little treshold to prevent flickering when it lays on a table 
     float viewAccelerationOffset = accelerationValue * 19 * -1; 

     newXPos = initialViewOrigin + viewAccelerationOffset; 
     myView.frame = CGRectMake(newXPos, myView.frame.origin.y, myView.frame.size.width, myView.frame.size.height); 

     lastAccelerationValue = accelerationValue; 
    } 
} 

Als Ergebnis der Vorrichtung 90 Grad auf der x-achsis gedreht wird oder 180 Grad bewegt sich die Ansicht nur langsam zur Zielposition. Ich weiß nicht, ob das an der Physik der Beschleunigungssensoren liegt oder ob es ein Fehler in meinem Filtercode ist. Ich weiß nur, dass es schnelle Spiele gibt, in denen die Beschleunigungsmesser zum Lenken verwendet werden, also kann ich mir fast nicht vorstellen, dass das ein Hardwareproblem ist.

Antwort

8

dieser Zeile:

accelerationX = acceleration.x * 0.05 + accelerationX * (1.0 - 0.05); 

ist ein Tiefpassfilter, der durch Berechnen eines gleitenden Durchschnitts der x Beschleunigung arbeitet. Mit anderen Worten, jedes Mal, wenn der Rückruf aufgerufen wird, verschieben Sie nur den Wert accelerationX um 5% auf den neuen Beschleunigungsmesserwert. Deshalb dauert es viele Iterationen, bevor accelerationX die neue Ausrichtung widerspiegelt.

Was Sie tun sollten, ist die 0.05 Wert zu erhöhen, um 0.2 zu sagen. Ich würde einen globalen #define machen und mit verschiedenen Werten zusammen mit verschiedenen Aktualisierungsraten herumspielen.

+0

Danke !! Das war genau die Lösung für das Problem. – Thanks

+0

Es sollte hinzugefügt werden, dass die Phasenverschiebung, die von einem RC LowPass-Filter erzeugt wird (den dieser Code implementiert), signifikant ist. Andere Implementierungen eines Tiefpassfilters (wie zum Beispiel einer, der unter Verwendung von FFT implementiert wird) sind ein wenig besser und diese Hinsicht. Sie sind jedoch viel schwieriger zu implementieren. –