Как мы размещали теги на небе. Дополненная реальность против разработчика.

МЕНЮ


Искусственный интеллект. Новости
Поиск
Регистрация на сайте
Сбор средств на аренду сервера для ai-news

ТЕМЫ


Новости ИИРазработка ИИВнедрение ИИРабота разума и сознаниеМодель мозгаРобототехника, БПЛАТрансгуманизмОбработка текстаТеория эволюцииДополненная реальностьЖелезоКиберугрозыНаучный мирИТ индустрияРазработка ПОТеория информацииМатематикаЦифровая экономика

Авторизация




RSS


RSS новости

Новостная лента форума ailab.ru


Около года назад перед нашей командой встала задача написать приложение в дополненной реальности для Yota, где различные виды контента / моделей располагались бы на небе. Строго говоря, приложение, с помощью которого пользователи могли бы устанавливать тэги над головой и просматривать объекты, добавленные другими пользователями. Немного забегая вперед, даю ссылки на App Store и Google Play, чтобы было проще понимать, о чем пойдет речь в статье (приложение доступно только для телефонов с поддержкой ARKit и ARCore).

Дополненная реальность — штука сложная, интересная и активно развивающаяся. Мы не могли обойти ее стороной. Вообще AR / VR исследовали давно, трогали, писали статьи, делали эксперименты. Но о том, чтобы поставить объекты на небо, не задумывались никогда. Отсюда началось наше более близкое знакомство с ARKit и ARCore.

Вопросы и задачи

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

  • Как понять, где небо. Как нам определять, что такое небо. Просто потолок над головой или все же купол? А деревья — это небо? А если я из окна хочу смотреть на улицу, то это небо? А когда гроза и дождь — это небо?
  • Сетка или угол наклона телефона. Как пользователю было бы удобно располагать объекты — видя какие-то ячейки для установки тега или просто наклоном телефона и кликом на экран. Важно было определиться с интуитивно понятной механикой добавления тегов на небо.
  • Как разворачивать добавленный контент по отношению к пользователю. Будут ли они повернуты горизонтально, словно стикеры, приклеенные к потолку? Или же висеть вертикально, как парящие в воздухе билборды, со временем погружая нас в мир “Бегущего по лезвию”… Или, может, как-то еще?
  • Как сделать так, чтоб объекты не накладывались друг на друга. Как не допустить того, чтобы одни объекты загораживали другие или чтоб были пересечения, которые могут визуально портить восприятие самих моделей. Небольшой спойлер: это единственная проблема, которая решилась сама собой ;)

Помимо этих, можно сказать UX, вопросов возник ряд технических задач, связанных с неподготовленностью AR SDK работать в небе. Проект мобильный, мы писали его на двух платформах: iOS и Android. По большей части вопросы на платформах были схожие, но так как я Android разработчик, то далее речь пойдет об ARCore в связке со Sceneform и их особенностях. При более детальном погружении в проект нас подстерегали уже более технические проблемы:

  • Ограничение ARCore на рендер только близлежащих объектов (до ~10м примерно). Самое пугающее на первый взгляд ограничение, решение которого в виде побочного эффекта улучшило качество и стабильность трекаемых объектов.
  • Сможет ли ARCore ловить движения телефона, если небо однотонное (голубое/серое) Когда небо чисто-голубое, а телефон смотрит точно вверх, то ARCore-у не за что “цепляться”, чтоб поймать изменение картинки. И иногда при движении телефоном объект остается на том же месте и как будто движется вместе с девайсом.
  • Отсутствие гео-ориентированных осей и неточные показания компаса. Кроме задачи добавления тега в пространство дополненной реальности перед нами также стояла задача отображения тегов другим пользователям. Соответственно тут не обойтись без перевода AR координат в географические и назад. На iOS эту задачу сильно упрощают встроенные в ARKit гео-ориентированные оси. То есть ты можешь использовать систему координат, ось Z которой всегда направлена на север. В ARCore это до сих пор не реализовано, feature request висит уже больше года. Пришлось самим искать север, используя какие-никакие данные компаса. Затем добавили калибровку — и в принципе погрешность получилась приемлемой.

Что такое небо?

Обилие статей и сэмплов наглядно нам рассказывает, как работать с дополненной реальностью на поверхности, как создавать объекты и располагать их в 3d пространстве. Но как понять, что небо — это небо?

Первое, что приходит в голову — это использовать машинное обучение, чтоб распознать небо. Вычесть деревья, крыши и провода и разрешать пользователю добавлять объекты именно на небо. Поискали — готовых решений / библиотек / наработок — не нашлось. Писать такое решение самим довольно затратно, особенно в рамках MVP проекта. Да и непонятно вообще, как с этим работать дальше. Тогда у нас возникла идея определять время суток и погоду в данный момент времени, чтоб в зависимости от этого “предполагать”, чем может быть перекрыто небо. Так мы планировали понимать, давать ли пользователю располагать стикеры. Подумали и решили оставить это как “улучшение” проекта, а пока небо — это потолок над головой на определенной высоте (ориентировочно 30 метров). Ведь формально для человека, находящегося на земле, это выглядит именно так.

Как добавлять объекты?

Вроде условились, что небо — это плоская ограниченная доска над головой. Как будем располагать на ней наши картинки? Чтоб не было наложений объектов друг на друга, прикинули, что нужна своего рода разметка, что-то вроде сетки, на которую пользователь бы кликнул и поставил туда объект. Достаточно долго только этот подход нам казался единственным верным. В голове представляли красивую картинку с “плюсиками” в ячейках в режиме добавления объектов на небо. То есть пользователю показывается разметка, показываются занятые места, а на свободные можно нажать и добавить свой объект в центр ячейки. Уже даже придумали, как разделить весь мир на такие квадратики — оставалось только эмпирическим путем выяснить размеры ячейки и высоту потолка…

Но! Пришел новый человек в команду и сказал, что мы слишком усложняем, что сетку рисовать трудоемко, что ограничивать пользователя в местах для установки тегов — не user friendly и что можно просто наклоном телефона задавать желаемое место расположения тега. Как оказалось, у заказчика было похожее видение. Решили задавать направление расположения модельки наклоном телефона к горизонту. Звучит проще с точки зрения добавления фигур на сцену — теперь не нужно рисовать в дополненной реальности кучу линий, образующих сетку. К тому же, таким образом довольно интуитивно решается вопрос с наклоном контента. Кажется, что нужно ставить его лицом к пользователю. Так и решили: разворачивать всегда лицом, даже те, что добавлены другими пользователями — чтоб объекты на небе всегда задорно глядели на людей. Но снова возвращаемся к вопросу:

Как минимизировать пересечения / наложения объектов?

И добавляется еще один:

Как понять, на каком расстоянии от телефона пользователь устанавливает объект? Что он расположил его именно над домом, а не за ним на той же линии, но большего размера?

Причина обоих этих сложностей таится в том, что мир дополненной реальности — это объемный 3D мир, который мы пытаемся запихнуть на плоский экран телефона. Важно сделать наиболее консистентный перенос.

Механика добавления тега

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

Пришло понимание, что:

  1. Небо — это потолок ~ 20 метров над головой
  2. Объекты разворачиваются всегда лицом к людям.
  3. Пользователь будет ставить тег, наклоняя телефон и наводя камеру на место, где он хочет увидеть объект. То есть условно из девайса выходит луч, и где-то на этом луче будет располагаться картинка.
  4. Превью объекта будет показываться на экране, когда пользователя устроит место, ему останется только тапнуть, чтобы закрепить.

Главный вопрос: Где окажется тег в итоге? Пользователю не будет понятно расстояние, на котором он закрепил тег. Действительно ли он находится над тем собором или он ближе, но меньшего размера?

Картинка ниже наглядно показывает наши сомнения.

Идеальное решение, которое приходит в голову, — это добавить слайдер дальности. Но на это не было времени. Пошли снова думать… Решили, что для начала у пользователя будет возможность ставить тег только на определенной высоте над горизонтом в некотором отдалении. “Но это же все упрощает” — утвердились в мысли мы и решили реализовать именно такой подход. Задаем фиксированное расстояние и надеемся, что через некоторое время пользователь привыкнет и вскоре будет примерно представлять, где ожидать размещенный объект. Ведь практически во всех играх требуется пройти обучалку по управлению, не правда ли? У нас остались некоторые сомнения по поводу ограничения степеней свободы — но ничего, в следующих релизах доработаем. Реализовали установку тега на расстоянии 60 метров вдаль и 30 метров вверх от экрана смартфона и пошли тестировать “в поля”.

К нашему приятному удивлению, работать с такой механикой оказалось вполне удобно. Немного не хватало возможности добавлять объект прямо над головой, подняв телефон в небо. Зато приходит осознание, как и куда тебе нужно отойти, чтоб поставить тег, куда ты хочешь. Можно крутиться вокруг себя, выбирая направление. Можно закрепить тег, а потом подойти и убедиться, что он оказался там, где запланировали. Привыкание было безболезненным. Этот подход показал себя гораздо более быстрым и интуитивно понятным по сравнению с плоскостью в MVP версии. И сам собой решился вопрос наложения:) Во-первых, физически оказалось достаточно трудно расположить объекты близко друг к другу. Шаг в сторону — и объект вдалеке значительно поменял свое положение. Во-вторых, можно немного повернуть или наклонить девайс, изменяя ракурс, чтоб рассмотреть другие объекты, если они вдруг оказались загорожены. По крайней мере, этот вопрос больше не доставлял неудобств, а значит перестает быть проблемой!

Больше свободы действий (или продолжение работы над механикой)

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

То есть хочу чуть сильнее наклонить — вижу объект над собой. Ох. Эта задача снова открывает некоторые вопросы:

  1. Располагать на равном удалении по линии или на фиксированной высоте?
  2. Либо делать купол над человеком, чтоб скейл объекта оставался одинаковым. Но тогда другим людям в отдалении этот объект будет казаться меньше.
  3. Когда экран направлен вверх на небо, то картинка может быть однотонной и AR не к чему привязывать объекты. Может возникнуть “плавание” тегов.

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

Подумали, что можно не откладывать эту хотелку в долгий ящик, а точнее до следующего релиза, и добавили такую фичу. Результат понравился. Оказалось, что мы как пользователи очень этого хотели ;) А вопрос пересечения тегов стал еще менее заметным.

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

Дальность отрисовки тегов

Открою вам секрет, мы не отображаем объекты в реальном мире, мы отображаем их проекции на том расстоянии, на котором позволяет рисовать ARCore. Простой математический аппарат позволяет из географических координат телефона и показаний компаса построить проекцию тэга, которую мы рассчитываем на каждом кадре в зависимости от перемещений девайса. Для размещения объектов на сцене механизм дополненной реальности в большей степени опирается на картинку, полученную с камеры. При недостаточном освещении или качестве камеры точность картинки довольно мала, что напрямую влияет на стабильность сцены дополненной реальности. На больших расстояниях ситуация усугубляется. За счет отображения маленьких копий на близких расстояниях мы добились более стабильного качества мониторинга объектов. Благодаря этому наше приложение более ли менее приемлемо заработало на стареньких девайсах типа Nexus 5x. В MVP версии добавленные теги просто уплывали с экрана даже с хорошей картинкой.

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

  1. Благодаря более близкому размещению тегов на сцене исчезает часть проблем, связанных с артефактами и миганием 3D моделей. На iOS стали заметны визуальные неточности моделей, которые расположены на расстоянии 40–50 метров от пользователей. В реализации Android приложения подобная ситуация просто невозможна.
  2. Незадолго до релиза экстренно понадобилось ограничить рисование объектов, находящихся далее 600 метров от девайса. Из-за большого расстояния стало казаться, будто они лежат на земле. Это получилось сделать очень легко, так как лимит был уже задан при реализации “переноса” тегов. На iOS мы были вынуждены идти другим путем, так как пришлось бы переписывать логику расстановки тегов, а делать это перед релизом крайне рискованно.

Чистое небо и что с ним не так

К сожалению, перерисовка тегов на каждом кадре не смогла помочь в случае однотонной картинки. Вопрос с полностью чистым небом все еще остается открытым. Высчитывая изменение положения девайса, мы используем данные, предоставляемые ARCore. То есть в плохую видимость мы “помогаем” объектам найти их правильные места на текущей картинке. Но если камера отдает абсолютно черный (ночью) или чисто голубой (ясным днем) кадр, то ARCore не присылает никаких данных о его изменении, так как просто этого не замечает и объекты на экране не меняют своего положения. Тут мы не можем ничего поделать, кроме как ограничить вредоносную зону. Понятно, что наше приложение не предназначено для использования в ночное время суток, но вот ясное небо?… Какие бы слухи ни ходили, в России оно бывает довольно часто. А так как команда разработки находится в Омске, одном из самых солнечных городов страны, то тестировать при чистом небе приходилось регулярно. Мы частично решили этот вопрос, запретив пользователю располагать тег прямо над своей головой. Во-первых, задирать голову и руки наверх довольно неудобно. Проще отойти на пару шагов, чтоб увидеть полную картину. Во-вторых, тут еще возникают математические задачки перехода угла наклона телефона через 180 градусов и требовали бы дополнительных проверок. И в-третьих, частично решается наш вопрос с плаванием объектов на однотонной картинке с камеры. Таким образом, мы минимизировали случаи “пустого кадра”. Теперь пользователь сталкивается с этой ситуацией, только если проходит под уже размещенными тегами и направляет камеру ровно на небо.

Привязка тегов к местности

Напоследок осталась одна из самых непонятных для нас задач: перевод AR координат в географические и обратно без какой-либо помощи ARCore. По гео координатам необходимо размещать объекты на сцене дополненной реальности для того, чтобы теги, добавленные одними пользователями рядом с собой, были видны остальным. Ух… Веселуха. Ищем азимут и мерим показатели компаса.

Достаточно быстро поняли, что наша задача сводится к качественному определению направления севера. Затем мы поворачиваем нашу систему координат так, чтоб ось Z всегда смотрела на север, и получаем своего рода гео-ориентированные оси.

Осторожно, следующий абзац хардкор ->

Итого у нас есть: север, гео позиция начала системы координат и гео позиции тегов. Вычислив угол поворота тега от севера (азимут) и расстояние до тега по этим позициям, мы получаем координаты каждого тега в полярной системе координат. Далее переводим их в прямоугольную и поднимаем на 30 метров. Только и всего! Теперь мы знаем, где разместить наш тег в AR. Ну и конечно не забываем про логику с проекциями, ведь 30 метров высоты — это небольшая иллюзия…

Найти север было не слишком просто. Компасы на Android работают крайне нестабильно, девайсов разного уровня много, а погрешность всего лишь в 2–5 градусов дает смещение на наших расстояниях в десятки метров. Сначала мы брали первое же относительно стабильное значение компаса, но этот результат нас не устраивал. При разных запусках приложения теги располагались вокруг тебя на небе в новых позициях. Причем специально установленные для тестирования “Компас”-ы не давали особо лучших результатов. Уже почти отчаявшись, мы решили добавить экран с руководством “поводить девайс по восьмерке” для достижения более хорошего результата.

Это имело колоссальный эффект! Помимо самой восьмерки некоторую калибровку создает дополнительное время, дающее возможность показателям сенсоров стабилизироваться, пока пользователь не нажмет “Продолжить”.

Что получилось

Теперь все встало на свои места — теги оказываются примерно там, где мы их ожидаем. К тому же использование приложения по назначению — на улице :) — создает совершенно другое впечатление, нежели тестирование в стенах офиса.

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

Еще раз взглянуть на то, что у нас получилось, можно по ссылкам: App Store и Google Play.


Источник: medium.com

Комментарии: