0

I have a simple Swift motion tracking app that pulls the triaxial rotation rate and attitude of the phone. I am trying to normalize the attitude using multiply(byInverseOf: ) with the initial attitude as reference. Currently initialAttitude is coming back 0,0,0. In my viewController class I have the following:

var results : [(rotationRateX: Double, rotationRateY: Double, rotationRateZ: Double, pitch: Double, roll: Double, yaw:Double)] = []
var motionManager = CMMotionManager()
var attitudes : [(CMAttitude)] = []

func startCollectingData()
{

    motionManager.deviceMotionUpdateInterval = 1.0 / 100
    motionManager.startDeviceMotionUpdates(using: CMAttitudeReferenceFrame.xArbitraryZVertical, to: OperationQueue.current!) { (data, error) in

        if let myData = data
        {

            let rotationRateX = (myData.rotationRate.x)
            let rotationRateY = (myData.rotationRate.y)
            let rotationRateZ = (myData.rotationRate.z)

            let attitude = (myData.attitude)
            self.attitudes += [(attitude)]

            let initialAttitude = self.attitudes.first
            attitude.multiply(byInverseOf: initialAttitude!)

            let pitch = attitude.pitch
            let roll = attitude.roll
            let yaw = attitude.yaw

            self.results += [(rotationRateX:rotationRateX, rotationRateY:rotationRateY, rotationRateZ:rotationRateZ, pitch:pitch, roll:roll, yaw:yaw)]

            }
        }
}

When I try to pull initialAttitude first, before deviceMotionUpdates (like below) it comes by nil.

var results : [(rotationRateX: Double, rotationRateY: Double, rotationRateZ: Double, pitch: Double, roll: Double, yaw:Double)] = []
var motionManager = CMMotionManager()


func startCollectingData()
{
    let initialAttitude = motionManager.deviceMotion!.attitude
    motionManager.deviceMotionUpdateInterval = 1.0 / 100
    motionManager.startDeviceMotionUpdates(using: CMAttitudeReferenceFrame.xArbitraryZVertical, to: OperationQueue.current!) { (data, error) in

        if let myData = data
        {

            let rotationRateX = (myData.rotationRate.x)
            let rotationRateY = (myData.rotationRate.y)
            let rotationRateZ = (myData.rotationRate.z)

            attitude.multiply(byInverseOf: initialAttitude!)

            let pitch = attitude.pitch
            let roll = attitude.roll
            let yaw = attitude.yaw

            self.results += [(rotationRateX:rotationRateX, rotationRateY:rotationRateY, rotationRateZ:rotationRateZ, pitch:pitch, roll:roll, yaw:yaw)]

            }
        }
}

1 Answers1

0

When I try to pull initialAttitude first, before deviceMotionUpdates (like below) it comes by nil.

Right, so you just keep throwing away those results until you first get a result that is not nil.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • See https://github.com/mattneub/Programming-iOS-Book-Examples/blob/70e9543f1150bb0acc6276895bfbbf9d483fd2ad/bk2ch22p789attitudeRotation/ch25p1046attitudeRotation/ViewController.swift for example. – matt Jun 16 '20 at 18:00
  • Thanks, this worked great. Any ideas why the first example returns (0,0,0) for initalAttitude? – eclarkralce Jun 24 '20 at 14:12