Stereopi + WebRTC = téléprésence à domicile

Pour commencer, une vidéo YouTube pour l'inspiration:


Attention: le projet dans la vidĂ©o n'est qu'un exemple qui peut ĂȘtre rĂ©alisĂ© selon le tutoriel de l'article concernant la vision stĂ©rĂ©o et les «tours de tĂȘte». Les rĂ©servoirs avec tĂ©lĂ©commande Xbox ne sont pas inclus.

Malgré la clarté, la maigre histoire de l'auteur du projet sur la vidéo et la disponibilité des liens, tout de suite pour comprendre comment tout cela fonctionne n'est pas facile. Si vous souhaitez collecter quelque chose de similaire et dans un format beaucoup plus pratique, il est recommandé de lire.

* Je ferai immédiatement une réservation, la personne sur la vidéo avec YouTube ne m'est pas familiÚre, je n'ai pas transmis de données secrÚtes, quel est l'état de son projet maintenant, je ne sais pas.
** Nous ne contrĂŽlerons pas le mouvement du robot sur la framboise en surface via la tĂ©lĂ©commande de xbox, cela peut ĂȘtre gĂ©rĂ© indĂ©pendamment.
*** Veuillez ne pas jeter de chaussures de faufilage, car le projet est encore en développement.

Donc, nous nous intéressons à deux choses:

  • comment obtenir une image stĂ©rĂ©o sur le tĂ©lĂ©phone dans un casque;
  • comment contrĂŽler les servos avec des tours de tĂȘte.

Le concept utilisé dans la vidéo, s'il est résumé, ressemble à ceci:

  • 2 raspberry pi envoient des flux vidĂ©o au rĂ©seau depuis leurs camĂ©ras via les services webrtc;
  • le tĂ©lĂ©phone (dans le casque) accepte les flux dans 2 applications identiques sur le tĂ©lĂ©phone - applications flottantes.
  • en mĂȘme temps, le tĂ©lĂ©phone contrĂŽle les serveurs connectĂ©s Ă  la framboise.

Tout est simple. Mais diablo, comme vous le savez, réside dans les détails et les inconvénients, à savoir:

  • vous devez exĂ©cuter 2 framboises, surveiller les paramĂštres de 2 camĂ©ras, alimenter la framboise * 2.
  • les applications flottantes glissent constamment dans le tĂ©lĂ©phone, vous devez aligner les images sur l'Ă©cran.
  • ...

Par conséquent, nous allons transférer sur stéréopi, heureusement, il est apparu dans les magasins russes (j'espÚre qu'il ne disparaßtra pas aprÚs ce post):



Stereopi est le développement de notre compatriote, qui conquiert désormais activement le marché.

Son charme vient du nom - vous pouvez connecter 2 camĂ©ras CSI raspberry pi en mĂȘme temps. Dans le mĂȘme temps, tout cela fonctionne sur la base d'un module de calcul raspberry pi. Malheureusement, le module lui-mĂȘme n'est pas inclus dans le package, vous devez l'acheter vous-mĂȘme.

À propos de Stereopi, il y a des articles sur HabrĂ©.

De là, nous aurons besoin de 2 flux vidéo et du contrÎle des serveurs via GPIO.
Comme base pour StereoPi, nous utiliserons le module de calcul Raspberry Pi 3+.

Préparation de Stereopi


AprÚs avoir assemblé les stéréopi (insérez le module de calcul dans les stéréopi, les caméras), remplissez le logiciel.

Nous utilisons l'image prĂȘte Ă  l'emploi pour le module de calcul Raspberry Pi - Raspbian (Stretch). Il est disponible sur le site stereopi.com - Image Raspbian Stretch OpenCV, Google Drive
Remplissez-le de framboise.

S'il y a des difficultés à remplir, d'autres vont sur wiki stéréopi .

Installation de webrtc.


Installez le logiciel webrtc sur StereoPi. Le matériel d'installation est partiellement extrait de cette page: Installation pour ARM (Raspberry Pi)


Nous éviterons les commentaires inutiles qui se trouvent déjà sur la page ci-dessus et installerons simplement tout ce qui est nécessaire.

curl http://www.linux-projects.org/listing/uv4l_repo/lpkey.asc | sudo apt-key add - sudo nano /etc/apt/sources.list deb http://www.linux-projects.org/listing/uv4l_repo/raspbian/stretch stretch main sudo apt-get update sudo apt-get install uv4l uv4l-raspicam sudo apt-get install uv4l-raspicam-extras sudo raspi-config  Anvanced Options  Memory Split   256   enter sudo apt-get install uv4l-server uv4l-uvc uv4l-xscreen uv4l-mjpegstream uv4l-dummy uv4l-raspidisp sudo apt-get install uv4l-webrtc sudo apt-get install uv4l-demos sudo apt-get install uv4l-xmpp-bridge sudo apt-get install uv4l-raspidisp-extras 

Maintenant, vous devez (dans les instructions, c'est) générer des clés SSL, car Chrome peut ne pas afficher la vidéo via la connexion http (uniquement via https):

 openssl genrsa -out selfsign.key 2048 && openssl req -new -x509 -key selfsign.key -out selfsign.crt -sha256 

* lors de la génération des clés, des questions seront posées sur l'entreprise, la région, etc. - Vous pouvez y répondre arbitrairement.

Les clĂ©s gĂ©nĂ©rĂ©es (selfsign.key et selfsign.crt apparaĂźtront dans le dossier actuel) doivent ĂȘtre placĂ©es dans le dossier:

 /etc/ssl/private/ 

Tous les paramÚtres de webrtc sont stockés dans 2 fichiers:

 /etc/uv4l/uv4l-raspicam.conf /etc/uv4l/uv4l-raspidisp.conf 

Afin de ne pas se lasser de lister les articles dans des fichiers qui ne doivent pas ĂȘtre commentĂ©s ou
pour corriger, Ă©crasez les fichiers de paramĂštres avec vos uv4l-raspicam.conf et uv4l-raspidisp.conf.

Redémarrez Raspberry et connectez-vous à l'IP Raspberry à l'aide de Chrome:

 https://192.168.1.100:8080 

WebRTC est un grand fan de possibilités, mais nous nous limiterons à une chose - nous irons à l'onglet webrtc:

image


Vérifiez maintenant si la vidéo fonctionne avec stéréopi.

Appuyez sur le bouton "Appeler" en bas de la page Web du téléphone.

image


Une vidéo des caméras stéréo devrait apparaßtre.

Cliquez sur le bouton «Plein Ă©cran» sous la fenĂȘtre avec l'image des camĂ©ras Web:

image


* Ne rechargez pas la page sur le téléphone! Si cela se produit toujours, vous devez tuer les processus sur la framboise:

 sudo killall uv4l 

Et redémarrez les services dessus:

 sudo service uv4l_raspidisp restart sudo service uv4l_raspicam restart 

Ensuite, sur la page du navigateur du téléphone, cliquez sur «Appeler».
** L'appel ne fonctionnera pas si aucune caméra n'est connectée à la framboise.

Nous traiterons des servos.


Pour gérer les servos sur framboise à partir du téléphone, vous avez besoin d'un code qui s'exécutera sur framboise et des actions sur le téléphone.

Mais d'abord, dĂ©cidons des servos. La vidĂ©o YouTube utilise des servos directement connectĂ©s Ă  gpio framboise. Étant donnĂ© que les servos sont de faible puissance, vous pouvez probablement accrocher 2 servos sur gpio framboise. Ces astuces peuvent facilement ĂȘtre effectuĂ©es sur des serveurs sg-90. Ils ne sont pas exigeants en nutrition, mais aussi pas particuliĂšrement bons pour les charges. En principe, ils devraient ĂȘtre suffisants pour contenir une suspension avec deux camĂ©ras stĂ©rĂ©oscopiques. Le cardan lui-mĂȘme peut ĂȘtre achetĂ© sur le mĂȘme aliexpress, pour la recherche «pan-tilt». Cependant, ces servos ont aussi un sĂ©rieux inconvĂ©nient - ils "tremblent de peur". C'est cet effet que l'auteur de la vidĂ©o YouTube observe. Pourquoi cela se produit et que faire avec cela ne sera pas considĂ©rĂ© ici.

Dans notre cas, les servos mg-996n et l'articulation du robot sont utilisés, dont j'espÚre qu'il n'aura pas besoin dans un proche avenir.

Image


* Le Mg-996N ne «tremble» pas.

Stereopi a une disposition gpio similaire Ă  la norme sur framboise 3 .

Par conséquent, les fils de signal des servos iront à gpio, et il est préférable de prendre 5V non pas de framboise, mais de cÎté, combinez GND serv avec GND framboise et GND d'une source externe.

Maintenant, la chose la plus importante est le logiciel


Sur la framboise, nous avons besoin d'un démon, mais pas de Lermontov, mais de pigpio. Vous n'avez pas besoin de prendre de mesures spéciales pour le configurer, l'essentiel est de savoir qu'il se bloque sur le port 8888 et vous devez d'abord l'exécuter:

 sudo systemctl start pigpiod.service 

Ensuite, crĂ©ez un fichier qui gĂ©rera les serveurs, recevant les donnĂ©es du socket, qu'il crĂ©e lui-mĂȘme:

datachannel_server_tele.py
 # python 3 # Taken from: # https://stackoverflow.com/questions/45364877/interpreting-keypresses-sent-to-raspberry-pi-through-uv4l-webrtc-datachannel # based on: # https://raspberrypi.stackexchange.com/questions/29480/how-to-use-pigpio-to-control-a-servo-motor-with-a-keyboard # public domain # systemctl status pigpiod.service # sudo systemctl start pigpiod.service # goto http://raspberrypi:8080/stream/webrtc and press Call! # video from raspberry pi appear # run from cmd raspberry: sudo python3 datachannel_server.py # turn on gps on phone # put V on 'send device orientation' from phone import socket import time import pigpio import os import re import json socket_path = '/tmp/uv4l.socket' try: os.unlink(socket_path) except OSError: if os.path.exists(socket_path): raise s = socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET) ROLL_PIN = 4 #gpio PITCH_PIN = 17 #gpio ! not phisical pin YAW_PIN = 15 MIN_PW = 1000 # 0 degree MID_PW = 1500 # 90 degree MAX_PW = 2000 # 180 degree print ('socket_path: %s' % socket_path) s.bind(socket_path) s.listen(1) def cleanup(): pi.set_servo_pulsewidth(ROLL_PIN, 0) pi.set_servo_pulsewidth(PITCH_PIN, 0) pi.set_servo_pulsewidth(YAW_PIN, 0) pi.stop() while True: print ('awaiting connection...') connection, client_address = s.accept() print ('client_address %s' % client_address) try: print ('established connection with', client_address) pi = pigpio.pi() #pi = pigpio.pi('soft', 9080) rollPulsewidth = MID_PW pitchPulsewidth = MID_PW yawPulsewidth = MID_PW pi.set_servo_pulsewidth(ROLL_PIN, rollPulsewidth) pi.set_servo_pulsewidth(PITCH_PIN, pitchPulsewidth) pi.set_servo_pulsewidth(YAW_PIN, yawPulsewidth) while True: try: data = json.loads(connection.recv(200).decode('utf-8')) # dict except ValueError: # no data return continue # data #{"do":{"alpha":0.1,"beta":-0.3,"gamma":-0.2,"absolute":false}, # "dm":{"x":0,"y":0,"z":-0.2,"gx":0,"gy":0,"gz":-9.6,"alpha":-0.1,"beta":-0.1,"gamma":0.1} #print ('received message"%s"' % data) #print ('received message"%s"' % data['dm']['x']) # coordinate x from data #print ('received message"%s"' % data['dm']['y']) # coordinate y from data time.sleep(0.01) key1 = float(data['do']['alpha']) # os x 0 to 360 degree #key2 = float(data['do']['beta']) # os y #print(key1) #print(key2) rollPW = rollPulsewidth pitchPW = pitchPulsewidth yawPW = yawPulsewidth pitchPW = key1*5+500 print ('x: '+str(pitchPW)) #if pitchPW > MAX_PW: # pitchPW = MAX_PW #elif pitchPW < MIN_PW: # pitchPW = MIN_PW #rollPW = int(key2 + 1000) #print ('y: '+ str(int(rollPW))) #if rollPW > MAX_PW: # rollPW = MAX_PW #elif rollPW < MIN_PW: # rollPW = MIN_PW if rollPW != rollPulsewidth: rollPulsewidth = rollPW pi.set_servo_pulsewidth(ROLL_PIN, rollPulsewidth) if pitchPW != pitchPulsewidth: pitchPulsewidth = pitchPW pi.set_servo_pulsewidth(PITCH_PIN, pitchPulsewidth) if yawPW != yawPulsewidth: yawPulsewidth = yawPW pi.set_servo_pulsewidth(YAW_PIN, yawPulsewidth) #if data: #print ('echo data to client') #connection.sendall(str(data)) #else: #print ('no more data from', client_address) #break finally: # Clean up the connection cleanup() connection.close() 


Des commentaires sont laissĂ©s dans le texte pour comprendre d'oĂč vient le code et quoi d'autre peut ĂȘtre corrigĂ©.
La signification générale du code est la suivante:

  • au dĂ©marrage, les servos sont placĂ©s en position mĂ©diane.
  • Il y a 3 broches (gpio) sur lesquelles les fils de signal des servos sont suspendus. Dans notre cas, 2 broches (suspension de 2 servos).
  • gpio sont contrĂŽlĂ©s en appliquant un signal dans la gamme PWM de 1000 Ă  2000.
  • une ligne arrive du tĂ©lĂ©phone, qui est analysĂ©e par json (vous pouvez faire autre chose), puis les valeurs x et y en sont extraites. Ensuite, ces valeurs sont converties en valeurs PWM pour faire tourner les servos.

* Le problĂšme est que x prend des valeurs de 0 Ă  360 (le tĂ©lĂ©phone tourne autour de son axe), comme y. Et ces valeurs doivent ĂȘtre liĂ©es Ă  PWM, qui prennent des valeurs de 1000 Ă  2000. Le code utilise la formule pitchPW = key1 * 5 + 500. 500 est la valeur minimale du servo PWM (bien que l'hypothĂšse soit 1000 dans le code). Et la multiplication par 5 est conditionnelle. Ce point doit ĂȘtre amĂ©liorĂ©, car Ă  x = 360, la valeur PWM est plusieurs fois supĂ©rieure au maximum. Les servos sont protĂ©gĂ©s contre le dĂ©passement des angles de rotation maximum afin d'Ă©viter les dommages, mais ce n'est pas trĂšs agrĂ©able.

Exécutez le code dans le terminal framboise:

 sudo python3 datachannel_server_tele.py 

Nous allons activer le GPS sur le téléphone (chaque téléphone a une icÎne correspondante dans les paramÚtres) et passer par ip framboise.

 https://192.168.1.100:8080/stream/webrtc 

Cliquez sur "Appeler". Une fois la connexion Ă©tablie, sur le tĂ©lĂ©phone dans le navigateur de la page, cochez "envoyer les angles d'orientation de l'appareil alpha, bĂȘta, gamma".

Les valeurs x iront au terminal avec le script. Et, si vous faites pivoter le téléphone, ils changeront.
Les servos se déplaceront également.

* Actuellement l'un d'eux (le second est commenté).

Parmi les jolis bonus webrtc vous donne également la possibilité :

  • crĂ©er un semblant de telebridge entre le tĂ©lĂ©phone et la framboise (votre interlocuteur sera volumineux),
  • diffuser du son dans les deux sens (non testĂ©, mais pris en compte dans les rĂ©glages),
  • Diffusez sur une page Web, YouTube en 3D.
  • crĂ©er une confĂ©rence tĂ©lĂ©phonique Ă  partir de plusieurs amis (jitsi meet).
  • modifier les paramĂštres de la camĂ©ra Ă  la volĂ©e via l'interface Web (pourquoi la rotation! &? ne fonctionne pas).

Maintenant sur le triste.


1. Shalturit en connectant deux camĂ©ras diffĂ©rentes avec des yeux de poisson sur la rĂšgle de l'Ă©cole n'a pas fonctionnĂ©. Il s'avĂšre que les poissons ont des yeux diffĂ©rents. Nous avons besoin du mĂȘme type de camĂ©ra:



2. Il n'a pas été possible d'agrandir l'image à partir de caméras stéréo via les paramÚtres de l'interface Web webrtc. Alors que les photos sont étroites, comme un pantalon de Français.



3. Le servo MG996N est limitĂ© Ă  -180 angles de rotation. En fait - 160. Peut-ĂȘtre que quelqu'un conseillera avec 360, mais sans rotation continue.

4. Le logiciel nécessite une mouture.

5. L'appel tombe parfois, vous devez vous reconnecter.

Application:

Source: https://habr.com/ru/post/fr473750/


All Articles