android - 检测向下加速度,特别是电梯

时间:2016-06-09 13:26:32

标签: android accelerometer android-sensors hardware-acceleration acceleration

我希望能够检测到手机向地面加速的情况(可能意味着此处也必须使用重力传感器)。

我在Android文档中已经阅读了很多关于此主题的内容,关于高通和低通滤波器以及其他帖子,现在我所拥有的是一个代码示例,它在剥离后获得X,Y和Z轴的加速度引力:

if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {

        final float alpha = (float) 0.8;

        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];  
}

所以,linear_acceleration应该是没有重力的X,Y,Z轴加速度。

这一切都很好,但问题显然在于这取决于用户如何握住手机,例如,在电梯中 - 如果他保持平坦,平行于地面 - Z axis会改变如果他直截了当 - Y axis会改变,等等。

因此,例如,如果用户对角地握住电话,则加速将被分开"在不同的轴之间,以及某种数学工作,考虑重力方向的位置,将需要计算该方向的实际加速度。

如果我错了,请纠正我?

是否有可靠的方法来检测向下(朝向地球)的加速度?也许使用像陀螺仪这样的其他传感器?

BTW - 关于TYPE_LINEAR_ACCELERATION类型,我读了answer,说它实际上不是很准确。

2 个答案:

答案 0 :(得分:1)

我也希望能够测量垂直运动。这就是我做到的,它对我有用。第一次在这个网站上发帖,我不知道如何正确格式化。

使用两个不同的Android传感器:Type_linear_Acceleration and Type_Gravity

线性加速度可以让你在手机的X,Y和Z轴上加速,而重力会做同样的事情,但只是为了重力。您知道重力值的总和应该= 9.8,但这将根据手机方向在X,Y和Z坐标之间分开。

我不会对它进行过多的数学计算,但是下面的内容将为您提供没有重力的垂直加速度。如果你想要了解它,可以通过某些值来运行,就好像手机是垂直握持的,然后是水平的,即使手机是倾斜的,也能正常工作。

  

垂直加速度=(LinearAccelX * GravityX / 9.8)+(LinearAccelY * GravityY / 9.8)+(LinearAccelZ * GravityZ / 9.8)。

请参阅下面的代码(删除了相关部分):

{public class MainActivity extends AppCompatActivity implements SensorEventListener {

SensorManager sm;
Sensor linearaccelerometer;
Sensor gravity;
double Yaccel;
double Xaccel;
double Zaccel;
double gravityY;
double gravityX;
double gravityZ;
double verticalAccel;

    sm = (SensorManager) getSystemService(SENSOR_SERVICE);
    linearaccelerometer = sm.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION);
    gravity = sm.getDefaultSensor(Sensor.TYPE_GRAVITY);

    sm.registerListener(this, linearaccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
    sm.registerListener(this, gravity, SensorManager.SENSOR_DELAY_NORMAL);
}

public void onSensorChanged(SensorEvent event) {

    Sensor sensor = event.sensor;

    if (sensor.getType() == Sensor.TYPE_LINEAR_ACCELERATION) {
        Xaccel = (double) event.values[0];
        Yaccel = (double) event.values[1];
        Zaccel = (double) event.values[2];
    }

    if (sensor.getType() == Sensor.TYPE_GRAVITY) {
        gravityX = (double) event.values[0];
        gravityY = (double) event.values[1];
        gravityZ = (double) event.values[2];
    }

    verticalAccel = (Xaccel * gravityX / 9.8) + (Yaccel * gravityY / 9.8) +  (Zaccel *gravityZ /9.8);

}

答案 1 :(得分:0)

使用一些基本物理。加速度是一个向量。矢量v的大小总是等于(v.v)^ .5,或点积的平方根。或者用更简单的术语(x ^ 2 + y ^ 2 + z ^ 2)^。5。这将告诉你加速度的数量,但不会告诉你它是朝向还是远离地球。

如果您需要知道它是朝向还是远离地球 - 您可以将其与SensorManager.getOrientation中的数据相结合。您可能需要在他们进入电梯之前这样做 - 方向代码使用重力作为其输入之一,因此如果您尝试在电梯中使用它,它可能会搞砸。你需要测试一下。

如果需要将其分解为地球x,y和z轴的加速度 - 简单的几何形状。从定向结果中取出角度,并使用trig属性转换轴。如果你不知道公式,你需要阅读一下,或者即使我告诉你,你也会弄错它们。