3
votes

I'm currently working on an app that has to track yaw (rotation around z-axis). The user will have the iPhone in landscape orientation pointing to an object like a car in front of him. As the user starts walking around the object I have to track the yaw for a complete 360 rotation.

I'm currently using CoreMotion with CMQuaternion to track the rotation:

private func startDeviceMotionUpdates() {
    if motionManager.isDeviceMotionAvailable {
      let queue = OperationQueue()
      motionManager.deviceMotionUpdateInterval = 1 / 60
      motionManager.startDeviceMotionUpdates(using: .xArbitraryZVertical, to: queue, withHandler: { (motion, error) in
        guard let motion = motion else { return }

        let quat = motion.attitude.quaternion
        let yaw = 2 * (quat.x * quat.y + quat.w * quat.z)
        let yawDegrees = self.degreesFromRadians(yaw)
        print(yawDegrees)
      })
    }
  }

  private func stopDeviceMotionUpdates() {
    motionManager.stopDeviceMotionUpdates()
  }

  private func degreesFromRadians(_ radians: Double) -> Double {
    return radians * 180 / .pi
  }

This currently works fine as long as the roll or pitch of the device doesn't change.

What I would like to know is:

  1. Why does the yaw change when the roll or pitch of device changes?
  2. How can I accurately track the yaw around the z-axis without it being affected by change on the x and y-axis?

I've been banging my head for two weeks against this problem. I would really appreciate if someone could help me understand why this is happening and how to get around it.

1
Facing same issue, any solution?Roy K
Hi @RoyK. Apologies for the late reply. I unfortunately couldn't find a solution for this. Do let me know if you come up with a solution. Really interested in knowing how to actually achieve this.martisan
Hi thanks for the reply, I ended up using magnetic heading with location services. Seems to be more accurate, no drift, very stable.Roy K
Are you able to track a complete 360 movement around an object now?martisan
Yes, assuming you keep the device pointing at the object.Roy K

1 Answers

0
votes

try below code.

let yaw = atan2(motion.gravity.x, motion.gravity.y) - Double.pi
let yawDegrees = self.degreesFromRadians(yaw)
print(yawDegrees)