В чому сила, Дарт? Телекінез за допомогою Sphero та Kinect

Якщо останні півроку ви не просиділи в печері, то однозначно чули про найгучнішу подію у кінематографі останнього часу — прем’єру сьомого епізоду «Зоряні війни». Однак «Пробудження Сили» відбулося не тільки у фільмі, але й у наших головах. Ми в ELEKS багато думали, як би знайти суперсилу, а потім зрозуміли, що насправді нам просто-напросто потрібно було поєднати Kinect 2.0 для Windows із Sphero 2.0. І пересувати предмети за допомогою телепатії стало можливо (ну майже).

Sphero — це невеличкий, розміром з бейсбольний м’яч, керований через bluetooth робот. На його борту — акселерометр, магнітометр, гіроскоп, LED підсвітка, bluetooth-модуль і мотори, які забезпечують його рух. Існує багато Android/iOS програм для керування Sphero. Його можна використовувати не лише як цікаву іграшку, але і як маніпулятор, оскільки є можливість програмного доступу до його датчиків.

Kinect — безконтактний сенсорний ігровий контролер, спочатку представлений для консолі Xbox 360, і значно пізніше для ПК під керуванням ОС Windows. Розроблений фірмою Microsoft. Заснований на додаванні периферійного пристрою до гральної консолі Xbox 360, Kinect дозволяє користувачеві взаємодіяти з нею без допомоги контактного ігрового контролера через усні команди, пози тіла, об’єкти або малюнки.

Використання Kinect

Ви вже знаєте, що Kinect — це дуже круто. Серйозно, він може зробити будь-кого трішки Дартом Вейдером. Але навчитися працювати з ним — ось у чому полягає справжня сила. У Kinect 2.0 передбачене використання лише USB 3.0, оскільки він надсилає таку кількість даних, яку USB 2.0 витримати не здатен. Відповідно, це вимагає також DirectX 11 та драйверів, які підтримують Windows 8 і пізніші версії. Але коли усіх вимог дотримано, до ваших послуг 20 Mb/sec Color data, 13 Mb/sec Depth data, 13 Mb/sec Infrared data, 32 Kb/sec audio та багато інших цікавих можливостей. Круто, правда? Окрім цього, Kinect SDK дозволяє відслідковувати скелети одразу шести людей. Усе це свідчить про те, що Kinect — ідеальний сенсор для створення взаємодії між людиною і технологією.

Чому Sphero? Очевидно, що поява BB-8 дуже надихнула нашу команду. І оскільки BB-8 був створений на основі Sphero, який на той час вже був у нас на озброєнні, для нашого експерименту ми обрали саме цю технологію. Ми використали неофіційний .NET SDK, який дозволив нам створити кастомізовану систему контролю Sphero, використовуючи Kinect та Kinect SDK для Windows.

Функціонал Sphero .NET SDK доволі обмежений. Для того, щоб змусити Sphero рухатись в потрібному напрямку, потрібно задати йому вектор руху, що робиться через кут і швидкість. Кінцеві кординати Sphero отримуються з Kinect завдяки JediGestureRecognizer — класу, який ми створили для відслідковування позиції, куди вказує рука «джедая». Для визначення вектора руху Sphero до кінцевих координат, виконується його калькуляція на основі різниць поточної і кінцевої координат. То як же перемістити Sphero з його поточної точки на іншу?

Погляньмо:

Відповідно до ґайдлайнів Microsoft про взаємодію з Kinect, перша річ, яку ви повинні зробити — це визначити фізичну зону взаємодії (PHIZ — physical human interaction zone). Найчастіше Kinect із Windows використовують тоді, коли хочуть створити взаємодію з екраном, відповідно PHIZ створюють навпроти користувача.

Спершу ми думали створити квадратний простір перед людиною і спроектувати його на підлогу. Таким чином, коли людина рухає рукою в повітрі, Sphero відтворює цей рух на підлозі. Але цей концепт здавався нам не дуже природнім, адже коли ви хочете щось пересунути (навіть якщо телепатично), ви як правило, фокусуєте свою руку на предметі, який хочете перемістити.

Отже ми вирішили розташувати PHIZ на підлозі, і це виявилося легше, ніж ми очікували. За основні точки ми взяли голову людини та її активну руку, і за допомогою прямої, що пролягає через точку голови і точку активної руки, ми вирахували точку, спроектовану на підлогу.

Трошки математики

Точка В (голова) має координати (0.26, 1.90, 3.20), лінія М (активна рука) має координати (0.30, 1.40, 2.80). Kinect надсилає координати в метрах. Вісь Y спрямована по вертикалі, вісь Z спрямована від Kinect і показує відстань до об’єкту, розташованого перед ним. Ми повинні знайти спроектовану точку С. С має Y=0.

Щоби вирішити це завдання, ми звернулися до тригонометрії:

Ми використали формулу тангенсу.

Звідси, алгоритм такий:
1. Знайти спроектовану точку для осі ZY згідно вказівок, поданих нижче.
2. Знайти спроектовану точку для осі XZ згідно вказівок, поданих нижче.

Як знайти спроектовану точку з трикутника:

Маючи ці результати, ви можете легко знайти координати спроектованої на підлозі точки.

Далі ми повинні примусити Sphero котитись до цієї точки. У нас вже є обчислений кут і відстань, яку має пройти Sphero. Так само нам дано швидкість переміщення Sphero — 2 м/с. Ми можемо змінити коефіцієнт швидкості, отже, якщо ви встановите коефіцієнт, рівний 0.5, реальна швидкість Sphero буде 1 м/с.

Sphero .NET SDK має функцію, яка дозволяє надсилати команду «Roll (angle, velocity)», що примушує Sphero котитись в цьому напрямку, допоки ви не надішлете команду «Roll(angle, 0)». Для більшої точності управління кулею, ми створили таймер, який дозволяє надсилати команди ґаджету з вказаною частотою.

Щоби краще контролювати Sphero, ми дозволили користувачу змінювати кінцеву точку під час руху. Для цього ми поділили відстань (1) від точки А до точки В на маленькі ітераційні проміжки (dl) — відстані, які Sphero долає між спрацюваннями таймера, не змінюючи напрямку. Під час кожного спрацювання таймера відбувається рекалькуляція кінцевої точки, а також наступної точки, куди докотисься Sphero до наступного спрацювання таймера. Отже, якщо кінцева точка (В) змінюється під час руху Sphero, ґаджет змінює свій напрямок до нової проміжної точки, пов’язаної з новою кінцевою точкою (В’).

Як це виглядає у коді:

//Sphero is in next point
Point currentPosition = _nextIntermediaryPoint;
SetCurrentPosition(currentPosition);
Point destinationPosition = GetDestinationPosition();

//recalculate the Sphero angle (0.0 <= a <= 359.0):
double spheroAngle = GetSpheroAngle(currentPosition, destinationPosition);

//recalculate distance
double realDistance = GetDistance(currentPosition, destinationPosition);

if (realDistance >= _iterationDistance)
{
    //Save recalculated sphero angle (for correct stop)
    _lastAngle = (int)spheroAngle;
  
    //Move with recalculated values
    Roll(_lastAngle, (int)_spheroSpeed);

    //Recalculate real angle (-180.0 < a <= 180.0)
    double realAngle = GetAngle(currentPosition, destinationPosition);

    //Recalculate next intermediary point
    Point nextPoint = CalculateNextIterationPosition(currentPosition, realAngle, _iterationDistance);
    SetNextIterationPosition(nextPoint);
}

else
{
    //Sphero near or on destination point
    Roll(_lastAngle, 0);
}

Як ми відслідковуємо силу

Щоби розпізнавати жести рук, ми використали Body data. Зважаючи на те, що алгоритми, які зчитують людський скелет, були далекими від ідеалу, ми повинні були відфільтровувати потрібні нам дані від шуму, відповідно до формули:

FrameRecived — HandTrackedFrames <= Epsilon

FrameRecived — кількість кадрів, які ми охопили.
HandTrackedFrames — кількість кадрів, коли долоня була відкрита.
Epsilon — стала, що визначає допустиму кількість шуму.

Ця формула допомагає визначити, чи людина тримає відкриту долоню перед собою, бо саме цей жест забезпечує переміщення Sphero. Після ряду тестів ми визначили, що Epsilon дорівнює 3, а кількість кадрів до опрацювання — 8. Це означає, що якщо ми відстежили жест відкритої руки щонайменше на 5 кадрах — сила активна.

Логіку трекання можна знайти тут.

Сило, прибудь!

Для того, аби випробувати свої нові здібності, потрібно створити належні умови. Перш за все облаштуйте сцену дій:
1. Покласти Sphero на підлогу;
2. Встановити коректний кут (задній вогник повинен бути розміщений протилежно до Kinect’у);
3. Встановити швидкість.

Займіть своє місце на сцені, як молодий падаван. Відчуйте силу в собі. Розкрийте свою долоню і сфокусуйте її (а також свої думки) на Sphero. А тепер телепатично переміщайте Sphero за допомогою руки. Для того, щоби зупинити Sphero, стисніть кулак. Якщо ви відчуєте силу знову, перейдіть на інше місце і продовжуйте переміщати Sphero.

Концепт ви можете знайти на GitHub. Нехай буде з вами сила!


Стаття написана у свівавторстві з Олександром Кудіновим. Дякуємо Марті Чавазі за адаптацію з англійської.

LinkedIn

13 комментариев

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

Респект, классно придумали )

1 — покатать так мячик я могу и просто встроив в него нехитрую схему и моторчик, тем более, никто не показал нам все при свете, так что фейком попахивает видео.
2 —

Маючи ці результати, ви можете легко знайти координати спроектованої на підлозі точки.
 вы прикалываетесь? Какому пользователю будет “интересно” высчитывать точку, по формулам? бред.
3 — Не вижу пока применения даже в индустрии развлечений...
4 — вот если бы он заставил его летать...)

Сразу видно кому в детстве Дед Мороз не принёс машинку на радиоуправлении.

А если серьёзно, ценность киннекта слишком раздута. Психологически приятнее и комфортнее держать в руках пульт управления, чем управлять жестами. Ещё круче — когда устройство управления даёт обратную связь. Так что будущее — за активными устройствами.

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

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

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

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

Скажу более кратко: киннект переоценен. Если интересно, можешь поинтересоваться опенсорс-разарботками на эту тему.

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

Причина чому кінек, бо він у нас вже був + є хороше SDK під .NET. Якщо можеш кинь посилання на ці проекти мені, буду вдячний.

Кінект не настільки вже і поганих сеснсор. Просто потрібно знайти правильно використання для нього. У випадку якщо тобі не потрібна відстань, чи зчитування 3D об’єктів у реальному часі, то і кінект тобі не потрібний.

Так дуже хотілося червоної машинки.

А якщо серйозно, ми не розробляли прототип для керування речами, нам стало цікаво зробити щось на тему Star Wars.

На момент вибору, що саме робити, вже було дуже багато проектів і рішень нарахунок світлових мечів, але тематика Star Wars має ще багато інших аспетів які можна розкрити, тому ми і вибрали телекінез.

Але я погоджуюся із думкою — що майбутнє за активними пристроями.

Ааа, якщо хотіли тренд вхопити — правильно робите, респект. Але мені здається цей тренд досить короткий, монетизувати не встигнете.

Але мені здається цей тренд досить короткий, монетизувати не встигнете.
Так оно не для монетизации создавалось, просто just for fun и тут они молодцы, да и для компании такая репутация не лишней будет.

З`єднайте тепер Sphero та квадрокоптер і будете мати у всіх площинах.

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

Подписаться на комментарии