TigerJython | xx für Gymnasien |
Deutsch English |
Das Verhalten vieler Roboter ist nicht fest einprogrammiert, sondern die Roboter verhalten sich gemäss Informationen, die sie aus einem Speicher, analog einem Gedächtnis, zurück holen. Der Speicher kann entweder durch "Anlernen" mit einen "Teacher" oder durch "Selbstlernen" (Lernen aus eigener Erfahrung) gefüllt werden. In den folgenden Beispielen wird an einfachen Beispielen aufgezeigt, wie ein Roboter durch einen Mensch angelernt wird Dann soll er auch mit Hilfe seiner Sensoren selbst lernen, eine Aufgabe zu erfüllen. |
Beispiel 1: Der Roboter lernt im "Teach-Mode"
Industrierobotern werden in einem "Teach Mode" durch einen Spezialisten (Teacher) "angelernt", beispielsweise welche Armbewegungen durchzuführen sind, um eine bestimmte Arbeit auszuführen. Der Teacher verwendet dabei meist ein Eingabesystem ähnlich einer Fernsteuerung. Dabei wird der Roboter nacheinander in die gewünschten Positionen gefahren und der jeweilige Zustand abgespeichert.
In unserem Beispiel wird der Roboter in der Lernphase mit einem zweiten micro:bit ferngesteuert, um den Weg in einem einfachen Labyrinth zu finden. Da in dieser einfachen Bahn die geraden Wegstücke gleich lang sind und senkrecht auf einander stehen, muss der Teacher den Roboter nur anweisen, ob er links oder rechts abbiegen soll. Er führt die Befehle aus und speichert die Left- bzw. Right-Commandos in der Liste memory. Die Liste ist zu Beginn leer. Beim Erhalt der Message LEFT wird mit dem Befehl memory.append(0) eine 0 , beim Erhalt der Message RIGHT mit memory.append(1) eine 1 hinzugefügt. Ist der Lernprozess abgeschlossen, wird der Roboter zurück an die Startposition versetzt und fährt mit Klick auf den Button A die Strecke selbständig. |
Programm Teacher (micro:bit): | ||
#Mr6a.py from microbit import * import radio radio.on() state = "STOP" oldState = "" while True: if button_a.was_pressed(): state = "LEFT" display.show('L') elif button_b.was_pressed(): state = "RIGHT" display.show('R') else: state = "STOP" display.show('S') if oldState != state: radio.send(state) oldState = state sleep(10) |
|
Programm Roboter: | ||
# Mr6b.html (receiver) from microbit import * from mbrobot import * import radio def fd(): forward() delay(moveTime) stop() def run(): for k in memory: if k == 0: left() delay(turnTime) elif k == 1: right() delay(turnTime) fd() moveTime = 1000 turnTime = 500 radio.on() setSpeed(20) memory= [] while not button_a.was_pressed(): rec = radio.receive() if rec == "LEFT": memory.append(0) left() delay(turnTime) fd() elif rec == "RIGHT": memory.append(1) right() delay(turnTime) fd() else: stop() run() stop() |
|
Erklärungen zum Programmcode:
memory = [] : Die Liste memory ist zu Beginn leer | |
memory.append(0): beim Linksabbiegen wird eine 0 in die Liste hinzugefügt | |
memory.append(1): beim Rechtsabbiegen wird eine 1 hinzugefügt | |
def run(): Definiert unter Verwendung der Liste memory, wie die Bahn abzufahren ist |
Beispiel 2: Der Roboter lernt mit Hilfe seiner Infrarotsensoren, ein einfaches Labyrinth durchzufahren
Mit Hilfe seiner Sensoren lernt der Roboter selbst, eine Bahn mit gleich langen Wegstücken abzufahren. Dabei verfolgt er folgende Strategie: Er beginnt beim Start und fährt vorwärts auf der weissen Bahn, bis er eine schwarze Unterlage detektiert. Danach fährt er eine kurze Strecke zurück, dreht er 90° nach links. Wenn er in den nächsten 2 Sekunden keine schwarze Unterlage "sieht", fährt er weiter bis zur nächsten Kreuzung. Sonst hat er mit Linksdrehen die falsche Richtung gewählt, eine Rechtdrehung wäre richtig. Er dreht also 180° und fährt weiter bis zur nächsten Kreuzung. In der Liste memory speichert er 0 für links und 1 für rechts. Um den Roboter am Ende des Labyrinths zu stoppen, drückt man den Button A auf dem micro:bit. |
|
#Mr6c.py from mbrobot import * from microbit import* import time RobotContext.useBackground("sprites/bg.gif") RobotContext.setStartPosition(310, 460) def run(): for k in memory: print("forward") forward() delay(moveTime) if k == 0: print("left") left() delay(turnTime) elif k == 1: print("right") right() delay(turnTime) forward() delay(moveTime) turnTime = 540 moveTime = 3000 memory = [] startTime = time.clock() forward() while not button_a.was_pressed(): forward() v1 = irLeft.read_digital() v2 = irRight.read_digital() if v1 == 0 or v2 == 0: dt = time.clock() - startTime if dt > 2: backward() delay(300) memory.append(0) left() delay(turnTime) elif memory != []: memory.pop() memory.append(1) left() delay(2 * turnTime) print("Memory: " + str(memory)) forward() startTime = time.clock() stop() while not button_b.was_pressed(): pass print("start") reset() run() |
|
Erklärungen zum Programmcode:
import time : Importiert das Modul time, mit dem man eine Echtzeitmessung vornehmen kann | |
startTime = time.clock(): Aktuelle Zeit | |
dt = time.clock() - startTime : Die Zeit, die seiten seit Beginn der Messung vergangen ist | |
memory.pop(): Da der Roboter zuerst immer links abzubiegen versucht, wird im Memory bereits eine 0 gespeichert. Falls dieser Entschein falsch war, wir der Eintrag wieder gelöscht und mit einer 1 für Rechtsfhren ersetzt | |
reset(): Nur im Simulationsmodus. Der Roboter wird an die Startposition versetzt. Im Realmodus muss reset() gelöscht oder deaktiviert werden |
Beispiel 3: Der Roboter lernt eine Bahn mit beliebig langen Wegstücken durchfahren.
Der Roboter muss nicht nur lernen, wo er links und wo rechts abbiegen soll, sondern er muss sich auch die Zeit, die er braucht, um die geraden Wegstücke zurückzulegen, merken. Zu Beginn jedes Wegstücks startet er einen Timer und misst die Zeit, bis er bei der nächsten Kreuzung ankommt. In seiner Memory-Liste speichert er für jedes Wegstück 2 Werte: Die Fahrzeit in Millisekunden und 0 bzw. 1 für eine Drehung nach links oder rechts. Durch Drücken des Buttons A wird der Roboter am Schluss der Lernphase gestoppt. Durch Drücken des Buttons B fährt er anschliessend die Bahn selbständig ab, indem er die gespeicherten Informationen verwendet. |
Das Programm kann im Simulationsmodus mit dem Hintergrundbild bg2.gif augeführt werden. Im realen Modus muss man die beide Robot.Context-Zeilen und die Zeile reset() deaktivieren.
#Mr6d.py from mbrobot import * from microbit import* import time RobotContext.useBackground("sprites/bg2.gif") RobotContext.setStartPosition(410, 450) def run(): for node in memory: moveTime = node[0] k = node[1] print("forward") forward() delay(moveTime) if k == 0: print("left") left() delay(turnTime) elif k == 1: print("right") right() delay(turnTime) forward() turnTime = 540 moveTime = 0 backTime = 400 memory = [] startTime = time.clock() while not button_a.was_pressed(): forward() v1 = irLeft.read_digital() v2 = irRight.read_digital() if v1 == 0 or v2 == 0: dt = time.clock() - startTime backward() delay(backTime) if dt > 2: moveTime = int(dt * 1000) - backTime node = [moveTime, 0] memory.append(node) left() delay(turnTime) elif memory != []: memory.pop() node = [moveTime, 1] memory.append(node) right() delay(2 * turnTime) print("Memory: " + str(memory)) startTime = time.clock() stop() while not button_b.was_pressed(): pass print("start") reset() run() |
|
Erklärungen zum Programmcode:
moveTime = int(dt * 1000) - backTime : Bestimmt die Fahrzeit für das zurückgelegte Wegstück | |
node = [moveTime, 0]: Fahrzeit für ein Wegstück und 0, bzw, 1 für eine Links- bzw. Rechtsdrehung | |
memory.append(node) : Nach jedem Wegstück werden zwei Werte gespeichert: Memory: [[2706, 0]] |
Aufgaben: |
1) |
|
2) |
Löse die Aufgabe im Simulationsmodus mit dem Hintergrundhild bg3.gif. RobotContext.useBackground("sprites/bg3.gif")
|