Skip to content

Instantly share code, notes, and snippets.

@Paulomart
Created July 17, 2017 08:12
Show Gist options
  • Save Paulomart/b44a785a6427b117527521677bd5b209 to your computer and use it in GitHub Desktop.
Save Paulomart/b44a785a6427b117527521677bd5b209 to your computer and use it in GitHub Desktop.

🚧 Python mit Lego

Dieses Handbuch behandelt die Programmierung von EV3 Hardware mithilfe von Python und der Lego Labview Software. Zuerst werden wir uns die Hardware anschauen.

Hardware vorbreiten

Für den EV3

Für den EV3 ist eine besondere Vorbereitung notwendig.

Für den BrickPi3

Voraussetzungen

Im ersten Schritt wird der BrickPi3 ausgepackt. Vorsicht, der elektronischen Bauteile auf den BrickPi sind empfindlich und können durch elektromagnetische Ladungen zerstört werden! In den Bausatz sind viele Kleinteile wie Schrauben, die schnell verloren gehen könnten.

Zusätzlich benötigen wir noch:

  • Einen Raspberry Pi3
  • 2 Kreuzschlitzschraubendreher
  • Batterien
  • Ein Mini USB Ladegerät für den Raspberry Pi
  • Eine Tastatur und Maus
  • Eine MicroSD Karte (mindestens 8GB) und eventuell einen Adapter

photo_2017-06-08_09-53-11

Zusammenbau

  1. Von den größeren Schrauben, werden jeweils eine durch die Löcher gesteckt und mit den Hülsen auf der anderen Seite fixiert: photo_2017-06-08_10-59-45

  2. Nun werden die kleineren Schrauben durch die Löcher gesteckt. Auf der anderen Seite wird eine Mutter gerade bis zu Kante der Schraube aufgedreht (Auf dem Bild fehlt eine Schraube vorne rechts, das erste Loch). photo_2017-06-08_10-59-36

  3. Nun wird der Raspberry Pi aufgesetzt. Er wird mit zwei Schrauben, die in die Hülsen greifen fixiert. photo_2017-06-08_11-04-11

  4. Als nächstes werden die beiden Seitenteile aufgesetzt, die Muttern der Schrauben sollten die Seitenteile dann an Ort und Stelle halten. Die Muttern müssen in den Ausbuchtungen des Seitenteils sitzen. photo_2017-06-08_11-07-14 Achtet darauf, dass die Öffnungen zu denen des Raspberry Pis passen. photo_2017-06-08_11-09-20 photo_2017-06-08_11-09-24

  5. Jetzt kommt der BrickPi auf den Raspberry Pi, dieser wird auf die Steckverbindungen des Pis gesteckt. Achtet darauf, dass die Steckverbindung so wie gezeigt ist. photo_2017-06-08_11-13-19 photo_2017-06-08_11-13-23

  6. Nun bauen wir die Deckplatte, dafür kommen wieder wie im ersten Schritt, die Schrauben mit Muttern zum Einsatz. Die Schrift muss nach unten zeigen, wenn die Muttern nach oben zeigen. photo_2017-06-08_11-17-36

  7. Im nächsten Schritt wird der Deckel auf das Gehäuse gesetzt, wieder müssen die Muttern in den Ausbuchtungen sitzen. Falls es nicht passt einfach die Schrauben ein bisschen lösen, dann klappt es besser. photo_2017-06-08_11-19-29

  8. Nun werden die Vorderseite und die Rückseite montiert, damit ist wieder auf die Anschlüsse des BrickPis zu achten. photo_2017-06-08_11-23-05 photo_2017-06-08_11-23-17 Falls es nicht passen wollte, einfach die Schrauben lösen, und die Mutter vorher in die Ausbuchtung setzen und dann vorsichtig die Schraube hineindrehen: photo_2017-06-08_11-38-40 photo_2017-06-08_11-38-42

SD Karte mit Betriebssystem erstellen

Damit der EV3/BrickPi laufen kann, benötigen wir ein Betriebssystem. Dieses Betriebssystem hängt von der verwendeten Hardware ab. Für den Anfang werden wir die Lego EV3 Hardware verwenden, da die dort der Start leichter ist.

Hardware Software
Lego EV3
  • Lego EV3 Firmware
  • EV3 Dev
Brick Pi3
  • Dexter Industries Raspbian
  • EV3 Dev

Für die Lego Firmware ist fest auf dem EV3 installiert, sobald keine SD Karte im EV3 steckt, startet der EV3 seine normale Firmware.

Betriebssystem auf SD Karte installieren

Software auswählen

Um die EV3 Dev oder Dexter Industries Raspbian zu installieren benötigen wir eine SD Karte, auf diese SD Karte wird das Betriebssystem gespielt. Der BrickPi oder der EV3 booten dann von der SD Karte.

Software Download Hinweise
EV3 Dev http://www.ev3dev.org/downloads/ Je nach Hardware unterschiedlich
Dexter Industries Raspbian https://sourceforge.net/projects/dexterindustriesraspbianflavor/ Oben rechts auf Download klicken

Zusätzlich benötigt man noch ein Programm, welches das Image auf die SD Karte schreiben kann, dafür empfiehlt sich Etcher.

SD Karten flashen

  1. Image auswählen, dazu klickt man auf Select Image grafik

  2. Als nächtes einfach die heruntergeladene ZIP-Datei auswählen: grafik

  3. Etcher sollte nun automatisch die SD Karte auswählen, falls nicht einfach unter Change die richtige auswählen: grafik

  4. Auf Flash klicken, danach muss man einmal die Aufforderung bestätigen.

  5. Sollte alles gut gehen, wird folgendes angezeigt: grafik

Einrichtung

BrickPi3 einrichten

Raspberry Pi anschließen

  1. Steckt die Mirco SD in den Raspberry Pi
  2. Schließt den Raspberry Pi über HDMI an einem Monitor an.
  3. Verbindet Tastatur und Maus mit den Raspberry Pi.
  4. Versorgt den Raspberry Pi mit Strom, schließt auch die Batterie an.
  5. Der Raspberry Pi startet automatisch sobald er Strom hat, auf dem Monitor sollte der Startbildschirm erscheinen.

Raspberry Pi mit den WLAN verbinden

Damit der Pi updates bekommen kann, muss er mit den WLAN verbunden werden. Dies erfolgt über die Wifi Setup Verknüpfung auf dem Desktop. Dort findet man unter Scan alle WLAN Netzwerke, mit einem Doppelklick kann das gewünschte ausgewählt werden. Jetzt ist der Pi mit den WLAN verbunden.

Alternativ kann der Raspberry Pi auch über LAN angeschlossen werden.

Software auf den neusten Stand bringen

Jetzt, nachdem der Raspberry Pi mit den Internet verbunden ist, können wir die Software auf den Pi aktualisieren. Dafür einfach das Programm Dl Software Update welches auf dem Desktop liegt ausführen. Nach wenigen Augenblicken sollte sich ein Fenster öffnen:

Screenshot

Dort muss auf Update Dexter Software geklickt werden. Im Hintergrund erkennt man, dass der Pi in der Konsole arbeitet. Sobald der Update fertiggestellt wurde, erscheint Update complete in der Konsole.

Nun muss noch der BrickPi selbst geupdatet werden, die erfolgt ebenfalls über das Fenster, dort einfach BrickPi3 auswählen und dann auf Update Robot klicken. Nach ein paar Minuten erscheint Firmware update is done!. Dies mit OK bestätigen und anschließend auf Exit klicken, dies sollte den Pi neustarten.

EV3 Dev einrichten

EV3 Dev mit den WLAN verbinden

Damit wir auf den EV3 zugreifen können, müssen wir den EV3 mit einem WLAN verbinden. Da der EV3 keine integierte WLAN Schnittstelle hat, benutzen wir ein USB WLAN Dongle welchen wir in den USB Anschluss stecken.

Nachdem der EV3 hochgefahren ist, im Menu auf Wireless and Networks klicken, dann wird eine Liste mit allen verfügbaren WLAN Netzwerken angezeigt. Dort kann dann einfach das gewünschte WLAN Netzwerk ausgewählt werden und dann verbunden werden.

Jetzt sollte oben im Display die IP des EV3s angezeigt werden, diese benötigen wird später.

EV3 Lego

Die Lego eigene Firmware sollte sofort funktionieren.

Programmierung

Dieses Handbuch ist so aufgebaut, dass zu erst ein Beispiel über die LEGO MINDSTORMS EV3 Software, auch LabView genannt, umgesetzt wird. Anschließend wird das Programm dann in Python übertragen. Dabei werden nach und nach mehr Funktionen von Python erklärt.

LabView

Zunächst müssen wir die LEGO MINDSTORMS EV3 Software installieren, genaue Installationsanleitungen finden sich auf der Herstellerwebseite. Zum loslegen gibt es ebenfalls einige Tutorials auf der Lego Webseite.

Python

Was ist Python?

Python ist eine objektorientierte Skriptsprache, die universall interpretiert werden kann. Auf dem EV3 Dev verwenden wir Python um den Roboter zu steuern, Python hat jedoch noch viele andere Anwendungsbereiche. In dieser Anleitung werden wir Python 3 verwenden, da es für die EV3 Programmierung empfohlen wird.

Kommentare in Python beginnen mit einem # der Rest der Zeile wird dann ignoriert.

Die Entwicklungsumgebung

Damit wir beginnen können müssen wir zu ersteinmal Python 3 lokal auf unseren Computer oder Mac installieren. Je nach Betriebssystem varriert die Installation, auf der Webseite von Python gibt verschiedene Versionen.

Unter MacOS lässt sich Python 3 auch ganz einfach installieren, wenn der Package Manager brew 🍺 bereits installiert ist: brew install python3, damit wird Python 3 automatisch installiert.

Um mit EV3 Dev zu arbeiten müssern wir nur noch das EV3 Dev Python Module installieren. Dies machen wir über den Befehl pip3 install python-ev3dev.

Für Python empfiehlt sich eine Integrierte Entwicklungsumgebung, kurz IDE. Im Gegensatz zu einem Texteditor erkennt die IDE automatisch Fehler, unterstützt Syntax Highlighting und vieles mehr.

PyCharm CE ist eine solche IDE, die man unter Windows und MacOS installieren kann.

Unter MacOS hier PyCharm CE nach den ersten Start so aus:

grafik

Dort wählen wir Create New Project aus.

grafik

Jetzt können wir einen Ordner für das zu erstellende Projekt festlegen. In meinen Fall ist dies unter /Users/paulheidenreich/dev/ev3dev/HelloWorld.

Dann klicken wir einfach auf Create. Dies bringt uns zum nächsten Fenster, dies ist unsere Entwicklungsumgebung. Links sieht man das aktuelle Projekt und die Dateien. Da wir noch keine haben wird hier nur der Ordner gelistet. Wir wollen nun eine Datei erstellen, in der wir beginnen können zu programmieren.

grafik

Als Name der Datei wählen wir einfach HelloWorld.

grafik

In dem Editorfenster können wir jetzt programmieren.

Hello world!

Zuerst werden wir uns den Grundaufbau einer Python Datei anschauen:

Jede Python Datei beginnt mit: #!/usr/bin/env python3. Um Sonderzeichen zu Unterstützen müssen wir Python noch auf die Kodierung hinweisen: # -*- coding: utf-8 -*-.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# hier kommt der Quelltext hin

Um Ausgaben in der Konsole zu erzeugen verwenden wir die print() Funktionen, diese können wir so aufrufen:

print("Hallo Welt!")

Wenn wir dies in unser Programm einbauen sieht das so aus:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

print("Hello World!")

Wenn wir mit einem Terminal in den Ordner des Projektes gehen, in meinen Fall ist das /Users/paulheidenreich/dev/ev3dev/helloworld, können wir den Python Quellcode mit python3 HelloWorld.py aufrufen. Dieser sollte dann die Konsolenausgabe Hello World anzeigen.

todo add more lang examples

Mit imports lassen sich andere Python Module einbinden, diese können spezielle Funktionen bereitstellen. Das time Modul, bietet z.B. viele Nützliche Funktionen im Zusammenhang mit Zeit. Hauptsächlich werden wir dort die sleep Funktion benutzen, welche den ganzen Programmablauf warten lässt.

Auch das python-ev3dev Modul welches wir vorher mit pip3 installiert haben, stellt Funktionen zur Verfügung. Bei dem ev3dev Modul handelt um Funktionen um mit den EV3 Brick zu interagieren (Motoren ansteuern und so weiter).

Das sieht dann so aus:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import ev3dev.ev3 as ev3
import time

print("Hello World!")

Die Verbindung zum EV3

Damit wir unsere Programme auch auf dem EV3 laufen lassen können, müssen diese auf den Speicher des EV3 übertragen werden. Dies geschied mit der LEGO Software über ein USB Kabel, aus LabView kann dann einfach das Programm gestartet oder auf dem EV3 gedownloaded werden.

Bei ber EV3 Dev Firmware verhält sich das ganze anders: Wir müssen uns über SSH verbinden. SSH steht für Secure Shell und bezeichnet ein Protocoll mit den sich ein Client, in dem Fall ist das unser Laptop, auf einem Server, hier der EV3 Brick, verbinden kann. Wenn verbunden können wir Befehlen auf dem EV3 ausführen, damit starten wir dann auch die Programme auf dem EV3.

Um uns mit den EV3 zu verbinden benötigen wir die IP Addresse des EV3 und einen SSH Client, auf MacOS ist dieser bereits vorinstalliert. Die IP Addresse des EV3s steht im Display oben, nachdem er hochgefahren und mit den WLAN verbunden ist.

Um zu den EV3 zu verbinden öffnen wir ein Terminal und geben ssh robot@192.168.161.144 ein. Hier ist die IP Addresse 192.168.161.144, der Benutzer ist robot. Nach wenigen Augenblicken werden wir nach dem Passwort gefragt, dies ist Standartmäßig maker.

grafik

Wenn alles gut läuft sollte es jetzt wie dort oben aussehen. Nun können wir Befehle auf dem EV3 aufführen, jedoch haben wir unser Programm noch nicht auf dem EV3. Dies dafür benötiges wir ein neues Konsolenfenster und das Programm scp. Auf MacOS ist es standartmäßig installiert.

scp kann Dateien über ssh kopieren, wir werden es benutzen um unsere Python Programme auf den EV3 zu kopieren. Die Syntax ist dabei ähnlich wie beim ssh Befehl: scp <Lokale Quelldatei> <Entfernter Nutzer>@<Addresse>:<Entferner Zielordner>. Diesen Befehl führen wir am besten in den Projekt Ordner von PyCharm aus:

scp helloworld.py robot@192.168.161.144:~

Danach muss einmal das Passwort für den robot Nutzer eingegeben werden. Dann wird unser Python Programm auf den EV3 kopiert. Führen wir nun in der anderen Konsole, die über SSH verbunden ist, ls aus, sollte das Programm angezeigt werden.

grafik

Mit python3 helloworld.py können wir das Programm ausführen.

Der erste Test

Nun wollen wir ein Roboter bauen, bei dem der Motor A für eine Sekunde gedreht wird.

Lego

Mit dem LabView Programm kann diese Aufgabe in 3 Programmblöcken gelöst werden. Programmblöcke sind in der LabView Software Module, die Aktionen ausführen können, Sensoren einlesen können und dem Programmfluß steuern können.

Der erste Progammblock, den wir benötigen, ist der Motorblock, dieser kann, wie der Name bereits sagt, einen Motor ansteuern. Zu finden ist dieser Block unter den grünen Tab. Wir ziehen diesen Block per Drag 'n' Drop hinter die Startblock. Der erste Knopf auf dem Programmblock bietet mehrere Auswahlmöglichkeiten, dort wählen wir An aus (Die An für n Sekunden Option wäre einfacher, jedoch nicht so gut mit Python vergleichbar).

Wenn wir hier aufhören würden, wäre das Programm sofort vorbei: Nachdem der Motor eingeschaltet wird, beendet sich das Programm sofort. Daher müssen wir warten, nachdem der Motor eingeschaltet wurde und ihn dann wieder ausschalten.

Um zu warten, gibt es den Warten Programmblock, dieser findet sich unter dem Orangen Tab. Wir ziehen diesen einfach hinter den Motorblock.

Zum Schluss fügen wir noch einen Motorblock ein, wählen dort aber Aus aus. Damit stoppt der Motor nach Ende des Programmes.

Das ganze Programm sollte schließlich so aussehen: grafik

Python

In Python für den EV3 gibt es die Möglichkeit Motoren für eine Anzahl von Sekunden laufen zu lassen. Zu erst muss für den Motor eine Variable erstellt werden, dies funktioniert so:

motorA = ev3.LargeMotor('outA')

Damit wird ein neuer LargeMotor an Anschluss A initialisiert. Der Motor wird dann in der Variable motorA gespeichert. In einer Variable können wir Daten speichern, die wir später benötigen. In diesen Fall ist motorA ein Object auf dem wir dann Funktionen aufrufen können.

motorA.run_timed(time_sp=1000, speed_sp=300)

Die Funktion run_timed kann den Motor für eine bestimmte Zeit gestartet werden. Dabei werden benannte Argumente übergeben werden: time_sp und speed_sp. time_sp gibt die länge der Zeit in Millisekunden an, für die der Motor laufen soll. speed_sp bestimmt wie schnell der Motor sich drehen soll.

Das ganze Programm kann nun so aussehen:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-


import time # Time ist die Library welche Funktionen wie sleep() mitbringt.
import ev3dev.ev3 as ev3 # Das sind die Treiber und Funktionen für die Steuerung des Roboters

motorA = ev3.LargeMotor('outA')
motorA.run_timed(time_sp=1000, speed_sp=300)
BrickPi3

Python

Genau wie im LabView Programm machen wir folgende Schritte:

  • Motor A starten
  • Eine Sekunde warten
  • Motor A anhalten

Unseren Motor steuern wir mithilfe von BP.set_motor_power(BP.PORT_A, 100) an. BP.PORT_A steht für den Anschluss und 100 für die Geschwindigkeit, diese kann von 0 bis 100 gestellt werden, wobei 0 aus und 100 die maximal Geschwindigkeit ist.

Eine Sekunde lang warten ist ebenfalls einfach, dafür verwenden wir einfach die bereits importierte time Library: time.sleep(1).

Zum Schluss muss der Motor wieder ausgeschaltet werden.

Hier der ganze Python Code:

#!/usr/bin/env python
# -*- coding: utf-8 -*-


from __future__ import print_function
from __future__ import division

import time
import brickpi3

BP = brickpi3.BrickPi3()

# Die Geschwindigkeit des Motors auf 100 setzen
BP.set_motor_power(BP.PORT_A, 100)

# eine Sekunde warten
time.sleep(1)

# Motor ausschalten
BP.set_motor_power(BP.PORT_A, 0)

Der erste Test - Aufgabe

Steuert nun die Motoren A und B an, die entsprechend an den EV3 angeschlossen sind. Schreibe dafür ein Programm in LEGO und in Python.

Lösung

Lego

grafik

In der LabView Software gibt es zusätzlich zu dem Block, der einen Motor ansteuert, einen Block der zwei Motoren gleichzeigt steuert. Bei diesem Block können wir konfigurieren welche Motoren mit welcher Geschwindigkeit angesteuert werden.

Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-


import time  # Time ist die Library welche Funktionen wie sleep() mitbringt.
import ev3dev.ev3 as ev3  # Das sind die Treiber und Funktionen für die Steuerung des Roboters

motorA = ev3.LargeMotor('outA')
motorB = ev3.LargeMotor('outB')

motorA.run_timed(time_sp=1000, speed_sp=300)
motorB.run_timed(time_sp=1000, speed_sp=300)
BrickPi3
#!/usr/bin/env python
# -*- coding: utf-8 -*-


from __future__ import print_function
from __future__ import division

import time
import brickpi3

BP = brickpi3.BrickPi3()

# Die Geschwindigkeit der Motoren auf 100 setzen
BP.set_motor_power(BP.PORT_A, 100)
BP.set_motor_power(BP.PORT_B, 100)

# eine Sekunde warten
time.sleep(1)

# Motoren ausschalten
BP.set_motor_power(BP.PORT_A, 0)
BP.set_motor_power(BP.PORT_B, 0)

Erweiterte Bewegung

Die Motoren nach Zeit zu steuern ist für den Anfang gut, allerdings berücksichtigt dies nicht, was passiert wenn ein Motor stecken bleibt und blockiert. Die Wartezeit würde einfach ablaufen und der Motor danach ausgeschaltet, das wollen wir aber nicht: Unser Roboter muss sich präzise bewegen!

Um dies Problem zu lösen, benutzen wir absolute Positionen der Moteren, denn immer wenn sich ein Motor ein Stück nach vorne bewegt, wird dieser Zähler erhöht. Wenn der Motor sich zurück dreht, wird dieser Zähler verringert. Gleichzeigt können wir den Motor anweisen einen bestimmte Position anzufahren, er dreht sich dann solange, bis er diese Position erreicht hat.

Diese Funktion können wir uns zu Nutzen machen, um exakte Bewegungen durchzuführen: Wir sagen den Roboter einfach bewege den Motor 10 Schritte nach vorne.

LabView

In LabView diese Art von Steuerung sehr einfach, man stellt den Motorblock statt auf an auf An für n Grad oder An für n Umdrehungen. Abschließend kann eingestellt werden wieviel Grad/Umdrehungen der Motor bei welcher Geschwindigkeit machen soll.

grafik

Python

Auch bei Python gibt eine Funktion um den Motor für eine bestimme Anzahl Umdrehungen zu drehen. Dazu benötigen wir wieder eine Motor Variable, wie wir sie vorher erstellt haben. Die Funktion um den Motor zu bewegen heißt run_to_rel_pos. Diese müssen wir so aufrufen:

motorA = ev3.LargeMotor('outA')
motorA.run_to_rel_pos(position_sp=10)

Der Parameter position_sp steht dabei für die Umdrehungen die der Motor machen soll. In diesen Fall sind es 10 Umdrehungen.

BrickPi3 Leider ist es in Python nicht so leicht, da die Motoren immer mit _absoluten_ Werten angesteuert werden müssen. Mit
BP.set_motor_position(BP.PORT_A, 10)

wird der Motor A an die absolute Position 10 gefahren. Wollen wir jedoch nur Zehn Schritte nach vorne fahren, müssen wir die aktuelle Position des Motors plus Zehn rechenen. Das Ergebniss ist die absolute Position an die sich der Motor bewegen soll.

Um die aktuelle absolute Position des Motors zu ermitteln, verwenden wir BP.get_motor_encoder(BP.PORT_A). Da wir mit diesen Wert weiter arbieten wollen weisen wir ihn auf eine Variable zu:

motor_pos = BP.get_motor_encoder(BP.PORT_A)

Jetzt können einfach motor_pos plus 10 rechenen:

target_pos = motor_pos + 10

Wir speichern unsere Zielposition in target_pos, nun können wir den Motor zu der Position bewegen:

BP.set_motor_position(BP.PORT_A, target_pos)

Zusammengefasst sieht das ganze so aus:

motor_pos = BP.get_motor_encoder(BP.PORT_A)
target_pos = motor_pos + 10
BP.set_motor_position(BP.PORT_A, target_pos)

Erweiterte Bewegung - Aufgabe

Damit wir nun unseren Roboter richtig gut bewegen können, müssen wir herrausfinden, wieviele Umdrehungen für bestimmte Aktionen notwending sind. Die Anzahl an Umdrehungen variiert je nach Roboter.

Folgende Dinge solltet ihr messen:

  • Eine 90° Drehung
  • 30 Zentimeter geradeaus fahren
  • ???

Das Messen der Werte ist recht einfach: Wir setzen einen Wert ein und probieren dann aus. Danach modifizieren wir die Werte und versuchen es erneut. Für diese Aufgabe könnt ihr die Lego Software als auch Python verwenden.

Beispiel Quellcode
motorA = ev3.LargeMotor('outA')
motorB = ev3.LargeMotor('outB')

motorA.run_to_rel_pos(position_sp=10)
motorB.run_to_rel_pos(position_sp=-10)

Schleifen I

Nun wollen wir uns Schleifen anschauen: Dazu werden hier zunächst die Grundladen erklärt und im nächsten Schritt anschauen wie das mit den Motoren verknüpfen. Schleifen dienen dazu identischen Programmcode mehrmals auszuführen. Dies dient dazu, Programmcode, der sonst doppelt wäre, nur einmal zu schreiben.

Zunächst schauen wir uns jedoch erstmal einfacher Beispiele an:

LabView

In LabView gibt es einen Schleifenblock, diesen konfigurieren wir zunächst auf Zählen. Zählen bedeutet, dass die Programmblöcke im inneren der Schleife x Mal ausgeführt werden. Wie oft die Schleife sich wiederholen soll, können wir ebenfalls im Schleifenblock einstellen:

grafik

Innerhalb der Schleife wurde hier ein Klangblock eingefügt, dieser spielt ein Ton ab. Insgesammt wird der Ton daher 4 Mal abgespielt.

Python

In Python gibt es verschiedene Schleifentypen, wir werden uns zunächst die for Schleife genauer ansehen:

for x in range(0, 5):
    print(x)

range() ist eine Funktion die eine Liste von Zahlen erstellt, in diesem Fall könnte range(0, 5) durch [0, 1, 2, 3, 4] ersetzt werden.

Python beginnt mit den ersten Element der Liste und legt dieses in der Variable x ab. Dies wird solange wiederholt, bis keine Elemente mehr vorhanden sind. Dann wird der Quelltext, der sich in der Schleife befindet ausgeführt. Dabei kann natürlich auf den aktuellen Wert der Variable x zu gegeriffen werden.

Damit Python weiß, welcher Quelltext sich in der Schleife befindet und welcher nicht, wird der Teil, der sich in der Schleife befinden soll, mit vier Leerzeichen eingerückt.

Der Pythoncode gibt folgendes in der Konsole aus:

0
1
2
3
4

Schleifen II

Nun wollen wir, dass sich unser Roboter wirklich bewegt: Anstatt einen Sound in der Schleife abzuspielen, wollen wir den Roboter vorwährts fahren lassen und dann drehen. Das ganze soll der Roboter 4 mal machen, dadruch fährt er ein Quadrat.

Lego

bildschirmfoto 2017-07-05 um 13 48 38

Python

Wir wir bereits oben gelernt haben, können wir mit for und range eine Schleife bauen, die 4mal läuft: for x in range(0, 3):. Jetzt brauchen wir den Quellcode der 4mal ausgeführt werden soll. Dieser setzt sich einfach aus dem vorwährts und den dreh Code zusammen. Die Werte dafür haben wir ja bereits ermittelt.

motorA.run_to_rel_pos(position_sp=300)
motorB.run_to_rel_pos(position_sp=300)
time.sleep(1)
motorA.run_to_rel_pos(position_sp=-200)
motorB.run_to_rel_pos(position_sp=200)
time.sleep(1)

Nun müssen wir diesen Code nur vier mal ausführen lassen, dies erreichen wir einfach damit, dass wir ihn in eine for Schleife packen. Der Quelltext muss natürlich mit vier Leerzeichen eingerückt sein.

for x in range(0, 3):
    motorA.run_to_rel_pos(position_sp=300)
    motorB.run_to_rel_pos(position_sp=300)
    time.sleep(1)
    motorA.run_to_rel_pos(position_sp=-200)
    motorB.run_to_rel_pos(position_sp=200)
    time.sleep(1)

Jetzt fehlt nur der obere Teil des Programmes, dort müssen die APIs importiert und die Motoren initialisiert werden.

Sensoren

Im nächsten Schritt wollen wir uns Sensoren anschauen, für den Anfang verwenden wir den Drucksensor. Der Drucksensor ist einfach nur ein Knopf, der gedrückt werden kann. Unser Programm soll warten bis der Drucksensor gedückt wurde und dann ein Ton abspielen.

LabView

Als ersten Block fügen wir einen Warteblock an, bei diesen wählen wir Berührungssensor > Ändern > Zustand. Damit wartet das Programm bis sich der Berührungssensor gedrückt wird, danach läuft es weiter.

Dann fügen wir einen Klangblock ein, dort wählen wir einfach Ton abspielen aus.

grafik

Python

Um Sensoren in Python auszulesen, gehen wir wie mit den Motoren vor, zu ersten definieren wir welcher Sensor an welchen Anschluss sitzt. Diesen können wir dann einer Variable zu weisen. Mit der Variable kann dann gearbeitet werden.

Ein Drucksensor kann z.B. so angestuert werden: touch = ev3.TouchSensor('in1'). Gleichzeitig wird in der Variable touch das Sensor Objekt gespeichert. Um jetzt den Wert des Sensors auszulesen, können wir einfach die Methode touch.value() aufrufen.

Je nach Type von Sensor gibt es weitere Funktionen die entsprechend genauere Werte liefern. Für den Drucksensor gibt es, z.B. sensor.is_pressed() diese gibt einen Wahrheitswert, auch boolean genannt zurück. Ein Wahrheitswert kann true (wahr) oder false(falsch) sein.

Damit wir nun warten können bis der Sensor gedrückt wird, müssen wir uns einen weiteren Schleifentype angucken: Die while Schleife. Eine solche Schleife läuft so lange wie eine bestimmte Wahrheitsbedingung, die bei jedem Durchlauf neu getestet wird, erfüllt ist.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-


import ev3dev.ev3 as ev3

ts = ev3.TouchSensor('in1')
# "not" kehrt den Wert der Bedinung um, in diesen Fall wollen wir,
# dass die Schleife läuft solange, der Knopf nicht gedrückt ist.
while not ts.is_pressed:
    print("Hi")

# So einfach wird ein Klang abgespielt
ev3.Sound.beep()

Das Programm oben gibt so lange Hi in der Konsole aus, bis der Drucksensor an Anschluss 1 gedrückt wurde, dann gibt der Roboter einen beep Ton von sich und das Programm ist beendet.

Sensoren II

Im nächsten Szenario wollen wir, dass unser Roboter mit beiden Motoren gerade aus fährt, bis er gegen eine Wand fährt, dies wird dann vom Drucksensor festgestellt und der Roboter stoppt.

LabView

Zunächst müssen wir eine Helbelsteuerung hinzufügen, bei diesen wählen wir An als Modus aus. Der Helbelsteuerungsblock kann zwei Motoren gleichzeitig steuern.

Als zweites fügen wir wieder einen Warteblock ein, wir warten bis der Sensor gedrückt ist.

Zum Schluss fügen wir wieder eine Helbelsteuerung ein, der beide Motoren stoppt.

grafik

Python

Für die Umsetzung in Python verwenden wir das gleiche Prinzip:

  • Motoren A und B starten
  • Warten bis der Drucksensor gedrückt wird
  • Motoren A und B stoppen

Um Motoren für immer zu starten, müssen diese sich zuerst drehen, dies erreichen wir damit, dass die Motoren für 30 Millisekunden gestartet werden. Während die Motoren noch laufen können wir dann run_forever() aufrufen. Diese Funktion weißt den Motor an, seine aktuelle Geschwindigkeit zu halten, bis wir stop() aufrufen.

#!/usr/bin/env python3

import ev3dev.ev3 as ev3
import time

# initialisierung des Sensors
ts = ev3.TouchSensor('in1')
# initialisierung der Motoren
motorA = ev3.LargeMotor('outA')
motorB = ev3.LargeMotor('outB')

motorA.run_timed(time_sp=30, speed_sp=500)
motorB.run_timed(time_sp=30, speed_sp=500)
motorA.run_forever()
motorB.run_forever()

while not ts.is_pressed:
    # hier warten wir 0.01 sekunden, damit die
    # CPU nicht so stark belastet wird.
    time.sleep(0.01)

# Der Knopf wurde gedrueckt, jetzt stoppen wir die Motoren.
motorA.stop()
motorB.stop()
BrickPi3 In Python müssen wir immer zu erst definieren welcher Sensor an welchen Anschluss ist. Dies machen wir über `BP.set_sensor_type(BP.PORT_1, BP.SENSOR_TYPE.TOUCH)`, `BP.PORT_1` steht wieder für den Anschluss und `BP.SENSOR_TYPE.TOUCH` für den Typ von Sensor den wir benutzen. In diesen Fall ist es ein Drucksensor.

Nachdem wir definiert haben, welcher Sensor wo angeschlossen ist, können wir den Wert der Sensoren über BP.get_sensor(BP.PORT_1) aufrufen.

Dabei gibt es leider nur ein Problem: Es kann passieren, dass ein Fehler auftritt, wenn z.B. der Sensor nicht richtig angeschlossen ist. Dies führt uns zu einem weiteren wichtigen Konzept von Python: Ausnahmen, auch Exceptions genannt. Jede Methode, die wir aufrufen kann eine solche Exception werfen. Wenn wir diese nicht abfangen, stützt das gesamte Programm ab.

Um eine Ausnahme zu fangen verwenden wir try und except:

try:
    # Hier ist der Quelltext, der eine Ausnahme werfen kann
  
except brickpi3.SensorError as error:
    # Hier koennen wir entscheiden wie wir mit den Fehler umgehen
    # wollen, in unserem Fall wollen wir ihn einfach in der Konsole ausgeben
    print(error)

Um jetzt den Wert des Sensors verarbeiten zu können, müssen wir diesen in eine Variable speichern, in einer Variable können Daten für die spätere Verwendung gespeichert werden. In diesen Fall wollen wir natürlich den Wert des Sensors speichern, dies machen wir so:

value = BP.get_sensor(BP.PORT_1)

Mit print() können wir nun sogar den Wert des Sensors ausgeben:

value = BP.get_sensor(BP.PORT_1)
print("Der Wert des Sensors ist {}".format(value))

Zusammengefasst sieh das ganze nun so aus:

try:
    value = BP.get_sensor(BP.PORT_1)
    print("Der Wert des Sensors ist {}".format(value))
except brickpi3.SensorError as error:
    print(error)

Funktionen

Jetzt haben wir die Grundlagen der Python Programmierung gelernt,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment