Lego Robots mit AkSen-Board

Teil 2



Software

Die Programmierung des AkSen-Boards wird durch die vorbereitete Softwarebibliothek schon recht einfach gemacht, man muß sich also nicht mit Low-Level-Programmierung aufhalten.
Die verwendete Sprache ist ANSI-C. Unverzichtbar sind die Beispielprogramme und Codestücke der AkSen-CD.

Programmstruktur

Es gilt auch hier: alles lieber etwas einfacher halten. Der Programmcode mitsamt der gelinkten Bibliothek darf 64 KB groß sein, was weit mehr als benötigt ist, wenn man den Platz nicht gerade mit Strings für umfangreiche LCD-Menüs belegt. Leider dauert das Flashen bei den meisten Boards sehr lange, bei einigen wenigen ist eigenartigerweise mehrfach schneller. Dies hängt nicht, wie lange vermutet, vom verwendeten PC ab. Jedenfalls ist es schon deshalb empfehlenswert, den Code nicht zu sehr aufgebläht werden zu lassen, da man beim Testen von Routinen doch häufiger 'mal eben' etwas ändern muß.

Subsumption (Einordnung)

Diese Programmiertechnik hat sich als besonders passend für Systeme dieser Art erwiesen. Till Peters hat dieses Thema bereits abgehandelt (Praxis/SW-Strategien). Hier ist noch eine einfachere Erklärung, die nicht auf einer Multitaskingumgebung basiert. Im Projekt wird single threaded gearbeitet.
Man muß sich natürlich nicht genau an die Vorgaben dieser Technik halten, solange man den Überblick behält und sich nicht verzettelt. Wild alle möglichen Programmverzweigungen von allen möglichen Subroutinen aus einzubauen, kann schnell ein undurchdringliches Chaos ergeben.

Globaler Systemzustand

Es reicht für den Wettbewerb nicht, den Roboter ein einziges Mal fahren und einen Torschuß ausführen zu lassen. Der Torschuß kann danebengehen und es werden mehrere Runden gefahren, so daß er unablässig laufen muß, bis er beispielsweise durch das Drücken eines Schalters unterbrochen wird. Man sollte sich wegen des fehlenden Multitaskings also Gedanken darüber machen, wo und wann bestimmte Routinen unterbrochen werden können und sich um eine saubere Initialisierung von Variablen kümmern, um mehrere komplette Durchläufe der gesamten Programmstruktur fehlerfrei zu ermöglichen.


Abfrage der Hardware

Rückgrat des Programms und Basis für alle weiteren Schritte.

Ballsensoren

Wer es einfach haben will, kann den Robot sich beim Sehen des Balles links oder rechts einfach ein Stück in die entsprechende Richtung drehen, beim Ansprechen der Phalanx nach vorn und ansonsten auf dem Spielfeld herumfahren lassen. Wir hatten anfangs, als die Seitensensoren noch nicht angebracht waren, den Ball mit der Phalanx sozusagen angepeilt, indem ein Abfall des Wertes einer bestimmten Stärke nach Überschreiten der Schwelle für Erkennen des Balls berücksichtigt und dann in die Richtung zurückgedreht wurde.
Wichtig ist, daß das Signal des Balls aus geringer Entfernung stark schwankt und sogar aussetzen kann, weil keine seiner LEDs in Richtung des Sensors strahlt. Das ist bei der Prüfung des Ballbesitzes zu berücksichtigen.

Torsensoren

Diese unterscheiden sich von den anderen Sensoren des Systems, insofern als ihre Ansteuerung keinen Absolutwert anzeigt sondern bei Erkennen des Tores einen 8-bittigen Zähler hochzählt. Für eine Peilung braucht man also mehrere Sensoren, die bei vielen Teilnehmern auch noch ein gewisses Eigenleben zeigten, was die Angelegenheit komplizierte.
Die Umschaltung der Torseite per DIP-Schalter läßt sich sehr einfach durch folgendes in der Funktion für die Initialisierung der Torsensoren realisieren:

unsigned char freq=dip_pin(0)+4;

Das ergibt 100/125 Hz bei Schalter 0 off/on.

Sharps

Die unproblematischsten der Sensoren. Einfach abfragen, auf welcher Seite der Schwellwert überschritten wurde und entsprechend drehen. Ändert sich innerhalb eines Zeitlimits nichts, zurückfahren. return sobald die Werte wieder in Ordnung sind oder nach der Rückfahrt.


DIP-Schalter

Das Board verfügt über 4 DIP-Schalter, dazu sind im Labor einige Taster vorhanden, die an die digitalen Eingänge angeschlossen werden können. Den ersten Schalter haben wir für die Torumschaltung reserviert, mit den restlichen 3 plus insgesamt 3 Tastern wurde der Roboter bedient. Mindestens ein Taster sollte immer verwendet werden, und zwar für das Unterbrechen/Fortsetzen des Spielbetriebs, da die DIPs klein sind und man an sie je nach Konstruktion nicht unbedingt gut herankommt. Der Beschriftung nach zu urteilen sind die Schalter invertiert. Manche Taster sind es, manche nicht.
Da drei freie DIP-Schalter nicht gerade viel sind, kann man sich die Möglichkeiten durch Bitmapping erweitern:

unsigned char mode=(!dip_pin(2)*2)+(!dip_pin(3));

Hier bestimmen die beiden rechten Schalter einen von 4 Modi. Bitmapping von 3 Schaltern gibt einem mit 8 Modi viel Spielraum, wurde uns aber zu unübersichtlich.
Fast jedes Team, so auch unseres, hatte Probleme mit dem Abfragen der DIP-Schalter. Es konnte oft nur ein Schaltvorgang registriert werden, danach blieb das Bit auf 1 stehen. Bei einer Gruppe verschwand das Problem reproduzierbar, nachdem die Abfrage als direkte Bedingung für eine Schleife entfernt und statt dessen vorher in eine Variable gelesen worden war. Später tauchte es dort an anderer Stelle jedoch wieder auf, so daß die Angelegenheit mysteriös bleibt.
Wichtig: immer eine Verzögerung nach Drücken eines Tasters einbauen. Ansonsten nimmt man mit einem Druck die nächsten Abfragen gleich mit.

Kalibrierung

Das Arbeiten mit festen Schwellwerten empfiehlt sich nur für die anfängliche Testphase. Schon eine geänderte Beleuchtung und vor allem ein ungewöhnlich warmer Tag kann den Robot im wahrsten Sinne des Wortes an die Wand fahren lassen, wenn die Werte nicht anpaßbar sind.
Zu Anfang hatten wir eine Kalibrierung, bei der der momentan gesehene Wert direkt übernommen wurde. Vor allem bei den schwankenden Werten des Balls ist das von Nachteil und brachte keine zufriedenstellenden Ergebnisse. Wesentlich besser klappte diese Methode:
Die Werte sind fest vordefiniert, lassen sich aber bei der Kalibrierung in bestimmten Schritten mit zwei Tastern nach oben und unten verändern. Gleichzeitig wird der momentan gemessene Wert angezeigt. Solange der Schwellwert überschritten ist, wird der eingestellte Wert auf dem Display mit > < drumherum markiert. Der dritte Taster fungiert als Enter-Taste. Beim Tor ist die Empfindlichkeit in 10 Stufen veränderbar, nur bei den Sharps wurden die Werte noch direkt übernommen. Die Funktion ist bei unserem Programm am Ende, ich empfehle einen Blick hinein.
In Betracht gezogen werden sollte auch, Wartezeiten (sleeps) für Richtungskorrekturen im Programm veränderbar zu machen. Dadurch kann man ihn zu Batterien kompatibel machen, mit denen er bis zu 1/4 schneller fährt. Deren Spannung fällt allerdings schnell ab.

LCD

Das LCD stellt jeweils 16 Zeichen in 2 Reihen dar. Seine Ansteuerung, vor allem das Löschen der Anzeige, kostet wie schon angesprochen viel Zeit und sollte während der Fahrt ausbleiben. Sollte es doch mal nötig sein: das Überschreiben einzelner Inhalte mit Leerzeichen oder dem neuen Wert (formatieren nicht vergessen, 0 an den Anfang bei Werten < 100 usw.) sollte schneller sein, als lcd_cls() zu benutzen.

Taktiken

Für eine umfassende Taktik Fehlen leider wichtige Eckdaten. Vor allem wissen die Roboter nicht, wo sie sich befinden. Mit einigem Aufwand könnte man eventuell die Position durch das gleichzeitige Betrachten der Werte beider Tore ungefähr bestimmen, aber zuverlässig wird das kaum sein, abgesehen davon, daß der andere Roboter manchmal die Sicht zu den Torsensoren blockiert. Weiterhin bemerken sie nicht einmal, wenn ein Tor fällt, und ebenfalls nicht, ob die Sharps gerade die Wand oder den anderen Robot gesehen haben.
Es bleiben also nur simple Ansätze. Etwa kann der Robot, nachdem er mit einem Tor in Führung gegangen ist, vor dem anschließenden Mittelanstoß in einen Torwart-Modus geschaltet werden, in dem er nur noch das Tor blockiert. Das ist allerdings für Zuschauer wohl wenig interessant und wurde deshalb nicht weiter verfolgt.
Eine weitere Idee, die mir erst beim Wettbewerb kam, ist der Versuch, das Trennen der verkeilten Robots durch den Schiedsrichter zu erkennen, etwa mit einem Bodensensor. Da die beiden Kontrahenten mit der Front zur Wand und dem Ball in der Mitte wieder aufs Spielfeld gesetzt werden, kann in diesem Fall ohne Umschweife eine 180°-Drehung zum Ball hin gemacht werden, während zumindest bei Robots ohne Ballsensor am Heck eher an der Wand entlanggefahren würde, bis der Ball zufällig in Sicht kommt.
Solche Spezialfälle mit behelfsmäßiger Situationserkennung hängen aber stark von den Regeln ab und können solide Routinen zur Ball- und Torfindung (mit ihnen steht und fällt die Sache) nicht ersetzen. Sie sind mehr als interessante Spielereien zu verstehen.

Versionskontrolle

Jedes Team sollte genau darauf aufpassen, daß Änderungen am Code wieder zurückgenommen werden können. Gerade beim Erreichen gewisser Meilensteine (Ball gefangen, Tor gefunden) und vor allem bei der ersten komplett funktionierenden Version gehört diese unbedingt gesichert. Spätere Änderungen des Codes mit wieder flott machen des Programms in letzter Minute sollen im Projekt öfters vorgekommen sein. Wer seine Nerven (und die der Professoren) schonen will, hält statt dessen eine sozusagen in Stein gemeißelte, lauffähige Version bereit, die dann vielleicht nicht ganz so raffinierte Strategien beinhaltet, aber zumindest den Totalausfall und damit lange Gesichter verhindert.
Unerwartete Nebeneffekte können immer mal auftreten, auch bei scheinbar unbedeutenden Änderungen ist also eine Sicherung des alten Zustandes sinnvoll.


Ich hoffe, ich konnte kommenden Semestern durch diese Zusammenstellung einen kleine Hilfe geben. Gutes Gelingen.

Bei Fragen und Anregungen: jawad_n@informatik.haw-.... <Spamschutz>.
Programmcode: robot7_final.c