Roboter programmieren mit Arduino (Teil 7: Line-Tracking)

 

 

Eine beliebte Aufgabenstellung für einen fahrbaren Roboter ist das Abfahren einer bestimmten Strecke (Routing). Eine programmtechnisch vorgegebene Lösung könnte wie folgt aussehen:

 

1. Fahre zunächst 50 cm geradeaus,

2. biege dann in einem Winkel von 20° nach rechts ab,

3. fahre dann 120 cm geradeaus ...

4. etc.

 

Doch diese Programmvorgabe hat entscheidende Nachteile, denn Sie müssen den Roboter jedes Mal komplett umprogrammieren, wenn sich die Strecke ändert. Außerdem wächst das Programm mit der Anzahl der Knotenpunkte auf der Strecke.

 

Bei einem anderen Ansatz teilen Sie die Aufgabe in 2 Lösungsabschnitte:

1. Sie markieren die Route in irgendeiner Form auf dem Boden,

2. Sie programmieren den Roboter so, dass er dieser Linie folgt.

 

Dieses Verfahren wird als "line tracking" bezeichnet. Der RoverROM B3000 hat 2 spezielle Sensoren, um diese Aufgabe zu realisieren. Sie sind vorn an der Bodenplatte angebracht.

 

linetracker

 

Diese Linetracking-Sensoren arbeiten nach dem Prinzip der aktiven Lichtrefelexion. Dabei wird über eine kleine LED ein Lichtstrahl gegen das Objekt gesendet und das reflektierte Licht wird gemessen. Bei hellen Objekten ist die Lichtstärke höher, bei dunklen entsprechend niedriger. Um Fehler durch Fremdlichtquellen zu vermeiden, wird allerdings kein sichtbares Licht verwendet, sondern Infrarotlicht (Wärmestrahlung). Sie verhält sich in Bezug auf die Reflexion sehr ähnlich wie das sichtbare Licht. Auf dunklen Flächen wird sie absorbiert, auf hellen reflektiert. Deshalb ist es in einem schwarzen Auto eben im Sommer bei strahlender Sonne sehr heiß.

Bevor wir jedoch mit der eigentlichen Aufgabenstellung beginnen, wollen wir die Linetracking-Sensoren genauer unter die Lupe nehmen. Unsere Linetracker sind mit den Anschlüssen A1 und A2 verbunden, wir arbeiten also mit einem analogen Signal. Das ist nicht die einzige Möglichkeit, denn die Sensormodule haben einen kleinen Taster auf der Oberseite und damit können Sie den Modus zwischen analog und digital wechseln.

 

linetracker_detail

 

Wenn Sie momentan nicht wissen, in welchem Modus Sie sich befinden, können Sie das recht einfach über die integrierte LED herausfinden. Diese leuchtet nämlich analog zu dem gemessen Lichtwert. Halten Sie z. B. ein dunkles Blatt Papier unter den Sensor und die LED wird ebenfalls dunkler, dann sind Sie im analogen Modus, wechselt die LED lediglich zwischen "ein" und "aus" ist der Digitalmodus gewählt.

Wir werden uns jetzt zunächst einmal einfach nur die Werte ausgeben lassen, die beide Sensoren messen. Das Programm ist praktisch identisch aufgebaut wie das Testprogramm für den Lichtsensor, denn nichts anderes sind die beiden Linetracker ja, nur das sie ihre eigene Lichtquelle mit an Bord haben.

 

LineTrackerTest

 

In der setup-Funktion wird nur die serielle Schnittstelle intialisiert. In der loop werden dann die Werte der Sensoren eingelesen, nacheinander ausgegeben und nach jedem Durchgang eine halbe Sekunde gewartet.

Das Ergebnis auf einer silbergrauen Schreibtischplatte sieht dann bei mir so aus:

Linetracker_Values_1

 

Der Unteschied zwischen linkem und rechtem Sensor scheint bauteilbedingt auszufallen, übermäßig groß ist die Differenz nicht. Als ersten Versuch habe ich einen Teil einer Visitenkarte mit einem Marker schwarz gefärbt und lege diese Karte so unter den RoverROM, das sich der linke Sensor über dem schwarzen und der rechte über dem weißen Bereich befindet. Der Abstand zwischen Sensor und Boden beträgt ca. 10 mm.

 

Tracking_sw

 

Damit erhalte ich die folgende Ausgabe:

LineTracking_sw

 

Der linke Sensorwert sinkt zwar deutlich ab, allerdings ist die Differenz trotz der doch deutlichen Helligkeitsunterschiede immer noch recht gering. Ich muss auch zugeben, wenn ich nicht einen wirklich tiefschwarzen Marker genommen hätte, wäre der Unterschied noch geringer, bzw. gar nicht wahrnehmbar. Ein kleinerer oder größerer Abstand zum Boden wirkt sich dabei auch nicht wirklich spürbar aus.

Ich probiere eine eher dunkelgraue Visitenkarte und jetzt sinkt der Wert auf 311. Ähnlich gute bzw. zum Teil noch bessere Ergebnisse erreiche ich auch mit schwarzem Isolierband. Das ist vorteilhaft, denn damit können wir sehr gut eine Strecke abkleben. Sie sollten also immer erst das Anprechverhalten der Sensoren auf unterschiedliche Materialien testen. Allein die optische Wahrnehmung reicht hier nicht aus.

 

Die richtige Line-Tracking-Strategie

 

Es gibt unterschiedliche Ansätze, um einen Roboter mittles Line-Tracking-Sensoren auf der Linie zu halten. Diese unterscheiden sich z. B. durch die Anzahl der verwendeten Sensoren.

 

linetracking_1sensor

 

Line-Tracking mit 1 Sensor

 

Die einfachste Form kommt mit einem einzigen Sensor aus. Nehmen wir dazu fiktiv an, der Sensorwert über dem schwarzen Strich wäre 100 und neben dem Strich auf dem weißen Untergrund läge er bei 800. So lange der Roboter also auf der schwarzen Linie fährt bleibt der Wert bei 100 und wir müssen nicht eingreifen. Kommt er aber von seinem Kurs ab, so wird der Wert irgendwann ansteigen. Im direkten Grenzübergang nimmt er dabei Werte zwischen 100 und 800 ein. Allerdings ist dieser Grenzbereich sehr eng.

Wir müssen jetzt also eingreifen. Dabei gibt es nur ein Problem: In welcher Richtung ist der Roboter von der Linie abgekommen. Das können wir bei einer Lösung mit einem Sensor nicht ahnen. Also müssen wir den Roboter kurz anhalten, damit er nicht unnötig weit vom Kurs abkommt. Dann müssen wir ihn ein kurzes Stück in eine zufällig gewählte Richtung drehen lassen. Die Dauer des Drehvorgangs richtet sich dabei nach der Fahrgeschwindigkeit und der Trägheit, wie lange unser Gefährt braucht, um in den Stillstand zu kommen. Wir müssen also mindestens so stark korrigieren, wie der Roboter maximal vom Weg abgekommen sein könnte.

 

Korrektur1

 

Liegt nach der 1. Korrektur immer noch der Wert für den hellen Bereich vor, war die Richtung falsch und wir müssen mindestens die doppelte Korrektur in die andere Richtung vornehmen. Theoretisch wäre natürlich die Nutzung des Übergangsbereiches günstiger, weil wir beim Steigen des Wertes sofort die falsche Richtung erkennen könnten, doch dazu ist wie gesagt, der Übergang zu kurzzeitig. Wir könnten natürlich eine entsprechende Linie aufbringen, die nur in der Mitte tiefschwarz ist und nach außen heller wird. Doch das wäre ein recht mühsames Unterfangen.

 

Line-Tracking mit 2 Sensoren

 

Wesentlich komfortabler gestaltet sich die Sache, wenn wir 2 Sensoren nutzen. Dabei können wir sogar mehrere Strategien anwenden.

1. Wir detektieren wieder die schwarze Linie, aber dieses Mal versuchen wir, dass beide Sensoren über dem dunklen Bereich bleiben.

 

line_tracking_2Sensor_a

 

Weisen beide Sensoren den gleichen niedrigen Wert auf, befinden sich beide Sensoren über der schwarzen Linie.

Hinweis: Da beide Sensoren praktisch nie identische Werte anzeigen, sollten Sie für beide Sensoren zunächst die Schwarzwerte ermitteln und dann durch einen Offset anpassen. Damit lässt es sich dann leichter rechnen.

Steigt der Wert des linken Sensors an, so weicht der Roboter nach links vom Kurs ab und umgekehrt. Dieses Verfahren lässt sich sehr gut einsetzen, wenn die schwarze Linie gerade so breit ist, dass beiden Sensoren über dem schwarzen Bereich liegen.

 

2. Wir detektieren nicht die schwarze Linie selbst, sondern die Hell-Dunkel-Kante. Dabei ist es egal, ob wir die rechte oder die linke Kante wählen.

 

Kantendetektion

 

Für dieses Beispiel wählen wir die linke Kante als Referenz (Fahrtrichtung nach rechts). Der Normalfall liegt dann vor, wenn sich der linke Sensor im weißen und der rechte Sensor im schwarzen Bereich befindet. Misst der rechte Sensor hellere Werte als der linke, driftet der Roboter nach rechts ab. Messen beide Sensoren hohe Werte, befinden sie sich über dem weißen Bereich und der Roboter kommt nach links von der Bahn ab. Diese Situation tritt dann auf, wenn die schwarze Linie in etwa so schmal ist, wie ein Sensor. Sie können diese Art der Verfolgung aber auch sehr gut bei sehr breiten Linien oder sogar an ganzen Bereichen anwenden.

 

Kantendetektion2

 

Im Normalfall sind die Werte der beiden Sensoren unterschiedlich. Beim Abweichen werden beide Werte identisch. Im obigen Beispiel werden beide Werte niedrig, wenn der Roboter nach rechts driftet und beide Werte werden hoch, wenn er nach links vom Weg abkommt.

 

Line-Tracking mit mehr als 2 Sensoren

 

Ein 2-Sensor-System erfüllt also 2 Forderungen: Sie können erkennen, ob die Linie verlassen wird und in welche Richtung. Damit ist eine Korrektur eindeutig möglich. Sie können allerdings erst reagieren, wenn der Fehler eingetreten ist. Bei einem System mit mehr als 2 Sensoren können Sie auch Prognosen erstellen, das ist aber erst ab ca. 5 Sensoren wirklich sinnvoll. Diese Verfahren sind aber sehr aufwendig. Sie ermitteln dabei über die Zeit zwischen den Zustandsänderungen der Sensoren die Geschwindigkeit, mit der sich der Roboter von der Linie weg bewegt und können dementsprechend differenziell nachregeln.

5_Sensor_Linetracker

 

Im Beispiel weisen die Sensoren 0, 1L und 1 R eine niedrige Spannung auf, weil sie sich über dem schwarzen Bereich befinden. Wechselt 1L auf weiß, erkennt das System ein Abweichen nach links. Jetzt kommt es darauf an, ob und wie schnell auch Sensor 0 auf weiß wechselt. Geschieht dies erst lange Zeit nach dem der erste Wechsel erfolgte, liegt nur eine sehr geringe Kursabweichung vor und wir müssen dementsprechend die Richtung nur geringfügig nachregeln. Wechselt auch noch 1R auf weiß erhalten wir 2 Zeitspannen:

t1 = Wechsel 1L bis Wechsel 0

t2 = Wechsel 0 bis Wechsel 1R

Ist t1 kleiner als  t2 verlangsamt sich die Abweichung, ist t2 jedoch kleiner als t1 nimmt die Änderungsgeschwindigkeit zu. Wir können also genaue Aussagen darüber machen, wann der definierte Fehlerfall (z. B. alle Sensoren im weißen Bereich) eingetreten ist und dementsprechend reagieren.

 

Die praktische Umsetzung im RoverROM B3000

 

Nach all der Theorie wollen wir das Ganze jetzt in die Praxis umsetzen. Für einen ersten Versuch legen wir die folgenden Bedingungen fest:

1. Wir kleben eine Strecke mit Isolierband auf den Boden.

2. Wir messen mit unserem Testprogramm für beide Sensoren die Werte, die sich ergeben, wenn sie sich genau über dem Isolierband befinden. Das sind bei mir für den rechten Sensor 375 und für den rechten3280. Die Werte liegen also recht dicht beieinander. Eine größere Differenz wäre aber auch kein Problem. Diese Werte sind allerdings noch nicht die Minimalwerte, weil das Isolierband in etwa so breit ist, dass beide Sensoren sich schon eher im Kantenbereich befinden. Das ist eine sehr gute Ausgangssituation.

3 Wir ermitteln für beide Sensoren die Werte außerhalb des Isolierbandes. Das ergibt für den linken Sensor 890 und rechts werden 820 angezeigt.

Wir können jetzt recht eindeutig die Bedingungen für das Abweichen nach rechts oder links definieren:

 

Drift nach rechts:

linker Wert < 400 UND rechter Wert > 600

 

Drift nach links:

rechter Wert < 400 UND linker Wert > 600

 

Wir reagieren dabei zunächst folgendermaßen:

Bei einem Rechtsdrift erhöhen wir die Geschwindigkeit des rechten Motors um den Wert 5, gleichzeitg verringern wir die Gechwindigkeit des linken Motors um den gleichen Wert. Das ist notwendig, damit die Geschwindigkeit sich nicht hochschaukelt. Wir müssen hier aber noch eine Begrenzung einbauen, sonst könnte die Geschwindigkeit die Variablengrenze überschreiten und zu unvorhersehbaren Ergebnissen führen.

 

In ein Arduino-Programm übertragen sieht das Ganze wie folgt aus:

 

LineTracking_Fahrt_Teil1

 

Im 1. Teil des Programms definieren wir ein paar Konstanten und Variabeln, außerdem konfigurieren wir die Motor-Pins. Das dürfte mittlerweile bekannt sein.

 

LineTracking_Fahrt_Teil-2

 

Im 2. Teil erfolgt dann die Messung und die Kontrolle wie oben beschrieben. Die Defintion der Konstanten DIFF für die Angabe der Geschwindigkeitsänderung ist sinnvoll, da wir sie mit Sicherheit anpassen müssen und das erfolgt dann zentral oben.

Der 1. if-Block direkt nach dem Einlesen der Sensordaten beschreibt das Erkennen und die Reaktion auf den "Rechtsdrift". Wir ändern die Motorspannungen wie oben beschrieben und fragen ab, ob die minimale bzw. maximale Geschwindigkeit erreicht wurde.

Im 2. if-Block wird der "Linksdrift" behandelt. Wir brauchen hier übrigens keine if-else-Unterscheidung, da sich zwischen den if-Abfragen die Bedingungswerte nicht ändern können und es nur diese drei Fälle geben kann.

Drei Fälle? Bislang haben wir ja nur zwei unterschieden. Ein fahrbarer Roboter ist aber kein theoretisches Modell, sondern ein reales "Wesen" mit entsprechenden Vor- und Nachteilen. Was würde z. B. passieren, wenn unser RoverROM sehr schnell von der Bahn abkommt und beide Werte größer als 600 wären? Das kann durchaus passieren, wenn die Geschwindigkeit so groß ist, das die Korrektur zu langsam erfolgt (z. B. durch ein zu kleines DIFF). In diesem Fall düst der RoverROM unkontrolliert geradeaus oder auch in einer großen Kurve, je nachdem wie die letzten Geschwindigkeiten eingestellt waren. Bei der Robotik gilt allerdings immer der Grundsatz: im Zweifel einen sicheren Zustand wählen und der ist bei einem Fahrzeug der Stillstand. Also fügen wir noch einen 3. Block hinzu, der abfragt, ob der RoverROM unsere Linie verlassen hat.

 

Video_Bild

 

Das sieht für die erste Version doch schon sehr gut aus. Der RoverROM watschelt zwar ein wenig, aber man kann gut erkennen, wie er korrigiert. Wenn es ein wenig komplizierter wird (wie in der Kurve) kann es allerdings unter Umständen passieren, dass er die Linie verliert und stehen bleibt. Aber das Grundprinzip funktioniert. Und durch unsere Sicherheitsfunktion bleibt der RoverROM am Ende der schwarzen Linie auch stehen.

 

Anregungen für weitere Verbesserungen

Das leichte Schlingern des RoverROM deutet darauf hin, das er ein Abweichen überreguliert, ein höherer DIFF-Wert wirkt sich deshalb wie ein steigender Promillespiegel aus. Senken Sie den DIFF-Wert wird die Fahrt wesentlich ruhiger. Aber: bei zu geringen Werten kann es sein, dass die Korrektur in der Kurve nicht mehr ausreicht.

Auch eine höhere oder niedrige Grundgeschwindigkeit wirkt sich sehr stark auf die Stabilität aus. Bei geringeren Geschwindigkeiten ist ein Reagieren natürlich wesentlich einfacher. Deshalb wäre eine weitere Möglichkeit, den DIFF-Wert dynamisch an die Geschwindigkeit anzupassen.

Um die Line-Tracking-Funktionalität noch weiter zu optimieren, wäre die Integration von Zuständen von Vorteil, damit weiß der RoverROM praktisch in welcher Situation er sich befindet. Eine Zustandsmaschine (State Machine) befindet sich immer genau in einem definierten Zustand. Innerhalb dieses Zustands legt sie wiederum ein fest gelegtes Verhalten an den Tag. Durch bestimmte Einflüsse von außen oder durch innere Entscheidungen, wechselt sie in einen anderen Zustand. 

Mögliche Ansätze für unseren RoverROM wären dabei:

ON_THE_LINE: Der Zustand wird aktiviert, wenn beide Sensoren einen niedrigen Pegel haben. Das Verhalten: Der RoverROM fährt gleichmäßig geradeaus.

EXIT_RIGHT: Der RoverROM ist nach rechts abgekommen (rechter Sensor = hoher Pegel, linker Sensor = niedriger Pegel). Das Verhalten: er korrigiert nach links.

EXIT_LEFT: Umgekehrt wie EXIT_RIGHT.

OUT_OF_RANGE: Beide Sensoren liefern hohe Pegel, der RoverROM steht im Nirvana.

Bis jetzt ist das ja im Grunde noch nahezu identisch wie unser bisheriges Programm, nur dass die Abfragen und damit die Einteilung der Zustände an einer separaten Stelle vorgenommen wird und die Reaktion z. B. in Form eines switch-case-Blockes an einer davon getrennten Stelle. Interessant wird es aber, wenn wir die Reihenfolge der Zustände mit berücksichtigen:

Vom Zustand ON_THE_LINE gibt es drei mögliche Folgezustände: EXIT_RIGHT, EXIT_LEFT und OUT_OF_RANGE (am Ende der Linie).

Von den Zuständen EXIT_RIGHT und EXIT_LEFT  gibt es nur 2 Zustände:

Zurück auf die Linie ON_THE_LINE oder ganz ins Abseits, das wir dann etwas dramatisch RIGHT_OUTBACK bzw. LEFT_OUTBACK nennen. 

Die Zustände RIGHT_OUTBACK und LEFT_OUTBACK wären bei unserem bisherigen Vorgehen untereinander und auch von OUT_OF_RANGE nicht  zu unterscheiden, denn sie sind dadurch gekennzeichnet, dass beide Sensoren hohe Pegel aufweisen. Durch die Verwendung von Zuständen ist es aber problemlos möglich. Dabei werden zunächst beide Sensoren in der loop-Schleife ausgewertet und wenn beide hohe Pegel zeigen, werden die aktuellen Zustände abgefragt und in Abhängigkeit davon der Folgezustand ermittelt. Und jetzt können Sie ein vollkommen anderes Verhalten bestimmen, obwohl die Messwerte immer identisch sind:

Im Zustanhd OUT_OF_RANGE lassen wir den RoverROM einfach stehen, denn wir gehen davon aus, dass das Ende der Linie erreicht ist. Im Zustand RIGHT_OUTBACK drehen wir den Roboter so lange auf der Stelle, bis er wieder in den Zustand EXIT_RIGHT gelangt und für diesen Zustand haben wir ja schon eine korrigierende Regelstrategie. Das Gleiche gilt für LEFT_OUTBACK.

Als weitere Alternative können Sie auch einmal probieren, wie es mit der Kantenerkennung funktioniert. Das Prinzip ist absolut gleich, Sie müssen nur die Bedingungen für die jeweiligen Zustände neu definieren.

 

Für weitere Informationen und Bestellungen des

RoverROM-B3000

einfach auf nachfolgenden Link klicken: Böcker RoverROM-B3000 Version 2

oder als Bausatz: Böcker RoverROM-B3000 Version 2 Bausatz

 

Sie wollen Arduino-Profi werden? Dann ist unser Video Mikrocontroller-Lehrgang MC1 genau das Richtige für Sie!

 

Falls Sie Fragen zum Thema haben, wenden Sie sich einfach an uns.

Wir helfen Ihnen gern weiter!

 

Ihr Team von Böcker Systemelektronik

 

Hinweis: Unser Tutorialangebot wird in unregelmäßigen Abständen erweitert. Wenn Sie sofort über eine Neuerscheinung informiert werden möchten, tragen Sie sich bitte hier in unsere Benachrichtigungsliste "Tutorials" ein. Sie können diesen unverbindlichen Service jederzeit in Ihrem Kundenkonto oder per E-Mail wieder abbestellen.  

 

 

Copyright © Böcker Systemelektronik