Android: Accelerometer falsche Erkennung
-
06-07-2019 - |
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;
}
}
}
Lösung
Hier sind ein paar Code Diskrepanzen ...
-
Es kann ein Problem in Bezug auf die Aktualisierung von
last_x
,last_y
undlast_z
sein. Ich glaube, sie sollten enthalten innen werden dieif ((curTime - lastUpdate) > 100) {
Aussage. Mit anderen Worten, werden sie jedes MalonSensorChanged
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 nurdiffTime
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 vondiffTime
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ürspeed
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.