正确使用CMAttitude:multiplyByInverseOfAttitude的方法是什么?
假设一个iOS5设备平放在桌子上,在启动CMMotionManager后:
CMMotionManager *motionManager = [[CMMotionManager alloc]init];
[motionManager startDeviceMotionUpdatesUsingReferenceFrame:
CMAttitudeReferenceFrameXTrueNorthZVertical];然后,获取CMDeviceMotion对象:
CMDeviceMotion *deviceMotion = [motionManager deviceMotion];我预计deviceMotion的态度反映了设备从正北方向的旋转。
通过观察,deviceMotion userAcceleration在设备参考系中报告了加速度。也就是说,将设备从一边移动到另一边(将其平放在桌面上)会在x轴上记录加速度。将设备旋转90°(仍然是平坦的)并将设备左右移动时,仍会报告x加速度。
将deviceMotion userAcceleration转换为北南/东西加速而不是左-右/前-后的正确方法是什么?
CMAttitude multiplyByInverseOfAttitude似乎没有必要,因为已经指定了参考框架,并且文档中不清楚如何将该态度应用于CMAcceleration。
发布于 2011-11-04 16:48:45
如果CMDeviceMotion在参考系的坐标中有userAcceleration的存取器,这个问题就不会出现。因此,我使用了一个类别来添加所需的方法:
在CMDeviceMotion+TransformToReferenceFrame.h中:
#import <CoreMotion/CoreMotion.h>
@interface CMDeviceMotion (TransformToReferenceFrame)
-(CMAcceleration)userAccelerationInReferenceFrame;
@end在CMDeviceMotion+TransformToReferenceFrame.m中:
#import "CMDeviceMotion+TransformToReferenceFrame.h"
@implementation CMDeviceMotion (TransformToReferenceFrame)
-(CMAcceleration)userAccelerationInReferenceFrame
{
CMAcceleration acc = [self userAcceleration];
CMRotationMatrix rot = [self attitude].rotationMatrix;
CMAcceleration accRef;
accRef.x = acc.x*rot.m11 + acc.y*rot.m12 + acc.z*rot.m13;
accRef.y = acc.x*rot.m21 + acc.y*rot.m22 + acc.z*rot.m23;
accRef.z = acc.x*rot.m31 + acc.y*rot.m32 + acc.z*rot.m33;
return accRef;
}
@end在Swift 3中
extension CMDeviceMotion {
var userAccelerationInReferenceFrame: CMAcceleration {
let acc = self.userAcceleration
let rot = self.attitude.rotationMatrix
var accRef = CMAcceleration()
accRef.x = acc.x*rot.m11 + acc.y*rot.m12 + acc.z*rot.m13;
accRef.y = acc.x*rot.m21 + acc.y*rot.m22 + acc.z*rot.m23;
accRef.z = acc.x*rot.m31 + acc.y*rot.m32 + acc.z*rot.m33;
return accRef;
}
}现在,以前使用deviceMotion userAcceleration的代码可以改为使用deviceMotion userAccelerationInReferenceFrame。
发布于 2016-03-30 03:27:03
根据苹果公司的文档,CMAttitude指的是物体相对于给定参照系的方向。userAcceleration或gravity是设备帧的值。因此,为了得到参考系的值。我们应该照@Batti说的做
这是Swift的版本
import CoreMotion
import GLKit
extension CMDeviceMotion {
func userAccelerationInReferenceFrame() -> CMAcceleration {
let origin = userAcceleration
let rotation = attitude.rotationMatrix
let matrix = rotation.inverse()
var result = CMAcceleration()
result.x = origin.x * matrix.m11 + origin.y * matrix.m12 + origin.z * matrix.m13;
result.y = origin.x * matrix.m21 + origin.y * matrix.m22 + origin.z * matrix.m23;
result.z = origin.x * matrix.m31 + origin.y * matrix.m32 + origin.z * matrix.m33;
return result
}
func gravityInReferenceFrame() -> CMAcceleration {
let origin = self.gravity
let rotation = attitude.rotationMatrix
let matrix = rotation.inverse()
var result = CMAcceleration()
result.x = origin.x * matrix.m11 + origin.y * matrix.m12 + origin.z * matrix.m13;
result.y = origin.x * matrix.m21 + origin.y * matrix.m22 + origin.z * matrix.m23;
result.z = origin.x * matrix.m31 + origin.y * matrix.m32 + origin.z * matrix.m33;
return result
}
}
extension CMRotationMatrix {
func inverse() -> CMRotationMatrix {
let matrix = GLKMatrix3Make(Float(m11), Float(m12), Float(m13), Float(m21), Float(m22), Float(m23), Float(m31), Float(m32), Float(m33))
let invert = GLKMatrix3Invert(matrix, nil)
return CMRotationMatrix(m11: Double(invert.m00), m12: Double(invert.m01), m13: Double(invert.m02),
m21: Double(invert.m10), m22: Double(invert.m11), m23: Double(invert.m12),
m31: Double(invert.m20), m32: Double(invert.m21), m33: Double(invert.m22))
}
}希望它能帮上点忙
发布于 2011-11-04 07:13:08
在阅读了上面链接的论文后,我尝试实现了一个解决方案。
具体步骤如下:
生成的向量将是该向量的投影。
-x北,+x南
-y东部,+y西部
我的代码还不够完美,我正在努力。
https://stackoverflow.com/questions/7950096
复制相似问题