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
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)
Zeile 3
importieren wir die notwendigen Funktionen aus dem Motor
-Modul der compLib.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.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.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
Zeile 14
) Die Funktion Vorwärtsfahrt wird aufgerufenZeile 5
) Motor 1 wird auf -100 gesetztZeile 6
) Motor 4 wird auf 100 gesetztZeile 7
) Zwei Sekunden warten und Motor 1 mit der Geschwindigkeit -100 und Motor 4 mit der Geschwindigkeit 100 bewegen (z.B. vorwärts fahren)Zeile 15
) Zwei Sekunden warten, die Motoren sind immer noch auf -100 und 100 eingestellt, also fahren wir weiter vorwärtsZeile 16
) Die Funktion Rückwärtsfahren wird aufgerufenZeile 5
) Motor 1 wird auf 100 gesetztZeile 6
) Motor 4 wird auf -100 gesetztZeile 7
) Warte zwei Sekunden und bewege Motor 1 mit der Geschwindigkeit 100 und Motor 4 mit der Geschwindigkeit -100 (z.B. Rückwärtsfahren)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.