如何计算掉手时Android Phone的垂直距离?

问题描述 投票:1回答:1

因此,我使用加速度计来检查手机是否掉落。这部分工作很好。我将以下给出的链接用于上述目的。https://github.com/altermarkive/experimental-fall-detector-android-app

现在,下一步是计算它垂直移动的距离。我为此目的尝试了很多事情,但是每次高度都不正确时。另外,高度在不同设备上的变化也不同。

我从加速度传感器获得加速度数据,之后我使用下面给出的公式来计算行进距离。

我尝试的第一个代码:-

    long curTime = System.currentTimeMillis();

    if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
        // sampling frequency f= 10Hz.
        if ((curTime - lastUpdate) > CHECK_INTERVAL) {

            long diffTime = (curTime - lastUpdate);
            lastUpdate = curTime;

            accel_values = event.values.clone();

            if (last_accel_values != null) {

                mAccelLast = mAccelCurrent;
                mAccelCurrent =(float)Math.sqrt(accel_values[0]* accel_values[0] + 
                          accel_values[1]*accel_values[1]
                        + accel_values[2]*accel_values[2]);

                Message msg = mHandler.obtainMessage(Constants.MESSAGE_CHANGED);
                Bundle bundle = new Bundle();
                bundle.putFloat(Constants.VALUE, mAccelCurrent);
                msg.setData(bundle);
                mHandler.sendMessage(msg);

                mWindow.add(mAccelCurrent);
                if (mWindow.isFull() && mWindow.isFallDetected()){
                    Log.w(TAG, "Fall detected by window class");
                    actime = curTime - diffTime;
                    velocity = actime * acceleration;
                    avgvelocity = velocity / 2;
                    height = avgvelocity * actime;
                    mWindow.clear();
                    msg = mHandler.obtainMessage(Constants.MESSAGE_EMERGENCY);
                    mHandler.sendMessage(msg);
                }
            }

            last_accel_values = accel_values.clone();
        }
    }

我尝试的第二个代码:-

            final double alpha = 0.8;

            double gravity[] = new double[3], linear_acceleration[] = new double[3];
            // Isolate the force of gravity with the low-pass filter.
            gravity[0] = alpha * gravity[0] + (1 - alpha) * sensorEvent.values[0];
            gravity[1] = alpha * gravity[1] + (1 - alpha) * sensorEvent.values[1];
            gravity[2] = alpha * gravity[2] + (1 - alpha) * sensorEvent.values[2];
            double curr_gravity = gravity[0] + gravity[1] + gravity[2];

            // Remove the gravity contribution with the high-pass filter.
            linear_acceleration[0] = sensorEvent.values[0] - gravity[0];
            linear_acceleration[1] = sensorEvent.values[1] - gravity[1];
            linear_acceleration[2] = sensorEvent.values[2] - gravity[2];

            double curr_acc = linear_acceleration[0] + linear_acceleration[1] + linear_acceleration[2];

            long seconds = System.currentTimeMillis();
            double velocity = curr_acc * seconds;
            double init_vel = velocity / 2;

            double time = (velocity - init_vel) / curr_gravity;
            double height = (((seconds * 9.8)/2) - init_vel);

我尝试的第三个公式:-

long curTime = System.currentTimeMillis();

    if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
        // sampling frequency f= 10Hz.
        if ((curTime - lastUpdate) > CHECK_INTERVAL) {

            long diffTime = (curTime - lastUpdate);
            lastUpdate = curTime;

            accel_values = event.values.clone();

            if (last_accel_values != null) {

                mAccelLast = mAccelCurrent;
                mAccelCurrent =(float)Math.sqrt(accel_values[0]* accel_values[0] + 
                          accel_values[1]*accel_values[1]
                        + accel_values[2]*accel_values[2]);

                Message msg = mHandler.obtainMessage(Constants.MESSAGE_CHANGED);
                Bundle bundle = new Bundle();
                bundle.putFloat(Constants.VALUE, mAccelCurrent);
                msg.setData(bundle);
                mHandler.sendMessage(msg);

                mWindow.add(mAccelCurrent);
                if (mWindow.isFull() && mWindow.isFallDetected()){
                    Log.w(TAG, "Fall detected by window class");
                    actime = curTime - diffTime;
                    height = 0.5*9.8*actime*actime;
                    mWindow.clear();
                    msg = mHandler.obtainMessage(Constants.MESSAGE_EMERGENCY);
                    mHandler.sendMessage(msg);
                }
            }

            last_accel_values = accel_values.clone();
        }
    }

我还尝试过将其他传感器用于同一目的,例如晴雨表,但从中得到相同的结果(高度并没有达到预期的水平)。另外,我尝试寻找第三方SDK,但它们也使用自己的硬件。任何帮助将不胜感激。同样,如果有人可以以正确的方式进行指导,那将非常有帮助。预先感谢。

android height accelerometer android-sensors
1个回答
0
投票

似乎您在这三种方法中都有相同的错误。在这三者中,有时都将加速度乘以System.currentTimeMillis()的绝对时间戳。这是自1970年以来的毫秒数,在您的情况下没有直接含义,除非您使用它来计算时间间隔作为差异。在某些示例中,您执行了此操作,但是您再次从System.currentTimeMillis()中减去了它,这再次导致自1970年以来的毫秒数。

似乎您尝试实现s = 1/2 at²,但这仅对于在时间间隔t内从静止状态持续加速的情况下有效。如果要从一系列测量加速度中得出距离,则需要对它们进行数值积分(听起来比实际困难),并且可能需要使用一些滤波。

但是,我的建议是假设自由落体的加速度为9.81 m /s²。这忽略了空气阻力或地球加速度的局部变化,但是除非您想在某些奇怪的情况下使用它,否则它可能比使用传感器的读数精确得多。特别是当手机旋转时,还由于校准不当以及某些过滤将实际加速度与重力加速度分开,我不希望传感器的读数优于逼近完美的自由落体。毕竟,智能手机是比较稠密的物体,不受空气阻力的影响很大。

好处是,您可以简单地使用s = 1/2 at²。只要确保t不是1970年以来的时间间隔,而是从跌落开始(您说可以可靠地检测到)到跌落结束(即开始和结束之间的时间戳记之差)的计时器间隔即可。最后的时间戳记)。另外,我建议使用来自传感器事件的时间而不是System.currentTimeMillis(),因为它具有更好的分辨率,并且是针对这种类型的计算而设计的。

© www.soinside.com 2019 - 2024. All rights reserved.