线性加速度方向跟踪手机的上下移动

我试图跟踪设备的运动只在垂直方向上,即向上和向下移动。 这应该与设备的方向无关。 事情,我已经知道或尝试过这些

  1. 线性加速度由传感器TYPE_LINEAR_ACCELERATION给出,轴是电话轴,因此跟踪任何特定的轴没有什么区别。

  2. 我尝试应用旋转vector的转置或反转(对于旋转vector的反转或转置相同),然后尝试跟踪线性加速度vector的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. 

这个方法有什么缺点? 请帮忙,我一直在这一段时间卡住了。

Solutions Collecting From Web of "线性加速度方向跟踪手机的上下移动"

正如我所看到的,在第三种方法中,您试图find两个vector(重力vector和加速度vector)之间的angular度的cos。 而这个想法是,如果angular度接近180度你有运动,如果angular度接近0度,你有下移动。 当angular度从-90到90度时,余弦函数具有正值。 所以当你的cosineVal值是正值时,这意味着手机正在下降,即使cosineVal接近1的运动是直线下降。 所以反之亦然。 当余弦为负数时(从90度到270度),你已经有了运动。

可能你可以从https://developer.android.com/reference/android/hardware/SensorEvent.html#values那里得到来自Sensor.TYPE_ACCELEROMETERvector,那里有重力vector和加速度vector。
我做了一个代码片段,你可以尝试。

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