首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >相对于world的DeviceMotion - multiplyByInverseOfAttitude

相对于world的DeviceMotion - multiplyByInverseOfAttitude
EN

Stack Overflow用户
提问于 2011-10-31 12:50:06
回答 4查看 11.5K关注 0票数 13

正确使用CMAttitude:multiplyByInverseOfAttitude的方法是什么?

假设一个iOS5设备平放在桌子上,在启动CMMotionManager后:

代码语言:javascript
复制
CMMotionManager *motionManager = [[CMMotionManager alloc]init];
[motionManager startDeviceMotionUpdatesUsingReferenceFrame:
    CMAttitudeReferenceFrameXTrueNorthZVertical];

然后,获取CMDeviceMotion对象:

代码语言:javascript
复制
CMDeviceMotion *deviceMotion = [motionManager deviceMotion];

我预计deviceMotion的态度反映了设备从正北方向的旋转。

通过观察,deviceMotion userAcceleration在设备参考系中报告了加速度。也就是说,将设备从一边移动到另一边(将其平放在桌面上)会在x轴上记录加速度。将设备旋转90°(仍然是平坦的)并将设备左右移动时,仍会报告x加速度。

将deviceMotion userAcceleration转换为北南/东西加速而不是左-右/前-后的正确方法是什么?

CMAttitude multiplyByInverseOfAttitude似乎没有必要,因为已经指定了参考框架,并且文档中不清楚如何将该态度应用于CMAcceleration。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-11-04 16:48:45

如果CMDeviceMotion在参考系的坐标中有userAcceleration的存取器,这个问题就不会出现。因此,我使用了一个类别来添加所需的方法:

在CMDeviceMotion+TransformToReferenceFrame.h中:

代码语言:javascript
复制
#import <CoreMotion/CoreMotion.h>

@interface CMDeviceMotion (TransformToReferenceFrame)
-(CMAcceleration)userAccelerationInReferenceFrame;
@end

在CMDeviceMotion+TransformToReferenceFrame.m中:

代码语言:javascript
复制
#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中

代码语言:javascript
复制
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。

票数 23
EN

Stack Overflow用户

发布于 2016-03-30 03:27:03

根据苹果公司的文档,CMAttitude指的是物体相对于给定参照系的方向。userAccelerationgravity是设备帧的值。因此,为了得到参考系的值。我们应该照@Batti说的做

  1. 在每次更新时获取姿态旋转矩阵。
  2. 计算UserAcceleration向量的逆矩阵。

这是Swift的版本

代码语言:javascript
复制
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))

    }

}

希望它能帮上点忙

票数 4
EN

Stack Overflow用户

发布于 2011-11-04 07:13:08

在阅读了上面链接的论文后,我尝试实现了一个解决方案。

具体步骤如下:

  • 在每次更新时获取姿态旋转矩阵。
  • 计算UserAcceleration向量的逆矩阵。

生成的向量将是该向量的投影。

-x北,+x南

-y东部,+y西部

我的代码还不够完美,我正在努力。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7950096

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档