使用陀螺仪检测iOS设备360°的旋转

5

我希望我的应用程序能够在设备水平持握时检测设备旋转。我可以使用罗盘的读数,但我认为陀螺仪的偏航值更准确。给定偏航读数,确定360°旋转(顺时针或逆时针)的最佳算法是什么?而且它必须是完整的360°旋转,不能只是将手机向一个方向旋转180°,再向相反方向旋转180°。

2个回答

3

您可以使用CoreMotion获取垂直轴的旋转。您需要添加旋转事件的增量。每当超过最小值,与先前不同的方向时,您就会重置起始点。然后当您从此起始点到达加或减360度时,您就有了旋转。


是的,CoreMotion使用陀螺仪和罗盘的组合来给出设备方向更精确和准确的读数。 - Fogmeister

2
假设您可以在短时间间隔内获得读数,并且偏航角可以在特定起点归零,这是一种想法。这与其他答案不同,其他答案从连续适应的起点检测完整的圆。在此方法中,我们将当前偏航角与上一个偏航角进行比较,询问是否已经通过180度或PI的检查点。最初,检查点标志cp_piNO,并且在任何方向上通过它都会切换其状态。请注意,偏航角在两个位置改变其符号,在零点处再次改变符号,并到达PI-PI
假设您的对象具有两个属性,这些属性在探测器的tick之间保持不变,BOOL cp_pi;float prev_yaw;,我们认为对于穿过0的情况,d_yaw小于PI,而对于穿过圆形相反端点的情况,d_yaw大于PI。当穿过相反的端点时,我们切换cp_pi。当cp_piYES并穿过0时,我们保证已经通过了一个完整的圆 - 否则,cp_pi将被切换回NO
-(void)tick
{
    float yaw = [self zeroedYaw];
    if ((fabs(yaw) == PI) || (yaw == 0.0f)) return;

    if (yaw * prev_yaw < 0)
    {
        float d_yaw = fabs(yaw - prev_yaw);
        if (d_yaw > PI)
        {
            cp_pi = ! cp_pi;
        }
        else if (cp_pi)
        {
            // fire detection event
        }
    }
    prev_yaw = yaw;
}

请注意,为了让我们的生活更轻松,如果 yaw 恰好位于其中一个检查点上,则会完全跳过检测函数。

如果我向一个方向旋转超过180度,然后又向相反的方向旋转180度回到0度,这是否仍然算作一次旋转? - thisiscrazy4
这是没问题的,因为 cp_pi = ! cp_pi 在第二次交叉时会翻转回 NO,所以它不会被检测为旋转。 - s.bandara
如果您再次完成整个圆圈,cp_pi 就会在 +/- PI 时再次翻转到 YES,并且事件最终将在 0 处触发。因此,只有完整的圆圈才会计数。 - s.bandara
嘿,真是一个不错的解决方案... 请问 zeroedYaw 是什么作用? - Ahmed Z.
1
@AbmedZ,zeroedYaw必须返回一个在 -PIPI 之间的偏航角,并且围绕初始偏航角为零。 - s.bandara

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