Reputation: 3433
I am having difficulty getting the syntax right to return the roll, pitch, yaw in Swift correctly. The accelerometers all work fine but can't sort this one out. Here's the material code:
var roll: Double = 0.0
var pitch: Double = 0.0
var yaw: Double = 0.0
var manager = CMMotionManager()
override func viewDidLoad() {
manager.startDeviceMotionUpdatesToQueue(NSOperationQueue.currentQueue()!, withHandler: { (rpyData: CMDeviceMotionHandler?, NSError) -> Void in self.outputRPY(rpyData!.deviceMotion)
if(NSError != nil) {
print("\(NSError)")
}
})
}
func outputRPY(data: CMDeviceMotion){
roll = data.attitude.roll
pitch = data.attitude.pitch
yaw = data.attitude.yaw
rollLabel.text = String(format: "%.2f°", roll)
pitchLabel.text = String(format: "%.2f°", pitch)
rollLabel.text = String(format: "%.2f°", yaw)
}
Upvotes: 1
Views: 2102
Reputation: 3433
The thing that was throwing me is that the Roll, Pitch, Yaw appear to work differently from the accelerometers, gyros, magnetometers. Here's the fresh off the press code:
var manager = CMMotionManager()
override func viewDidLoad() {
super.viewDidLoad()
manager.deviceMotionUpdateInterval = 0.2
manager.startDeviceMotionUpdatesToQueue(NSOperationQueue.currentQueue()!, withHandler: {(motionData: CMDeviceMotion?, NSError) -> Void in self.outputRPY(motionData!)
if (NSError != nil){
print("\(NSError)")
}
})
}
func outputRPY(data: CMDeviceMotion){
let rpyattitude = manager.deviceMotion!.attitude
roll = rpyattitude.roll * (180.0 / M_PI)
pitch = rpyattitude.pitch * (180.0 / M_PI)
yaw = rpyattitude.yaw * (180.0 / M_PI)
rollLabel.text = String(format: "%.2f°", roll)
pitchLabel.text = String(format: "%.2f°", pitch)
yawLabel.text = String(format: "%.2f°", yaw)
}
Upvotes: 1
Reputation: 388
The 2nd parameter type should be a NSError? (Aka an optional) and in the body of your closure, you are comparing a type to a value.
In all, it should look like this:
manager.startDeviceMotionUpdatesToQueue(NSOperationQueue.currentQueue()!, withHandler: { (deviceMotion: CMDeviceMotion?, err: NSError?) -> Void in
self.outputRPY(deviceMotion!)
if(err != nil) {
print("\(err)")
}
}
You could also use optional binding to be more swifter... :)
if error = err {
print("\(error)")
}
Edit:
After testing on my home machine, I realised that there was one more issue. CMDeviceMotionHandler
declares the type of the closure (or function pointer, if you will). It is declared as:
public typealias CMDeviceMotionHandler = (CMDeviceMotion?, NSError?) -> Void
So your closure (or handler) should be like:
{ (deviceMotion: CMDeviceMotion?, error: NSError?) -> Void in
// code goes here
}
Finally, your second parameter is making the identifier NSError
refer to a variable, when it is already a type (which is legal). I personally wouldn't name it as such, since it can be easy confuse with the type NSError
. Maybe you could perhaps name it nserror
, which would avoid any confusion with the existing type.
The first code snippet should just copy-paste into your project.
Upvotes: 1