Боевое знакомство с Leap Motion

в 14:43, , рубрики: gadjet, Hackathon, Leap Motion, unity3d, Гаджеты. Устройства для гиков, метки: , , ,

Боевое знакомство с Leap Motion


Сегодня я хотел бы рассказать о простеньком приложении для небольшого, но интересного гаджета, случайно попавшего мне в руки (да еще и бесплатно!).
Рассматривать и пробовать будем девайс под названием LeapMotion, который красуется на сайте за «притягательные» 79.99$…
О нем речь и пойдет дальше.

Для начала несколько слов о самом устройстве. Это маленький, похожий на флешку приборчик, который захватывает движение ваших рук. Продвигается как некий «убийца» kinect-a. Подробнее о нем можно прочитать на wiki.

Боевое знакомство с Leap Motion

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

Однако, ближе к делу.
Само действие длилось всего около 6 часов, поэтому мне и команде предстояло разобратся в новой для себя технологии на лету. Разрабатывать было решено аналог кубика-рубика, а использовать для этих средств Unity3d, который как нельзя подходит для такой задачи. Документация нашлась быстро и мы приступили.

Далее обо всем по порядку.

1) Драйвера

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

2) SDK

Сам SDK содержит в себе набор библиотек, необходимых для разработки и пример работы: UnitySandbox, который по сути является тем же приложением, указывающем на строение вашей руки. Единственным изменением является то, что нам дадут пощупать настоящий кубик! Который мы можем поднимать и опускать, увеличивать и делать другие всевозможные пакости с бедным кубом.
Интересности SDK на этом заканчиваются.

3) Приложение

Так как использовать примеры из SDK — это не интересно, пришлось крутить собственный велосипед для работы с этим чудом.
Ну начнем. Для начала создадим проект и добавим в папку с библиотеками следующие dll-ки, которые возьмем из скачанного SDK (для x86):
x86/LeapCSharp.dll
x86/Leap.dll

Далее складываем в наш Assets folder файл LeapCSharp.NET.3.5.dll.
Затем создаем скрипт с оригинальным названием LeapBehavior, приписываем его к main camera и добавляем в него следующий код:

LeapBehavior.cs

using UnityEngine;
using System.Collections;
using Leap;

public class LeapBehavior : MonoBehaviour {
    Controller controller;

    void Start ()
    {
        controller = new Controller();
    }

    void Update ()
    {
        Frame frame = controller.Frame(); //Создаем фрейм
        if(controller.IsConnected) //Проверяем, что наше устройство подключено
        {
             Frame frame = controller.Frame(); //Устанавливаем последний фрейм(по умолчанию)
             Frame previous = controller.Frame(1); //...и сохраняем предыдущий
             Debug.Log(frame.Fingers.Count); //Выведем сколько пальцев уловил наш сенсор
        }
    }
}

Пара слов о Controller и Frame. Первый нужен для управления и контроля за самим девайсом, а Frame содержит в себе все, что сумел «увидеть» наш чудо гаджет в данный момент. Frame так же может вернуть списки увиденных рук, кистей, пальцев и все другие прелести.
frame.Fingers.Count вернет нам размер списка, который содержит все пальцы, увиденные прибором.

Проверим — работает.

Однако есть несколько тонкостей. Во-первых Leap motion, очень часто, считает сведенные вместе пальцы за один, во-вторых, часто не может определить какой руке принадлежат пальцы(две поставленные рядом руки, перекрестил — развел — свел) и бедный датчик может показать невероятное, но это мелочи.

С определением числа пальцев покончено, теперь попробуем найти их позицию. Все так же тривиально, надо лишь чуточку модифицировать функцию Update. Добавим после вывода в логи следующие строчки:

int IDFinger = 0;
Debug.Log(frame.Fingers[IDFinger].TipPosition.x);

С помощью Fingers получаем лист пальцев на Fream-е и берем позицию 0-го.

Теперь попробуем как-то это визуализировать. Воспользуемся самым быстрым и простым способом. Попробуем привязать к нашим пальцам какой нибудь объект. Например, сферу. Для этого добавим сферу на сцену и добавим к ней наш скрипт (не забудьте убрать этот же скрипт с главной камеры).

Теперь изменим его так, чтобы позиция сферы менялась вместе с позицией пальца. Для этого создадим Vector3 (объект, содержащий 3 компоненты — X, Y и Z). Проинициализируем его полученными с сенсора координатами пальцев. Также, для визуализации пальцев, создадим новый скрипт под названием fingerController. В итоге немного исправленный скрипт будет иметь следующий вид:

<h6>fingerController.cs </h6>
<source lang="cs">
using UnityEngine;
using System.Collections;
using Leap;
using System;

public class fingerController : MonoBehaviour {
	public int IDFinger = 0;
	 Controller controller;

         void Start ()
         {
              controller = new Controller();
         }
	
	void Update ()
	{
		if(controller.IsConnected) //controller is a Controller object
		{
			Frame frame = controller.Frame(); 
			Frame previous = controller.Frame(1); 
			this.transform.position = new Vector3(frame.Fingers[IDFinger].TipPosition.x,
			                                      frame.Fingers[IDFinger].TipPosition.y,
			                                      frame.Fingers[IDFinger].TipPosition.z);
		}
	}
}

Теоретически наш объект — сфера, должна плыть вслед за пальцем, номер которого, указан в поле IDFinger. Например так.

Боевое знакомство с Leap Motion

Изменим цвет сферы на наш любимый (чтобы та была отлична от фона) запускаем приложение и ура — все работает!
Добавим сферу для второго пальца на форму. После запускаем проект и крутим пальцами во все стороны. Сферы должны следовать за движением пальцев.

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

Теперь добавляем сам «кубик-рубик»(можно и обычный cube) и попробуем его повертеть.

Боевое знакомство с Leap Motion

Для этого напишем простенький скрипт.

Условимся, что двигать куб, можно минимум двумя пальцами и поехали.
Перетаскиваем на форму куб, добавляем в prefabs там же добавляем ему новый скрипт и вписываем имя: «enterCube». Добавляем свойство Box Collider и устанавливаем галочку, что наш кубик — это триггер. Копируем следующий код:

enterCube.cs

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class enterCube : MonoBehaviour {

	private int CountOfFingerInCube = 0;
	private List<Collider> ListFinger = new List<Collider>();
	void Start ()
        {
	}
	void FixedUpdate () {
		if(CountOfFingerInCube==2)
		{
			Vector3 vector = new Vector3(0,0,0);
			vector.x = (ListFinger[0].transform.position.x + ListFinger[1].transform.position.x)/2;
			vector.y = (ListFinger[0].transform.position.y + ListFinger[1].transform.position.y)/2;   
			vector.z = (ListFinger[0].transform.position.z + ListFinger[1].transform.position.z)/2;  
			this.transform.position = vector;
		}
	}
	void OnTriggerEnter(Collider other)
	{
		CountOfFingerInCube++;
		ListFinger.Add(other);		
	}
	void OnTriggerExit(Collider other)
	{
		CountOfFingerInCube--;
		ListFinger.Remove(other);
	}
}

Кратко о ListFinger. Он хранит в себе все зашедшие в триггер пальцы, при выходе — удаляет выходящий из списка.
Проверяем — куб действительно движется. Однако — не вертится. Думаю, не составит труда, используя Vector3.Angle найти угол поворота.

Ниже представлен результат работы на данный момент (после которого время аренды девайса прошло, и его пришлось возвращать):

Видно, что в первой части видео куб иногда бросает в разные стороны когда оба пальца слишком близко. Связано это с несовершенством датчиков, которые иногда не могут различить реальные координаты пальцев.
С точностью определения координат каждого пальца в отдельности проблем нет. Устройство реагирует явным изменением координат даже на легкое движение руки, при попытке удержать ее на одном месте.
То есть в перспективе с помощью Leap motion можно создать неплохой симулятор тетради. Настраивается он специальным пером, к которому однако не удалось прикоснутся, так как настройка была проведена задолго до нас.

Как только проект будет доведен до конца тут появится ссылка на его исходники.

Спасибо.

P.S. Также я благодарен своим друзьям, участвовавшим в этом мероприятии и помогавшим мне в освоении этого удивительного девайса!

Автор: DizzyStyle

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js