Braitenberg Lösung

Aus microbit - Das Schulbuch
Zur Navigation springen Zur Suche springen

Grundsätzliche Überlegungen

Für dieses Beispiel sind folgende Ideen wichtig:

  • Was sind Ereignisse und welche gibt es beim micro:bit?
  • Wie funktionieren Abfragen und wie können damit Vergleiche verwendet werden?
  • Wie lese ich analoge Werte von Sensoren am BBC micro:bit ein? Welche Wertebereiche haben die Sensoren?
  • Wie kann ich Motoren mit dem BBC micro:bit ansteuern? Mit welchen minimalen und maximalen Geschwindigkeiten kann ich die Motoren betreiben?

Tipps und Tricks

Beim Starten des Programms, was müssen wir alles festlegen?
Denke immer daran: Sicherheit geht vor - alle Variablen initialisieren, d.h. auf einen vernünftigen Startwert setzen und - vor allem bei Robotern - einmal alle Motoren ausschalten. <spoiler>Wichtig ist es zur Sicherheit einmal die Motoren auszuschalten. Dann sollten wir auch die Variable mit der wir Start/Stopp regeln wollen auf den Stopp-Wert setzen und auch die Geschwindigkeiten einmal für den Anfang auf 0.</spoiler>
Wie können wir nun das Starten und Stoppen des Roboters mit den Tasten A und B bewerkstelligen?
Wenn wir in der Hauptschleife "Dauerhaft" immer prüfen, ob eine bestimmte Variable gesetzt ist, bevor wir echte Geschwindigkeiten an die Motoren ausgeben, müssen wir nur beim Drücken von A oder B diese Variable auf die richtigen Werte setzen.
Wenn das Programm läuft, muss nur noch die Lichtstärke dauerhaft abgefragt, umgerechnet und an die Motoren ausgegeben werden.
Das ist etwas trickreich und kann nacheinander oder in einer einzigen Anweisung gemacht werden. Nacheinander heißt das zB
  • Speichere den Wert des rechten Sensors, den du von Pin 1 einliest (oder wo auch immer der Sensor verbunden ist!) in die Variable für den rechten Sensor
  • Rechne den Wert auf den prinzipiell richtigen Bereich um. <spoiler>Damit ist gemeint, wenn der Sensor zB Werte von 0 bis 1023 zurückgibt, den Motor aber nur Werte von 0 bis 100 erlaubt, dann dividieren wir den Sensorwert einmal durch 10.</spoiler>
  • Prüfe ob der Wert in einem gültigen Bereich ist, um damit den Motor anzusteuern. <spoiler>Da gibt es einen coolen Befehl, der alles auf einmal macht: Mathematik -> Minimal (damit nimmt der micro:bit den kleineren der beiden Werte)</spoiler>
  • Setze die Motorgeschwindigkeit des richtigen (je nach gewünschtem Verhalten) Motors auf diesen Wert, wenn er fahren soll.
Das sieht dann alles nacheinander zB so aus: <spoiler text="Lösung">

basic.forever(function () {

   SpeedR = pins.analogReadPin(AnalogPin.P1)
   SpeedR = SpeedR / 10
   SpeedR = Math.min(SpeedR, 100)
   if (Go) {
       kitronik_motor_driver.motorOn(kitronik_motor_driver.Motors.Motor1, kitronik_motor_driver.MotorDirection.Reverse, SpeedR)
   } else {
       kitronik_motor_driver.motorOff(kitronik_motor_driver.Motors.Motor1)
   }

})

</spoiler>

Mache das gleiche dann für den linken Sensor nochmal!

Komplettlösungen

Beim Starten des Programms, was müssen wir alles festlegen?
Eine mögliche Lösung für den Start? <spoiler text="Lösung">

let SpeedL = 0 let SpeedR = 0 let Go = false kitronik_motor_driver.motorOff(kitronik_motor_driver.Motors.Motor1) kitronik_motor_driver.motorOff(kitronik_motor_driver.Motors.Motor2) basic.showIcon(IconNames.Happy) </spoiler>

Wie können wir nun das Starten und Stoppen des Roboters mit den Tasten A und B bewerkstelligen?
Eigentlich muss ja nur die entsprechende Variable gesetzt werden ... <spoiler text="Lösung">

input.onButtonPressed(Button.A, function () { Go = true }) input.onButtonPressed(Button.B, function () { Go = false }) </spoiler>

Wenn das Programm läuft, muss nur noch die Lichtstärke dauerhaft abgefragt, umgerechnet und an die Motoren ausgegeben werden.

Lichtfolger

Das sieht im einfachsten Fall für einen Roboter, der auf das Licht zufährt, so aus: <spoiler text="Lösung">

basic.forever(function () {

   SpeedR = Math.min(pins.analogReadPin(AnalogPin.P1) / 10, 100)
   SpeedL = Math.min(pins.analogReadPin(AnalogPin.P2) / 10, 100)
   if (Go) {
       kitronik_motor_driver.motorOn(kitronik_motor_driver.Motors.Motor1, kitronik_motor_driver.MotorDirection.Reverse, SpeedR)
       kitronik_motor_driver.motorOn(kitronik_motor_driver.Motors.Motor2, kitronik_motor_driver.MotorDirection.Reverse, SpeedL)
   } else {
       kitronik_motor_driver.motorOff(kitronik_motor_driver.Motors.Motor1)
       kitronik_motor_driver.motorOff(kitronik_motor_driver.Motors.Motor2)
   }

})

</spoiler>

Lichtflüchter

Und für einen Roboter, der vor dem Licht flüchtet so: <spoiler text="Lösung">

basic.forever(function () {

   SpeedL = Math.min(pins.analogReadPin(AnalogPin.P1) / 10, 100)
   SpeedR = Math.min(pins.analogReadPin(AnalogPin.P2) / 10, 100)
   if (Go) {
       kitronik_motor_driver.motorOn(kitronik_motor_driver.Motors.Motor1, kitronik_motor_driver.MotorDirection.Reverse, SpeedR)
       kitronik_motor_driver.motorOn(kitronik_motor_driver.Motors.Motor2, kitronik_motor_driver.MotorDirection.Reverse, SpeedL)
   } else {
       kitronik_motor_driver.motorOff(kitronik_motor_driver.Motors.Motor1)
       kitronik_motor_driver.motorOff(kitronik_motor_driver.Motors.Motor2)
   }

})

</spoiler>

Vielleicht sollte bei dem Lichtflüchter dann auch ein anderes Symbol am Bildschirm ausgegeben werden, damit man die Modelle leichter unterscheiden kann, wie zB <spoiler text="Lösung">

let SpeedL = 0 let SpeedR = 0 let Go = false kitronik_motor_driver.motorOff(kitronik_motor_driver.Motors.Motor1) kitronik_motor_driver.motorOff(kitronik_motor_driver.Motors.Motor2) basic.showIcon(IconNames.Sad)

</spoiler>