Benutzer-Werkzeuge

Webseiten-Werkzeuge


Seitenleiste

techniken:tensorflownodebluetooth

Dies ist eine alte Version des Dokuments!




TensorFlow & Kommunikation mit dem Arduino per Bluetooth

1. Einführung

TensorFlow ist ein Framework, welches eine vereinfachte Anwendung von Algorithmen aus dem maschinellen Lernen ermöglicht. Damit kann man z.B.:

  • Posenet: die Stellung von einem oder mehreren Menschen erkennen,
  • Body-Pix: den menschlichen Körper segmentieren,
  • Facemesh: markante Punkte im Gesicht erkennen,
  • Handpose: die Handstellung erkennen usw.

Es gibt TensowFlow-Implementationen für verschiedene Sprachen, z.B. Python, C++, Java und JavaScript. Die JavaScript-Variante scheint einfacher für den Start zu sein. Eure TensorFlow-Code läuft dabei im Browser.

Probiert die TensorFlow-Beispiele aus, indem ihr auf die entsprechenden Links in der Liste oben klickt!

TensorFlow ist rechenintensiv. Deswegen ist es (zu diesem Zeitpunkt im Januar 2021) ziemlich langwierig, es auf einem Smartphone oder Raspberry Pi zu betreiben (bzw. wir haben noch keine gute Lösung gefunden). Es gibt zwar die abgespeckte Variante TensorFlow Lite, jedoch scheint es momentan einfacher, TensorFlow auf einem PC zu laufen und nur die Ergebnisse bei Bedarf an den Arduino über die serielle Kommunikation zu schicken. Bei mobilen Robotern kann die serielle Kommunikation über Bluetooth laufen. Diesem Thema (TensorFlow & Kommunikation über die serielle Schnittstelle) widmet sich dieser Artikel.

Bei mobilen Robotern kann man über die App DroidCam die Handy-Kamera als externe kabellose Webcam nutzen. Wenn der Rechner und das Handy beide im gleichen WLAN-Netzwerk sind, kann man sie kabellos über WLAN verbinden. Die dafür erforderliche IP-Adresse wird in der App angezeigt.

2. Einfacher(er) Einstieg in TensorFlow

Da ihr euch im Crashkurs mit Processing vertraut gemacht habt, könnt ihr p5.js nutzen – die Processing-Variante für JavaScript. Hier gibt es eine gute Einleitung, wie man die TensorFlow-Bibliothek Posenet (für die Einschätzung der menschlichen Stellung) in p5.js verwendet.

In dieser Video-Einleitung wird das Programm im p5.js-editor ausgeführt. Alternativ könnt ihr Dasselbe in Textdateien auf eurem Rechner abspeichern und ausführen. Dass es verschiedene Text-Dateien gibt, wird auch im Einleitungsvideo (ab ca. 26. Min.) erwähnt. Die .html-Datei beinhaltet das Grundgerüst der Webseite, in der .js-Datei läuft euer Code.

Informiert euch, warum JavaScript überhaupt in Webseiten verwendet wird und wozu der <script>-Tag dient.

Aktuell gibt es eine neuere Version von p5.js als im Einleitungsvideo erwähnt, ihr könnt den folgenden Code in eurer .html-Datei nutzen (wir nennen diese Datei z.B. index.html):

index.html

index.html

<html>
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.js"></script>
    <script src="https://unpkg.com/ml5@latest/dist/ml5.min.js"></script>
    <script src="sketch.js"></script>
  </head>
</html>


In Zeile 5 bezieht sich der html-Code auf die JavaScript-Datei script.js. Diese Datei müsst ihr selbst erstellen, in den selben Ordner wie index.html legen und dorthin den Code aus dem p5.js-editor kopieren. (Wenn ihr dieser Datei einen anderen Namen wie script.js vergeben habt, müsst ihr die entsprechende Stelle in der html-Datei ändern.) Wenn ihr nun index.html in eurem Browser öffnet, soll dort die selbe Anwendung wie auf der p5.js-editor-Zeichenfläche laufen. Testet das, bevor ihr zum nächsten Punkt dieses Artikels übergeht.

3. Lokalen Server einrichten

3.1. Node.js-Installation

Wir konnten schon über den p5.js-editor die Ergebnisse von einem TensorFlow-Modell bekommen, warum brauchen wir den Server? Grund ist, wir wollen auf den seriellen Port zugreifen, um Daten an den Arduino zu schicken, und das geht nicht von der Client-Seite (Browser). In unserem Fall wird der Server auf dem gleichen Rechner laufen wie der Client (Browser), deswegen sagen wir, dass wir einen lokalen Server einrichten.

Informiert euch darüber, was ein Server und ein Client sind.

Es gibt viele Möglichkeiten, einen Server zu programmieren, z.B. mit Java, PHP oder Python. Wir werden einen Node.js-Server einrichten, u.A. weil Node.js ebenso auf JavaScript geschrieben ist.

Node.js verfügt über den Paket-Manager npm, über welchen man zusätzliche Node-Module installiert. Ladt Node.js und npm herunter und installiert sie. Anschließend könnt ihr mit den Befehlen node –v und npm –v auf dem Terminal (bzw. in der Anwendung cmd) überprüfen, ob alles geklappt hat. (Die Node/npm-Version wird angezeigt ⇒ geklappt.)

3.2. Hallo Welt

Erstellt einen Ordner (ich nenne ihn NodeOrdner – andere Namen möglich), wo ihr Dateien für euren Server ablegen werdet. Es hilft, wenn dieser Ordner auf dem Laufwerk ist, wo ihr Anwendungen ausführen dürft. Wechselt über die cd-Terminal-Befehle zu diesem Ordner. Bei Bedarf sucht online, wie man mit cd zwischen Ordnern wechseln kann. Wenn ihr im richtigen Ordner seid, führt diesen Befehl aus – er initialisiert euer Projekt:

npm init

Bestätigt mit der Enter-Taste (mehrfach) die Standard-Einstellungen. Die Datei package.json wird angelegt, wo diese Einstellungen gespeichert werden.

Installiert auch die Node-Module, die wir später brauchen werden:

  • express (minimalistische Node-Variante): npm install express –save
  • body-parser (analysiert HTTP-Requests): npm install body-parser –save
  • serialport (ermöglicht den Zugriff auf serielle Ports): npm install serialport –save

Erstellt im Ordner die Datei server.js (andere Namen möglich) mit dem folgenden Inhalt:

Code server.js

Code server.js

var express = require('express'); // use the express module
 
const hostname = '127.0.0.1'; // localhost
const port = 3000; // port number, can be changed
const folderName = 'public'; // use files from this folder
 
var app = express();
app.use(express.static(folderName)); // use files from this folder
var server = app.listen(port, function () {
  console.log("Example app listening at http://%s:%s", hostname, port) // console.log() is like println()
})


In diesem Beispiel starten wir den Server auf der lokalen Maschine (127.0.0.1, oder man kann stattdessen auch localhost schreiben) auf dem Port 3000 (andere Portnummer möglich). Dieser Server wird Dateien aus einem konkreten Ordner bereitstellen. Im Code haben wir diesen Ordner public genannt (andere Namen möglich).

Diesen Ordner gibt es noch nicht. Deswegen müssen wir im Ordner NodeOrdner einen Unterordner public erstellen. In diesem Unterordner erstellt bitte eine Datei index.html (andere Namen möglich), öffnet diesen und speichert dort eine Zeile: Hallo Welt.

Jetzt startet den Server. Im Terminal im Ordner NodeOrdner führt dafür den folgenden Befehl aus:

node server.js

Geht im Browser auf die Seite http://localhost:3000/index.html (oder http://127.0.0.1:3000/index.html, was das Selbe ist). Wenn ihr „Hallo Welt“ sieht, funktioniert alles richtig.

Was haben wir gerade gemacht? Wir haben einen Server eingerichtet, der in der Lage ist, Dateien (bzw. Inhalte dieser Dateien) aus dem bestimmten Ordner (in unserem Fall public) bereitzustellen. Dann haben wir einen Browser gestartet, der die konkrete Datei index.html angefordert hat. Diese Datei befand sich in dem Ornder, und so wurde ihr Inhalt an den Browser bereitgestellt: „Hallo Welt“. Das war einfacher Text, damit kann der Browser nicht viel mehr anfangen. Wenn die Datei stattdessen html-Code beinhaltet hätte, könnte der Browser diesen entsprechend verarbeiten – das machen wir im nächsten Schritt.

3.3. Eure Dateien über den Server bereitstellen

Löscht die Datei index.html aus dem Ordner public und fügt die im Punkt 2 erstellten Dateien index.html und script.js hinzu. Startet den Server neu und ruft im Browser den Link http://localhost:3000/index.html auf. Wenn alles richtig ist, sieht ihr euer Programm mit TensorFlow/Posenet.

4. GET & POST Requests

Der Server und der Client (Browser) kommunizieren über den Hypertext Transfer Protocol, HTTP (kurze Erklärung). Der Client kann an den Server bestimmte Anfragen schicken, am häufigsten kommen der GET- und der POST-Request vor (kurze Erklärung). In unserem Beispiel könnten wir sowohl GET als auch POST verwenden; Im folgenden Beispiel wird ein POST-Request verschickt.

Der POST-Request kann im Code so aussehen (es kann auch was anderes statt „distance“ und „dist“ stehen, aber es muss der gleiche String an beiden Seiten sein):

Code: POST-Request im Browser schicken

Code: POST-Request im Browser schicken

    var distance = 42; // The value that will be sent to the server
    var xhttp = new XMLHttpRequest();
    xhttp.open("POST", '/dist', true);
    //Send the proper header information along with the request
    xhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
 
    xhttp.onreadystatechange = function() { // Call a function when the state changes.
        if (this.readyState === XMLHttpRequest.DONE && this.status === 200) {
            // Request finished. Do processing here. Remove this if you are not doing anything.
        }
    }
    xhttp.send("distance=" + distance);
 

Code: POST-Request auf dem Server verarbeiten

Code: POST-Request auf dem Server verarbeiten

// listen to post request:
const bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({extended : true}));
 
app.post('/dist', (req, res) => {
    console.log('Got distance:', req.body.distance);
    res.sendStatus(200);
    // TODO: continue with further processing
});


5. Seriellen Bluetooth-Port einrichten

TODO

6. Daten über den seriellen Port vom Server zum HC-05 schicken

TODO

techniken/tensorflownodebluetooth.1611772668.txt.gz · Zuletzt geändert: 2021/01/27 19:37 von d.golovko