Parrot AR Drone 2.0 mit Raspberry Pi steuern

Die Parrot AR.Drone 2.0 Power Edition ist schon etwas älter, aufgrund der hervorragenden Entwicklungsumgebungen eignet sich der Quadrocopter jedoch sehr gut für ein Projekt mit dem Raspberry Pi. Im Folgenden soll die Steuerung mit Hilfe von, auf Node.js aufbauenden, Skripten erfolgen. Für das Fliegen über den Minicomputer sind keine Vorerfahrungen notwendig. Der Copter stabilisiert sich eigenständig in der Luft und die Kommunikation erfolgt direkt über WLAN. Das Linux Betriebssystem des Quadrocopter ist in Teilen konfigurierbar. Außerdem verfügt das Gerät über zwei Kameras welche sich zur Gesichtserkennung oder für Videoaufnahmen eignen.

Alle Befehle der Parrot AR.Drone 2.0 sind im AR.Drone Developer Guide beschrieben. Das mehrere hundert Seiten umfassende Werk bietet sich aber eher zum Nachschlagen an. Unter dem Projekt NodeCopter hacking ist eine Node.js basierende Skript Bibliothek entstanden. Diese bildet die Grundlage für die folgende Implementierung. Die Idee der Gesichtserkennung basiert dabei auf dem Artikel How to build an autonomous, voice-controlled, face-recognizing drone for $200. In dem Artikel bilden die Microsoft Azure Cognitive Services die Grundlage. Für die Spracheingabe lässt sich auch IBM Watson nutzen.

Pakete installieren mit npm

Zuerst erfolgt das Anlegen eines Verzeichnisses in dem die Daten liegen. Die Initialisierung über npm (Node Package Manager) ist hierbei Optional. Das Tool generiert eine package.json in der später die Abhängigkeiten abgelegt werden, falls der Code beispielsweise auf github veröffentlicht werden soll.

$ mkdir ardrone
$ cd ardrone
#OPTIONAL
$ npm init
This utility will walk you through creating a package.json file.
name: (ardrone)
version: (1.0.0)
description: Parrot AR.Drone 2.0 Control
entry point: (index.js)
test command:
git repository:
keywords: Drone
author: Sebastian Pech
license: (ISC)
About to write to /home/pi/ardrone/package.json

Im Anschluss daran erfolgt die Installation der ar-drone Pakete.

$ npm install ar-drone
# ODER mit -save wenn die package.json über npm init erstellt wurde
$ npm install ar-drone -save

WLAN einrichten

Die Parrot AR.Drone stellt ein öffentliches und unverschlüsseltes WLAN zur Verfügung. Zum kontrollieren des Quadrocopter muss sich der Raspberry Pi mit diesem verbinden. Danach lassen sich die Steuerbefehle übermitteln.

$ sudo iwlist wlan0 scan

Nach dem Scan sollte in der Liste ein Eintrag mit _ESSID:“ardrone2123456″ oder ähnlichem erscheinen. Zu diesem soll nun die Verbindung hergestellt werden.

$ sudo nano /etc/wpa_supplicant/wpa_supplicant.conf
network={
        ssid="ardrone2_123456"
        key_mgmt=NONE
}
# Bei mehreren WLAN Einträgen können diese priorisiert sein
network={
        ssid="ardrone2_123456"
        key_mgmt=NONE
        priority=1
}

Die korrekte Verbindung lässt sich dann wie folgt ermitteln.

$ wpa_cli status

Weitere Informationen im Fehlerfall finden sich im Setting WiFi up via the command line Artikel. Mit einem weiteren WLAN Empfänger können auch zwei Netze genutzt werden.

Drone steuern mit dem Raspberry Pi

Nun kommt der spannendste Teil des ganzen Projektes. Der Quadrocopter soll sich magisch in die Luft erheben, etwas drehen und dann wieder landen. Dazu dient der folgende Code vom Node Copter Projekt in einer Datei namens ardrone.js.

$ nano ardrone.js
# oder vi ;-)
var arDrone = require('ar-drone');
var client = arDrone.createClient();

client.takeoff();

client
  .after(5000, function() {
    this.clockwise(0.5);
  })
  .after(1000, function() {
    this.stop();
    this.land();
  });

Checkliste vor dem Ausführen:

  • Smartphone nicht verbunden (oder Pooling aktiviert)
  • Raspberry Pi mit der Drone verbunden
  • Akku voll
  • Indoor-Gehäuse angebracht
  • Kinder, Tiere, Glas, Papierblätter, … außer Reichweite gebracht
  • Keinen Mut angetrunken (Nüchtern! ;-))

Dann kann nicht mehr viel schief gehen (außer einige Crashes, usw.) … Viel Glück!

$ node ardrone.js

Sicherheit

Das WLAN der AR.Drone ist unverschlüsselt, ein Zugriff ist also jederzeit von jedem Gerät möglich! Das Anlegen eines WPA Schlüssels kann hier Abhilfe schaffen.

Grundsätzlich gelten alle Sicherheitsbestimmungen der Anleitung. Ich rate dazu, die Drone drinnen nur mit dem Indoor-Gehäuse zu fliegen. Die Bewegung der Quadrocopter ist dadurch etwas träger und schwammiger aber die Einrichtung wird es einem danken.

Um das Unsanfte Fallen der Drone ein bisschen zu verbessern kann ein Landegestell aus Kabelbindern helfen.

Probleme mit dem Video

Die Beispiele png-stream.js und tcp-video-stream.js setzen das veraltete FFmpeg voraus. Die Installation ist leider nicht ganz trivial. Dennoch gibt es ein paar gute Anleitungen für experimentierfreudige Bastler. How to compile ffmpeg on a Raspberry Pi und Compiling software from source code on the raspberry pi – the ffmpeg suite.

# Wenn mstorsjo-fdk-aac und faac-1.28 installiert sind:
$ git clone http://source.ffmpeg.org/git/ffmpeg.git
$ cd ffmpeg
$ ./configure --prefix=/usr/local --enable-gpl --enable-nonfree --enable-libass 
  --enable-libfdk-aac --enable-libfreetype --enable-libmp3lame --enable-libopus 
  --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libxvid
$ make && sudo make install
$ ffmpeg
iBeacon Scanner mit Raspberry Pi

In der Vergangenheit hatte ich bereits über iBeacons für die Haussteruerung berichtet. Der Raspberry Pi 3 und der brandneue Raspberry Pi Zero W verbauen standardmäßig Bluetooth Chips. Beide Geräte sind dazu geeignet einen iBeacon in der Nähe zu scannen. Findet der Pi dann eine Gerät in der Nähe kann man mittels Skript auf die Präsenz reagieren.

Prüfen und scannen

Im ersten Schritt ermitteln wir den Bluetooth Status des Gerätes und scannen dann nach Bluetooth Low Energy (BLE) Geräten. Idealerweise taucht hier dann der erste iBeacon auf.

$ systemctl status bluetooth
$ sudo hcitool lescan --duplicates
20:CD:XX:XX:XX:XX (unknown)
20:CD:XX:XX:XX:XX (unknown)

Für eine weitere Analyse lassen sich die Daten mitschneiden.

$ sudo apt-get install bluez-hcidump
$ sudo hcidump --raw

Ausgabe optimieren

Die Ausgabe von hcidump ist nicht sehr leserlich. Mit einem Skript von radiusnetworks oder einem geklonten Skript auf Github.com lässt sich die Ausgabe optimieren.

$ wget http://developer.radiusnetworks.com/ibeacon/idk/ibeacon_scan
$ chmod u+x ibeacon_scan
$ sudo ./ibeacon_scan

Fehlerbehebung

Die Fehlermeldung „Set scan parameters failed: Input/output error“ weißt auf ein belegtes/gesperrtes Bluetooth Gerät hin (bsp. durch den Kill eines hci* Prozesses). Die folgende Lösung schafft Abhilfe.

$ sudo killall hcitool
$ sudo killall ibeacon_scan
$ hciconfig hci0 down
$ hciconfig hci0 up
Spracherkennung, Chatbot mit Watson und Raspberry Pi

IBM stellt in seiner Bluemix Cloud-Plattform als Service (PaaS) unter anderem die Dienste von Watson Analytics zur Verfügung. Mit Hilfe der Services Speech to Text (Spracherkennung), Conversation (Chatbot) und Text to Speech (Sprachausgabe) lässt sich auf dem Raspberry Pi ein intelligentes System erschaffen. Durch die tiefere Integration der Dienste können hiermit auch Haussteuerungen oder Kundeninformationssysteme (KIS) realisiert werden.

Grundlage ist neben der Anschaffung eines Raspberry Pi (Einkaufsliste) mit allen relevanten Komponenten, die komplette Einrichtung des Systems. Darauf baut die Installation, der für Watson notwendigen Teile, auf. Zusätzlich ist ein USB Mikrofon notwendig und Lautsprecher oder ein Fernseher mit HDMI Anschluss.

HINWEIS: Die hier beschriebene Installation ist auf Deutsch. Leider sind nicht alle Watson Dienste für die deutsche Sprache erhältlich. Insbesondere die Spracherkennung funktioniert noch nicht auf Deutsch.

Mikrofon prüfen

Bei dem Raspberry Pi 3 funktioniert der Playstation Eye Treiber direkt.

$ lsusb
Bus 001 Device 006: ID 1415:2000 Nam Tai E&E Products Ltd. or OmniVision Technologies, Inc. Sony Playstation Eye

Zum Testen reicht das Aufnehmen und Abspielen einer kurzen Datei. Hierbei helfen die Advanced Linux Sound Architecture (ALSA) Tools.

$ sudo apt-get install alsa-base alsa-utils

$ arecord -D plughw:1,0 -f cd test.wav
$ aplay test.wav

Speech to Text (Spracherkennung)

Der folgende Teil basiert auf den Beispielen des TJBot welcher von IBM selber zur Verfügung gestellt wird.

Der erste Schritt besteht darin, das Node.js Repository einzubinden. Dies ermöglicht die Installation der aktuellsten Version. Danach lässt sich der Code von Github.com auschecken und die Abhängigkeiten installieren.

$ sudo apt-get update
$ sudo apt-get dist-upgrade
$ curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
$ sudo apt-get install -y nodejs

$ git clone https://github.com/ibmtjbot/tjbot.git
$ cd tjbot/recipes/speech_to_text
$ npm install

Jetzt ist ein guter Zeitpunkt erreicht einen (kostenlosen) Bluemix Account anzulegen. Der Prozess ist selbsterklärend. Andernfalls gibt es ein kleines PDF dazu. Nach der Einrichtung des Accounts ist unter Services – Watson – Text to Speech ein neuer Dienst anzulegen. In der Einstellung des Services stehen unter dem Punkt Serviceberechtigungsnachweise – Berechtigungsnachweise anzeigen die Zugangsdaten. Diese sind in der config.js zu hinterlegen.

Der Beispielcode sieht das Einschalten einer mehrfarbigen LED von Adafruits vor. Ich habe diese LED nicht und war nur an der Ausgabe des Dienstes interessiert. Ich habe daher eine Kopie der Hauptdatei erstellt und den Code innerhalb der LED Steuerung auskommentiert. Nach dem Starten lauscht der Raspberry Pi auf die Sprache und wartet bis zur ersten Sprechpause. Die erkannten Sätze erscheinen dann in der Textausgabe.

$ vi config.js

$ cp stt.js stt_console.js
# Licht Code auskommentiert
$ sudo node stt_console.js

Update: Der vereinfachte Code ohne die Lichtsteuerung kann jetzt in meinem Github.com Projekt heruntergeladen werden.

$ git clone https://github.com/spech66/watson_speech_to_text.git
$ cd watson_speech_to_text
$ npm install
$ vi config.js
$ sudo node speech_to_text.js

Chatbot und Text to speech (Sprachausgabe)

Mit den beiden zusätzlichen Services ist das Erstellen von interaktiven Systemen sehr einfach. In dem oben bereits ausgecheckten Code findet sich das Verzeichnis conversations. Hier lauscht der Raspberry Pi auf ein Aktivierungswort (Watson als Default) und schickt den Satz nach dem Schlüsselwort an den Conversations Dienst, dieser ermittelt eine sinnvolle Antwort und schickt den Text zurück. Der Text kann dann durch den Sprachausgabedienst in eine Audiodatei umgewandelt werden, die sich dann abspielen lässt. Zuerst die Services Text to Speech und Conversation aktivieren. Danach sind in beiden Services wieder die Zugangsdaten hinterlegt. Diese gehören in die config.js Datei.

$ cd ~/crmcopter/tjbot/recipes/conversation
$ vi config.js

Damit eine sinnvolle Konversation entstehen kann muss noch ein Dialog angelegt werden. In dem Service Conversatin gibt es den Button „Launch Tool“, hier gelangt man zum eigentlich Designer. Nach dem Anlegen eines Workspaces kann unter der Übersicht – Workspaces – View Details die Workspace ID kopiert werden.

Intents

Mit den Intents sind Schlüsselwörter und Sätze für den folgenden Dialog zu definieren. Für das Beispiel sollten mindestens zwei Intents („Hello“ und „Goodbye“) erstellt werden. Jeder Intent erhält dazu eine Reihe von möglichen Alternativen Worten und Sätzen (siehe Bild unten).

Dialoge

Dialoge verknüpfen Intents zu einer Verknüpfung von Aktionen und Reaktionen. Mit der Hilfe von If Abfragen können die Intents ermittelt werden (siehe Bild). Die Reaktion definiert die Rückgabe des Textes des Service.

Starten

    sudo node conversation.js

WATSON und TEXT sagen

IBM Watson Dialog
IBM Watson Dialog
IBM Watson Intents
IBM Watson Intents
IBM Bluemix Watson Raspberry Pi
IBM Bluemix Watson Raspberry Pi

Buzzwords zur Digitalisierung und Startups

„Startups erstellen ein Minimum Viable Product um ihr disruptives Geschäftsmodell zu testen!“. Die Buzzwords zum Thema Digitalisierung und der Gründerszene sind vielfältig. Nicht alles lässt sich auf Anhieb verstehen. Die wichtigsten Begriffe sind hier in Kürze vorgestellt.

MVP – Minimum Viable Product

Ein Minimum Viable Product umfasst die Entwicklung eines neuen Produktes, welches mit dem minimal sinnvollsten Funktionsumfang auf den Markt gebracht wird. Der Kunde soll die Möglichkeit haben einen ersten Eindruck zu bekommen und die Entwickler können durch das Feedback der Kunden zielgerichtet neue Funktionen einbauen. Im Gegensatz zu klassischen, langjährigen Produktentwicklungen lässt sich das Risiko eines teuren Fehlschlags somit vermeiden.

Disruption

Disruption oder auch Disruptive Innovation definiert Neuerungen die bestehende Technologien, Produkte und Dienstleistungen vollständig vom Markt verdrängen. Dies betrifft oft auch große und etablierte Konzerne, welche die Gefahr einer solchen Innovation lange unterschätzen oder nicht erkennen.

Beispielsweise sind hier Musikstreamingdienste genannt, die das klassische CD Geschäft stark zurückgedrängt haben. Ein weiteres (zukünftiges) Beispiel ist der Elektroautohersteller Tesla. Lange wurden die Elektroautos vom Automotive Markt unterschätzt. Mittlerweile versuchen die großen Autokonzerne den Anschluss zu bekommen.

Startup

Der Begrifft Startup definiert an sich durch ein neues Unternehmen. Im Sinne der Startup und Technologie Branche bedeutet ein Startup ein junges innovatives Unternehmen, dass durch schnellen Wachstum erfolgreich sein will. Die Finanzierung erfolgt hierbei oft durch Venture Kapital, Crowdfunding und andere Investoren.

Unicorn

Für Startups mit einer Marktbewertung von über eine Milliarde US-Dollar hat sich die Bezeichnung „Einhorn“ (englisch: Unicorn) etabliert. (Quelle: https://de.wikipedia.org/wiki/Start-up-Unternehmen)

Rapid Prototyping

Mit dem Begriff Rapid Prototyping ist eine Reihe von Technologien und Herstellungsverfahren beschrieben mit deren Hilfe sich Prototypen am schnellsten Herstellen lassen.

Für einfache Formen und zur Produktvorstellung wären in diesem Fall 3D Drucker ein Beispiel. Hier können neue Formen schnell aus Granulaten gedruckt werden.

Hackathon

Hackathons sind in der Regel mehrtägige Veranstaltungen bei denen sich Programmierer, Designer und andere fachliche Vertreter treffen, mit dem Ziel in kurzer Zeit zu vorgegeben Themen neue Lösungen zu entwickeln. Der Veranstalter gibt ein grobes Thema, eine Technologie oder ein Gebiet vor. Die Teilnehmer organisieren sich dann in Gruppen und arbeiten an neuen Produkten. Der Ort der Veranstaltung ist dabei idealerweise so gewählt, dass Schlafmöglichkeiten und Essen in unmittelbarer Nähe vorhanden sind, so dass der Arbeitsfluss nicht gestört wird.

Leseempfehlungen

 

Bild: Pixabay

Dungeons & PowerShell

PowerShell ist nicht nur ein mächtiges Werkzeug für Administratoren und Entwickler auch Rollenspieler können die umfangreiche Skriptsprache nutzen. Egal ob Dungeons & Dragons, Das schwarze Auge, Pathfinder oder Splittermond, jedes System kann mit Hilfe der PowerShell als Grundlage für Würfel und Zufallsereignisse dienen.

Würfeln

Die Würfel lassen sich als Kombination aus Anzahl und Seiten darstellen, getrennt mit einem W für Würfel oder im Englischen mit d für dice. Somit ergibt 1W6 einen sechsseitigen Würfel mit den Augen von 1 bis 6. Der klassische 1W20 für D&D würfelt die Zahlen von 1 bis 20. Bei 2W4 werden zwei Würfel mit je vier Seiten gewürfelt, das Ergebnis liegt zwischen 2 und 8. PowerShell simuliert dies durch die Funktion Get-Random. Der minimale Wert ist dabei inklusive, der maximale Wert ist exklusiv! Dadurch ergeben sich die folgenden Aurufe für den 1W6 und 1W20.

Get-Random -Minimum 1 -Maximum 7
# oder
1..6 | Get-Random

Get-Random -Minimum 1 -Maximum 21
oder
1..20 | Get-Random

Mehrere Würfel lassen sich simulieren wenn für jeden Würfel ein eigenes Array erstellt wird. Aus der Gesamtmenge sind dann die Zahlen zufällig zu wählen. Wird die Count Option von Get-Random auf einem einfachen Array genutzt können die Zahlen nicht doppelt vorkommen. Die Funktion für 2W20 sieht damit wie folgt aus.

$Seiten = 20
$Anzahl = 2
(1..$Seiten)*$Anzahl | Get-Random -Count $Anzahl

Möchte man das Ergebnis aller Würfel addieren kommt Measure-Object zum Einsatz. Dabei kann optional auch ein Wert aufaddiert werden, beispielsweise um Fähigkeitsmodifikatoren einzurechnen. Das 2W20 Beispiel von oben, ergänzt um einen +4 Modifikator, also 2W20+4 sieht dann wie folgt aus.

(((1..$Seiten)*$Anzahl | Get-Random -Count $Anzahl) | Measure-Object -Sum).Sum + 4

Zum Schluss werfen wir einen Blick auf die Charaktererstellung von D&D und Pathfinder. Eine Möglichkeit der fünften Edition ist das Auswürfeln. Bei der Methode „4d6 drop lowest“ werden vier sechsseitige Würfel genutzt und der Kleinste entfernt. Dadurch entstehen Werte von 3 (sehr unwahrscheinlich) bis 18 (sehr unwahrscheinlich), im Schnitt liegen die Werte bei 9 bis 16. In die Formeln oben eingesetzt lassen sich die Attribute des Charakters somit wie folgt auswürfeln.

(1..6)*4 | Get-Random -Count 4 | Sort-Object | Select -Last 3 | Measure-Object -Sum | Select -ExpandProperty Sum

Zufallsbegegnungen

Spielleiter sind von Natur aus oft faule Zeitgenossen. Nicht umsonst erklären sich die Seitenlangen Begegnungstabellen in vielen Regelwerken. Mit Hilfe der PowerShell können solche Tabellen auch zufällig ermittelt werden. Eine Variante wäre das Speichern der Begegnungen in diversen Dateien. Exemplarisch ist in diesem Artikel aber eine statische Liste auf Basis der Tabelle „Gewölbe (für niedrige Stufen) HG 2“ aus dem Pathfinder Referenz Dokument gezeigt.

# Begegnungen definieren mit Wahrscheinlichkeit
$Begegnungen = 
@([pscustomobject]@{Min=1; Max=6; Name="1W6 Schreckensratten"},
[pscustomobject]@{Min=7; Max=12; Name="1W6 Feuerkäfer"},
[pscustomobject]@{Min=13; Max=20; Name="1W6 Menschliche Skelette"},
[pscustomobject]@{Min=21; Max=24; Name="1W4 Riesentausendfüßler"},
[pscustomobject]@{Min=25; Max=26; Name="1 Spinnenschwarm"},
[pscustomobject]@{Min=27; Max=32; Name="1W6 Menschliche Zombies"})

# Maximale Wahrscheinlichkeit ermitteln und einen zufälligen Wert bestimmen
$Max = $Begegnungen | foreach { $_.Max } | Measure-Object -Maximum | Select-Object -ExpandProperty Maximum
$Auswahl = Get-Random -Minimum 1 -Maximum ([int32]$Max+1)

#Begegnung darstellen
$Begegnungen | Where-Object { $Auswahl -ge $_.Min -and $Auswahl -le $_.Max }

NPCs

NPCs können beliebig komplex aufgebaut sein. Ein einfaches Mittel ist das Definieren von verschiedenen Feldern, die sinnvoll kombiniert werden.

$Namen = "Sarah", "Annabelle", "Johanna", "Lindsey", "Elaine"
$Eigenschaften = "abenteuerlustige", "böse", "chaotische", "erfinderische", "mutige", "risikofreudige"
$Klassen = "Kriegerin", "Magierin", "Schurkin", "Adelige", "Bettlerin", "Händlerin"
"{0} ist eine {1} {2}." -f ($Namen | Get-Random), ($Eigenschaften | Get-Random), ($Klassen | Get-Random)

„Johanna ist eine mutige Kriegerin.“

 

Bilder: Pixabay, Wikipedia