Praktikum Mikrocontrollerperipherie

Prof. Jürgen Plate

Praktikum Mikrocontrollerperipherie

Aufgabe 2: Programmierung eines teil-autonomen Roboters

Viele kleine, mobile Staubsauger-, Rasenmäher- und Experimentalroboter sind ähnlich aufgebaut. Sie besitzen zwei getrennt motorisierte Antriebsräder vorne und ein Laufrad hinten, wie die folgende, schematische Draufsicht zeigt.

Auch der Experimentalroboter Asuro hat einen entsprechenden Aufbau. Andere Varianten finden sich in den unterschiedlichsten Größen und Bauformen, das Prinzip ist jedoch immer gleich und geht auf noch frühere Experimentalsysteme ohne computersteuerung zurück. Damals bekamen solche System den Gattungsnamen Turtle wegen der schildkrötenartigen Fortbewegung.

Unter http://www.turtlebot.com/ gibt es sogar eine größere Open-Source-Version.

Die Praktikumsaufgabe besteht nun darin, ein Programmpaket für eine solche Turtle zu schreiben. Das Basissystem der Turtle besitzt folgende Eigenschaften:

Um vorwärts oder rückwärts zu fahren, drehen sich beide Räder um den gleichen Winkel bzw. führen die gleiche Anzahl Schritte aus.

Frage 1: Wieviele Schritte muss der Schrittmotor für 1 cm Fahrstrecke machen?

Für Drehungen können die Räder entweder gegenläufig arbeiten ("Drehen auf dem Teller") oder ein Rad bleibt stehen und bildet den Mittelpunkt der Drehung, wie es die folgende Schemazeichnung zeigt:

Frage 2: Wieviele Schritte muss der Schrittmotor für 1° Drehwinkel machen?

Schon in den 80er Jahren des vergangenen Jahrhunderts wurde eine Steuersprache für Turtle-Systeme entwickelt, zunächst auf Basis der Programmiersprache Logo, später in vielen anderen Sprachen. Um den Weg zu verfolgen, hat man den Turtle-Roboter mit einem dicken Stift ausgerüstet, so dass der eine Spur hinterlassen konnten. So gibt es z. B. auch eine aktuelle Python-Bibliothek für Turtle-Grafik auf dem Bildschirm.

Für die Praktikumsaufgabe sollen folgende Befehle implementiert werden:

Da keine reale Hardware existiert, muss für die folgenden Programmieraufgaben eine Simulationsumgebung geschaffen werden. Der Antrieb stützt sich auf eine Funktion:
typedef enum Motor(M1, M2, BOTH) motor_t;
typedef enum Direction (Vor, Rueck) direction_t;

void stepper(motor_t motor, direction_t richtung, unsignet int zentimeter); 
Die Funktion rechnet die Zentimeterangabe in Schritte des Schrittmotors um (abhängig vom Durchmesser des Rades und den Schrittmotordaten). Statt jedoch einen Motor zu treiben gibt die Funktionen den aktuellen Status auf der Standardausgabe aus: Die aktuelle Position muss sich die Funktion zudem für den nächsten Aufruf merken, da fast alle Befehle inkrementell arbeiten. Auf dieser Abstaktionsebene aufsetzend lassen sich die folgenden Aufgaben bearbeiten.

Aufgabe 1: Implementierung der Turtle-Befehle

Schreiben Sie eine Funktion, der einen Turtle-Befehl als zweibuchstabigen String und seine Parameter entgegennimmt, intepretiert und in einen oder mehrere Aufrufe von stepper() umsetzt:

#define NOP -1

typedef unsigned char* befehl_t;

int turtle(befehl_t befehl, int p1, int p2;)
Bei Befehlen mit nur einem Parameter wird p2 mit NOP belegt. Die Funktion prüft, ob es sich um einen zulässigen Turtle-Befehl handelt, führt ihn aus und gibt 0 zurück. Im Fehlerfall gibt die Funktion -1 zurück. Testen Sie diese Funktion ausführlich mit allen in Fragen kommenden Befehlen.

Aufgabe 2: Implementierung einer vorgegebenen Fahrstrecke

Verwenden Sie nun zum Speichern eines Turtle-Befehls eine Structure:

typedef struct 
  {
  befehl_t befehl;
  int p1;
  int p2;
  } turtle_t;
Erweitern Sie Ihr Programm dahingehen, dass es von einer Datei Turtle-Befehle einliest (ein Befehl mit Parametern je Zeile), diese Befehle an den Leerzeichen in Befehlscode und Parameter aufbricht und in einem Array aus o. a. Strukturen speichert.

Schreiben Sie eine Funktion

int do_it(turtle_t *befehle, int anzahl));
die ein solches Array als Parameter hat und die alle im Array befindlichen Befehle abarbeitet, indem sie die Funktion turtle() für jeden Befehl aufruft. Testen Sie diese Funktion ausführlich mit allen in Fragen kommenden Befehlen.

Aufgabe 3: Implementierung eines Rasenmähers

Es ist nun eine rechteckige Fläche vorgegeben, deren linke, untere Ecke die Koordinaten (0 cm, 0 cm) und deren rechte, obere Ecke die Koordinaten (600 cm, 500 cm) hat. Programmieren Sie ein zufälliges Bewegen der Turtle über diese Fläche: Drehen m einen zufälligen Winkel und fahren einer zufälligen Distanz. Sobald der Roboter eine Randbegrenzung erreicht, soll er eine Drehung vollziehen, die ihn zurück auf die Fläche leitet. Legen Sie obere und untere Grenzen für die jeweiligen Zufallswerte für Drehung und Strecke fest.

Um die Effektivität Ihre Algorithmus zu prüfen, legen Sie ein char-Array von 60 x 50 Elementen an, in dem Sie die Anwesenheit der Turtle in einem 10 x 10 cm² großen Planquadrat dokumentieren. Dazu ziehen Sie die X- und Y-Position der Turtle heran. Durch division dieser Werte durch 10 ergibt sich automatisch das Planquadrat. Es wird im Array an der Stelle [Turtle-X-Position/10, Turtle-Y-Position/10] einfach ein '*' eingetragen, bevor die Turtle sich wieder weiter bewegt. Update und Ausgabe des Array können als Erweiterung innerhalb der Funktion stepper() erfolgen.


Copyright © Hochschule München, FK 04, Prof. Jürgen Plate
Letzte Aktualisierung: