Frage

Ich habe einen Code-Schnipsel Beschleunigungs-Bewegungen zu erfassen. Es funktioniert einige Male durch leichte Bewegungen richtig zu erfassen, aber manchmal ist es erkennt Bewegungen, wenn ich zu meinem Gerät im Leerlauf gehalten. Gibt es Probleme mit den eingebauten Beschleunigungssensor Erkennung auf Android?

Ich verwende ein HTC G-1-Gerät. Mein Code-Schnipsel ist unten. Wie kann ich es beheben, damit ich kleine Gerät Bewegungen erkennen kann, aber nichts erkennen, wenn das Gerät im Leerlauf ist?

private static final int SHAKE_THRESHOLD = 50;

public void onSensorChanged(int sensor, float[] values) {

    if (sensor == SensorManager.SENSOR_ACCELEROMETER) {
        long curTime = System.currentTimeMillis();
        // only allow one update every 100ms.
        if ((curTime - lastUpdate) > 100) {
            long diffTime = (curTime - lastUpdate);
            lastUpdate = curTime;

            x = values[SensorManager.DATA_X];
            y = values[SensorManager.DATA_Y];
            z = values[SensorManager.DATA_Z];

            float speed = Math.abs(x+y+z - last_x - last_y - last_z) / diffTime * 10000;

            if (speed > SHAKE_THRESHOLD) { 
                long curTime = System.currentTimeMillis();
                long diff = (curTime - shakeTime);              
                shakeTime = curTime;

                if (myFlagIgnoreShakeDetection==true)  //Caused unneccessary accelerometer   
                                                       //notification looping when device is idle
                   return;

                // Doing something...
            }
         last_x = x;
         last_y = y;
         last_z = z;
        }

    }

}
War es hilfreich?

Lösung

Hier sind ein paar Code Diskrepanzen ...

  • Es kann ein Problem in Bezug auf die Aktualisierung von last_x, last_y und last_z sein. Ich glaube, sie sollten enthalten innen werden die if ((curTime - lastUpdate) > 100) { Aussage. Mit anderen Worten, werden sie jedes Mal onSensorChanged heißt, nicht alle 100 Millisekunden aktualisiert. Sie sollten wahrscheinlich die Aktualisierung dieser drei Variablen in die geschweifte Klammer über sie bewegen.

  • Auf der Linie, wo Sie die speed berechnen, endet die Formel mit ... / diffTime * 10000; Sind Sie wollen von 10000, oder dem gesamten Ergebnis nur diffTime zu multiplizieren? Da / und * typischerweise die gleiche Operatorpräzedenz href="http://en.wikipedia.org/wiki/Order_of_operations" haben weiß ich (wie < a href = "http://www.cs.uwf.edu/~eelsheik/cop2253/resources/op_precedence.html" rel = "nofollow noreferrer"> Java ), wird Ihre Gleichung von links nach rechts ausgewertet werden , die zuerst von diffTime Dividieren und das Ergebnis durch 10000 multipliziert wird.

    Ich vermute, Sie nur diffTime von 10000 zu multiplizieren bedeuten, also Teilungs das Endergebnis um diesen Betrag. Das ist der Unterschied zwischen durch 10000 dividiert oder durch 10000 multipliziert wird, das heißt, Sie sind wahrscheinlich Werte für speed erhalten, die 10 ^ 8 größer sind, als Sie sollten, damit Ihre Auslöseschwelle selbst wenn das Gerät in Betrieb ist. Sie müssen Klammern um die Multiplikation, wie ... / (diffTime * 10000); setzen, um sicherzustellen, dass es ausgeführt vor die Aufteilung erfolgt.

    Darüber hinaus, wenn Sie beabsichtigen, diffTime von Millisekunden bis Sekunden zu skalieren, soll Ihr Skalierungsfaktor 1000 sein.

Andere Tipps

ich in meiner Augmented-Reality-Bibliothek persönlich, verwenden Sie einen gleitenden Durchschnitt für den Updates:

float kFilteringFactor = (float)0.05;    
rollingZ = (float) ((rawZValue * kFilteringFactor) + (rollingZ * (1.0 - kFilteringFactor)));

Dies führt dazu, ziemlich gut, die Daten zu glätten, und Sie können den Filterfaktor zwicken die Ansprechempfindlichkeit Sie wollen bekommen.

rawZValue ist der Rohwert in von dem Beschleunigungsmesser kommen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top