Echtzeitbetriebssystem?

Unser Programm ist in letzter Zeit extrem gewachsen, besonders die Zeilenkamera bereitet uns ein paar Timingprobleme. Unsere Software hat keine wirkliche zeitliche Ordnung, das meiste wird in der Hauptschleife gemacht (bis auf Geschwindigkeitsmessung und die Timer). Besonders für Regelungen (Geschwindigkeit, Abstand…) ist eine geordnete zeitliche Reihenfolge aber sehr wichtig. Wir haben uns nun dazu entschieden, uns etwas in Echtzeitbetriebssysteme einzuarbeiten.

Echtzeitbetriebssysteme arbeiten, wie der Name schon erahnen lässt, in Echtzeit. Wenn also an einem bestimmten Zeitpunkt im Programm ein Ereignis erkannt wird, wird direkt darauf reagiert (wenn es so erwünscht isr). Im Gegensatz zu Betriebssystemen wie Linux oder Windows (beides keine Echtzeitbetriebssysteme, eng. Real Time Operation System, deshalb auch oft abgekürzt als RTOS) ist das Verhalten der Software dabei wesentlich besser vorhersehbar.

Eigentlich brauchen wir nur einen Scheduler, der unsere Prozesse einteilt. In Hinsicht auf einfache Erweiterbarkeit wollen wir aber doch etwas nutzen, was man ohne viel Aufwand auf andere Prozessorarchitekturen portieren kann. Genauer angesehen haben wir uns bis jetzt FreeRTOS. FreeRTOS ist eigentlich kein richtiges Betriebssystem, nur der Kernel mit Scheduler und Management der Tasks, also genau richtig für uns. Des Weitereren ist es sehr klein und optimiert auf unsere geringen Ressourcen.
Das Anlegen der Tasks sieht recht einfach aus, mal sehen, ob es wirklich so toll funktioniert (Zeit haben wir ja jetzt genug, es dauert noch 5 Monate bis zum Wettbewerb). Vielleicht entscheiden wir uns aber auch noch für etwas anderes…
Hier eine kleine aktuelle Zeitplanung:

 September  Einarbeitung in RTOS’
 Oktober  Implementierung von RTOS auf unsere Hardware und Anpassung unserer Treiber
 November  Roboter ist jetzt auf Stand von vor Implementierung → Tests und Debugging
 Dezember Implementierung weiterer Algorithmen
 Januar  Testen/Debuggen
 Februar Testen/Debuggen
 März  Testen/Debuggen/Wettbewerb

Zusammen mit einem Echtzeitbetriebssystem wollen wir auch eventuell auf eine IDE umsteigen (bis jetzt haben wir alles mit einem Texteditor und Syntaxhighlighting gemacht), da wir sonst wahrscheinlich irgendwann den Überblick verlieren. Da ziehen wir Eclipse in Betracht.

Soweit die Theorie. Mal sehen, was daraus wird, aber wir sind sehr zuversichtlich, da der Zeitplan auch EXTREM großzügig dimensioniert ist (evtl. verschiebt sich einiges um einen Monat nach hinten, schaffen werden wir es also zeitlich auf jeden Fall). Unsere Navigation und Kartenerstellung funktioniert ja außerdem schon einwandfrei, lediglich die Fahranweisungen (wie 30cm geradeaus oder 90° drehen) müssen noch perfektioniert werden. Dann natürlich noch einen Algorithmus, der es uns ermöglicht, den Roboter nach einem Lack of Progress per Tastendruck an einen beliebigen Punkt in der Arena zu stellen. Das ist aber das kleinste Problem. 😉

Softwareanpassung und Zeilenkamera!

Nachdem die Hardware soweit fast fertig war (nur noch eine Erkennung der schwarzen Fliesen fehlt(e)), haben wir uns intensiv mit der Anpassung der Software beschäftigt. Besonders in Sachen Karte und Navigation haben wir einiges getan; wir haben viel optimiert, angepasst und Fehler ausgebessert. Wenn wir auf alle Details eingehen würden, wären wir morgen mit dem Auflisten noch nicht fertig, aber wir können sagen, dass der Roboter nun in der Lage ist, relativ zuverlässig eine Karte zu erstellen, alle Fliesen abzufahren, wieder zum Startpunkt zurückzukehren und dabei ist es egal, wo im Labyrinth der Roboter gestartet wird! Das hat sehr viele Vorteile und macht alles wesentlich zuverlässiger.
In Sachen Software steht als nächstes neben Verbesserungen und Optimierungen eine Implementation eines Algorithmus an, mit dem wir den Roboter während der Aufzeichnung und Navigation an eine andere Stelle des Labyrinths setzen können (natürlich nach Mitteilen der neuen Position per Inkrementalgeber), nachdem der Roboter sich zum Beispiel verfahren hat. Es müssen dann nämlich alle Markierungen bis zu dem Punkt gelöscht werden, damit der Algorithmus zur Navigation sinnvoll weiterarbeiten kann. Alternativ kann man den Roboter einfach machen lassen und, wenn der Algorithmus keine Lösung findet (theoretisch beim Startpunkt ist) den Roboter einfach automatisch die Karte neu starten lassen. Dann ist zwar der gespeicherte Startpunkt weg, dafür kassiert man keine Strafpunkte für einen Eingriff. Muss man eben abwägen.
Des Weiteren muss dann bald eine neue Erkennung der Rampe implementiert werden, damit die Karte 100%ig autonom ist (zuvor hat der Roboter die Rampe und somit einen Wechsel der Etagen mithilfe der Karte erkannt, das ist aber nicht gut). Das sollte allerdings auch recht schnell erledigt sein. Danach ist eigentlich nur noch perfektionieren, perfektionieren und nochmals perfektionieren angesagt.

Zuvor muss aber noch eine zuverlässige Erkennung der schwarzen Flächen implementiert werden. Der Sensor selbst muss sich weit vorne am Roboter und zudem 6cm über dem Untergrund befinden, damit die Bodenfreiheit nicht eingeschränkt wird. Ein einzelner Phototransistor mit kleinem Öffnungswinkel und eine High-Power LED wollten wir nicht nutzen, da die LED recht viel Energie verschwendet. Nach einigem Hin- und Her haben wir uns vorerst entschieden, mit einer Zeilenkamera (TSL1401) zu experimentieren. Es werden lediglich 3 Pins benötigt:

  • Pin 1: Starte Belichtung
  • Pin 2: Clock
  • Pin 3: Analogausgang

Pin 1 wird gesetzt (ab jetzt wird belichtet), gleichzeitig kann oder muss Clock an- und ausgeschaltet werden, bei jedem Clock wird der Analogausgang der Kamera mit dem ADC des Mikrocontrollers ausgelesen. Wenn Pin 1 nochmal gesetzt wird, endet die Belichtung, die nächste startet und parallel kann das letzte Ergebnis ausgelesen werden. Hört sich schwieriger an, als es ist (die Implementierung der I²C Wärmesensoren hat uns mehr Arbeit gemacht 😀 ). Die Kamera hat eine Auflösung von 1×128 Pixel und einen einstellbaren Fokus. Man bekommt dann eine Linie mit Grauwerten, woraus man erkennen kann, ob sich da eine schwarze Fläche vor dem Roboter befindet oder nicht. Wie oben erwähnt, muss die Belichtungszeit selbst geregelt werden. Dabei gibt es ein Problem: Angenommen, die Kamera sieht komplett schwarz oder komplett weiß. Wie soll sie das dann unterscheiden? Man hat ja keine Referenz mehr. Und da ist das Stichwort schon: Referenz. Einfach ein weißes Stück Papier vor die unteren Pixel der Kamera gelegt. Das Blatt Papier muss immer weiß sein, darauf wird also geregelt. Wenn dann ein großer Sprung in den Grauwerten ist, ist da eine schwarze Fliesen.
Die Kamera hat allerdings einen Haken: Sie muss ständig mit dem Mikrocontroller kommunizieren (der muss ja ständig die Belichtungszeit regeln und parallel auslesen), der Mikrocontroller hat aber kein richtiges Multitasking. Also muss das Hauptprogramm nebenbei laufen. Die Hauptschleife benötigt aber schon ca. 20ms, dann könnten wir die Belichtungszeit nur in 20ms Schritten einstellen (wir brauchen aber mindestens 5!), weshalb die Kamera in einem Timer laufen muss. Der Timer wird beim STart des Roboters konfiguriert, unterbricht das Hauptprogramm in entsprechenden Abständen und führt dann einen entsprechenden anderen Teil aus (in dem Fall also das Auswerten der Kamera). Da gibt es aber noch ein paar Konflikte (da in dem Timer ja auch die Analogeingänge ausgewertet werden müssen; Wenn dann eine laufende Analogwandlung (beispielsweise eines Entfernungssensors) unterbrochen wird und danach an der Stelle weitergemacht wird, kommt da Müll raus), die wir hoffentlich noch in den Griff kriegen. Mal sehen.
Die Kamera wird vorsichtshalber noch von einer High-Power-LED unterstützt, die automatisch dazugeschaltet wird, wenn es SEHR dunkel ist (was normalerweise nie passiert).
Mal sehen, wie gesagt kriegen wir das hoffentlich noch auf die Reihe, bei der Kamera stößt unser Mikrocontroller allerdings langsam an seine Grenzen. Ansonsten haben wir schon eine andere Idee parat, dazu dann aber ggf. mehr. 😉

Zeilenkameramodul: Links die Kamera, rechts die LED mit Schaltregler.

Modul: Rückansicht

 

Und eingebaut im Roboter. Hier wird die Problematik vielleicht noch etwas besser deutlich.