Дрейфующий угол рыскания после быстрого движения

В моем текущем проекте я столкнулся с проблемой, связанной с кватернионом, предоставляемым CMAttitude от Core Motion. Я поместил iPhone 5 (iOS 6.0.1) в четко определенную начальную позицию. Затем я начинаю быстро перемещать устройство, как в динамичной игре. Когда я возвращаюсь в исходное положение через 10-30 секунд, сообщаемый угол рыскания отличается от исходного положения на 10-20 градусов (в большинстве случаев ≈11°).

Я использовал старый (и, к сожалению, больше не доступный) образец Core Motion Teapot, чтобы проверить эффект. Углы Эйлера для регистрации считываются непосредственно из CMAttitude:

Начальная позицияТо же место через 15 секунд

        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. График рыскания воспроизводимо отклоняется от исходной точки.


person Kay    schedule 28.11.2012    source источник
comment
Проголосовал, интересный вопрос! Да, у меня тоже был плохой опыт работы с магнитометром: он отстает (вызывая смещение!) и чертовски шумит. Я также заметил, что гироскоп легко насыщается, особенно. с быстрыми движениями. Есть ли способ исключить насыщение от подозреваемых?   -  person Ali    schedule 29.11.2012
comment
@Али, я не знаю, как. Но, с другой стороны, мой iPhone 4 с iOS 5.1.1 прекрасно работал и с ранее установленной iOS 4.3. Выстрел в темноте, но я думаю, виновата iOS 6.   -  person Kay    schedule 29.11.2012
comment
Я надеюсь, что кто-то знает ответ, извините, я не могу помочь :(   -  person Ali    schedule 29.11.2012
comment
Это сентябрь 2015 года, и у меня все еще есть эта проблема с моим iPhone 5 (купленным в 2014 году) и iOS 8.1. Я предполагаю, что алгоритм объединения датчиков неправильно фильтрует гироскоп или что сам гироскоп не так хорош, как в других iPhone. Что случилось с вашим отчетом об ошибке?   -  person Konstantinos Gaitanis    schedule 16.09.2015
comment
Через 2 месяца после регистрации ошибки они ответили Мы не можем сделать оценку смещения гироскопа, если устройство движется. Если калибровка смещения устройства отключена, его курс будет дрейфовать во время движения устройства. Я думаю, что это связано с магнитометрической частью алгоритма объединения датчиков, так как это единственный способ откалибровать углы рыскания.   -  person Kay    schedule 16.09.2015


Ответы (2)


Не окончательное решение, но, по крайней мере, обходной путь для моего собственного вопроса (я оставляю его без ответа, чтобы пригласить вас). Выяснилось, что как минимум DeviceMotion.gravity баг не затрагивает. Поэтому я решил переделать эту довольно простую часть обнаружения движения и использовать arcsin (gravity.x/||gravity||) для перемещения основного персонажа игрока в сторону при наклоне устройства.

Это определенно второе лучшее решение, поскольку оно уничтожает информацию о состоянии полного вращения, содержащуюся в кватернионе. Я решил так по стратегическим соображениям:

  1. Я думаю, что большинство разработчиков определяют движение наклона с помощью вектора гравитации, а не CMAttitude.quaternion, потому что большинство людей не в восторге от математики кватернионов ;-) Таким образом, любые будущие ошибки, связанные с вектором гравитации, вероятно, будут исправлены во время бета-фазы из-за большего количества пользователей.
  2. Если это программная ошибка, не связанная с аппаратными проблемами, что я предполагаю, и если ошибка будет исправлена ​​как можно скорее, все еще существует ряд устройств, которые по какой-либо причине могут не обновляться. Таким образом, риск того, что у потенциального будущего клиента возникнут проблемы, невелик, но > 0. Таким образом, второе лучшее решение иногда может быть лучшим.
person Kay    schedule 29.11.2012

Я сделал что-то подобное в своем собственном коде и обнаружил тот же дрейф вращения по оси Z (рыскание). Я применил сбалансированный фильтр. В каждый временной интервал диспетчера движения я беру текущий кватернион (z-компоненту), а затем сохраняю его после вычислений как oldZ для использования в следующем наборе вычислений. Мой фильтр просто уравновешивает НОВОЕ значение z со значением z, непосредственно предшествующим ему, предотвращая его слишком быстрое перемещение. В зависимости от вашего оборудования и точного допуска в вашей программе, вы можете довольно хорошо управлять дрейфом таким образом. Вы увидите, как гироскоп слегка дрейфует, но затем начнет корректироваться, поскольку фильтр продолжает действовать. Мой фильтр выглядит примерно так и предотвращает более 0,5 степени «беспорядка»:

filtZ = 0,65 * oldZ + 0,35 * z;

Значения 0,65 и 0,35 были определены экспериментально, и я бы посоветовал вам поиграть с ними, пока у вас есть время. Вывод по-прежнему будет масштабироваться от 0 до 1, и затем его можно будет использовать так же, как вы это делали (или повторно ввести в кватернион, если вы должны сохранить все 4 измерения).

person Amber    schedule 30.01.2013