使用 CMDeviceMotion 跟踪 iPhone 随着时间的推移的倾斜度

发布于 2024-11-01 13:45:19 字数 2746 浏览 1 评论 0原文

我正在尝试使用 CMDeviceMotion 来跟踪 iPhone 何时向后倾斜,然后执行某些操作。我已经成功创建了 CMMotionManager,我正在从系统获取运动数据,并且正在过滤高于特定加速度的结果。

不过,我想做的是检测设备何时向后或向前倾斜超过一定速度。我该怎么做?

这是我到目前为止的代码:

更新:我想我解决了它。我正在寻找旋转速率属性,CMRotationRate。我已经将它们配对在一起,我实际上只需要 x 值,所以我会继续努力。如果有人对下面的代码有一些提示,我们将不胜感激。

    - (void)startMotionManager{
        if (motionManager == nil) {
            motionManager = [[CMMotionManager alloc] init];
        }

        motionManager.deviceMotionUpdateInterval = 1/15.0;
        if (motionManager.deviceMotionAvailable) {

            NSLog(@"Device Motion Available");
            [motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue currentQueue]
                                               withHandler: ^(CMDeviceMotion *motion, NSError *error){
                                                       //CMAttitude *attitude = motion.attitude;
                                                       //NSLog(@"rotation rate = [%f, %f, %f]", attitude.pitch, attitude.roll, attitude.yaw);
                                                   [self performSelectorOnMainThread:@selector(handleDeviceMotion:) withObject:motion waitUntilDone:YES];

                                               }];
                //[motionManager startDeviceMotionUpdates];


        } else {
            NSLog(@"No device motion on device.");
            [self setMotionManager:nil];
        }
    }

   - (void)handleDeviceMotion:(CMDeviceMotion*)motion{
    CMAttitude *attitude = motion.attitude;

    float accelerationThreshold = 0.2; // or whatever is appropriate - play around with different values
    CMAcceleration userAcceleration = motion.userAcceleration;

    float rotationRateThreshold = 7.0;
    CMRotationRate rotationRate = motion.rotationRate;

    if ((rotationRate.x) > rotationRateThreshold) {
        if (fabs(userAcceleration.x) > accelerationThreshold || fabs(userAcceleration.y) > accelerationThreshold || fabs(userAcceleration.z) > accelerationThreshold) {

            NSLog(@"rotation rate = [Pitch: %f, Roll: %f, Yaw: %f]", attitude.pitch, attitude.roll, attitude.yaw);
            NSLog(@"motion.rotationRate = %f", rotationRate.x);

            [self showMenuAnimated:YES];
        }
    }

    else if ((-rotationRate.x) > rotationRateThreshold) {
        if (fabs(userAcceleration.x) > accelerationThreshold || fabs(userAcceleration.y) > accelerationThreshold || fabs(userAcceleration.z) > accelerationThreshold) {

            NSLog(@"rotation rate = [Pitch: %f, Roll: %f, Yaw: %f]", attitude.pitch, attitude.roll, attitude.yaw);
            NSLog(@"motion.rotationRate = %f", rotationRate.x);

            [self dismissMenuAnimated:YES];
        }
    }
}

I'm trying to use CMDeviceMotion to track when the iPhone is tilted backwards, and then do something. I've successfully created the CMMotionManager, I'm getting motion data from the system, and I'm filtering for results above a certain acceleration.

What I want to do though, is detect when the device is being tilted backwards or forwards above a certain speed. How do I do that?

Here's the code I have so far:

UPDATE: I think I solved it. I was looking for the rotationRate property, CMRotationRate. I've paired them together, I really only need the x value, so I'll keep working on it. If anyone has some tips at the below code, it's much appreciated.

    - (void)startMotionManager{
        if (motionManager == nil) {
            motionManager = [[CMMotionManager alloc] init];
        }

        motionManager.deviceMotionUpdateInterval = 1/15.0;
        if (motionManager.deviceMotionAvailable) {

            NSLog(@"Device Motion Available");
            [motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue currentQueue]
                                               withHandler: ^(CMDeviceMotion *motion, NSError *error){
                                                       //CMAttitude *attitude = motion.attitude;
                                                       //NSLog(@"rotation rate = [%f, %f, %f]", attitude.pitch, attitude.roll, attitude.yaw);
                                                   [self performSelectorOnMainThread:@selector(handleDeviceMotion:) withObject:motion waitUntilDone:YES];

                                               }];
                //[motionManager startDeviceMotionUpdates];


        } else {
            NSLog(@"No device motion on device.");
            [self setMotionManager:nil];
        }
    }

   - (void)handleDeviceMotion:(CMDeviceMotion*)motion{
    CMAttitude *attitude = motion.attitude;

    float accelerationThreshold = 0.2; // or whatever is appropriate - play around with different values
    CMAcceleration userAcceleration = motion.userAcceleration;

    float rotationRateThreshold = 7.0;
    CMRotationRate rotationRate = motion.rotationRate;

    if ((rotationRate.x) > rotationRateThreshold) {
        if (fabs(userAcceleration.x) > accelerationThreshold || fabs(userAcceleration.y) > accelerationThreshold || fabs(userAcceleration.z) > accelerationThreshold) {

            NSLog(@"rotation rate = [Pitch: %f, Roll: %f, Yaw: %f]", attitude.pitch, attitude.roll, attitude.yaw);
            NSLog(@"motion.rotationRate = %f", rotationRate.x);

            [self showMenuAnimated:YES];
        }
    }

    else if ((-rotationRate.x) > rotationRateThreshold) {
        if (fabs(userAcceleration.x) > accelerationThreshold || fabs(userAcceleration.y) > accelerationThreshold || fabs(userAcceleration.z) > accelerationThreshold) {

            NSLog(@"rotation rate = [Pitch: %f, Roll: %f, Yaw: %f]", attitude.pitch, attitude.roll, attitude.yaw);
            NSLog(@"motion.rotationRate = %f", rotationRate.x);

            [self dismissMenuAnimated:YES];
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

中二柚 2024-11-08 13:45:19

您是否看过 CMAttitude?听起来像是你需要的,再加上一些数学我猜。


编辑:好的,你做到了。

引用 Apple 文档,第 1 章“获取当前设备方向”

如果您只需要了解一般信息
设备的方向,而不是
精确的方向向量,你
应该使用 UIDevice 的方法
类来检索该信息。
使用 UIDevice 接口很简单
并且不要求您
计算方向向量
你自己。

太好了,他们为我们做了数学。然后我想像上面的文档所解释的那样,像您一样跟踪加速度+跟踪方向应该可以使用 UIDeviceOrientationFaceUpUIDeviceOrientationFaceDown 来完成这项工作?

如果没有一个 UIDeviceOrientation 满足您的需求,您需要从两个 CMAttitude 引用计算一些空间角度,它提供了一个 rotationMatrix 和一个四元数...这些学校数学对我来说很遥远...然后我建议也许用这些搜索/问一个仅数学问题。

Have you looked at CMAttitude? Sounds like what you need, plus some mathematics I guess.


EDIT: Ok you did.

Quoting Apple documentation, at chapter "Getting the Current Device Orientation" :

If you need to know only the general
orientation of the device, and not the
exact vector of orientation, you
should use the methods of the UIDevice
class to retrieve that information.
Using the UIDevice interface is simple
and does not require that you
calculate the orientation vector
yourself.

Great, they do the maths for us. Then I guess that tracking acceleration like you do + tracking orientation, as above documentation explains, should do the job, using UIDeviceOrientationFaceUp and UIDeviceOrientationFaceDown ?

If none of the UIDeviceOrientation fit your needs, what you will need is to calculate some spatial angles from two CMAttitude references, which provides a rotationMatrix and a quaternion... these school maths are far away for me... I would then suggest to maybe search/ask a math only question with these.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文