2014-10-02 9 views
8

Sto provando a seguire il movimento del dispositivo solo sulla direzione verticale, cioè verso l'alto e verso il basso. Questo dovrebbe essere indipendentemente dall'orientamento del dispositivo. Cose che so già o provato sono questiDirezione di accelerazione lineare per tracciare il movimento verso l'alto e il basso del telefono

  1. accelerazione lineare è dato dal sensore TYPE_LINEAR_ACCELERATION e gli assi sono gli assi del telefono e quindi il monitoraggio qualsiasi asse particolare non fa differenza.

  2. Ho provato ad applicare la trasposizione o l'inverso del vettore di rotazione (inverso o trasposto per il vettore di rotazione sono gli stessi) e quindi ho cercato di tracciare la direzione z del vettore di accelerazione lineare. Non sembra aiutare.

  3. Sto provando a fare un prodotto punto con valori di gravità (TYPE_GRAVITY) per ottenere la direzione dell'accelerazione, ma sembra essere soggetto a errori. Anche quando sposto il mio dispositivo rapidamente, dice che sta andando giù.

illustrerà questo metodo qui

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

Qual è il difetto con il metodo? Per favore aiuto, sono stato bloccato su questo per un po 'di tempo.

risposta

1

Come vedo, nel terzo metodo si sta cercando di trovare il cos dell'angolo tra due vettori (vettore di gravità e vettore di accelerazione). E l'idea è che se l'angolo è vicino a 180 gradi hai il movimento in su, se l'angolo è vicino a 0 gradi hai movimento verso il basso. Il coseno è una funzione che ha un valore positivo quando l'angolo è compreso tra -90 e 90 gradi. Quindi, quando il tuo valore cosineVal è positivo significa che il telefono sta scendendo e anche se il cosenoVal più vicino a 1 movimento è diretto verso il basso. Quindi è vero viceversa. Quando il coseno è negativo (da 90 gradi a 270) si ha movimento verso l'alto.

Probabilmente è possibile ottenere vettori da Sensor.TYPE_ACCELEROMETER da https://developer.android.com/reference/android/hardware/SensorEvent.html#values lì si dispone di vettore di gravità e vettore di accelerazione.
Ho creato uno snippet di codice qui sotto puoi provare.

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) { 

    } 
} 
Problemi correlati