RoboCup 2014: Überarbeiteter Roboter Teil 2: Software

Nachdem die Hardware überarbeitet wird, wird natürlich (zwangsläufig?) auch die Software aktualisiert und verbessert. Zum Glück können wir da noch Einiges im alten Roboter machen und müssen nicht auf die Fertigstellung des neuen Roboters warten. Im Folgenden listen wir alle Ziele dieser Saison auf.
Achtung, alles sehr schwierig in wenig Worten zu erklären, weshalb das wahrscheinlich nicht für alle sofort verständlich sein wird :(

Zur Hilfe und vielleicht zum Verständnis deshalb hier die aktuellen Regeln (englisch).

 

Boot

Boot: Logo, Versionsanzeige, Status (Kalibrierung der IMU) und die Resetquelle (ResSRC); in diesem Fall PORF, also Power-On-Reset-Flag. Hier wird angezeigt, ob der Roboter zuletzt normal ausgeschaltet wurde, die Batterie zu leer war oder ob ein anderer Reset ausgelöst wurde.

  1. [Erledigt] Verbesserung des User Interfaces
    Für ein vernünftiges Debugging Menü hatten wir bis jetzt keine Zeit, lediglich die Temperaturwerte ließen sich am Display ausgeben und die Schwellwerte über eine Variable einstellen. Wenn man nun beim Start des Roboters die Enter Taste gedrückt hält, kommt man ins Setup- und Debuggingmenü:

    Setup- und Debuggingmenü. Der Pfeil zeigt an, was gerade geändert werden kann, wird auch noch einmal durch die beiden Nullen unten links angezeigt.

    Oben sieht man immer noch die Statusleiste (die wird immer angezeigt, die hatten wir auch schon immer vorher), in der Fehlermeldung, Informationen etc. angezeigt werden. Darunter dann die Menüeinträge:

    IR links [Ist-Wert] [Schwellwert] Einstellen des Schwellwerts für diesen Temperatursensor. Wert wird nach Änderung im EEPROM des Mikrocontrollers gespeichert und bleibt deshalb auch nach Neustart bestehen.
    IR rechts [Ist-Wert] [Schwellwert] ––––––––––––––––––––––––“––––––––––––––––––––––––––––
    Tarry [Ist-Wert] Wird der Algorithmus zum Abfahren des Labyrinth genutzt oder wird die rechte Hand Regel angewandt? Wird auch im EEPROM gespeichert.
    View Hier werden alle Sensorwerte auf einem Bildschirm dargestellt. Besonders die Entfernungssensoren lassen sich so gut darstellen und debuggen.
    ok Setup beenden
  2. View

    View: Darstellung aller Sensoren, in der Mitte der Roboter und die Entfernungssensoren als Striche

    [Erledigt] Speicherung der Karte
    Das war ein relativ großes Problem bei den deutschen Meisterschaften. Um Arbeitsspeicher zu sparen, war das Array, in dem die Karte gespeichert wurde, nur so groß, wie es sein musste. Die Startposition des Roboters mussten wir deshalb auch manuell einstellen. Das ist dann ein Problem, wenn der Roboter auf einmal im Labyrinth neu starten sollte oder mitten im Labyrinth gestartet werden sollte (theoretisch nach neuen Regeln möglich). Wir haben uns darüber recht viele Gedanken gemacht (dynamische Arrays, Verschiebung des Arrayinhalts etc.), aber nichts ist so unkompliziert, wie ein simpler offset: Sobald der Roboter vom Rand des Speichers fährt, wird eine Variable hochgezählt und es wird am anderen Speicherrand weitergemacht. Bei der Darstellung wird dieser Offset einfach aufaddiert und die Karte entsprechend zurück verschoben. Das Ganze braucht insgesamt ca. 50 Zeilen Code.

  3. [Erledigt] Darstellung der Karte
    Bei großen Labyrinthen braucht man einen großen Speicher. Bis jetzt haben wir immer den gesamten Speicher auf dem Display dargestellt. Das Display beansprucht die meiste Zeit des Programmdurchlaufs (Programmdurchlauf: bei normaler Größe des Labyrinths, d.h. 10x5x2 Fliesen ca. 12ms, Display 8ms), davon wiederum die Darstellung der Karte das meiste (ca. 5ms). Bei größerer Karte, wenn zum Beispiel zwei Räume in beide Richtungen nebeneinander liegen, die Karte also 10x10x2 Fliesen groß ist, beansprucht das Display weitere 5ms (es muss ja jede Wand aus dem Array ausgelesen und dargestellt werden). Das ist nicht so schön, weshalb wir uns einen zweiten Darstellungsmodus für die Karte überlegt haben: Es werden immer nur die nächsten 4 Fliesen in jede Richtung um den Roboter dargestellt. So müssen nur 64 Fliesen, also 192 Wände und Untergründe (für die schwarzen Flächen) anstatt im schlimmsten Fall 600 Wände und Untergründe dargestellt werden. Somit brauchen wir für einen Hauptschleifendurchlauf nur noch 10ms.

    Hauptansicht: Kartenmodus 0. Man sieht den gesamten Speicher der unteren Etage (z-Position 0). Ganz rechts die Zeit für einen Schleifendurchlauf: 14ms.

    Kartenmodus 1: Hier wird ein Ausschnitt von 6 Fliesen um den Roboter angezeigt. Die Dauer eines Schleifendurchlaufs beträgt 2ms weniger. Das ist zwar nicht viel, aber es ist besser.

  4. [Erledigt] Watchdog
    Wir kommen nochmal auf das „immer vom schlimmsten Fall ausgehen zurück: Das allerschlimmste, was passieren könnte, ist, dass der Roboter sich aufhängt, warum also auch immer das Programm einfriert. Damit hatten wir letztes Jahr Probleme, haben es auch mit einem Watchdog gelöst. Ein Watchdog wird in der Hauptschleife immer wieder gesetzt. Wenn er aber eine definierte Zeit (bei uns 120ms) nicht gesetzt wird, das Programm also eingefroren ist, resetet sich der Roboter automatisch (hier kommt wieder Punkt 2: Der Roboter befindet sich dann sehr wahrscheinlich irgendwo im Labyrinth und hätte Probleme mit dem Speicher, wenn er losfahren würde). Jetzt wird so eine Situation erkannt und auch, nachdem der Roboter neugestartet ist, angezeigt. Dieser Status lässt sich in Zukunft vielleicht auch von anderen Teilen des Programmes erkennen und diese könnten dann in einen bestimmten Modus springen (vielleicht ja die Karte in Zukunft auf einer SD Speicherkarte speichern und ggf. wiederherstellen?).
  5. Schwarze Fliesen
    Zusammen mit dem neuen Sensor zur Erkennung der schwarzen Fliesen muss auch die Programmierung daran angepasst werden. Was genau wir da machen, wissen wir noch nicht, dazu dann wenn es so weit ist noch ein Artikel.
  6. Rampe
    Bis jetzt haben wir die Rampe ganz einfach über die Position des Roboters in der Karte erkannt. Das ist aber keine 100%ig saubere Lösung, wenn die Rampe an einer anderen Position ist, kann der Roboter sie nicht vernünftig fahren (Problem bei der Rampe ist, dass sie ein eigenes Unterprogramm zum Fahren braucht und nicht Fliesenweise abgefahren werden kann, da die Rampe ja geneigt ist und es deshalb unter Umständen Konflikte mit den Maßen der Karte geben kann). Deshalb muss die Rampe nun über den Neigungssensor der IMU erkannt werden und die Position der Rampe in der Karte gespeichert werden. Wo die Rampe in der oberen Etage aufhört spielt dank Punkt 2 keine Rolle mehr, lediglich die Position muss dann gespeichert werden.
  7. Lack of Progress, Eingriff
    Auch, wenn das nachher noch so unwahrscheinlich ist, muss das vorgesehen werden… Genau, immer vom schlimmsten Fall ausgehen. Der Roboter muss aufgrund des Navigationsalgorithmus’ Markierungen in der Karte machen. Wenn der Roboter nun irgendwo hängen bleiben sollte, stimmt die Position und somit die Markierungen nicht mehr mit dem Roboter überein, evtl. bleibt der Roboter dann stehen. Das gleiche passiert (aber dann beabsichtigt), wenn der Roboter das Labyrinth einmal komplett durchfahren hat. Nach den neuen Regeln muss er dann nur noch 5 Sekunden auf der Startplatte stehen bleiben, anstatt komplett. Das können wir ausnutzen, um das Programm neu zu starten bzw. die Karte „auszuradieren”. Wenn das Programm also richtig funktioniert und der Roboter normal am Eingang für 5 Sekunden stehen bleibt, ist der Wertungslauf beendet und es gibt den Punktebonus, wenn zuvor ein Fehler passiert ist, bleibt der Roboter irgendwo im Labyrinth stehen, wartet 5 Sekunden (oder etwas mehr) und fängt dann von vorne an (und hier kommt erneut Punkt 2 mit der dynamischen Karte, wenn der Roboter nämlich irgendwo mitten im Labyrinth stehen bleibt). Das Einzige, was dann passiert, ist, dass es eventuell nicht den Startbonus gibt.
    Wenn man das nicht möchte, kann man einen Eingriff machen. Das gibt einen Punktabzug, aber man darf dafür dem Roboter die neue Position mitteilen (dabei wird er auch an einen bestimmten Punkt zurückgesetzt). Dann stimmen natürlich trotzdem die bereits gespeicherten Markierungen für den Algorithmus, weshalb der Roboter quasi seinen Pfad speichern muss, damit er weiß, bis zu welchem Punkt die Markierungen zurückgesetzt bzw. nicht beachtet werden müssen.
  8. Update der I²C-Kommunikations Bibliothek
    Wir haben festgestellt, dass wir einen Bug in der Programmbibliothek zur Kommunikation mit den Wärmesensoren haben. Die Ursprungsbibliothek ist voll mit Schleifen, die auf ein Ereignis warten, also für unseren Roboter tötlich, wenn mal keine Antwort kommen soll. Deshalb wird in den Schleifen eine Variable hochgezählt und die Schleife abgebrochen, wenn ein Schwellwert erreicht wird. Ganz einfach. Leider funktioniert das noch nicht 100%ig und das gesamte I²C Modul des Mikrocontrollers schmiert ab, wenn abgebrochen wird, weshalb wir da noch etwas optimieren müssen.
  9. Hindernisumfahrung
    Last but not least das i-Tüpfelchen: Wenn noch genug Zeit bleibt (und ich bin mir sicher, es bleibt noch genug Zeit bis zum Wettbewerb), implementieren wir auch noch die Hindernisumfahrung. Laut Regeln kann es vorkommen, dass ein Hindernis im Parcours platziert wird. Ein Hindernis darf eine bestimmte Größe nicht überschreiten, hat jedoch eine Mindestgröße und darf jede beliebige Form haben. Es ist garantiert, dass neben dem Hindernis min. 30cm, also eine Fliese, Platz für den Roboter zur ungehinderten Wegfindung bleiben. Das Hindernis kann also so aussehen (hellblau, rote Wände erstmal unwichtig):

    Hindernis

    Parcours: Hellblau: Hindernis

    Man sieht also, dass das Hindernis in diesem beispiel 4 Fliesen belegt, aber um das Hindernis noch ein pfad zum Vorbeifahren bleibt. Unsere Idee ist es, den Roboter normal fahren zu lassen, wenn aber plötzlich ein Hindernis erkannt wird, er die bis dahin gefahrene Distanz zurückfährt und eine „virtuelle” Wand einzeichnet (rot). So sperrt er nach und nach das Gebiet mit dem Hindernis.

Das war es vorerst – sicherlich werden wir nach uns nach auf weitere kleine Probleme stoßen, die wir in die Programmierung einbauen müssen. Auch dazu dann ggf. mehr.

Der Termin für die German Open 2014 wurden übrigens schon bekanntgegeben: Vom 3. bis zum 5. April findet der Wettbewerb wieder in Magdeburg statt. Wann die Vorqualifikationen stattfinden, wurde allerdings noch nicht verkündet.

RoboCup 2014: Überarbeiteter Roboter Teil 1: Hardware

Wie schon im letzten Beitrag von kurz nach den deutschen Meisterschaften, die jetzt schon fast drei Monate her sind, erwähnt, haben wir uns in letzter Zeit intensiv mit einer überarbeiteten Version unseres Roboters beschäftigt. Wir haben aus unseren Fehlern gelernt:

  • Keine LEGO Teile mit einem Selbstbau kombinieren:
    Wir dachten, wir hätten mit den LEGO Teilen insofern einen Vorteil, dass man sehr flexibel ist und einfach Teile auswechseln kann, beim Wettbewerb vielleicht bei anderen Teams fragen könnte, aber das (zum Glück) nicht nötig. Man ist mit den recht großen und klobigen LEGO Teilen eher recht unflexibel. Außerdem sind die LEGO Motoren nicht so robust, wie eigentlich gedacht – Nach zwei Jahren Betriebszeit kann da schon mal ein Motor kaputt gehen (indem er einfach von jetzt auf gleich blockiert).
  • Alles durchplanen:
    Wir haben bei unserem letzten Roboter nicht von Anfang an alles berücksichtigt und den Roboter bzw. nur die Aluminiumteile auf Papier geplant. Wenn man etwas erweitern möchte, muss bzw. mussten wir „aufstocken”, also unschön noch einen riesen Sensorkopf oben drauf setzen, weil einige Sensoren nicht eingeplant waren. Dieses Mal haben wir alles mit CAD durchgeplant – dazu später mehr.
  • Sollte eigentlich selbstverständlich sein, dazu hatten wir aber letztes Jahr, wie man gesehen hat (und wir auch gefühlt haben) keine Zeit mehr:
    Jeden Fall berücksichtigen und immer vom schlimmsten Fall ausgehen. Wenn einmal etwas schief läuft, kann es immer wieder passieren, d.h. jeden Fehler, egal, wie klein oder wie groß er ist, ernst nehmen.

Es hab da noch ein paar Kleinigkeiten, auf die hier nicht näher eingegangen wird.

Jetzt endlich zum neuen Roboter: Der alte Roboter war ja nicht komplett „falsch” (wie im Video zu sehen). Im Gegenteil, vieles hat sehr gut funktioniert! Problem war, dass wir vor den deutschen Meisterschaften zu wenig Zeit hatten, ein Eingriffsprogramm zu entwickeln (insgesamt waren wir bis Ende 2012, also zwei Monate vor dem ersten Wettbewerb, mit der Hardware beschäftigt). Natürlich darf auch das beim Wertungslauf nicht passieren, aber wie gesagt: Immer vom schlimmsten Fall ausgehen. Anfangs, direkt nach dem Wettbewerb, haben wir die Schuld auf die relativ Leistungsschwache Elektronik geschoben und wollten unbedingt auf was schnelleres umsteigen (Mikrocontroller mit ARM Kern (32bit), wir benutzen einen AVR (8bit) – Vor allem Speicherplatz und Geschwindigkeit waren verlockend, aber auch der sinnvolle Einsatz von C++. Außerdem sind ARMs zeitgemäß und werden immer öfter eingesetzt). Wir haben uns jedoch letztlich dagegen entschieden, wobei natürlich der finanzielle Aspekt keine kleine Rolle gespielt hat.
Bei guter Programmierung ist das System egal. 😉

Bei der Mechanik und speziell beim Fahrwerk musste aber unbedingt etwas passieren. Der alte Roboter war, da er komplett „handgefertigt” war, mehr oder weniger krumm und schief. Das hat es unmöglich (da eben (für uns) unberechenbar) gemacht, den Roboter 100%ig zuverlässig durch das Labyrinth fahren zu lassen. Deshalb haben wir uns wie gesagt für die Planung am Computer via CAD entschieden. Basismaterial, also das Chassis, sollte aus Plexiglas bestehen: Billig, leicht zu bearbeiten, extrem robust. Das Plexiglas sollte aber nicht von Hand bearbeitet, sondern Lasergeschnitten werden. Preislich macht das fast keinen Unterschied. Dafür hat man dann ein perfektes Ergebnis.

Plexiglasplatten halb transparent – unten Chassis (6mm Stärke) zur Aufnahme der Motoren und sämtlicher Elektronik, oben die „Bumperplatte” (3mm Stärke), die zur Begrenzung des Roboters und zum Befestigen der Sensoren und der Bedieneinheit dient.

Probleme hatten wir auch mit dem Schwerpunkt des Roboters, was mit den LEGO Motoren aus Kunststoff zusammenhing. Für den neuen Roboter nutzen wir „richtige“ Metallmotoren – vier Stück an der Zahl (das Konzept mit dem Allradantrieb hat sich bewährt, auch bei anderen Teams). Dabei werden später zwei Motoren pro Seite parallel angeschlossen, damit die alte Elektronik weiterverwendet werden kann. Der Akku befindet sich später zwischen den Motoren – so weit wie möglich unten.

Vier Motoren, griffige Räder, ein Akku in der Mitte

Wie oben bereits erwähnt, sollte die Elektronik und das Sensorkonzept vom letzten Jahr weiterverwendet werden. Die Elektronik hat allerdings nun zwei Schwachstellen:

  1. Wir haben letztes Jahr vergessen, quasi das gesamte „Power Management” mit auf die Platine zu setzen, dazu zählen eine Sicherung (deshalb ist uns bei einem Kurzschluss des Akkus schon einmal eine Leiterbahn verbrannt, die wir zum Glück überbrücken konnten) und der Spannungsteiler zum Messen der Akkuspannung.
  2. Die Aufteilung der zwei Motoranschlüsse auf vier Motoren
Platinenansicht

Platinenansicht auf 1. Ebene: Von links n. rechts: IMU – Mainboard – Power Unit

Deshalb haben wir uns dazu entschieden, für ein paar € dafür eine eigene Platine zu erstellen. Es ist zwar möglich, das Ganze irgendwie fliegend aufzubauen, aber da zu erwarten ist, dass so oder so viele Kabel verlegt werden müssen, macht das ein Debugging bei fehlerhafter Hardware später schwierig bis unmöglich. Auf der Platine befinden sich die oben erwähnten Einheiten. Da wir die Motoren parallel schalten, müssen sich die Motoren auf einer Seite gleich schnell drehen, weshalb auch nur ein Encoder pro Seite ausgewertet werden muss.

Power Unit – rohes Platinenlayout

Das Sensorkonzept hat uns sehr gut gefallen und sollte gleich bleiben: Pro Seite zwei Sensoren (einer vorne, einer hinten) zum Ausrichten, dann noch pro Seite ein Sensor in der Mitte zum Geradeausfahren bzw. Erstellen der Karte. Die IMU hat auch sehr gut funktioniert und wird weiter benutzt. Genau so das Display, dazu im nächsten Artikel aber mehr.

Roboter: Komplettansicht. Die vier Kegel stellen den Öffnungswinkel der Wärmesensoren dar.

Die nötigen Teile für den Roboter sind bereits bestellt, wahrscheinlich wird die Hardware also gegen Ende der Sommerferien (ca. 2 Wochen) stehen.
Lediglich der Sensor zur Erkennung der schwarzen Flächen fehlt noch. Wir haben schon eine Idee parat, dazu aber mehr, wenn es so weit ist.

CAD-Software