Der BoE-Shield Bot Arduino lässt sich so programmieren, dass er verschiedene Grundbewegungen ausführt:
vorwärts,
rückwärts,
Drehung nach links,
Drehung nach rechts und
Drehung auf der Stelle.
Wenn wir von Bewegungen sprechen, muss zuerst geklärt werden, was wir damit genau meinen. Es wird vereinbart, dass wir von oben auf den Robot herabschauen (im Bild ist ein BoE-Shield Bot mit einem Arduino UNO zu sehen). Das Steckbrett und das Heckrad (die kleine Kugel) beschreiben, wo vorne und wo hinten ist. Alles Weitere ist uns eigentlich bekannt.
Ein Roboter kann vorwärts und rückwärts fahren, nach links oder rechts abbiegen und er kann um die linke oder rechte Achse drehen. Letzteres heißt, die Drehachse bleibt am Platz und der Robot dreht um das feststehende Rad.
Je nachdem, von welcher Seite man sich den Robot anschaut, stellt man fest, wenn er sich vorwärts bewegt, dann dreht das eine Rad im Uhrzeigersinn und das andere gleichzeitig gegen den Uhrzeigersinn. Das sollte für uns keine Hürde sein, da wir inzwischen wissen, wie man mit dem writeMicroseconds-Befehl ein Rad links oder rechts herum drehen lässt und seine Geschwindigkeit verändert.
Programmbeispiel
Aufgaben |
|
Das Programm - Servo_vorw3sec
Wie arbeitet das Programm?
In einem ersten Schritt wird die Bibliothek Servo eingebunden, damit das Programm auf zusätzliche Funktionen zugreifen kann:
#include <Servo.h>
Im folgenden Schritt wird eine Instanz von Servo deklariert mit einem eindeutigen Namen für jedes der beiden Antriebsräder.
Servo servoLinks; Servo servoRechts;
Instanz eines Objektes
Ein Objekt ist ein Block von geschriebenem Programmcode, der kopiert und in einem Programm beliebig oft aufgerufen werden kann. Jede Kopie, die man auch Instanz nennt, lässt sich beliebig verändern. Die beiden Servo Deklarationen servoLinks und servoRechts erzeugen zwei Instanzen des Objektcodes. Die Funktionen innerhalb der beiden Instanzen lassen sich unabhängig voneinander verändern und aufrufen. ServoLinks.attach(13) konfiguriert die servoLinks Objektinstanz, die Steuersignale an P13 zu übertragen, während servoRechts.attach(12) der servoRechts Objektinstanz mitteilt, die Signale an P12 zu senden.
Ein Sketch beginnt immer mit der setup-Methode. Der dort befindliche Programmcode wird einmal abgearbeitet bevor es dann weiter geht mit einer Endlosschleife der Methode loop. Wir wollen diesmal nur erreichen, dass der BoE-Shield Bot Arduino drei Sekunden geradeaus fährt und dann stehenbleibt. Deshalb packen wir den Programmcode in die Methode setup und lassen loop leer.
Die servoLinks Objektinstanz ist mit P13 verbunden, servoRechts mit P12. Der Aufruf von servoLinks.writeMicroseconds betrifft deshalb die Servo Steuersignale, die an P13 gesendet werden, entsprechend gilt für servoRechts.writeMicroseconds, dass die Steuersignale an P12 übertragen werden.
servoLinks.attach(13); servoRechts.attach(12);
Erinnern wir uns; um geradeaus zu fahren, müssen die Räder des Roboters gegenläufig drehen. Der Funktionsaufruf servoLinks.writeMicroseconds(1700) lässt den linken Servo mit full-speed entgegen dem Uhrzeigersinn drehen, während servoRechts.writeMicroseconds(1300) den rechten Servo full-speed im Uhrzeigersinn dreht, mit dem Ergebnis, dass der BoE-Shield Bot geradeaus vorwärts fährt. Die Funktion delay(3000) sorgt dafür, dass die Servos drei Sekunden laufen. Anschließend unterbrechen die Funktionen servoLinks.detach und servoRechts.detach die Signalübertragung und bringen den Roboter zum Stehen.
servoLinks.writeMicroseconds(1700); servoRechts.writeMicroseconds(1300); delay(3000); servoLinks.detach(); servoRechts.detach();
Sind alle Programmzeilen der Methode setup abgearbeitet, geht das Programm automatisch zur Methode loop weiter. Da steht aber nichts drin und das wird ständig wiederholt.
void loop() { }
Jetzt kommst du! - Den zurückgelegten Weg verändern
Soll der zurückgelegte Weg eines Roboters verändert werden, dann muss nur die Zeit im Befehl delay(3000) angepasst werden. Ein Wert von 1500 halbiert die zurückgelegte Wegstrecke, 9000 verdreifacht sie.
Andere Bewegungen als die Geradeausfahrt mit einem Roboter lassen sich über verschiedene Kombinationen der Parameter in den Befehlen servoLinks und servoRechts writeMicroseconds herstellen. Das folgende Beispiel lässt den BoE-Shield Bot rückwärts fahren.
servoLinks.writeMicroseconds(1300); servoRechts.writeMicroseconds(1700);
Die folgenden beiden Befehle lassen den Roboter am Platz eine Linksdrehung vollführen.
servoLinks.writeMicroseconds(1300); servoRechts.writeMicroseconds(1300);
Entsprechend sehen die Befehle für eine Rechtsdrehung am Platz wie folgt aus:
servoLinks.writeMicroseconds(1700); servoRechts.writeMicroseconds(1700);
Wir packen alle eben angesprochenen Befehle in ein Programm und lassen den Roboter vorwärts fahren, eine Rechts- und Linksdrehung vollführen und rückwärts fahren.
Programmbeispiel
Zusätzlich zu den Drehungen am Platz kann der Roboter auch Drehungen um ein Rad (nach rechts oder links) ausführen. Der Trick dabei ist, dass das Rad, um das gedreht werden soll, still steht, während das andere weiterdreht. Die folgenden vier Beispiele zeigen Drehungen um das rechte und linke Rad bei Vorwärts- und Rückwärtsfahrt.
//Drehung vorwärts um linkes Rad
servoLinks.writeMicroseconds(1500); servoRechts.writeMicroseconds(1300);
//Drehung vorwärts um rechtes Rad
servoLinks.writeMicroseconds(1700); servoRechts.writeMicroseconds(1500);
//Drehung rückwärts um linkes Rad
servoLinks.writeMicroseconds(1500); servoRechts.writeMicroseconds(1700);
//Drehung rückwärts um rechtes Rad
servoLinks.writeMicroseconds(1300); servoRechts.writeMicroseconds(1500);
Aufgaben |
|
Setze im Programm Servo_vorw3sec.ino den delay-Befehl von 3000 auf 10000 hoch und speichere das Programm als Servo_vorw10sec ab. Lass den Roboter parallel zu einer geraden Kante fahren und beobachte, ob er vom Kurs nach rechts oder links abweicht.
Weicht er nach links ab, dreht sich das rechte Rad schneller; der Parameter Zeit in der Funktion servoRechts.writeMicroseconds muss dann näher an den Wert 1500 heranrücken. Probiere es aus. Bei einer Abweichung nach rechts dreht sich das linke Rad zu schnell und muss langsamer werden. Auch hier ist wie bei der Linksabweichung vorzugehen.
Drehungen werden über die delay-Funktion gesteuert. Da ein Steuerimpuls immer eine Länge von 20ms hat, reicht es, wenn die Zeitwerte der delay-Funktion Vielfache von 20ms sind.
Die Theorie hierzu wurde bereits in Der BoE-Bot BASIC Stamp - Navigation besprochen. Zur Bestimmung der Geschwindigkeit des BoE-Shield Bot Arduino nehmen wir einen Zollstock und lassen den Roboter eine Sekunde lang geradeaus parallel zum Zollstock laufen.
Aufgaben |
|
Das Programm
In vielen Roboterwettbewerben führt eine präzisere Roboternavigation am Ende auch zu einer besseren Platzierung. Ein sehr populärer Eingangswettbewerb ist die Koppelnavigation, bei der ein Roboter verschiedene Ziele anlaufen muss und am Ende zum Startpunkt zurückkehrt. Je genauer er den Startpunkt bei der Rückkehr trifft, um so höher sind die Siegchancen.
Bei einer gleichförmigen Bewegung erhält man, wenn man die Geschwindigkeit v durch die Entfernung s zu einem Objekt teilt, die Zeit t, die benötigt wird, um zum Objekt zu gelangen. Die Formel dazu lautet:
Für den BoE-Shield Bot Arduino berechnet sich die Laufzeit dann nach Formel (4) zu
Meine Messungen
Die mittlere Geschwindigkeit meines Roboters liegt bei cm pro sec
Mit dem sogenannten ramping wird die Geschwindigkeit eines Servos langsam hoch- bzw. heruntergefahren, statt sie abrupt starten und stoppen zu lassen. Damit erhöhen sich die Lebensdauern von Servos und Batterien.
Erzielt wird dieser Effekt über eine FOR...-Schleife, in der die Geschwindigkeit bei jedem Schleifendurchlauf um einen bestimmten Betrag erhöht wird, bis die maximale Geschwindigkeit erreicht ist. Erinnern wir uns, die Geschwindigkeit eines Roboters wird über die Funktion writeMicroseconds eingestellt. Erhöht man die Geschwindigkeit bei jedem Schleifendurchlauf um 2, dann benötigt man 100 Durchläufe um von 1500 auf 1700µs zu kommen.
for (int speed = 0; speed <= 100; speed+=2) { servoLinks.writeMicroseconds(1500+speed); servoRechts.writeMicroseconds(1500-speed); delay(20); }
Bei einer Pause von 20ms pro Schleifendurchlauf, wird die Schleife pro Sekunde 50 mal durchlaufen; die Variable speed hat sich in dieser Zeit von 0 auf 100 erhöht und beide Servos laufen nach einer Sekunde mit maximaler Geschwindigkeit.
Programmbeispiel Start/Stop mit ramping
Programmbeispiel Rückwärtsfahrt mit ramping
Der Unterschied zum vorherigen Beispiel ist, dass der Wert der Variablen speed bei 0 startet und bis -100 herunterzählt.
for (int speed = 0; speed >= -100; speed -= 2) { servoLinks.writeMicroseconds(1500+speed); servoRechts.writeMicroseconds(1500-speed); delay(20); }
Programmbeispiel Drehen mit ramping
In diesem Beispiel wird das ramping für eine Rechtskurve beschrieben. Bei einer Linkskurve müsste das Argument für writeMicroseconds geändert werden in 1500 - speed.
for (int speed = 0; speed <= 100; speed += 2) { servoLinks.writeMicroseconds(1500+speed); servoRechts.writeMicroseconds(1500+speed); delay(20); } for (int speed = 100; speed >= 0; speed -= 2) { servoLinks.writeMicroseconds(1500+speed); servoRechts.writeMicroseconds(1500+speed); delay(20); }