2014-10-02 15 views
8

Ich versuche, die Bewegung des Geräts nur in vertikaler Richtung, d. H. Aufwärts- und Abwärtsbewegung, zu verfolgen. Dies sollte unabhängig von der Ausrichtung des Geräts sein. Dinge, die ich bereits kennen oder versucht haben, sind dieseLineare Beschleunigungsrichtung, um die Aufwärts- und Abwärtsbewegung des Telefons zu verfolgen

  1. Lineare Beschleunigung durch den Sensor TYPE_LINEAR_ACCELERATION gegeben ist und die Achsen ist die Telefon Achsen und daher keine besonderen Achsen-Tracking macht keinen Unterschied.

  2. Ich habe versucht, Transponieren oder Kehrwert des Rotationsvektors (inverse oder transponieren für den Rotationsvektor sind die gleichen) und dann versucht, die Z-Richtung des linearen Beschleunigungsvektors zu verfolgen. Scheint nicht zu helfen.

  3. Ich versuche ein Skalarprodukt mit Gravitationswerten (TYPE_GRAVITY) zu erstellen, um die Richtung der Beschleunigung zu erhalten, aber es scheint fehleranfällig zu sein. Selbst wenn ich mein Gerät schnell hochfahre, sagt es, dass es nach unten geht.

Ich werde skizzieren diese Methode hier

dotProduct = vectorA[0]*vectorB[0]+vectorA[1]*vectorB[1] + vectorA[2]*vectorB[2];  
cosineVal = dotProduct/(|vectorA|*|vectorB|)  
if(cosineVal > 0) down else Up. 

Was ist der Fehler mit der Methode? Bitte helfen Sie mir, ich bin seit einiger Zeit daran fest.

Antwort

1

Wie ich sehe, in der dritten Methode, die Sie versuchen, den cos des Winkels zwischen zwei Vektoren (Schwerkraftvektor und Beschleunigungsvektor) zu finden. Und die Idee ist, wenn der Winkel nahe bei 180 Grad ist, hast du eine Aufwärtsbewegung, wenn der Winkel nahe bei 0 Grad ist, hast du eine Abwärtsbewegung. Kosinus ist eine Funktion, die einen positiven Wert hat, wenn der Winkel zwischen -90 und 90 Grad liegt. Wenn Ihr Wert cosineVal positiv ist, bedeutet dies, dass das Telefon nach unten geht und selbst wenn cosineVal näher bei 1 ist, ist die Bewegung gerade. So ist es umgekehrt. Wenn der Kosinus negativ ist (von 90 ° bis 270 °), haben Sie Bewegung.

Wahrscheinlich können Sie Vektoren von Sensor.TYPE_ACCELEROMETER von https://developer.android.com/reference/android/hardware/SensorEvent.html#values dort bekommen Sie haben Gravitationsvektor und Beschleunigungsvektor.
Ich habe ein Code-Snippet unter Sie können versuchen.

public class MainActivity extends AppCompatActivity implements SensorEventListener { 
    private float[] gravity = new float[3]; 
    private float[] linear_acceleration = new float[3]; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     SensorManager mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); 
     Sensor mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 
     mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL); 
    } 

    @Override 
    public void onSensorChanged(SensorEvent event) { 
     // alpha is calculated as t/(t + dT) 
     // with t, the low-pass filter's time-constant 
     // and dT, the event delivery rate 

     final float alpha = 0.8f; 

     gravity[0] = alpha * gravity[0] + (1 - alpha) * event.values[0]; 
     gravity[1] = alpha * gravity[1] + (1 - alpha) * event.values[1]; 
     gravity[2] = alpha * gravity[2] + (1 - alpha) * event.values[2]; 

     linear_acceleration[0] = event.values[0] - gravity[0]; 
     linear_acceleration[1] = event.values[1] - gravity[1]; 
     linear_acceleration[2] = event.values[2] - gravity[2]; 

     float scalarProduct = gravity[0] * linear_acceleration[0] + 
       gravity[1] * linear_acceleration[1] + 
       gravity[2] * linear_acceleration[2]; 
     float gravityVectorLength = (float) Math.sqrt(gravity[0] * gravity[0] + 
       gravity[1] * gravity[1] + gravity[2] * gravity[2]); 
     float lianearAccVectorLength = (float) Math.sqrt(linear_acceleration[0] * linear_acceleration[0] + 
       linear_acceleration[1] * linear_acceleration[1] + linear_acceleration[2] * linear_acceleration[2]); 

     float cosVectorAngle = scalarProduct/(gravityVectorLength * lianearAccVectorLength); 

     TextView tv = (TextView) findViewById(R.id.tv); 
     if (lianearAccVectorLength > 2) {//increase to detect only bigger accelerations, decrease to make detection more sensitive but noisy 
      if (cosVectorAngle > 0.5) { 
       tv.setText("Down"); 
      } else if (cosVectorAngle < -0.5) { 
       tv.setText("Up"); 
      } 
     } 
    } 

    @Override 
    public void onAccuracyChanged(Sensor sensor, int i) { 

    } 
}