检测平面上的iPhone移动

时间:2014-11-11 23:06:11

标签: ios cocoa-touch accelerometer gyroscope core-motion

我是一名核心动作初学者。

我需要检测平板表面上的iPhone移动 - 到目前为止,我通过访问陀螺仪的偏航来检测其侧向移动,但我想不出有办法检测上/下变化。我尝试使用加速度计,但它检测到更多的设备倾斜而不是移动。此外,当运动停止时会有反作用力。

您是否有任何想法,以便能够以相当精确的方式获得运动数据?我需要它来做空气曲棍球比赛。

4 个答案:

答案 0 :(得分:7)

为了确定来自deviceMotion的水平位置并不是真的可行。要使用的水平传感器是加速度计,但它们可以测量速度的变化。因此,要从中找到位置,您需要将传感器数据集成两次。一旦获得速度,那么第二次获得位置。

这意味着即使加速度数据中最小的不准确性也会导致速度误差,这意味着您的程序认为手机正在以恒定速度移动,而实际上它是静止的。

如果您不需要准确(例如,当您来回移动时不需要它回到相同的位置),那么如果强迫如果加速度计数据安静且接近零,则速度为零。

如果您真的尝试这样做,那么Kalman filter可能是从加速度计数据中获取速度和位置的最佳选择。 这意味着您的代码最终会显示如下内容,其中accelerationspeedposition是您保留的三个变量,acc是数据样本来自加速度计。

// correction step:
double delta = (acc - acceleration);
acceleration += FACTOR1 * delta;
speed += FACTOR2 * delta;
position += FACTOR3 * delta;

// prediction step:
position = position + speed * DT + 0.5 * acceleration * DT * DT;
speed = speed + acceleration * DT;

其中DT是数据样本之间的时间,以及FACTOR1..3的合适值,您需要找出它。

顺便说一句,Yaw不会给你水平运动,而是旋转。


编辑:现在,ARKit's Motion Tracking可以获得良好的效果,它将加速度计输入与相机的图像分析相结合。它为你做了所有艰苦的工作。

答案 1 :(得分:5)

所以我对CoreMotion也很陌生。我会尽力解释为什么你的要求无法完成,至少不准确。

根据我阅读的Apple Docs,iOS有3个动作处理程序:

  • 加速度计
  • 陀螺仪
  • 磁力

(我相信最新的设备有高度计?)

根据我对物理学的理解,我认为加速度计对你的场景最有用,因为陀螺仪和磁力计更注重旋转。我做了一些研究,发现this book。特别是第9.5章。从书中可以看出:

  

虽然加速度计可以测量x,y和y中的力   z轴无法测量旋转。另一方面,陀螺仪是   变化率设备;当手机围绕轴旋转时,它   允许您测量这种旋转的变化。

按照图9-5中的代码实现一个简单的app来观察加速度:

#import <UIKit/UIKit.h>
#import <CoreMotion/CoreMotion.h>

@interface ViewController : UIViewController {

    CMMotionManager *motionManager;
    NSOperationQueue *queue;
}


@property (weak, nonatomic) IBOutlet UILabel *xLabel;
@property (weak, nonatomic) IBOutlet UILabel *yLabel;
@property (weak, nonatomic) IBOutlet UILabel *zLabel;

@property (weak, nonatomic) IBOutlet UIProgressView *xBar;
@property (weak, nonatomic) IBOutlet UIProgressView *yBar;
@property (weak, nonatomic) IBOutlet UIProgressView *zBar;

@end

然后在.m viewDidLoad

- (void)viewDidLoad {
    [super viewDidLoad];

    motionManager = [[CMMotionManager alloc] init];
    motionManager.accelerometerUpdateInterval  = 1.0/10.0; // Update at 10Hz
    if (motionManager.accelerometerAvailable) {
        NSLog(@"Accelerometer avaliable");
        queue = [NSOperationQueue currentQueue];
        [motionManager startAccelerometerUpdatesToQueue:queue
          withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) {
            CMAcceleration acceleration = accelerometerData.acceleration;
            xLabel.text = [NSString stringWithFormat:@"%f", acceleration.x];
            xBar.progress = ABS(acceleration.x);

            yLabel.text = [NSString stringWithFormat:@"%f", acceleration.y];
            yBar.progress = ABS(acceleration.y);

            zLabel.text = [NSString stringWithFormat:@"%f", acceleration.z];
            zBar.progress = ABS(acceleration.z);
        }];

    }
}

将所有内容连接起来并在手机上运行之后,我看到加速度计正在测量我的手机在平台上移动时加速和减速的变化。现在我们有加速度,但要从中获得位置变化(这就是你所要求的)需要双重积分(即有趣的微积分)。虽然可行,但我查看了arduino的知识渊博的人对here所说的话,而男孩是一个严峻的新闻。 (他们没有讨论iPhone加速度计,但我推断这个信息也适用于这个问题)。

我在这里发布的相关部分:

  

从加速获得位置是一个双重整合,所以   错误叠加真的很邪恶。通过螺栓连接获得良好的位置数据   IMU(你想要做的)是一个真正难以解决的问题;该   需要这种加速度计非常昂贵。

  

你所说的是双重整合,也是如此   使用此硬件上的单个加速度计不准确。甚至单身   由于以下原因,每单位时间的集成误差会越来越大   这种设置缺乏准确性。

所有这些研究都得出结论,在iPhone上做你要求的事情是不可行的。虽然像我说的那样,我也是初学者!对不起,这不是你想听到的答案。

答案 2 :(得分:3)

设备无法检测移动。沿着桌子表面的直线恒定运动是绝对不可检测的。那是因为没有部队行动。

设备只能检测姿态(空间方向,方向变化)和(速度增加或减少)。

所以,你需要围绕这些能力形成你的期望。

答案 3 :(得分:1)

这个链接可能能够解释一些事情 http://blog.denivip.ru/index.php/2013/07/the-art-of-core-motion-in-ios/?lang=en

看起来你需要了解Y轴加速度。 Apple Docs似乎很好地涵盖了这一点。 https://developer.apple.com/library/ios/documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/motion_event_basics/motion_event_basics.html

使用运动处理方法检测运动何时发生变化,然后访问y位置的变化。如果您愿意,我可以尝试提供一些代码。