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