В моем текущем проекте я столкнулся с проблемой, связанной с кватернионом, предоставляемым CMAttitude от Core Motion. Я поместил iPhone 5 (iOS 6.0.1) в четко определенную начальную позицию. Затем я начинаю быстро перемещать устройство, как в динамичной игре. Когда я возвращаюсь в исходное положение через 10-30 секунд, сообщаемый угол рыскания отличается от исходного положения на 10-20 градусов (в большинстве случаев ≈11°).
Я использовал старый (и, к сожалению, больше не доступный) образец Core Motion Teapot, чтобы проверить эффект. Углы Эйлера для регистрации считываются непосредственно из CMAttitude:
NSLog(@"pitch: %f, roll: %f, yaw: %f", attitude.pitch * 180 / M_PI, attitude.roll * 180 / M_PI, attitude.yaw * 180 / M_PI);
Я нашел это на двух разных устройствах iPhone 5, произведенных в разное время на разных заводах. Но действительно странно, что мой iPhone 4 под управлением iOS 5.1.1 работает так, как ожидалось. Мне кажется это баг iOS и я уже подавал баг-репорт, но с другой стороны я с трудом представляю, что на это еще никто не наткнулся. Я подозреваю, что это может быть связано с переработанным Core Motion API. Начиная с версии 5, магнитометр (компас) также учитывается при слиянии датчиков. Консоль показывает, что оценки смещения от locationed передаются в CoreMotion:
locationd[41] <Notice>: GYTT inserted: bias,-0.196419,1.749323,-1.828088,variance,0.002644,0.004651,0.002527,temperature,31.554688
Мои вопросы: есть ли возможность заблокировать показания магнитометра при использовании Device Motion? Я попытался отключить службы определения местоположения, но это не влияет на Core Motion. Если это невозможно, какова альтернатива / обходной путь, оценка силы тяжести на основе акселерометра?
PS: Поскольку мы имеем дело с моделями на основе кватернионов, это не связано с Gimbal Lock.
РЕДАКТИРОВАТЬ: После проведения дополнительных измерений становится ясно, что это влияет только на рыскание. Тангаж и крен показывают отклонения в пределах допуска (‹= 1°), в то время как рыскание смещается независимо от начального положения. CMDeviceMotion.gravity
тоже выглядит чистым.
EDIT (2): я смог воспроизвести проблему с образцом MotionGraphs, прикрепленным к последним версиям XCode. График рыскания воспроизводимо отклоняется от исходной точки.