如何使用加速度计计步?

9

我需要开发与这个计步器应用相同的功能。

我已经非常详细地观察了这个计步器应用

它不是一个完美的计步器应用。例如,如果你呆在一个地方并摇动手,它也会检测到步数和距离。

忽略这种理想的重力行为,因为在这个应用程序的说明中已经提到,你应该把iPhone绑在身上或放在口袋里来计算步数。通过这种方式,我发现这个应用程序工作得非常好,几乎可以检测到所有的步数。

我的问题是:我根据以上逻辑开发了一个样本,但它的工作水平还没有达到那个水平。例如,有时它会同时检测到2-3个步骤。而有时它的工作正常。

我的代码:

在viewDidLoad中:

[[UIAccelerometer sharedAccelerometer] setUpdateInterval:0.2] 

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
    const float violence = 1.2;
    static BOOL beenhere;
    BOOL shake = FALSE;
    if (beenhere) return;
    beenhere = TRUE;
    if (acceleration.x > violence || acceleration.x < (-1* violence))
       shake = TRUE;
    if (acceleration.y > violence || acceleration.y < (-1* violence))
       shake = TRUE;
    if (acceleration.z > violence || acceleration.z < (-1* violence))
       shake = TRUE;
    if (shake) {
       steps=steps+1;
     }
  beenhere = false;
}

我做错了什么?我无法确定阈值。如果我将其设为高,它就无法检测到微小的步骤。如果我将它设为小,它会同时注册3-4个步骤。

这需要其他实现方式?还是需要对代码进行一些调整?

我已经看过所有其他类似的Stack Overflow链接,但没有找到能达到这个水平的解决方案。

请帮忙。


如果你得到了答案,能否请分享代码? - Chanchal Raj
2个回答

20

虽然在计数呼噜声而非步数,但问题类似。以下是一些建议,尽管没有确切答案:

  1. 要求步伐之间的时间间隔。是的,一个人可能走得很慢或者跑步,但即便是最快的速度,两步之间也会有大约1/5秒的时间间隔。如果"冲击"看起来比这个更频繁,它们可能只是来自于反弹/晃动。
  2. 与其使用固定阈值(violence),不如采用基于前面事件的指数移动平均值的可变阈值。
  3. 考虑保留x、y和z轴上的不同阈值,这些阈值基于手机在短时间内不会改变方向的假设。
  4. 与其仅忽略超过某个特定强度级别的事件,不如考虑忽略那些超出范围的事件,它们的限制由两个阈值(一个可能是另一个的一部分)指定。
  5. 考虑当你行走时会发生什么——身体会有前后加速运动,这是相当有节奏的,同时还有一个"冲击",即脚着地时发生的冲击。最好的方法可能是忽略这个短期信号,而是寻找前后运动的节奏。

另一个建议

无法在现场测试这个应用。(我可以想象你试图拿着笔记本电脑在前面跑步,试图让调试器控制台聚焦。)你应该先配置你的应用程序以记录一些原始测量值(即,编写文件),然后重新配置你的应用程序(#ifdefs会很方便)以能够"回放"这些测量值,以便你可以使用调试器逐步查看应用程序的行为。


2
+1 对于一个非常好的答案。另外,在#1上...作为一名跑步者,我可以告诉你,每步1/5秒是不可能的快速节奏。真正快速的转换率约为190 bpm,即每秒3个脚步声左右。对于OP的目的来说,这很好,因为您查看的分辨率越粗糙,您可以筛选出更多的抖动。我也非常喜欢移动平均建议,因为您击中地面的冲击力取决于您的跑步风格,形态质量,身体组成,速度和其他因素。魔术数字永远不会真正起作用。 - Dan Ray
谢谢Licks和Dan。那么,你们建议将setUpdateInterval的值设为多少,而不是0.2?你们能否提供如何设置阈值变量的建议? - Tariq
0.2 的更新间隔可能对于初学者来说是不错的选择。如果要使阈值变量化,您可能需要保持先前加速度计数值的移动平均值(x、y 和 z 分别计算),并使用移动平均值的 2 倍或 3 倍作为阈值。 - Hot Licks
可能有助于生成一些运动图表,以查看当它出现问题和正常时的值通常是什么。最好生成多个不同人的图表。 - Aberrant
如果不是图形,至少要有事件的常规NSLog,显示输入值、阈值和其他计算值。使用图形标志(例如 **)来指示“重要”的值,例如表明步幅的加速度测量值。(当然,一定要以某种方式 #ifdef NSLogs,以便在生产中关闭它们。) - Hot Licks

0
        var motionManager = CMMotionManager()
        motionManager.deviceMotionUpdateInterval = 0.1
        motionManager.startDeviceMotionUpdatesToQueue(NSOperationQueue.currentQueue(), withHandler:{
            deviceManager, error in

            var accelerationThreshold:Double = 1;
            var userAcceleration:CMAcceleration = deviceManager.userAcceleration;
            if(fabs(userAcceleration.x) > accelerationThreshold) || (fabs(userAcceleration.y) > accelerationThreshold) || (fabs(userAcceleration.z) > accelerationThreshold)
            {
                println("LowPassFilterSignal")
            }
        })

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接