我也对CoreMotion不太了解。我会尽力解释为什么你所要求的无法实现,至少不能准确地实现。
根据我阅读的苹果文档,iOS有三个运动处理程序:
加速度计
陀螺仪
磁力计
(我相信最新的设备有高度计)
根据我对物理学的理解,我认为加速度计对你的场景最有用,因为陀螺仪和磁力计更专注于旋转。我做了一些研究,并找到了
this book。特别是第9.5章。从书中得知:
虽然加速度计可以测量x、y和z轴上的力,但它无法测量旋转。另一方面,陀螺仪是一个变化率设备;当手机绕着一个轴旋转时,它允许您测量这种旋转的变化。
按照他们在图9-5下的代码来实现一个简单的应用程序来观察加速度:
#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;
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上做你要求的事情是不可行的。尽管我说过,我也是个初学者!很抱歉这不是你想听到的答案。