Ios 相对于世界的设备运动-倍数与振幅
使用Cmatitude的正确方法是什么:multiplyByInverseOfAttitude 假设iOS5设备平放在桌子上,在启动CMMotionManager后:Ios 相对于世界的设备运动-倍数与振幅,ios,core-motion,Ios,Core Motion,使用Cmatitude的正确方法是什么:multiplyByInverseOfAttitude 假设iOS5设备平放在桌子上,在启动CMMotionManager后: CMMotionManager *motionManager = [[CMMotionManager alloc]init]; [motionManager startDeviceMotionUpdatesUsingReferenceFrame: CMAttitudeReferenceFrameXTrueNorthZVer
CMMotionManager *motionManager = [[CMMotionManager alloc]init];
[motionManager startDeviceMotionUpdatesUsingReferenceFrame:
CMAttitudeReferenceFrameXTrueNorthZVertical];
稍后,将获取CMDeviceMotion对象:
CMDeviceMotion *deviceMotion = [motionManager deviceMotion];
我希望[设备运动姿态]反映设备从正北方向的旋转
通过观察,[deviceMotion userAcceleration]报告设备参考框架中的加速度。也就是说,将设备左右移动(使其平放在工作台上)会记录x轴上的加速度。将设备旋转90°(仍为平面)并将设备左右移动,仍报告x加速度
转换[deviceMotion userAcceleration]以获得南北/东西加速而不是左右/前后加速的正确方法是什么
Cmatitude multiplyByVerseOfattude似乎是不必要的,因为已经指定了一个参考坐标系,并且文档中不清楚如何将姿态应用于Cmax加速度。参考坐标系与姿态值相关,请查看偏航角的姿态值;如果不使用参考帧,则在启动应用程序时,该值始终为零,而如果使用参考帧CmatitureReferenceFramextrueNorthzVertical,则偏航值指示x轴与正北之间的角度。
通过这些信息,您可以确定手机在地球坐标系中的姿态,从而确定加速度计轴相对于基点的位置。在阅读了上面链接的文章后,我尝试实施一个解决方案 步骤如下:
- 每次更新时获取姿态旋转矩阵
- 计算逆矩阵
- 乘以用户加速度向量的逆矩阵
我的代码还不完善,我正在研究它。如果CMDeviceMotion在参考坐标系的坐标中有一个userAcceleration的访问器,这个问题就不会出现。因此,我使用了一个类别来添加所需的方法: 在CMDeviceMotion+TransformToReferenceName.h中:
#import <CoreMotion/CoreMotion.h>
@interface CMDeviceMotion (TransformToReferenceFrame)
-(CMAcceleration)userAccelerationInReferenceFrame;
@end
在斯威夫特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 UserAccelerationReferenceFrame]。根据苹果的文档,
Cmatitude
指的是身体相对于给定参考框架的方向。userAcceleration
或gravity
是设备帧的值。所以为了得到参考系的值。我们应该照@Batti说的做
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))
}
}
希望对你有所帮助谢谢@batti,我理解几何,问题是关于编码。API似乎不支持应用转换的简单方法。在Cmatitude中,euler角、四元数表示和旋转矩阵都很容易访问,但没有明显的方法将它们应用于Cmatitude加速度。更糟糕的是,CMAcceleration是只读的,所以我不能自己转换它并在发送之前更新对象。问题是加速度计的le轴与设备固定,因此加速度计可以在设备框架中测量加速度。如果传感器没有那么嘈杂,你应该找到加速度的水平面,垂直于重力矢量的平面,看看这个平面上的矢量,计算矢量和北方之间的角度,知道基数坐标系中加速度的方向。你的应用程序是做什么的?这应该是有帮助的,第3节。这是一个有趣的,很好的工作。我假设您正在将其与指南针(CLHeading)一起使用。你怎么处理从加速中得到的数字?你的答案不正确。为了将矢量从参考帧a移动到参考帧B,当给出从B到a的旋转矩阵时,该矢量应乘以逆旋转矩阵。下面是如何计算Vitaly的逆矩阵,感谢您的反馈。守则运作良好,运作良好;你试过了吗?您的链接提供了一种反转任意矩阵的方法,但“旋转矩阵的逆矩阵只是其转置”()。这很微妙,但代码在计算中转换了旋转矩阵。@Zaq,我收回我的话,你说得对。看一下我的旋转矩阵求逆代码,这是一个任意矩阵求逆代码,它产生了转置矩阵。显然,旋转矩阵逆是它的转置,因为有两个事实:a)行列式总是1,因为旋转时向量不缩放;b)旋转矩阵是正交矩阵。@xmkevinchen,谢谢你的兴趣。代码完全按照您的建议执行。正如VitalyStakhov逐渐意识到的那样,代码在计算中转换了旋转矩阵。我可以对俯仰和滚动也这么做吗>?你能分享代码吗?或者解释上述步骤。。我得到的只是存储你想要创建的姿态作为参考,计算当前姿态的倒数
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))
}
}