Как стать автором
Обновить

На пороге дополненной реальности: к чему готовиться разработчикам (часть 2 из 3)

Время на прочтение9 мин
Количество просмотров82K

Это продолжение (см. часть 1) стенограммы одноименного доклада с конференции ADD-2010.

В этой части речь пойдет о том, как обрабатывать данные с сенсоров, а именно: акселерометров, гироскопов и магнитных компасов. И зачем в современных устройствах ставят все три вида датчиков.


Gyroscope


Итак, первый сенсор — гироскоп.

Вы знаете, что в телефоне есть гироскоп, и вам нужно написать программу, которая обрабатывает с него данные. Сразу вспоминаются какие гироскопы? — ну какие-то такие:


Сильно раскрученное тяжелое тело, на мягких шарнирных подвесах, оно сохраняет, как бы вы не крутили тот предмет, к которому оно подвешено, он сохраняет свое направление, и вы можете померить два угла отклонения относительно локальной системы координат, и понять, как ваше устройство ориентировано. Значит, вроде как, вам должны приходить углы:


Если вы поставите два таких гироскопа, в перпендикулярных плоскостях, то вы можете получить все три угла:
  • крен (или тангаж);
  • рыскание;
  • и вот так угол атаки.





Не знаю, к чему привыкли вы, я лично ожидал такого от гироскопа, и наивно так думал — вот, сейчас я быстро напишу программу, которая все это делает.
Понимающий смех в зале


Все дело в том, что вот как выглядит гироскоп, который стоит внутри всех мобильных и тому подобных устройств:


Вот у меня сейчас здесь [показывает WiiMote+WiiMotionPlus, используемый как устройство для презентации] работает, и то, что я показываю — это данные с гироскопа, чтобы указка бегала.

Ничего вращающегося там, конечно, нет, тем более быстрого и тяжелого. Там есть такая штука, как какая-то фигня, извините, которая телебунькается в магнитном поле туда-сюда, типа маятника.


Соответственно, когда у вас возникает вращение вокруг оси, которая перпендикулярно проходит через эту плоскость, возникает сила Кориолиса, она отклоняет эту телебунькающуюся штуку и вы можете, измеряя как изменилась емкость этой конструкции, догадываетесь, какова сила. Если схематически — то это так. Вот у вас небольшая масса, которая так вот (вертикально) колеблется, вы ее возбуждаете:



Если есть вот такое вращение (против часовой стрелки), то возникает сила Кориолиса, она начинает отклонятся вот туда и собственно говоря, возникают вот такие поперечные колебания, и вы можете это померить как емкость конденсатора.

Кто помнит эту силу Кориолиса, она зависит от угловой скорости вращения, соответственно, что получается — у вас на выходе с этого устройства на самом деле не углы, а угловые скорости, несмотря на то, что это называется гироскопом.


Чтобы в одномерном случае получить угол, нам надо интегрировать — правда к нам сигнал приходит дискретный, поэтому это такое простое суммирование. В трехмерном случае все это выливается в кватернионы, если вы вообще всем этим хотите заниматься, то кватернионов не надо пугаться.


Это проекция этой угловой скорости на разные оси, и вот, примерно для WiiMote картинка из интернета, чтобы не запутаться, как это все обрабатывать.


Это все хорошо, но интегрируя, мы накапливаем ошибку. Происходит сдвиг, т.е. постоянно что-то уплывает у нас. Вот как здесь, несмотря на то, что у нас устройство находилось на месте, постепенно угол плывет, и кажется, что постепенно, постепенно устройство проворачивается. Что не есть гуд для наших целей, и вообще как-то отстой.


Вот есть картинка из Интернета, здесь погрешность, здесь — градусов в час, сколько накапливается, и здесь разные виды гироскопов. И видно, что микромеханические, которые ставят в наши дорогие устройства, они вот самые ужасные в этом плане.



Accelerometer


Надо с этим что-то делать, в принципе углы можно мерять при помощи акселерометра. Более того, в начале только при помощи его и пытались мерять эти углы.

Что такое акселерометр? Это какой-то грузик, грубо говоря, закрепленный на пружинках, и по отклонению этого грузика, по равновесному положению, мы понимаем, какая сила действует, и мы измеряем это ускорение.


Вот как выглядит этот акселерометр:


На самом деле, что получается меряет акселерометр? У вас есть ускорение свободного падения, есть какое-то собственное ускорение, устройство можно с ускорением двигать.
Соответственно, акселерометр измеряет вот этот вектор, причем в проекции на локальную систему координат устройства:


Это то, что вам подает акселерометр на выходе. В одномерном случае, все выглядит достаточно просто:
  • у вас есть как-то повернутая локальная система координат;
  • у вас есть проекция ускорения свободного падения;
  • соответственно, вы можете получить угол поворота относительно вертикали, пользуясь такой нехитрой функцией, как arctg2.

Можно конечно всякими арксинусами и аркосинусами запользоваться, просто акртангенс-2 выдает вам все 360 градусов, без геморроя.


Смотрите, вроде у нас от акселерометра угол есть, если собственное ускорение устройства близко к нулю, и мы в одномерном, несложном случае.

Получается как — у нас есть акселерометр, и есть гироскоп. И нам нужно что-то, что нам даст на выходе достаточно точный угол.

Проблема акселерометра в чем основная? В том, что он дико шумит. Причем шумит на высоких частотах.

Я тут пытался визуализировать, и если визуализировать этот вектор он там так дико колеблется, хотя само устройство абсолютно в состоянии покоя. Т.е. высокочастотные, сильные, причем с хорошей амплитудой. Просто так этим пользоваться тоже нельзя, надо как-то хитро.

Есть два стандартных подхода, как это делать:
  • Первый — это некая магия, которая называется фильтр Калмана.
  • Второй — это так называемый, complimentary filter, на русском точный аналог, это «альфа-бета фильтр».



Магия Калмана. Это очень сложный фильтр, честно говоря, я сам его не понимаю. Про него написана не одна книжка, защищена не одна диссертация. Его основная фишка в том, что он использует внутри себя, т.е. для фильтрации, как модель измерения самого себя, так и модель устройства. Соответственно эти модели, они многопараметрические. И чтобы у вас хорошо работал фильтр, вам нужно эту кучу параметров подобрать, каким-то образом.


Его используют, например, в самолетах, но там, все физические характеристики самолета давно и хорошо изучены, из-за его аэродинамических и прочих характеристик. Какие же характеристики у телефона, к тому же попавшего в чью-то руку? Его там будут круто крутить, это совершенно странные штуки…

В принципе так этот фильтр работает, ничего тут непонятно, но есть готовая имплементация на C++ по этой ссылке. Поэтому можно даже не разбираться, поставить, и дальше весь magic в том, чтобы подобрать эти параметры.


Если вы думаете, что это не нужно, то вы можете набрать «калман фильтр для андроида» и увидеть очень много результатов, т.е. вам само устройство шлет сырые данные, оно за вас ничего не делает с этим — трахаться, мучаться разработчику, вам.


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


Ну дельта тут какое-то небольшое число, единственный параметр этого фильтра, который надо подобрать. Почему он такой, альфа-бета, иногда его еще называют каким-то «композитным фильтром». Потому что этот коэффициент, он достаточно большой, он убивает низкие частоты, а этот коэффициент маленький, он убивает высокочастотный шум. Получается, что вы убиваете низкую частоту шума от интегрирования, а вот тут убиваете высокую частоту, тот самый шум, который идет с самого датчика.

Как подобрать этот параметр, тут тоже есть достаточно простая формулка: а-ля релаксация, если у вас сейчас неправильно измерен угол, то через сколько он у вас сойдется к правильному значению. Это время тау вычисляется примерно так, а здесь та частота, с которой вы получаете сигнал с датчиков, как правило, сто раз в секунду, как сейчас все современные устройства дают.


Ну вот, например, если у вас коэффициент, например, в сотых, вы раз в сто секунд получаете, что примерно за полсекунды устройство приблизится к тому положению, в котором оно должно быть.

Вот дальше идет видео, в общем, народ обленился, смотрите, как сравнить эти фильтры. Смотрите, как народ делает — вообще ничего не надо, достаточно камеры. Народ пытается сравнивать эти фильтры, и понять, какой лучше. Музычка хорошая, чуваки ненапряжно все так, зачем математика, смотреть разницу между функциями и т.п. Вот так вот. Слева — «альфа-бета» фильтр, в центре — «чисто кальман», а справа — это они еще какой-то свой изобрели еще.



Но на самом деле, это не очень такая визуализация, ибо не очень понятно, какие здесь параметры, очень все сильно зависит от параметров. Видно, что этот «альфа-бета», он например, более плавный, может из-за того, что там коэффициент подобран не очень здорово, «Калман» вроде более четкий…

Так вот, этот фильтр, «Калмановский», он зародился в радиолокации, в обработке радиолокационных сигналов, потому что там, вы посылаете волну, она к вам обратно приходит и вы по времени задержки измеряете расстояние, а по эффекту Допплера, который «ви-и-и-у», измеряете скорость. Почти как у нас, только у нас углы, но то же самое, т.е. есть величина и производная величины, замерянные в один момент времени. И дальше там надо максимально эффективно отфильтровать шум, «Калман» придуман для этого. У меня мама занималась всю свою жизнь вторичной обработкой радиолокационных сигналов. Я, уже когда со всем этим разобрался, реализовал этот complimentary filter, спросил у нее:
— А как вы фильтровали? Ты разбираешься в фильтре Кальмана? Можешь мне его объяснить?
— Ой, да, у нас там отдельный институт в Жуковском или еще где-то работал над этими фильтрами Калмана, все защитили кучу диссертаций…
— А как вы подбирали параметры?
— Ну так, чисто экспериментально, на глазок, кое-как…
— Хм, интересно. А другие фильтры, попроще, не пробовали применять?
И тут она мне выдала:
— Ну да, мы под конец использовали простейший «альфа-бета» фильтр, он работает примерно также, а вычислительно намного проще.
Там еще советские вычислительные машины стояли, и этот фильтр Калмана был очень вычислительно дорогой.

Ну вот, собственно говоря, это пример, если вам придется с этим столкнутся, не бросайтесь сразу грызть этот гранит Калмана, погрызите сначала что-то попроще.



Тем более здесь есть еще одна подстава, как перейти от одномерного случая к трехмерному. Ну на самом деле надо переходить к кватернионам, и примерно здесь все то же самое, интегрируют в кватернионах, но добавляется вот такая корректировка…


По сути, это углы отклонения вектора, который вы сейчас замерили, поворот, к которому мы можем рассчитать через текущий кватернион вращения.

Чтобы это рассчитать, у нас есть всего лишь два вектора… разбивается это на самом деле на три случая:


Если у нас устройство вертикально, то можно корректировать (показывает два перпендикулярных угла отклонения) по таким углам. А вот такой угол (вращения вокруг оси) мы никак из ускорения свободного падения получить не можем. Ну и аналогично рассматривая положения этого устройства (показывает две перпендикулярных горизонтальных ориентации), мы получаем, что мы можем скорректировать каждый раз только два угла из трех. Причем каждый раз, два разных угла из трех.


Получается, что это все здорово работает, но остается вот такой вот дрифт, вокруг вертикальной оси. Я могу вам показать, как сейчас вот выглядит устройство, которое я сейчас вращаю, мы можем положить его в какой-то ориентации, хотя бы примерно так, хотя стол двигается… сейчас мы вид сверху сделаем… под каким оно примерно углом, теперь я его быстро-быстро вращаю, накапливается ошибка, все плохо, я его кладу, и вот оно так хоп, чуть-чуть откорректировалось по тем углам, и так оно перевернулось, почти полностью.

Т.е. вот, все равно такая вот получается засада.

Magnetic Compass



И тут приходит нам на помощь магнитный компас. Если вы заметили, то многие устройства раньше им не комплектовались, то сейчас они стали бурно в него впихивать, казалось бы — зачем он?

Все помнят, что у нас магнитное поле опоясывает Землю, соответственно мы можем мерить напряженность магнитного поля, и у нас появляется вектор, дополнительный и ортогональный ускорению свободного падения!

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


Вот казалось бы такая простая задачка, но столько геморроя.

Вы можете посмотреть для примера, как сейчас работают разные программы дополненной реальности, они сейчас работают достаточно дерьмово, мягко скажем, и вот почему.

Поэтому магнитный компас очень важен, и покупая устройство, если вы хотите им так пользоваться, обращайте внимание на его наличие.

Cameras


Давайте перейдем к камерам…

А почему они не используют уровень, обычный?

Только как его в мобильник запихнуть? Почему бы не использовать обычный гироскоп — раскрутил его и все (сарказм detected).
А уровень можно маленький сделать…

Ну это будет один угол относительно горизонта. И тоже будет сильно фонить, в принципе, вам акселерометр тоже самое и дает, то же самое, что и уровень, если задуматься. Акселерометр это по сути уровень и есть.
… дрифт… тоже может дать, вращение вокруг оси…

Нет, не очень понятно. Уровень никак не отследит это.

Давайте перейдем… много еще хочется всего рассказать… на самом деле, сенсоры, с этим рано или поздно разберутся, уже появляются всякие SDK, в которых эти проблемы решены, и я думаю, так или иначе, через годик-два с этим будет также легко работать, как с мышкой, будет готовый класс, от которого можно будет наследоваться или использовать его и не знать обо всех этих подводных камнях.

Намного интересней и инновационней это как раз обработка видеоизображений, которые мы получаем с камер.

To be continued



Благодарности



Еще раз хочу поблагодарить Стаса Фомина (belonesox) за расшифровку стенограммы. Стас, кроме всего прочего, является бессменным председателем Программного Комитета конференций серии Application Developer Days и, на мой взгляд, сделал для этой конференции значительно больше, чем ее непосредственные организаторы, хотя не получает за это ни копейки. Например, на ближайшую конференцию в Питер Стас собрался везти на своем горбу из Москвы кучу дополнительного оборудования (доп. проекторы, мониторы, видео-камеры, всяческие переходники чтобы подключить любой ноутбук к любому проектору или плазме и т.д.) — и всё это ради того, чтобы ему самому не было стыдно за конференцию, к созданию которой он имеет самое непосредственное отношение.

Если вам нравится данный материал, поблагодарите belonesox кармой или/и посетите одно из мероприятий, в организации которого Стас принимает участие.
Теги:
Хабы:
Всего голосов 64: ↑62 и ↓2+60
Комментарии15

Публикации

Истории

Ближайшие события