Отношение iDevice: стабилизирующий кватернион

Я пытаюсь использовать отношение iDevice self.motionManager.deviceMotion.attitude.quaternionустройство лежит на столе, но значения не совпадают. как стабилизировать эти значения, не вызывая плохого вращения? Я использую ориентацию устройства для поворота узла камеры.

 (x = -0.0055437298906573507, y = -0.0078092851375721247, z = -0.041180405121897398, w = 0.999105828407855)
 (x = -0.0061666945840810842, y = -0.0067849414785486747, z = -0.041464744435584115, w = 0.99909789881469635)
 (x = -0.0057767614213563457, y = -0.0075097232630314727, z = -0.041803806548186787, w = 0.99908091506248087)
 (x = -0.0054897030127900098, y = -0.0077124534854605253, z = -0.04219926058901851, w = 0.99906436410664467)
 (x = -0.0052714642886002782, y = -0.0078368692177714049, z = -0.042675299607953819, w = 0.99904435034111316)
 (x = -0.0050140321661910547, y = -0.0078121993123853265, z = -0.043041870709832147, w = 0.99903014288315972)
 (x = -0.0050055928591862253, y = -0.0077335374133680208, z = -0.043505056503552082, w = 0.99901073392523531)
 (x = -0.0049666831093899792, y = -0.007717140215596976, z = -0.043913562364765651, w = 0.99899318158145256)
 (x = -0.0047768022686966614, y = -0.0078160798819143576, z = -0.044274861496884942, w = 0.99897739098280313)
 (x = -0.0047310514463435671, y = -0.0078007790545880336, z = -0.044670164461142137, w = 0.9989601300379195)
 (x = -0.004618244779613233, y = -0.0078641769042355775, z = -0.045003270721875412, w = 0.99894520978936451)
 (x = -0.0049526705779270597, y = -0.0076127708990477733, z = -0.045411652395276572, w = 0.99892707371465494)
 (x = -0.0053219441444451315, y = -0.0074858231291817018, z = -0.045723089011719641, w = 0.99891192729581401)
 (x = -0.0056345717154138147, y = -0.0073613453524927486, z = -0.046005287981812061, w = 0.99889818083421522)
 (x = -0.0056064974434034201, y = -0.0074105820596984404, z = -0.046130222648849362, w = 0.99889221291304886)
 (x = -0.0053487406143112462, y = -0.0076910190187535112, z = -0.046331716108766401, w = 0.99888218088156866)


    self.motionManager = [[CMMotionManager alloc] init];
    self.motionManager.deviceMotionUpdateInterval = 1.0/20.0;
    [self.motionManager startDeviceMotionUpdates];

1 ответ

Решение

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

Типичная формула для фильтра в реальном времени выглядит следующим образом:

newValue = (sampledValue * factor) + (lastValue * (1 - factor))

Таким образом, вы получаете newValue (отфильтрованный вход, который вы собираетесь использовать) из линейной интерполяции sampledValue (необработанный вход от датчика) и lastValue (newValue, вычисленное на предыдущем временном шаге; обязательно инициализируйте его чем-нибудь разумно в первом вычислении), с фактором, который контролирует, как далеко находится смесь. Вы можете настроить коэффициент, чтобы контролировать, сколько сигнала проходит через ваш фильтр.

Возможно, вы могли бы применить эту формулу отдельно к каждому из компонентов x, y, z и w кватерниона и получить неопределенно проходимый результат. Но а) писать один и тот же код четыре раза не так весело, и б) у кватернионов есть какая-то особая математика, которая заставит этот метод сломаться со временем.

Вместо этого вы можете сделать свой CMQuaternion в GLKQuaternion и сделать смешивание в один звонок GLKQuaternionSlerp, (И это имеет в виду особую математику для вас.)

filteredAttitude = GLKQuaternionSlerp(lastAttitude, sampledAttitude, factor)

Затем сделайте SCNQuaternion от твоего GLKQuaternion и вы можете установить ориентацию вашего узла.

Другие вопросы по тегам