Donnerstag, 20. August 2015

Roboter bewegen für Anfänger

Im “Roboter bewegen für Anfänger” Kurs geht es um die Basissoftware des Roboters. In einem Python Skript legen wir den Grundstein für alle folgenden Funktionen und Einsatzbereiche des Roboters. Ich zeige euch Schritt für Schritt was man alles machen muss. Als Ergebnis erhaltet ihr ein Programm über das man den Roboter über die Tastatur wie ein ferngesteuertes Auto steuern kann.


Roboter bewegen für Anfänger


Roboter bewegen für Anfänger


Zugegeben, einen Roboter zu bewegen gehört zu den Paradedisziplinen des Programmierens. Man denke an das Google Driverless Car. Die Entwicklung solcher autonomer Systeme dauert Jahre und wird auf universitärer Ebene oder von großen Konzernen gemacht. Andere tolle Beispiele sind die Marsrover der Nasa. All diese Beispiele zeigen wie es geht.


Bewegungstheorie


Mein Roboter hat 4 Räder, zwei auf jeder Seite. Diese sind fix montiert und können sich nur in zwei Richtungen bewegen. Den Roboter können wir deshalb nicht wie ein Auto steuern, es fehlt die Lenkstange – dafür wäre ein fünfter Motor notwendig. Wir bewegen den Roboter deshalb wie folgt:


  • vorwärts fahren

    alle 4 Räder bewegen sich vorwärts. Das heißt alle 4 Motoren drehen sich in die selbe Richtung. Achtung: So trivial die Bewegung nach vorwärts auch erscheint, solange diese nicht funktioniert bracht man keine andere Bewegung implementieren. Warum? Die 4 Motoren müssen sich in die selbe Richtung bewegen aus der Sicht vom Chassis. Tatsächlich drehen sich die 2 Motoren links genau in die Gegengesetze Richtung als die beiden Motoren rechts, diese sind ja gespiegelt angebracht.

  • rückwärts fahren

    die inverse Bewegung zum Vorwärts fahren. Man muss alle 4 Motoren einfach in die gegenteilige Richtung drehen.

  • Drehung nach links

    Gedreht wird indem sich die Räder rechts und links in unterschiedliche Richtungen bewegen. Die linken bewegen sich rückwärts, die auf der rechten Seite vorwärts. Das Chassis wird gedreht.

  • Drehung nach rechts

    die inverse Bewegung zur Drehung nach links. Die rechten Reifen bewegen sich rückwärts, die Reifen auf der linken Seite vorwärts.

  • Stopp

    alle Motoren stehen still. Das Reset des Programms. Das muss immer als letztes Kommando im Programm ausgeführt werden, sonst kann es passieren, dass der Roboter trotz Programmabbruch weiter fährt.

Software


Meine erste Version der Software basiert auf dem Arduino Skript, dass vom Roboter Chassis Hersteller auf dessen Wiki Seite angeboten wird. Das der Raspberry Pi keine analogen Pins hat funktioniert das Skript nicht exakt gleich, man kann damit den Roboter aber schon sehr gut steuern. Das fertige Skript gibts auch als Download. Der Source Code schaut wie folgt aus:


import RPi.GPIO as GPIO

Wir benötigen lediglich Zugriff auf die GPIO Pins, deshalb wird nur diese Bibliothek eingebunden.


#pins
M1     = 40 #rot
M1_PWM = 37 #gruen
M2_PWM = 38 #gelb
M2     = 36 #weiss
GPIO.setmode(GPIO.BOARD)

GPIO.setup(M1, GPIO.OUT)
GPIO.setup(M1_PWM, GPIO.OUT)
GPIO.setup(M2, GPIO.OUT)
GPIO.setup(M2_PWM, GPIO.OUT)

Wir legen uns Variablen an die wie am Board beschriftet heißen (damit man den Code auch Monate später noch versteht). Ich verwende die 4 letzten Pins des Raspberry Pi Modell B+, ihr könnt natürlich auch beliebig andere GPIO Pins verwenden. Die Verkabelung habe ich im ersten Teil bereits gezeigt. Alle 4 Pins werden als Ausgabepins initialisiert.


Nun wird es spannend. Wir legen 4 Funktionen an für die möglichen Bewegungsarten vorwärts, rückwärts, links und rechts und zusätzlich noch eine Stopp Funktion.


def move():
GPIO.output(M1, True)
GPIO.output(M1_PWM, True)
GPIO.output(M2, True)
GPIO.output(M2_PWM, True)

def reverse():
GPIO.output(M1, False)
GPIO.output(M1_PWM, True)
GPIO.output(M2, False)
GPIO.output(M2_PWM, True)

def left():
GPIO.output(M1, True)
GPIO.output(M1_PWM, True)
GPIO.output(M2, False)
GPIO.output(M2_PWM, True)

def right():
GPIO.output(M1, False)
GPIO.output(M1_PWM, True)
GPIO.output(M2, True)
GPIO.output(M2_PWM, True)

def stop():
GPIO.output(M1, False)
GPIO.output(M1_PWM, False)
GPIO.output(M2, False)
GPIO.output(M2_PWM, False)

def init():
stop()

Bei den Funktionen erkennt man schnell ein Muster. Alle PWM Pins sind immer True. Diese geben die Geschwindigkeit an. Da wir nur digitale Pins haben müssen diese klarerweise Spannung angelegt haben, sonst dreht sich der Motor nicht. Einzig bei der Stopp Funktion wird auf allen 4 Pins die Spannung abgeschaltet. Diese 4 Funktionen bilden die Basis der Bewegung. Wir benötigen jetzt nur noch Code der auf Tastenklick die korrekte Bewegungsfunktion aufruft.


In der ersten Version steuern wir den Roboter über die Tastatur. Über eine SSH Session wird der Code ausgeführt und über die Tasten werden Kommandos gegeben. Die gedrückten Tasten werden in der definierten getch() Funktion von der Tastatur geholt, ihr kennt vielleicht diese getch Funktion von C. Python hat so etwas nicht, deshalb müssen wir uns diese selber schreiben:


def getch():
import sys, tty, termios
old_settings = termios.tcgetattr(0)
new_settings = old_settings[:]
new_settings[3] &= ~termios.ICANON
try:
termios.tcsetattr(0, termios.TCSANOW, new_settings)
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(0, termios.TCSANOW, old_settings)
return ch

Damit sind wir mir der Definition der Variablen und der Funktionen fertig. Das restliche Programm ist recht einfach. Nach der Initialisierung wird in einer Endlosschleife mit getch() die Tastaturabfrage gemacht und abhängig der gedrückten Taste die gewünschte Bewegungsfunktion ausgeführt oder das Programm beendet.


init()
loop = True

_move = 0
_reverse = 0
_left = 0
_right = 0
while loop:
c = getch()
if c == 'a' and _left == 0:
left()
_left = 1
_right = 0
_move = 0
_reverse = 0
if c == 'd' and _right == 0:
right()
_left = 0
_right = 1
_move = 0
_reverse = 0
if c == 'w' and _move == 0:
move()
_left = 0
_right = 0
_move = 1
_reverse = 0
if c == 's' and _reverse == 0:
reverse()
_left = 0
_right = 0
_move = 0
_reverse = 1
if c != 'a' and c != 'd' and c != 'w' and c != 's':
_move = 0
_reverse = 0
_left = 0
_right = 0
stop()
if c == 'q':
loop = False
stop()

GPIO.cleanup()

Ganz wichtig ist die letzte Zeile. Ohne dem cleanup() würden bei Programmabbruch die Motoren munter weiter laufen und der Roboter ohne Rücksicht auf Hindernisse oder Klippen weiter fahren. Ganz schlecht!


Konfiguration


Ob ihr alles richtig verkabelt habt könnt ihr beim ersten Testlauf feststellen. In diesem lasst ihr den Roboter am besten umgedreht nach vorne fahren. Bewegen sich alle 4 Räder in die korrekte Richtung habt ihr schon gewonnen. Falls sich manche Räder falsch bewegen, dann gehören die beiden Kabel vertauscht. Dies ist am Board recht einfach möglich und erfordert keinen großen Aufwand.


Fazit


Den Roboter bewegen ist gar nicht so schwierig. Mit dieser Basissoftware könnt ihr den Roboter nun bereits über die Tastatur manuell bewegen. Das macht richtig Spaß! Das Skript kann man übrigens als Basis für eine spätere autonome Navigation des Roboters nehmen. Durch Sensoren lernt der Roboter seine Umgebung kennen und kann auf Basis dieser Informationen navigieren, aber dazu in einem der nächsten Artikel mehr!


Das Skript ist alles andere als perfekt. Vor allem die Steuerung über die Tastatur funktioniert mit Python recht schlecht. Habt ihr dafür Optimierungen? Vorschläge wie das besser geht?


Teil 1 | Teil 2



Roboter bewegen für Anfänger

Keine Kommentare:

Kommentar veröffentlichen