Stereopi + WebRTC = Telepräsenz zu Hause

YouTube-Video zur Inspiration:


Warnung: Das Projekt im Video ist nur ein Beispiel, das gemäß dem Tutorial im Artikel über Stereovision und „Kopfdrehungen“ durchgeführt werden kann. Tanks mit Xbox Remote sind nicht enthalten.

Trotz der Klarheit ist die magere Geschichte des Autors des Projekts auf dem Video und die Verfügbarkeit von Links nicht einfach, um sofort herauszufinden, wie alles funktioniert. Wenn Sie etwas Ähnliches und in einem viel bequemeren Format sammeln möchten, wird empfohlen, es zu lesen.

* Ich werde sofort eine Reservierung vornehmen. Die Person auf dem Video mit YouTube ist mir unbekannt. Ich habe keine geheimen Daten übermittelt. Wie ist der Stand seines Projekts? Ich weiß es nicht.
** Wir werden die Bewegung des Roboters auf Himbeere auf der Oberfläche nicht über die Fernbedienung von Xbox steuern, dies kann unabhängig behandelt werden.
*** Bitte werfen Sie keine Bastschuhe, da sich das Projekt noch in der Entwicklung befindet.

Wir interessieren uns also für zwei Dinge:

  • wie man ein Stereobild in einem Helm auf das Telefon bekommt;
  • wie man die Servos durch Drehen des Kopfes steuert.

Das im Video verwendete Konzept sieht zusammenfassend so aus:

  • 2 Himbeer-Pi senden Videostreams von ihren Kameras über webrtc-Dienste an das Netzwerk;
  • Das Telefon (im Helm) akzeptiert Streams in 2 identischen Anwendungen auf dem Telefon - Float-Apps.
  • Gleichzeitig steuert das Telefon die mit Himbeeren verbundenen Server.

Alles ist einfach. Aber Diablo liegt, wie Sie wissen, in den Details und Unannehmlichkeiten, nämlich:

  • Sie müssen 2 Himbeeren ausführen, die Einstellungen von 2 Kameras überwachen und Himbeeren * 2 mit Strom versorgen.
  • Float-Apps gleiten ständig im Telefon, Sie müssen die Bilder auf dem Bildschirm ausrichten.
  • ...

Daher werden wir zu Stereopi wechseln, zum Glück erschien es in russischen Läden (ich hoffe, es wird nach diesem Beitrag nicht verschwinden):



Stereopi ist die Entwicklung unseres Landsmanns, der jetzt aktiv den Markt erobert.

Sein Charme ergibt sich aus dem Namen - Sie können 2 CSI-Himbeer-Pi-Kameras gleichzeitig anschließen. Gleichzeitig funktioniert dies alles auf der Basis eines Himbeer-Pi-Compute-Moduls. Leider ist das Modul selbst nicht im Paket enthalten, Sie müssen es selbst kaufen.

Über Stereopi gibt es Artikel über Habré.

Davon benötigen wir 2 Videostreams und die Steuerung der Server über GPIO.
Als Basis für Stereopi verwenden wir das Raspberry Pi Compute Module 3+.

Stereopi-Vorbereitung


Füllen Sie nach dem Zusammenbau von Stereopi (Einsetzen des Rechenmoduls in Stereopi, Kameras) die Software aus.

Wir verwenden das fertige Bild für das Himbeer-Pi-Rechenmodul - Raspbian (Stretch). Es ist verfügbar unter stereopi.com - Raspbian Stretch OpenCV-Bild, Google Drive
Füllen Sie es mit Himbeere.

Wenn es Schwierigkeiten beim Füllen gibt, gehen andere zu Wiki Stereopi .

Webrtc installieren.


Installieren Sie die webrtc-Software auf Stereopi. Teilweise stammt das Installationsmaterial von dieser Seite: Installation für ARM (Raspberry Pi)


Wir vermeiden unnötige Kommentare, die sich bereits auf der obigen Seite befinden, und installieren einfach alles, was erforderlich ist.

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 

Jetzt müssen wir (in der Anleitung) die SSL-Schlüssel generieren, da Chrome das Video möglicherweise nicht über die http-Verbindung anzeigt (nur über https):

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

* Beim Generieren von Schlüsseln werden Fragen zum Unternehmen, zur Region usw. gestellt. - Sie können sie beliebig beantworten.

Die generierten Schlüssel (selfsign.key und selfsign.crt werden im aktuellen Ordner angezeigt) sollten im folgenden Ordner abgelegt werden:

 /etc/ssl/private/ 

Alle Webrtc-Einstellungen werden in 2 Dateien gespeichert:

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

Um nicht müde zu werden, Elemente in Dateien aufzulisten, die nicht kommentiert werden müssen oder
Um dies zu beheben, überschreiben Sie die Einstellungsdateien mit Ihrer uv4l-raspicam.conf und uv4l-raspidisp.conf.

Starten Sie Himbeere neu und melden Sie sich mit Chrome bei der IP-Himbeere an:

 https://192.168.1.100:8080 

WebRTC ist ein großer Fan von Möglichkeiten, aber wir werden uns auf eine Sache beschränken - wir werden zur Registerkarte webrtc gehen:

Bild


Überprüfen Sie nun, ob das Video mit Stereopi funktioniert.

Drücken Sie die Taste "Anrufen" unten auf der Webseite des Telefons.

Bild


Ein Video von den Stereokameras sollte erscheinen.

Klicken Sie unter dem Fenster mit dem Bild von Webkameras auf die Schaltfläche „Vollbild“:

Bild


* Laden Sie die Seite nicht neu auf das Telefon! Wenn dies immer noch passiert ist, müssen Sie die Prozesse auf Himbeere abbrechen:

 sudo killall uv4l 

Und starten Sie die Dienste darauf neu:

 sudo service uv4l_raspidisp restart sudo service uv4l_raspicam restart 

Klicken Sie dann auf der Seite im Browser des Telefons auf "Anrufen".
** Der Anruf funktioniert nicht, wenn keine Kamera an Himbeere angeschlossen ist.

Wir werden uns um die Servos kümmern.


Um die Servos auf Himbeere vom Telefon aus zu verwalten, benötigen Sie einen Code, der auf Himbeere ausgeführt wird, und Aktionen auf dem Telefon.

Aber zuerst entscheiden wir uns für die Servos. Das YouTube-Video verwendet Servos, die direkt mit gpio raspberry verbunden sind. Da die Servos stromsparend sind, können Sie wahrscheinlich 2 Servos an GPIO-Himbeeren hängen. Diese Tricks können problemlos auf SG-90-Servern ausgeführt werden. Sie sind nicht anspruchsvoll in der Ernährung, aber auch nicht besonders gut für Lasten. Im Prinzip sollten sie ausreichen, um eine Aufhängung mit zwei Kameras von Stereopi zu halten. Das Gimbal selbst kann auf demselben Aliexpress für die Suche „Pan-Tilt“ gekauft werden. Diese Servos haben jedoch auch ein ernstes Minus - sie "zittern vor Angst". Diesen Effekt beobachtet der Autor des YouTube-Videos. Warum dies geschieht und was damit zu tun ist, wird hier nicht berücksichtigt.

In unserem Fall werden die mg-996n-Servos und das Robotergelenk verwendet, die er hoffentlich in naher Zukunft nicht benötigen wird.

Bild


* Mg-996N "zittert" nicht.

Stereopi hat ein GPIO-Layout ähnlich dem Standard für Himbeere 3 .

Daher gehen die Signalkabel von den Servos zu GPIO, und es ist besser, 5 V nicht von Himbeere zu nehmen, sondern von der Seite GND-Serv mit GND-Himbeere und GND einer externen Quelle zu kombinieren.

Das Wichtigste ist jetzt die Software


Auf Himbeere brauchen wir einen Dämon, aber nicht Lermontovs, sondern Pigpio. Sie müssen keine besonderen Schritte unternehmen, um es zu konfigurieren. Hauptsache, Sie wissen, dass es an Port 8888 hängt, und Sie müssen es zuerst ausführen:

 sudo systemctl start pigpiod.service 

Erstellen Sie als Nächstes eine Datei, die die Server verwaltet und Daten vom Socket empfängt, den sie selbst erstellt:

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() 


Im Text bleiben Kommentare, um zu verstehen, woher der Code stammt und was noch korrigiert werden kann.
Die allgemeine Bedeutung des Codes lautet wie folgt:

  • Zu Beginn werden die Servos in die mittlere Position gebracht.
  • Es gibt 3 Pins (GPIO), an denen die Signalkabel der Servos hängen. In unserem Fall 2 Stifte (Aufhängung von 2 Servos).
  • gpio werden durch Anlegen eines Signals im PWM-Bereich von 1000 bis 2000 gesteuert.
  • Vom Telefon kommt eine Zeile an, die von json analysiert wird (Sie können etwas anderes tun), und dann werden die Werte x und y daraus entnommen. Als nächstes werden diese Werte in PWM-Werte übersetzt, um die Servos zu drehen.

* Das Problem ist, dass x Werte von 0 bis 360 annimmt (das Telefon dreht sich um seine Achse), wie z. B. y. Und diese Werte müssen an PWM gebunden sein, die Werte von 1000 bis 2000 annehmen. Der Code verwendet die Formel PitchPW = key1 * 5 + 500. 500 ist der minimale PWM-Servowert (obwohl die Annahme im Code 1000 ist). Und die Multiplikation mit 5 ist bedingt. Dieser Punkt muss verbessert werden, da bei x = 360 der PWM-Wert um ein Vielfaches höher als das Maximum ist. Servos sind vor Überschreitung der maximalen Drehwinkel geschützt, um Beschädigungen zu vermeiden. Dies ist jedoch nicht sehr erfreulich.

Führen Sie den Code im Himbeer-Terminal aus:

 sudo python3 datachannel_server_tele.py 

Wir schalten GPS auf dem Telefon ein (jedes Telefon hat ein entsprechendes Symbol in den Einstellungen) und gehen über IP-Himbeere.

 https://192.168.1.100:8080/stream/webrtc 

Klicken Sie auf "Anrufen". Nachdem die Verbindung hergestellt wurde, aktivieren Sie auf dem Telefon im Browser auf der Seite die Option "Geräteausrichtungswinkel Alpha, Beta, Gamma senden".

Die x-Werte werden mit dem Skript an das Terminal gesendet. Und wenn Sie das Telefon drehen, ändern sie sich.
Servos bewegen sich ebenfalls.

* Derzeit einer von ihnen (der zweite ist auskommentiert).

Von den netten Boni bietet webrtc Ihnen auch die Möglichkeit :

  • Erstellen Sie einen Anschein eines Telebridge zwischen Telefon und Himbeere (Ihr Gesprächspartner wird umfangreich sein).
  • Ton in beide Richtungen senden (nicht getestet, aber in den Einstellungen berücksichtigt),
  • Stream auf eine Webseite, Youtube in 3D.
  • Erstellen Sie eine Telefonkonferenz von mehreren Freunden (Jitsi-Treffen).
  • Ändern Sie die Kameraeinstellungen im laufenden Betrieb über die Weboberfläche (warum funktioniert Drehen! &? nicht).

Nun zu den Traurigen.


1. Shalturit durch Verbinden von zwei verschiedenen Kameras mit Fischaugen am Schullineal funktionierte nicht. Es stellt sich heraus, dass Fische unterschiedliche Augen haben. Wir brauchen den gleichen Kameratyp:



2. Es war nicht möglich, das Bild von Stereokameras über die Einstellungen der Webrtc-Weboberfläche zu erweitern. Während die Bilder schmal sind, wie die Hosen eines Franzosen.



3. Das MG996N-Servo ist auf -180 Drehwinkel begrenzt. In der Tat - 160. Vielleicht rät jemand mit 360, aber ohne kontinuierliche Rotation.

4. Software muss geschliffen werden.

5. Der Anruf fällt manchmal ab, Sie müssen die Verbindung erneut herstellen.

Anwendung:

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


All Articles