当iPhone垂直时CMDeviceMotion偏航值不稳定

在iOS原型中,我使用了CMDeviceMotion.deviceMotion.yaw和CLHeading.trueHeading的组合来制作稳定的罗盘标题,这是一个响应和准确的标题。 这在iPhone保持平坦的时候效果很好,我有一个指向稳定罗盘标题的graphics箭头。

当iPhone在portait模式下保持垂直状态时,问题就出现了。 UIDeviceOrientation不断从UIDeviceOrientationFaceDown更改为UIDeviceOrientationFaceUp并返回。 这使得偏航值可以根据音高的微小变化来回跳动+/- 180度。 是否有可能将设备locking在一个方向上,以获得稳定的偏航值,预测没有毛刺的变化或以其他方式计算陀螺仪偏航(或以此方向滚动)?

这个可怜的家伙有同样的问题,没有答案。 双点可能的人! 🙂 https://stackoverflow.com/questions/10470938/euler-angle-yaw-not-working-when-iphone-orientation-changes

我只是在寻找这个问题的答案。 一年前,我发现你已经发布了这个消息,但是我想,也许你或者其他人可以从这个解决scheme中受益。

这个问题是万向锁。 当俯仰angular大约90度时,偏航和滚动匹配,陀螺仪失去一定的自由度。 四元数是避免万向节locking的一种方法,但我真的不想绕过这个念头。 相反,我注意到,偏航和滚动实际上匹配,可以简单地总结来解决问题(假设你只关心偏航)。

解:

float yawDegrees = currentAttitude.yaw * (180.0 / M_PI); float pitchDegrees = currentAttitude.pitch * (180.0 / M_PI); float rollDegrees = currentAttitude.roll * (180.0 / M_PI); double rotationDegrees; if(rollDegrees < 0 && yawDegrees < 0) // This is the condition where simply // summing yawDegrees with rollDegrees // wouldn't work. // Suppose yaw = -177 and pitch = -165. // rotationDegrees would then be -342, // making your rotation angle jump all // the way around the circle. { rotationDegrees = 360 - (-1 * (yawDegrees + rollDegrees)); } else { rotationDegrees = yawDegrees + rollDegrees; } // Use rotationDegrees with range 0 - 360 to do whatever you want. 

我希望这可以帮助别人!

如果有人对iOS Swift中的实现感兴趣,那么代码如下:

  let queue = NSOperationQueue() motionManager.startDeviceMotionUpdatesToQueue(queue) { [weak self] (data: CMDeviceMotion!, error: NSError!) in var yawDegrees: Double = self!.motionManager.deviceMotion.attitude.yaw * (180.0 / M_PI) var pitchDegrees: Double = self!.motionManager.deviceMotion.attitude.pitch * (180.0 / M_PI) var rollDegrees: Double = self!.motionManager.deviceMotion.attitude.roll * (180.0 / M_PI) if(rollDegrees < 0 && yawDegrees < 0){ self!.rotationDegrees = 360 - (-1 * (yawDegrees + rollDegrees)) } else { self!.rotationDegrees = yawDegrees + rollDegrees } } 

不过,我有一些问题,我希望@ blkhp19可以帮助我,因为在某些点的angular度进入负值,然后混淆整个计算,我不明白什么是问题是。