Reputation: 2800
I would like to calculate compass heading to true north using CoreMotion (Not CoreLocation if possible). I have found some formulas, but working only when phone is flat on the table. Can someone help me find a way to calculate compass heading, which will work in every device position like compass app?
Upvotes: 2
Views: 735
Reputation: 2800
I have found an answer. This is how I get compass heading in radians from CoreMotion:
guard let a = motionManager.deviceMotion?.attitude, g = motionManager.deviceMotion?.gravity else { return }
let deviceAngle = { () -> Double in
switch interfaceOrientation {
case .LandscapeLeft: return -M_PI_2 + atan2(g.x, g.y)
case .LandscapeRight: return M_PI_2 + atan2(g.x, g.y)
default: return M_PI + atan2(g.x, g.y)
}
}()
// Calculate Heading.
let cA = cos(a.yaw), sA = sin(a.yaw), sB = sin(a.pitch), cG = cos(a.roll), sG = sin(a.roll)
let rA = cA * sG + sA * sB * cG
let rB = sA * sG - cA * sB * cG
var compassHeading = -atan(rA / rB) + M_PI + deviceAngle
if rB > 0 { compassHeading += M_PI }
Still need to test this, but for now it seems to work.
Upvotes: 2