2014-10-02 3 views
8

장치의 수직 방향, 즉 위쪽 및 아래쪽 이동에서만 장치의 움직임을 추적하려고합니다. 이것은 장치의 방향에 관계없이 이루어져야합니다. 내가 이미 알고 또는 시도 상황이 이러한전화의 위아래 이동을 추적하기위한 선형 가속 방향

  1. 선형 가속도 센서 TYPE_LINEAR_ACCELERATION에 의해 ​​주어진다하고 축이 전화 축이며, 따라서 특정 축 추적하는 차이를 만들지 않습니다.

  2. 회전 벡터의 전치 또는 역 (회전 벡터에 대해 역 또는 전치가 동일 함) 적용한 다음 선형 가속 벡터의 z 방향을 추적하려고 시도했습니다. 도움이되지 않는다.

  3. 중력 값 (TYPE_GRAVITY)을 가진 내적 생성을 수행하여 가속 방향을 얻으 려하지만 오류가 발생하는 것으로 보입니다. 내 장치를 신속하게 위로 올리더라도 내려간다고합니다.

여기이 방법

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

방법에 결함이 무엇입니까 개설 할 것이다? 제발 도와주세요, 나는 지금 당분간이 일에 매달 렸습니다.

답변

1

내가 본 것처럼, 세 번째 방법에서는 두 벡터 (중력 벡터와 가속 벡터) 사이의 각도 cos을 찾으려고합니다. 그리고 만약 각도가 180도에 가까우면 움직임이 있습니다. 각도가 0도에 가까워지면 아래로 움직입니다. 코사인은 각도가 -90 ~ 90 도일 때 양수 값을 갖는 함수입니다. 따라서 cosineVal 값이 양수이면 전화가 내려 가고 1 운동에 근접한 코사인 값이 곧게 떨어 졌음을 의미합니다. 그래서 그 반대입니다. 코사인 값이 음수이면 (90도에서 270 도로) 움직임이 있습니다.

아마도 Sensor.TYPE_ACCELEROMETER에서 https://developer.android.com/reference/android/hardware/SensorEvent.html#values의 벡터를 얻을 수 있습니다. 중력 벡터와 가속 벡터가 있습니다.
아래에서 코드 스 니펫을 만들었습니다.

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

    } 
}