Компас на основе CoreMotion

Я хотел бы рассчитать направление компаса на истинный север, используя CoreMotion (если возможно, не CoreLocation). Я нашел несколько формул, но они работают только тогда, когда телефон лежит на столе. Может ли кто-нибудь помочь мне найти способ расчета направления по компасу, который будет работать в любом положении устройства, например, в приложении компаса?


person Damian Dudycz    schedule 06.08.2016    source источник
comment
По какой причине вы не используете CoreLocation?   -  person jbehrens94    schedule 06.08.2016
comment
Я делаю приложение AR, которое уже использует CoreMotion для отображения объектов. Мне нужен этот компас для радара. Я заметил, что когда я использую CoreLocation trueHeading, иногда точки на радаре немного смещаются по сравнению с тем, что я вижу в представлении AR. Вероятно, используется какая-то дополнительная фильтрация для расчета курса по CoreLocation. В любом случае, если бы можно было получить курс от основного положения движения, то я думаю, что этой проблемы не было бы.   -  person Damian Dudycz    schedule 06.08.2016


Ответы (1)


Я нашел ответ. Вот как я получаю направление компаса в радианах от 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 }

Все еще нужно проверить это, но пока это работает.

person Damian Dudycz    schedule 07.08.2016