Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/183.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Android加速计检测步行_Android_Filter_Accelerometer_Kalman Filter - Fatal编程技术网

如何使用Android加速计检测步行

如何使用Android加速计检测步行,android,filter,accelerometer,kalman-filter,Android,Filter,Accelerometer,Kalman Filter,我正在编写一个应用程序,我的目标是检测用户何时行走。 我使用的是这样的卡尔曼滤波器: float kFilteringFactor=0.6f; gravity[0] = (accelerometer_values[0] * kFilteringFactor) + (gravity[0] * (1.0f - kFilteringFactor)); gravity[1] = (accelerometer_values[1] * kFilteringFactor) +

我正在编写一个应用程序,我的目标是检测用户何时行走。 我使用的是这样的卡尔曼滤波器:

float kFilteringFactor=0.6f;

        gravity[0] = (accelerometer_values[0] * kFilteringFactor) + (gravity[0] * (1.0f - kFilteringFactor));
        gravity[1] = (accelerometer_values[1] * kFilteringFactor) + (gravity[1] * (1.0f - kFilteringFactor));
        gravity[2] = (accelerometer_values[2] * kFilteringFactor) + (gravity[2] * (1.0f - kFilteringFactor));

        linear_acceleration[0] = (accelerometer_values[0] - gravity[0]);
        linear_acceleration[1] = (accelerometer_values[1] - gravity[1]);
        linear_acceleration[2] = (accelerometer_values[2] - gravity[2]);

        float magnitude = 0.0f;
        magnitude = (float)Math.sqrt(linear_acceleration[0]*linear_acceleration[0]+linear_acceleration[1]*linear_acceleration[1]+linear_acceleration[2]*linear_acceleration[2]);
        magnitude = Math.abs(magnitude);
if(magnitude>0.2)
  //walking
数组重力[]初始化为0

我可以检测用户是否在行走(查看加速度向量的大小),但我的问题是,当用户不在行走并且移动手机时,他似乎在行走

我是否使用了正确的过滤器


仅仅观察向量的大小是正确的还是让我看单个值?

编辑:我认为它不够精确,因为正常行走时平均加速度接近0。你能做的最多的测量加速度的方法就是检测某人何时开始行走或停止(但正如你所说的,很难从站在一个地方的人移动的设备中过滤出来)

所以。。。我之前写的东西可能无论如何都不管用:

当用户不移动时,您可以通过丢弃来“预测”用户是否正在移动(很明显),我想到的前两个选项是:
使用接近和光线传感器(可选)检查手机是否“隐藏”。这种方法精度较低,但更简单。

控制移动的连续性,如果手机移动超过。。。10秒的动作并不是卑鄙的,那么你认为他在走路。我知道这也不太好,但是如果不使用任何一种定位的话,顺便说一句。。。为什么不直接使用
LocationManager

对于行走检测,我使用应用于加速计平滑信号的导数。当导数大于阈值时,我可以认为这是一个步骤。但我想这不是最好的做法,而且只有当手机放在裤子口袋里时,它才起作用

此应用程序中使用了以下代码


我的第一个直觉是对传感器历史进行FFT分析,看看哪些频率在行走时具有较高的量级

它本质上是观察行走“听起来像什么”,将加速度计传感器的输入像麦克风一样对待,并观察行走时的响亮频率(换句话说,最大加速度发生的频率是多少)

我猜你会在某个低频率下寻找一个高震级(比如脚步速度)或者其他东西。看到这些数据会很有趣


我的猜测是你运行FFT,寻找某个频率的幅值大于某个阈值,或者两个频率的幅值之差大于某个数值。同样,实际数据将决定您尝试检测它的方式。

谷歌为这个名为
DetectedActivity
的API提供了一个API,可以使用
ActivityRecognitionApi
获取该API。这些文档可以访问和保存

DetectedActivity
具有获取用户当前活动的方法
public int getType()
,以及返回0到100之间的值的方法
public int getConfidence()
getConfidence()
返回的值越高,API越确定用户正在执行返回的活动

下面是由
getType()
返回的内容的持续摘要:

  • int IN_VEHICLE该设备位于车辆内,如汽车
  • int ON_BICYCLE该设备位于自行车上
  • int ON_FOOT该设备位于正在行走或跑步的用户身上
  • int运行设备的用户正在运行
  • int静止设备静止(不移动)
  • int倾斜装置相对于重力的角度发生显著变化
  • int UNKNOWN无法检测当前活动
  • int WALKING设备位于正在行走的用户身上

试着检测上下摆动、前后摆动以及每种摆动的频率,并确保它们在平均范围内保持一致,因为你可以检测到行走,特别是该人的步态风格,该步态应在几步内保持相对恒定,以符合移动的条件。 只要最后3次振荡在合理范围内排列,那么就可以得出结论,只要这也是正确的:-

测量水平加速度并使用它更新速度值。速度会随时间漂移,但你需要在一步的时间内保持速度的移动平均值平滑,只要它每3次振荡的漂移速度不超过行走速度的一半,那么它就是行走速度,但前提是它最初在短时间内上升到行走速度,即半秒或2次振荡。
所有这些都应该足以涵盖它。
当然,一点人工智能将有助于使事情变得更简单或同样复杂,但如果您将所有这些都视为神经网络的输入,则会令人惊讶地精确。Ie预处理

你是在考虑向前移动的加速度,还是只考虑“上下移动”?我在考虑手机的上下移动和旋转。当使用者不走路时,允许他做这种运动;但我不希望这些被检测为行走。用户是手持手机行走,还是将手机放在口袋中行走?用户是手持手机行走?您可以尝试使用摄像头来检测移动而不是加速计,正如你所说的,用户在使用你的应用程序/游戏时应将手机握在手中!我无法使用LocationManager,因为我想在用户不行走时停止获取位置更新。用户将使用我的游戏/应用程序查看手机。但使用加速度计检测行走是否正确?@havanakoda,现在我深入思考,它的准确度真的很低,因为当你行走时,你几乎没有加速,所以加速度计的值会很低。我不知道这是否值得一试。人类上下摆动,脚步声的冲击会射出thr
    @Override
    public void onSensorChanged(SensorEvent event) {
        if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER){
            return;
        }
        final float z = smooth(event.values[2]); // scalar kalman filter                               
        if (Math.abs(z - mLastZ) > LEG_THRSHOLD_AMPLITUDE)
        {
            mInactivityCount = 0;
            int currentActivity = (z > mLastZ) ? LEG_MOVEMENT_FORWARD : LEG_MOVEMENT_BACKWARD;                  
            if (currentActivity != mLastActivity){
                mLastActivity = currentActivity;
                notifyListeners(currentActivity);
            }                   
        } else {
            if (mInactivityCount > LEG_THRSHOLD_INACTIVITY) {
                if (mLastActivity != LEG_MOVEMENT_NONE){
                    mLastActivity = LEG_MOVEMENT_NONE;
                    notifyListeners(LEG_MOVEMENT_NONE);                                 
                }
            } else {
                mInactivityCount++;
            }
        }
        mLastZ = z;
    }