- PVSM.RU - https://www.pvsm.ru -

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

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


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

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

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

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

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

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

1) Драйвера

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

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 очень резко, для человека это сантиметр, а для прибора — серьезно. Поэтому, чтобы не видеть улетающие за горизонт сферы, можно отодвинуть главную камеру подальше для обхвата большей области.

Теперь добавляем сам «кубик-рубик» [8](можно и обычный 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

Источник [9]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/hackathon/54672

Ссылки в тексте:

[1] LeapMotion: https://www.leapmotion.com/

[2] wiki: http://ru.wikipedia.org/wiki/Leap_Motion

[3] статьи: http://habrahabr.ru/company/rozetked/blog/190404/

[4] устройстве: http://habrahabr.ru/post/169043/

[5] хабра: http://habrahabr.ru/post/172351/

[6] Документация: https://developer.leapmotion.com/documentation/csharp/

[7] лежат: https://www.leapmotion.com/setup

[8] «кубик-рубик»: https://mega.co.nz/#!BZ40VQBb!ECt3lNwD6SZpE_flBvR5zjr88IY_qWbp0RWWL-eJU0Q

[9] Источник: http://habrahabr.ru/post/212069/