Leap Motion

De Centre de Ressources Numériques - Labomedia
Révision de 2 novembre 2017 à 18:45 par Serge (discussion | contributions)

(diff) ← Version précédente | Voir la version actuelle (diff) | Version suivante → (diff)
Aller à : navigation, rechercher


leapd doit tourner avec le driver propriétaire

sudo service leapd start

Si la bibliothèque leap est introuvable avec l'API python, faire les "export" en terminal avant de lancer le script python.

Le code libre a été écrit en 2012, depuis les composants ont changés. Le driver libre ne marche donc plus !

Leap 03.png

Citation du jour

Super Super()

Franchement, qui se souvient de la syntaxe pour appeler proprement la méthode parente d’une classe ?

# Au revoir !
class FranchementHein(object):
 
    def __init__(self):
        super(FranchementHein, self).__init__()
 
# Bonjour !
class FranchementHein(MesVieux):
 
    def __init__(self):
        super().__init__()

Ressources

Les exemples pour python sont peu nombreux !

Matériel

Le principe c'est 2 caméras Infra Rouge.

J'étais un peu déçu de voir un dispositif presque standard à l'aide tant open source code BSD ne fonctionne pas sur un système ouvert.. D'après ce que j'ai compris, le dispositif de mouvement de saut est webcam UVC "seulement" un infra-rouge stéréo avec un objectif grand-angle.

Les principales composantes sont:

Pour comprendre les dispositifs de FX3 base:

Le matériel a changé depuis 2012, les références ne sont plus bonnes en 2014.

Reconnaissance de geste

Les fonctions/méthodes sont les mêmes en C++ et python. Après avoir testé et visualisé dans Blender, j'affirme que la reconnaissance de geste du Leap Motion avec le SDK est nulle !

  • C'est très mal documenté: la doc ne donne qu'une valeur courante des paramètres de configuration, pas de plage, ça n'explique pas comment ils influent.
  • Il n'y a pas d'exemples.
  • Ce n'est pas Open Sources.

Driver propriétaire

Installation des drivers et API python 3.4

Ressources

Résumé de la recompilation sans explications pour un 32 bits sous Linux Mint 17

Vérifié sous Linux Mint 17 XFCE.

Le SDK doit être dans votre home:

sudo dpkg -i Leap-2.0.5+18024-x86.deb
LeapControlPanel
cd LeapDeveloperKit_2.0.5+18024_linux/LeapSDK/include
sudo apt-get install swig g++ python3.4-dev
swig -c++ -python -o LeapPython.cpp -interface LeapPython Leap.i
g++ -fPIC -I /usr/include/python3.4/ LeapPython.cpp /usr/lib/Leap/libLeap.so -shared -o LeapPython.so
cp LeapPython.so ../lib/x86/
cd LeapDeveloperKit_2.0.5+18024_linux/LeapSDK/lib
2to3-3.4 -w Leap.py
cd .. && cd samples
2to3-3.4 -w Sample.py

Résultat

Dans un terminal,

LeapControlPanel

Leap 02.png

Paramètres: Leap 01.png Ca va directement en copie à la NSA !

Leapd

leapd sert à quoi ?

sudo service leapd start
Export permanent

Coller ces 2 lignes dans le fichier ~/.profile

Remplacer votre user par votre user
export PYTHONPATH=/home/votre_user/LeapDeveloperKit_2.0.5+18024_linux/LeapSDK/lib/x86:/home/votre_user/LeapDeveloperKit_2.0.5+18024_linux/LeapSDK/lib:$PYTHONPATH
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/Leap/

Mais ça ne marche pas, il faut refaire l'export dans le terminal qui lance le script !!

Test
cd /home/votre_user/LeapDeveloperKit_2.0.5+18024_linux/LeapSDK/samples
python3 Sample.py

API Python

Comment envoyer les événements dans Blender 3D ?

Des scripts en python3.4 récupèrent les événements et les envoient vers blender avec asyncio et sérialisé avec json.

sudo apt-get install blender python3-numpy

Essai d'un script de leapyosc

Ressources

Cloner le dépot.

Lancement de leapyosc

Ajouter dans le dossier la version python3 du fichier OSC.py récupéré à https://gitorious.org/pyosc/devel/source/633c0112318a3519314aa798a552a092566c73c1:OSC.py

Faire les export dans un terminal ouvert dans le dossier leapyosc, puis

python3 client.py

et écouter avec le patch pure data Fichier:OSC-PureData-Blender-xy.pd.

Essai avec Processing

Testé sur Ubuntu 14.04 32 bits.

Nécessité de se créer un compte sur https://developer.leapmotion.com

Puis télécharger le paquet deb ici : https://developer.leapmotion.com/downloads

sudo dpkg --install Leap-2.2.1+24116-x86.deb

Récupérer la lib pour Processing ici : https://github.com/voidplus/leap-motion-processing

Puis la placer dans le dossier "librairie" du dossier "sketchbook".

Brancher la Leap Motion puis lancer l'exemple e1_basic :

Leap-processing.png

L'exemple e2_gestures marchouille, mais bon...

L'exemple e3_camera_images ne marche pas : libEGL warning: DRI2: failed to authenticate

Pure Data vs Leapmotion

Driver libre

OpenLeap Ce driver permet de récupérer l'image envoyée par la Leap. Ensuite, il faut traiter l'image avec OpenCV, en C## ou en python. Une variante à explorer serait de reconnaître autre chose que les mains.

Récupération du fichier *.pcapng avec wireshark

Installer les drivers propriétaires.

cd /votre/dossier/de/projets
git clone https://github.com/elinalijouvni/OpenLeap.git
cd OpenLeap
lsusb -d f182:0003

retourne

Bus 002 Device 004: ID f182:0003 

pour la suite, BUS USB = 2, device address = 4

Wireshark

sudo modprobe usbmon
sudo wireshark

permet d'obtenir un fichier leap2.pcapng

Installation du driver libre

Ce code a été écrit en 2012, depuis les composants ont changés. Cela explique pourquoi le test final échoue.

Extrait du Readme

How to see Leap Motion images:

  • Plug the Leap,
  • run the command: "lsusb -d f182:0003" and note the bus and device address. Check if your device has a different VID/PID. Replace it if needed.
  • This step is needed only if there is no udev rule file installed.

Change device permission with the command, as root:

 chmod 666 /dev/bus/usb/BUS/DEV_ADDRESS

(replace BUS and DEV_ADDRESS with values from the previous command).

  • in case the usbmon kernel module is not loaded, run: "modprobe usbmon" as root
  • Run a capture of the USB bus traffic, with the command, as root:
tshark -i usbmonX -w leap-init.pcap

where X is the number of the USB bus. You may also use the graphical Wireshark as well.

  • Run the original Leap software, make sure the device is properly detected and initialized. If unsure, test with the visualizer that everything is working.
  • Stop the Leap software and the capture.
  • Generate the Leap initialization C code with the command:
make_leap_usbinit.sh DEV_ADDRESS leap-init.pcap > leap_libusb_init.c.inc
  • Build the low-level-leap and display-leap-data-opencv programs with the "make" command.
  • You should be able to see images from the Leap device with the command:
./low-level-leap | ./display-leap-data-opencv

Résumé des commandes et sorties

pierre@PC4 ~ $lsusb -d f182:0003
Bus 002 Device 004: ID f182:0003
pierre@PC4 ~ $ sudo chmod 666 /dev/bus/usb/002/004
[sudo] password for pierre:
pierre@PC4 ~ $ sudo modprobe usbmon

Fichier de config

Il faut installer tshark pour le make:

sudo apt-get install tshark

Nous utilisons le fichier leap2.pcapng obtenu précédemment, au lieu de tshark.

Dans le dossier OpenLeap, éditer le fichier make_leap_usbinit.sh, remplacer

  -Xlua_script:usb_c.lua

par:

 -Xlua_script:usb_c.lua \
 -2

bien ajouter le "\" !

$ ./make_leap_usbinit.sh 003 leap2.pcapng > leap_libusb_init.c.inc

Nous avons un fichier leap_libusb_init.c.inc

leap_libusb_init.c.inc

Ce fichier a été nettoyé de toutes les répétitions.

  ret = libusb_control_transfer(ctx->dev_handle, 33, 1, 2816, 512, (unsigned char[]){ 0x3c, 0x00 }, 2, 1000);
  if (ret != 2) {
    printf("strl out: ret == %i\n", ret);
  }
  ret = libusb_control_transfer(ctx->dev_handle, 33, 1, 1024, 1280, (unsigned char[]){ 0x10, 0x00 }, 2, 1000);
  if (ret != 2) {
    printf("strl out: ret == %i\n", ret);
  }
  ret = libusb_control_transfer(ctx->dev_handle, 33, 1, 2816, 512, (unsigned char[]){ 0xff, 0x01 }, 2, 1000);
  if (ret != 2) {
    printf("strl out: ret == %i\n", ret);
  }
  ret = libusb_control_transfer(ctx->dev_handle, 33, 1, 1024, 1280, (unsigned char[]){ 0x17, 0x00 }, 2, 1000);
  if (ret != 2) {
    printf("strl out: ret == %i\n", ret);
  }
  ret = libusb_control_transfer(ctx->dev_handle, 33, 1, 1536, 512, (unsigned char[]){ 0xe8, 0x03 }, 2, 1000);
  if (ret != 2) {
    printf("strl out: ret == %i\n", ret);
  }
  ret = libusb_control_transfer(ctx->dev_handle, 33, 1, 2816, 512, (unsigned char[]){ 0x95, 0x01 }, 2, 1000);
  if (ret != 2) {
    printf("strl out: ret == %i\n", ret);
  }
  ret = libusb_control_transfer(ctx->dev_handle, 33, 1, 2816, 512, (unsigned char[]){ 0xdf, 0x00 }, 2, 1000);
  if (ret != 2) {
    printf("strl out: ret == %i\n", ret);
  }
  ret = libusb_control_transfer(ctx->dev_handle, 33, 1, 2816, 512, (unsigned char[]){ 0x7b, 0x00 }, 2, 1000);
  if (ret != 2) {
    printf("strl out: ret == %i\n", ret);
  }
  ret = libusb_control_transfer(ctx->dev_handle, 33, 1, 2816, 512, (unsigned char[]){ 0x44, 0x00 }, 2, 1000);
  if (ret != 2) {
    printf("strl out: ret == %i\n", ret);
  }

Make

sudo apt-get install libusb-1.0-0-dev libsdl1.2-dev libopencv-dev
pierre@PC4 /media/data500/major_files/3_D/3D_current/aprojets/OpenLeap $ make
gcc -c -O2 -Wall -DNDEBUG -I/usr/include/libusb-1.0   -o low-level-leap.o low-level-leap.c
low-level-leap.c: In function ‘leap_init’:
low-level-leap.c:47:17: warning: unused variable ‘data’ [-Wunused-variable]
   unsigned char data[256];
                 ^
low-level-leap.c: At top level:
low-level-leap.c:30:1: warning: ‘fprintf_data’ defined but not used [-Wunused-function]
 fprintf_data(FILE *fp, const char * title, unsigned char *data, size_t size)
 ^
gcc -o low-level-leap low-level-leap.o  -lusb-1.0  
gcc -c -O2 -Wall -DNDEBUG -D_GNU_SOURCE=1 -D_REENTRANT -I/usr/include/SDL   -o display-leap-data-sdl.o display-leap-data-sdl.c
display-leap-data-sdl.c: In function ‘main’:
display-leap-data-sdl.c:236:10: warning: ignoring return value of ‘fread’, declared with attribute warn_unused_result [-Wunused-result]
     fread(&usb_frame_size, sizeof (usb_frame_size), 1, stdin);
          ^
display-leap-data-sdl.c:237:10: warning: ignoring return value of ‘fread’, declared with attribute warn_unused_result [-Wunused-result]
     fread(data, usb_frame_size, 1, stdin);
          ^
gcc -o display-leap-data-sdl display-leap-data-sdl.o  -lSDL  
gcc -c -O2 -Wall -DNDEBUG -I/usr/local/include/opencv -I/usr/local/include   -o display-leap-data-opencv.o display-leap-data-opencv.c
display-leap-data-opencv.c: In function ‘main’:
display-leap-data-opencv.c:139:10: warning: ignoring return value of ‘fread’, declared with attribute warn_unused_result [-Wunused-result]
     fread(&usb_frame_size, sizeof (usb_frame_size), 1, stdin);
          ^
display-leap-data-opencv.c:140:10: warning: ignoring return value of ‘fread’, declared with attribute warn_unused_result [-Wunused-result]
     fread(data, usb_frame_size, 1, stdin);
          ^
gcc -o display-leap-data-opencv display-leap-data-opencv.o  /usr/local/lib/libopencv_calib3d.so /usr/local/lib/libopencv_core.so /usr/local/lib/libopencv_features2d.so /usr/local/lib/libopencv_flann.so /usr/local/lib/libopencv_highgui.so /usr/local/lib/libopencv_imgcodecs.so /usr/local/lib/libopencv_imgproc.so /usr/local/lib/libopencv_ml.so /usr/local/lib/libopencv_nonfree.so /usr/local/lib/libopencv_objdetect.so /usr/local/lib/libopencv_optim.so /usr/local/lib/libopencv_photo.so /usr/local/lib/libopencv_shape.so /usr/local/lib/libopencv_stitching.so /usr/local/lib/libopencv_superres.so /usr/local/lib/libopencv_ts.a /usr/local/lib/libopencv_video.so /usr/local/lib/libopencv_videoio.so /usr/local/lib/libopencv_videostab.so -lrt -lpthread -lm -ldl

nouvel essai

gcc -o display-leap-data-opencv display-leap-data-opencv.o  /usr/lib/i386-linux-gnu/libopencv_calib3d.so /usr/lib/i386-linux-gnu/libopencv_contrib.so /usr/lib/i386-linux-gnu/libopencv_core.so /usr/lib/i386-linux-gnu/libopencv_features2d.so /usr/lib/i386-linux-gnu/libopencv_flann.so /usr/lib/i386-linux-gnu/libopencv_gpu.so /usr/lib/i386-linux-gnu/libopencv_highgui.so /usr/lib/i386-linux-gnu/libopencv_imgproc.so /usr/lib/i386-linux-gnu/libopencv_legacy.so /usr/lib/i386-linux-gnu/libopencv_ml.so /usr/lib/i386-linux-gnu/libopencv_objdetect.so /usr/lib/i386-linux-gnu/libopencv_ocl.so /usr/lib/i386-linux-gnu/libopencv_photo.so /usr/lib/i386-linux-gnu/libopencv_stitching.so /usr/lib/i386-linux-gnu/libopencv_superres.so /usr/lib/i386-linux-gnu/libopencv_ts.so /usr/lib/i386-linux-gnu/libopencv_video.so /usr/lib/i386-linux-gnu/libopencv_videostab.so -lopencv_calib3d -lopencv_contrib -lopencv_core -lopencv_features2d -lopencv_flann -lopencv_gpu -lopencv_highgui -lopencv_imgproc -lopencv_legacy -lopencv_ml -lopencv_objdetect -lopencv_ocl -lopencv_photo -lopencv_stitching -lopencv_superres -lopencv_ts -lopencv_video -lopencv_videostab

crée 6 fichiers:

  • low-level-leap
  • low-level-leap.o
  • display-leap-data-sdl
  • display-leap-data-opencv
  • display-leap-data-sdl.o
  • display-leap-data-opencv.o

Pour recommencer la compil:

make clean

et détruire:

  • display-leap-data-sdl
  • display-leap-data-opencv
  • display-leap-data-sdl.o
  • display-leap-data-opencv.o

Stop leapd

pierre@PC4 /media/data500/major_files/3_D/3D_current/aprojets/OpenLeap $ sudo service leapd stop
leapd stop/waiting

Test

./low-level-leap | ./display-leap-data-opencv
pierre@PC4 /media/data500/major_files/3_D/3D_current/aprojets/OpenLeap $ ./low-level-leap | ./display-leap-data-opencv
*** buffer overflow detected ***: ./display-leap-data-opencv terminated
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x696de)[0xb741a6de]
/lib/i386-linux-gnu/libc.so.6(__fortify_fail+0x6b)[0xb74ad13b]
/lib/i386-linux-gnu/libc.so.6(+0xfafca)[0xb74abfca]
/lib/i386-linux-gnu/libc.so.6(__fread_chk+0x112)[0xb74ac812]
./display-leap-data-opencv[0x80487f3]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0xb73caa83]
./display-leap-data-opencv[0x8048a29]
======= Memory map: ========
08048000-08049000 r-xp 00000000 08:12 23332232   /media/data500/major_files/3_D/3D_current/aprojets/OpenLeap/display-leap-data-opencv
08049000-0804a000 r--p 00000000 08:12 23332232   /media/data500/major_files/3_D/3D_current/aprojets/OpenLeap/display-leap-data-opencv
0804a000-0804b000 rw-p 00001000 08:12 23332232   /media/data500/major_files/3_D/3D_current/aprojets/OpenLeap/display-leap-data-opencv
08307000-083cf000 rw-p 00000000 00:00 0          [heap]
b5cef000-b5dd1000 rw-p 00000000 00:00 0 
...
...
...

Abandon

Ce code a été écrit en 2012, depuis les composants ont changés. Cela explique pourquoi le test final échoue.