Mit den beiden Schaltkreisen kann der Roboter unter verschiedenen Lichtbedingungen arbeiten. Es fehlt jetzt nur noch ein entsprechendes Programm, das die Fähigkeiten der Fototransistoren zur Navigation ausnutzt. Mit
if(tLinks > 2500) ...
funktioniert eine solche Navigation relativ schlecht bis überhaupt nicht. Wann etwas dunkler oder heller ist im Vergleich hängt immer auch von den Gegebenheiten ab und die ändern sich von Ort zu Ort. Die Festlegung auf Zahlenwerte ist deshalb nicht zielführend.
Wir konzentrieren uns auf den Differenzwert der beiden Sensoren. Der Roboter wird dann in die Richtung mit mehr oder weniger Licht weiterfahren, je nachdem, was gewünscht ist.
Die Lösung erfolgt über den normalisierten differentiellen Schatten (zero justified normalized differential shade) und ist definiert durch
Alle drei Formeln drücken das gleiche aus. Wir werden zur Interpretation die Formel (3) benutzen und im Programm die Formel (2); der zugrundeliegende Algorithmus nach (3) ergibt einen Wertebereich zwischen -100% und +100% und ist leicht zu interpretieren.
Wenn es auf der linken Seite des Roboters ein wenig heller als auf der rechten ist (tLinks < tRechts), ergibt sich nach (3) ein Wert von +20 oder ähnlich. Ist das Licht auf der rechten Seite heller (tLinks > tRechts, ergibt sich vielleicht ein Wert von -50. Mit diesen Werten lassen sich die Servos leicht so steuern, dass der Roboter in den helleren oder dunkleren Bereich steuert, je nachdem was gewünscht ist. Zur Ansteuerung der Servos halten wir fest
Der Prozentwert diff f ist positiv, wenn die Lichtquelle auf der linken Seite ist
Der Prozentwert diff f ist negativ, wenn die Lichtquelle auf der rechten Seite ist.
Die Formel nach (2) hat einen Wertebereich zwischen -0,5 und +0,5. Die negativen Werte stehen für die Erkenntnis, dass die Lichtquelle auf der rechten Seite und positive Werte, dass sie auf der linken Seite des Roboters steht. Im Programm sieht das dann so aus:
float ndSchatten;
ndSchatten = tRechts / (tLinks + tRechts) - 0.5;
Das Ergebnis wird in der Variablen ndSchatten abgelegt. Es können folgende Situationen eintreten
Wir werden das jetzt austesten und dazu die Werte für tLinks, ndSchatten und tRechts im Terminalfenster anzeigen lassen. So bekommt man ein Gefühl dafür, was das Programm macht.
Aufgaben |
|
Eine Möglichkeit, den BoE Bot Arduino in Richtung einer Lichtquelle laufen zu lassen ist, ihn vom Schatten wegzuführen. Dazu bietet sich im Programm die Variable ndSchatten an. Je größer der Unterschied zwischen den Lichthelligkeiten auf beiden Seiten des Roboters ist, umso stärker soll die Ausweichbewegung ausfallen.
Entscheidungen bei einer schattendefinierten Navigation
Mit einer if...else Anweisung starten wir. Wenn ndSchatten > 0.0 ist, steht die Lichtquelle auf der linken Seite des Roboters, die Geschwindigkeit des linken Antriebsrades wird verringert und der Roboter dreht sich aus dem Schattenbereich hin zur helleren Seite. Um das ausführen zu können, werden zwei Variable, speedLinks und speedRechts vom Typ int, eingeführt. Die neue Geschwindigkeit des linken Rades errechnet sich über
int speedLinks, speedRechts; if (ndSchatten > 0.0) { speedLinks = int(200 - ndSchatten * 1000.0); speedLinks = constrain(speedLinks, -200, 200); speedRechts= 200; }
In Abbildung 3 wird am Beispiel von ndSchatten = 0.125 gezeigt, wie der Roboter arbeitet. Das linke Rad dreht langsamer:
speedLinks = int(200.0 - 0.125 x 1000) = 75,
während das rechte Rad mit speedRechts = 200 mit höchster Geschwindigkeit weiterdreht.
Je größer der Wert von ndSchatten wird, desto mehr wird von 200 subtrahiert und es kann passieren, dass die Differenz unter den Wert von -200 fällt. Im Abschnitt BoE-Bot-Shield Arduino - Funktionsaufrufe haben wir mit der Funktion bewegung(int vLinks, int vRechts, int msZeit) den Geschwindigkeitsbereich zwischen -200 und +200 eingeschränkt. Um das weiterhin zu gewährleisten wird die Funktion constrain benutzt, die dafür sorgt, dass speedLinks den Bereich von -200 bis 200 nicht verlässt.
Das else-Statement kümmert sich um die zweite Variante, die Lichtquelle steht auf der rechten Seite und ndSchatten ist kleiner als Null. Das Programm sorgt jetzt dafür, dass das rechte Rad langsamer wird, während das linke seine Geschwindigkeit beibehält und der Roboter sich damit auf die Lichtquelle zubewegt. In diesem Fall wird (ndSchatten * 1000) zu 200 addiert, da die Variable ndSchatten < 0 ist. Auch hier wird der Geschwindigkeitsbereich mit Hilfe der constrain-Funktion wieder eingeschränkt.
else { speedRechts = int(200 + ndSchatten * 1000.0); speedRechts = constrain(speedRechts, -200, 200); speedLinks= 200; }
Bevor das Fahrverhalten im Realexperiment erprobt wird, überprüfen wir noch einmal die Werte aller Variablen im Terminal mit Hilfe der Serial.print Aufrufe.
Serial.print(speedLinks, DEC); Serial.print(" "); Serial.print(ndSchatten, DEC); Serial.print(" "); Serial.println(speedRechts, DEC); delay(1000);
Im Terminal erscheinen von links nach rechts die Spalten speedLinks, ndSchatten und speedRechts. Die hellere Seite zeigt immer 200 an (full-speed), während der andere Wert umso kleiner als 200 ist, je dunkler der Schatten ausfällt.
Aufgaben |
|
Das Programm Licht_MesswerteTerminal.ino
Nachdem alle Systeme getestet worden sind, geht es jetzt an den Feldtest. Dazu muss dass Programm Licht_MesswerteTerminal.ino angepasst werden.
Aufgaben |
|
Das Programm Licht_Navigation.ino
Die Lichtempfindlichkeit der Schaltung lässt sich dadurch verändern, dass der Wert 1000 in den beiden Kommandozeilen
speedLinks = int(200.0 - (ndSchatten * 1000.0)); speedRechts= int(200.0 + (ndSchatten * 1000.0));
erhöht wird.
Entsprechend kann die Lichtempfindlichkeit herabgesetzt werden durch einen Wert unter 1000.
Versuche es einmal aus.