Mein zweites Programm

Motoren ansteuern

Um die Motoren des Roboters zu steuern, müssen wir zunächst das entsprechende Python-Modul am Anfang der Datei importieren. Dann können wir Motor.power(port, power) verwenden, um den Motor zu steuern. Dies ist auch ein guter Punkt, um sich mit der Dokumentation vertraut zu machen: Besuchen wir https://lib.comp-air.at/lib/Motor.html#compLib.Motor.Motor.power. Hier werden die beiden relevanten Parameter beschrieben.

Als Beispiel wollen wir den rechten Motor für fünf Sekunden auf volle Geschwindigkeit setzen:

1# motor.py
2import time
3from compLib.Motor import Motor
4
5Motor.power(0, 100)
6time.sleep(5)

Gerade fahren

Um geradeaus zu fahren, müssen wir beide Motoren auf dieselbe Geschwindigkeit einstellen. Aber Achtung! Der rechte Motor muss umgedreht werden! Das liegt daran, dass einer nach rechts und einer nach links zeigt, sie sind also technisch gesehen gespiegelt. Wenn wir nun diesen Code ausführen, wird der Roboter 5 Sekunden lang vorwärts fahren:

1# motor.py
2import time
3from compLib.Motor import Motor
4
5Motor.power(0, -100)
6Motor.power(3, 100)
7time.sleep(5)

Erläuterung

In Zeile 2 wird das python-Paket time importiert. Wir brauchen es später, um auf die Fahrt des Roboters zu warten. Z.B.: time.sleep(5)
In Zeile 3 importieren wir die notwendigen Funktionen aus dem Motor-Modul der compLib.
In Zeile 5 stellen wir den rechten Motor so ein, dass er vorwärts fährt. Da der Motor rückwärts eingebaut ist, müssen wir den Wert auf -100 setzen.
In Zeile 6 stellen wir den linken Motor auf Vorwärtsfahrt ein. Hier können wir den Wert 100 verwenden, da der Motor in der richtigen Richtung eingebaut ist.
In Zeile 7 müssen wir warten, bis der Roboter die Fahrbefehle tatsächlich ausführt. In diesem Fall warten wir 5 Sekunden lang.

Danach wird das Programm beendet und der Roboter bleibt stehen.

Mehr fahren

Jetzt ist es Zeit für einige komplexere Bewegungen. Um unseren Code modular und leicht lesbar zu halten, werden wir jede Aktion in eine eigene Funktion packen.

1import time
2from compLib.Motor import Motor
3
4def driveForward():
5    Motor.power(0, -100)
6    Motor.power(3, 100)
7    time.sleep(2)

In Zeile 4 definieren wir die Funktion driveForward(), die den Roboter mit voller Geschwindigkeit zwei Sekunden vorwärts bewegt.

Jetzt werden wir eine Funktion für das Rückwärtsfahren definieren:

 1import time
 2from compLib.Motor import Motor
 3
 4def driveForward():
 5    Motor.power(0, -100)
 6    Motor.power(3, 100)
 7    time.sleep(2)
 8
 9def driveBackward():
10    Motor.power(0, 100)
11    Motor.power(3, -100)
12    time.sleep(2)

In Zeile 9 haben wir die Funktion driveBackward() definiert, die den Roboter zwei Sekunden lang rückwärts fahren lässt.

Jetzt können wir diese beiden Funktionen aufrufen und vorwärts und dann wieder rückwärts fahren:

 1import time
 2from compLib.Motor import Motor
 3
 4def driveForward():
 5    Motor.power(0, -100)
 6    Motor.power(3, 100)
 7    time.sleep(2)
 8
 9def driveBackward():
10    Motor.power(0, 100)
11    Motor.power(3, -100)
12    time.sleep(2)
13
14driveForward()
15driveBackward()

Wenn wir diesen Code ausführen, sollte der Roboter zunächst zwei Sekunden vorwärts und dann wieder zwei Sekunden rückwärts fahren und ungefähr an der gleichen Position wie beim Start anhalten.

Zwischen den Zeilen 14 und 15 brauchen wir kein time.sleep(2), da der sleep-Befehl bereits in den Funktionen integriert ist.

Jetzt wollen wir, dass der Roboter erst vorwärts fährt, dann zwei Sekunden stillsteht und dann wieder rückwärts in seine Ausgangsposition fährt.

 1import time
 2from compLib.Motor import Motor
 3
 4def driveForward():
 5    Motor.power(0, -100)
 6    Motor.power(3, 100)
 7    time.sleep(2)
 8
 9def driveBackward():
10    Motor.power(0, 100)
11    Motor.power(3, -100)
12    time.sleep(2)
13
14driveForward()
15time.sleep(2)
16driveBackward()

Wenn wir den obigen Code ausführen, bleibt der Roboter nicht zwei Sekunden lang stehen, sondern fährt nach der Funktion driveForward() noch zwei Sekunden lang weiter. Warum passiert das? Um das zu verstehen, müssen wir wie der Roboter denken!

Erläuterung

1. (Zeile 14) Die Funktion Vorwärtsfahrt wird aufgerufen
(Zeile 5) Motor 1 wird auf -100 gesetzt
(Zeile 6) Motor 4 wird auf 100 gesetzt
(Zeile 7) Zwei Sekunden warten und Motor 1 mit der Geschwindigkeit -100 und Motor 4 mit der Geschwindigkeit 100 bewegen (z.B. vorwärts fahren)
2. (Zeile 15) Zwei Sekunden warten, die Motoren sind immer noch auf -100 und 100 eingestellt, also fahren wir weiter vorwärts
3. (Zeile 16) Die Funktion Rückwärtsfahren wird aufgerufen
(Zeile 5) Motor 1 wird auf 100 gesetzt
(Zeile 6) Motor 4 wird auf -100 gesetzt
(Zeile 7) Warte zwei Sekunden und bewege Motor 1 mit der Geschwindigkeit 100 und Motor 4 mit der Geschwindigkeit -100 (z.B. Rückwärtsfahren)
4. Das Programm ist beendet, und alle Motordrehzahlen werden auf 0 gesetzt.

Wir sehen also, dass wir die Motoren nach der Vorwärts- oder Rückwärtsfunktion wieder auf Geschwindigkeit 0 setzen müssen, wenn wir den Roboter anhalten wollen. Für diesen Anwendungsfall können wir eine neue Funktion stopMotors() schreiben, die die Geschwindigkeit für Motor 0 und 3 auf 0 setzt:

 1import time
 2from compLib.Motor import Motor
 3
 4def driveForward():
 5    Motor.power(0, -100)
 6    Motor.power(3, 100)
 7    time.sleep(2)
 8
 9def driveBackward():
10    Motor.power(0, 100)
11    Motor.power(3, -100)
12    time.sleep(2)
13
14def stopMotors():
15    Motor.power(0, 0)
16    Motor.power(3, 0)

Wenn wir nun vorwärts fahren, dann zwei Sekunden warten und dann wieder rückwärts fahren wollen, können wir die Funktionen wie folgt aufrufen:

 1import time
 2from compLib.Motor import Motor
 3
 4def driveForward():
 5    Motor.power(0, -100)
 6    Motor.power(3, 100)
 7    time.sleep(2)
 8
 9def driveBackward():
10    Motor.power(0, 100)
11    Motor.power(3, -100)
12    time.sleep(2)
13
14def stopMotors():
15    Motor.power(0, 0)
16    Motor.power(3, 0)
17
18driveForward()
19stopMotors()
20time.sleep(2)
21driveBackward()

Und endlich bekommen wir die Bewegung, die wir uns wünschen.

More Optimizations

Während der Code für sehr einfache Bewegungen funktioniert, wollen wir normalerweise nicht, dass unsere Funktionen entscheiden, wie lange wir vorwärts fahren. Vielleicht müssen wir manchmal vier Sekunden vorwärts fahren, und manchmal nur eine Sekunde.

Nehmen wir an, wir wollen vier Sekunden vorwärts fahren. Wir wissen, dass driveForward() den Roboter zwei Sekunden vorwärts bewegen wird. Also können wir die Funktion einfach zwei Mal aufrufen!

 1import time
 2from compLib.Motor import Motor
 3
 4def driveForward():
 5    Motor.power(0, -100)
 6    Motor.power(3, 100)
 7    time.sleep(2)
 8
 9driveForward()
10driveForward()

Was aber, wenn wir uns nur eine Sekunde vorwärts bewegen wollen? Oder vielleicht drei Sekunden? Mit der Funktion driveForward() können wir das im Moment nicht machen.

Stattdessen werden wir die Funktion so umschreiben, dass sie einen Parameter akzeptiert, der die Zeit angibt.

1import time
2from compLib.Motor import Motor
3
4def driveForward(seconds):
5    Motor.power(0, -100)
6    Motor.power(3, 100)
7    time.sleep(seconds)
8
9driveForward(3)

Und mit dieser neuen Funktion können wir drei Sekunden lang vorwärts fahren. Wie funktioniert das nun?

In Zeile 4 definieren wir die Funktion driveForward und sagen, dass sie einen Parameter seconds benötigt. Dieser Parameter ist im Grunde eine Variable, die wir uns zum Zeitpunkt der Definition wie einen Platzhalter vorstellen können. Wenn wir die Funktion definieren, wissen wir noch nicht, welchen Wert seconds haben wird.

Später in Zeile 9, wenn wir die Funktion aufrufen, übergeben wir den Wert 3 an die Funktion und unser Platzhalter seconds wird den Wert 3 haben. Der Roboter wird also drei Sekunden vorwärts fahren.

Vielleicht wollen wir auch, dass der Roboter mit verschiedenen Geschwindigkeiten fahren kann. Wir können also einen weiteren Parameter mit dem Namen speed anlegen. Dann werden wir ein Programm schreiben, das den Roboter drei Sekunden mit voller Geschwindigkeit und dann fünf Sekunden mit halber Geschwindigkeit fahren lässt.

 1import time
 2from compLib.Motor import Motor
 3
 4def driveForward(seconds, speed):
 5    Motor.power(0, -speed)
 6    Motor.power(3, speed)
 7    time.sleep(seconds)
 8
 9driveForward(3, 100)
10driveForward(5, 50)

In Zeile 9 wird der Platzhalter seconds auf 3 und die Geschwindigkeit auf 100 gesetzt. In Zeile 10 wird der Platzhalter seconds auf 5 und die Geschwindigkeit auf 50 gesetzt.

Bewährte Praktiken Nun werden wir uns einige weitere Optimierungen und bewährte Verfahren ansehen.

1. Wir sollten den Schlafbefehl nicht in die Fahrfunktion einbauen.

Wir haben das bis jetzt getan, um ein Gefühl dafür zu bekommen, wie Funktionen funktionieren, und der Einfachheit halber. Später, wenn Sie anfangen, komplexere Programme zu schreiben, sollten Sie dies vermeiden.

Das Beispiel von oben, in dem wir vorwärts und rückwärts gefahren sind und zwei Sekunden gewartet haben, sollte also wie folgt aussehen:

 1import time
 2from compLib.Motor import Motor
 3
 4def driveForward(speed):
 5    Motor.power(0, -speed)
 6    Motor.power(3, speed)
 7
 8def driveBackward(speed):
 9    Motor.power(0, speed)
10    Motor.power(3, -speed)
11
12def stopMotors():
13    Motor.power(0, 0)
14    Motor.power(3, 0)
15
16driveForward(100)   # Set the motors to forward
17time.sleep(2)       # Let the robot drive for 2 seconds
18stopMotors()        # Now stop the robot
19
20time.sleep(2)       # Wait another 2 seconds, robot is not moving
21
22driveBackward(100)  # Now set the motors to a backwards speed
23time.sleep(2)       # Let the robot continue driving for 2 seconds
24stopMotors()        # And finally stop it again

Warum ist das so wichtig?

Normalerweise schlafen wir nicht sehr viel und führen in dieser Zeit andere Verarbeitungen durch. Zum Beispiel könnten wir ein Bild von der Kamera verarbeiten oder die IR-Sensoren auslesen. Wenn wir also eine Funktion wie driveForward() aufrufen, können wir davon ausgehen, dass sie im Hintergrund abläuft und wir andere Aufgaben erledigen, während sich der Roboter bewegt, anstatt nur darauf zu warten, dass er fertig wird.

2. Fahren Sie nicht zu langsam.

Wenn du die Fahrgeschwindigkeit auf eine sehr kleine Zahl einstellst, kann es sein, dass sich der Roboter gar nicht mehr bewegt, weil die Motoren eine bestimmte Menge an Energie benötigen, um den Roboter überhaupt zu bewegen.

3. Fahren Sie nicht zu schnell.

Wenn du die Fahrgeschwindigkeit auf eine sehr hohe Zahl einstellst (z. B. 100), könnte dein Roboter zu schnell für seine Sensoren sein. Dies wird später wichtig sein, wenn wir versuchen, eine schwarze Linie zu erkennen, aber zu schnell über sie fahren.