Kleine GUI Verbesserungen

 Nach diversen Aktualisierungen im Programmcode sollte auch etwas für die Optik getan werden. Zur leichteren Erkennbarkeit wurden weitere "LEDs" hinzugefügt:

Diese zeigen den Status diverser Module an:

  • Der Heartbeat blinkt im Rhythmus der Antworten vom Atmel-Board durch Abfrage des Sensorthreads. Sie leuchtet konstant rot, wenn der Roboter nicht als angeschlossen erkannt wurde.
  • Die Compass-LED zeigt an, ob das Compass-Modul mit dem Atmel-Board physisch verbunden ist.
  • Die Camera-LED leuchtet (derzeit), wenn mittels OpenCV eine angeschlossene Kamera erkannt wurde.
  • Die Joystick-LED ist grün, wenn ein Joystick angeschlossen ist.
  • Die Network-LED soll einmal anzeigen, wenn eine Kommunikation über WLAN mit direcs-remote stattfindet (welches wichtige Status.-Werte des Roboters remote anzeigt).
  • Eine hier noch nicht dargestellte weitere Laser-LED zeigt an, ob der Laserscanner erkannt wurde.

Als weitere Verbesserung wurden die Plot-Bereiche mit Gitternetzlinien versehen, was nicht nur eine leichtere Lesbarkeit bewirkt, sondern insgesamt einen professionelleren Eindruck macht: 

Um auf einen Blick noch schneller den Status des Roboters darzustellen, wurde ein weiterer Plot-Bereich hinzugefügt, der im Prinzip den wechselnden Status der Heartbeart-LED darstellt:

Und so sieht das ganze dann vollständig im Betrieb aus:

 

Screenshots direcs1

 

Zwei aktuelle Screenshots – einmal der erste Test mit dem neuen ARM-Board unter Linux in der Debian-VM (Parallels unter Mac OS X), der zweite nativ auf dem Mac.
15.04.2012

Erste Experimente mit der Microsoft Kinect Kamera und dem OpenKinect / libfreenect Sourcecode.
30.12.2010

Größeres Redesing: Grafischen Heartbeat korrigiert, Roboter-Motor-Status wird nun grafisch rechts oben angezeigt (mit GUI LEDs), Änderung der Hauptfenstergröße zur Anzeigen auf dem MacBook Pro.
30.11.2010

Kleine Verbesserungen in der GUI: Grafische LEDs über den Zustand diverser Module im „state“ Bereich rechts oben, Gitternetzlinien innerhalb der Plot-Fenster (Batteriespannungen) und ein grafischer Heartbeat (rot).
14.11.2010

Fotos vom neuen Commel Pico ITX Board

Hier ein paar aktuelle Fotos vom neuen ein Pico-ITX Board von Commel; das 170G, welches das neue "Herz" des Roboters direcs1 werden soll. Erste Tests liefen bereits erfolgreich, ein Debian brachte alle Treiber out-of-the-box mit, so dass auch die KDE ebenfalls korrekt mit passendem Grafikkartentreiber lief. Aber hier nun erstmal die Fotos:

      

Hier noch einmal im Größenvergleich mit dem defekten fit-PC2:

    

Hier liegt neben dem neuen Pico-ITX-Board die "alte" Mini-PCI-WLAN-Karte aus dem fit-PC2:

 

Und so sieht das ganze verkabelt und angeschlossen aus – mehr Kabel als Board  :

   

coding, coding, coding…

Nachdem es in der Vergangenheit öfter Probleme mit der seriellen Übertragung gab, fiel der Entschluss, alle Übertragungen zwischen dem Atmelboard und dem Computer nicht mehr in Binärform sondern in reinem ASCII zu senden. Dazu wurde im git Repository ein neuer Branch namens AtmelSerialClearText angelegt und seit Mitte August immer mal wieder daran gearbeitet. Nun ist es endlich soweit, nahezu alle Funktionen sind komplett auf die neue Übertragungsmethode umgestellt – sowohl auf Computer, als auch auf Atmel-Seite. Wie man sieht, waren dazu doch einige Änderungen nötig:

Merge made by recursive.

 direcs-avr/adconv.c         |   33 ++

 direcs-avr/adconv.h         |    6 +

 direcs-avr/main.c           | 1040 +++++++++++++++++++++++++++++————–

 direcs-avr/main.h           |   13 +-

 direcs-avr/micromag.c       |    4 +

 direcs-avr/usart.c          |  174 ++++++–

 direcs-avr/usart.h          |   38 ++-

 direcs/direcs.tag           |  193 ++++++–

 direcs/src/circuit.cpp      |  112 ++++-

 direcs/src/circuit.h        |   39 ++-

 direcs/src/direcs.cpp       |  127 +++++-

 direcs/src/direcs.h         |   19 +-

 direcs/src/direcsSerial.cpp |   65 ++–

 direcs/src/direcsSerial.h   |    2 +-

 direcs/src/gui.cpp          |   79 ++++-

 direcs/src/gui.h            |   37 ++-

 direcs/src/interfaceAvr.cpp |   98 ++++

 direcs/src/interfaceAvr.h   |   58 ++-

 direcs/src/mainWindow.ui    |   86 +++-

 direcs/src/motor.cpp        |  792 +++++++++++++++++++++———–

 direcs/src/motor.h          |   46 +-

 direcs/src/plotThread.cpp   |   47 ++-

 direcs/src/plotThread.h     |   14 +-

 direcs/src/sensorThread.cpp |  495 +++++++++++———-

 direcs/src/sensorThread.h   |   27 +-

 25 files changed, 2540 insertions(+), 1104 deletions(-)

Zusätzlich wurde das serielle Verfahren auf dem Atmel ebenfalls vollständig neu geschrieben und arbeitet nun – anstatt in einer Endlosschleife auf den Empfang eines Zeichens zu warten – vollständig interruptbasiert.

Wie aber weiß nun der Atmel, wann eine Übertragung für ihn anfängt oder abgeschlossen ist? ganz einfach: Jede Übertragung muss mit einem ‚*‘ starten und mit einem ‚#‘ enden. Alle anderen Zeichenketten werden ignoriert. Eine Signalisierung über LEDs auf der Platine findet ebenfalls statt: Bei jedem empfangenen Zeichen blinkt die rote LED abwechselnd und sobald das Ende eines Befehls mit # erkannt wurde (und zuvor auch mit * startete!) wird dieses über eine grüne LED angezeigt.

Diese Art der Übertragung hat den Vorteil, dass man sie per Terminalprogramm gut debuggen kann, denn es werden nur ASCII-Zeichen verwendet. Zusätzlich antwortet der Atmel auch immer mit der empfangenen Zeichenkette, die wiederum vom Computer als Antwort überprüft wird. Eine neue Sicherheitsfunktion, die zuvor fehlte. Auch kann man dem Atmel so selbst mit einem Terminalprogramm Befehle senden und „sieht“ was er antwortet. Fragt man einen Wert vom Atmel ab, so antwortet er nur mit diesem Wert und dem Starter und Terminator, also z.B. mit *42#.

Und das sind die derzeitigen Befehle:

re = reset

s1 = get value from sensor 1

s8 = get value from sensor 8

s16 = get value from sensor 16

cc = check if compass module is connected. ‚ok‘ or ‚er‘

cx = get value from compass axis x

cy = get value from compass axis y

cz = get value from compass axis z

ms1 = get value from motor sensor 1

ms4 = get value from motor sensor 4

dd1 = get driven distance 1

..

dd4 = get driven distance 4

id1 = init distance 1

id4 = init distance 4

mp1of = motor power 1 off

mp4of = motor power 4 off

md1cw = motor direction 1 clockwise

md4cw = motor direction 4 clockwise

md1cc = motor direction 1 counterclockwise

md4cc = motor direction 4 counterclockwise

mv1nnn = set motor velocity 1 to nnn (0-255)

mv4nnn = set motor velocity 4 to nnn (0-255)

mv0nnn = set motor velocity for all motors to nnn (0-255)

bdf = bot drive forward

bdb = bot drive backward

bdl = bot drive left

bdr = bot drive right

btl = bot turn left

btr = bot turn right

bgo = bot go

bst = bot stop

bwa = bot wait

Meanwhile: checking of the motor behavior

 After changing the serial method to transceive ASCII clear text instructions instead if binary data, I found out that that the motors do not react the same when using identical instructions. To ensure that this is not due to a hardware error – and since it does not look like a software error too – I built a small analysis connector which disconnects all connections at all to test every electrical module  seperately. This is how the test looked like:

 

As you can see the green LED shows the state of the corresponding Atmel port bit. For easier testings I simple connected some series resistors of 1.5 k Ohm in line with some LEDs connected to the common ground – with 7-segmend-LEDs, to be more precise. These were than directly soldered on the board connecter:

 

This stuff worked as expected. After this the input ports from the motor control boards were set to high (one after another) to check of these boards work as expected. The most important thing when testing things like this: a wel organised and tidy working environment! 

 

To be honest the reason for this wild flying wires here are was that I had to test this directly at and close to the robot. Since I wanted to have a realistic test case with the original power supply etc. This is why I unmounted the PCBs only this far that I was able to connect all relevant connectors and not resulting in a short circuit.

Using this opportunity I finally labeld the last connectors and cables with this DYMO stuff – since at least anything was disassembled at this moment:

   

Result so far: No error found. After reassambling everything, all motors worked like they should – allthough nothing was changed. Strange…. 

Schematischer Aufbau direcs1

Auf dieser Seite ist der aktuelle schematische Aufbau des Roboters direcs1 dargestellt:

Stand: 04.04.2011

 

3D-Kompass-Modul-Verbindung wird geprüft und in GUI angezeigt

Beim Testen des Atmelboards außerhalb des Roboter fiel auf, dass es manchmal bei der seriellen Übertragung nach einiger Zeit timeouts gab. Die Ursache lag im Atmelcode für den Micromag 3D-Kompass. Dieser initialisiert beim ersten Start des Atmels das SPI / I²C Protokoll. Danach fragt das direcs-Hauptprogramm den Atmel nach den Kompassdaten. Ist das Kompassmodul aber nun gar nicht mit dem Atmelboard verbunden, so kommt es zu den timeouts, da im SPI-Code auf bestimmte Bitzustände gewartet wird.

Um dieses zu verhindern und hiermit auch eine weitere Sicherheit einzubauen, wird nun beim Abfragen der Kompasswerte jedesmal geprüft, ob ein bestimmtes Portbit gesetzt ist. Dieses Portbit ist durch einen 100k-Widerstand am Atmelboard standardmäßig auf Masse gezogen. Wird das Kompassmodul nun per Falchbandkabel angesteckt, wird diese Leitung vom Kompassmodul aus auf 5V "hoch gezogen". 

Bei der Initialisierung des Atmelboards bzw. der Prüfung ob der Roboter eingeschaltet ist im direcs-Hauptprogramm, wird nun auch zusätzlich abgefragt, ob das Kompassmodul verbunden ist. Dieses wird auch in der GUI grafisch mit einer weiteren LED (rechts oben im Bild) angezeigt.

Atmel-Board gar nicht verbunden (Kompass damit natürlich auch nicht):

Atmel-Board verbunden, Kompassmodul nicht angeschlossen:

Atmel-Board verbunden, Kompassmodul ebenfalls angeschlossen:

 

ASIMO Vorführung im Miraikan in Japan 2010

Hier ein Video der ASIMO-Vorführung. Im Großen und Ganzen sicher nicht sehr aufregend, da die Veranstaltung sich eher an Kinder richtete. Leider ist das Video nur in iPhone (3GS) Qualität, da zum Zeitpunkt der Aufnahme leider keine andere Videokamera verfügbar war.

Man kann aber gut die Bewegungsfreiheiten des von Honda entwickelten Roboters erkennen. An einer Stelle des Videos erkennt er einen vor sich liegenden Fußball und bei Minute 06:00 rennt er sogar ein kurzes Stück. Letzteres ist für einen Roboter in der Tat um so erstaunlicher, da er beim Rennen kurze Zeit nur auf einem Bein läuft und – wie beim Rennen eben üblich – kurze Zeit eben auch gar keinen Bodenkontakt hat. Dieses ist natürlich extrem kurz (80 ms) und im Video nicht so erkennbar aber hier beschrieben (pdf).

(Dauer: 10:58 Minuten)

 

Alle Fotos, die wir parallel vor Ort gemacht haben, findet ihr übrigens hier!

 

Montage des ersten Rad-Encoders

 Um die Zeit nach dem fit-PC-Tod zu überbrücken, wurde der erste zum Testen mal ein Rad-Encoder montiert. Dazu wurde als erstes eines der Räder vollständig mit Achse entfernt:

Wie zeichnet man nun mitten auf der 10mm Stahlachse einen Punkt ein. Gelöst wurde dieses ganz gut, durch ein paar Linien auf einer transparenten Folie. Durch diese wurde dann die Achse angekörnt und ein 2,5 mm Loch hinein gebohrt:

 

 

Normalerweise wäre jetzt das Loch auch in der Mitte gewesen, aber leider drückt sich aufgrund der Härte des Stahls beim Bohren der Werkstoff nach unten womit das Loch dann leider nicht mittig wurde. So oder so sieht das ganze mit 3m Gewinde dann so aus:

    

Macht aber nichts. Mit zwei Unterlegscheiben, längerer Schraube und Mutter wurde nun die Encoderscheibe befestigt:

    

Diese wurde nun auf der Achse montiert, in dem die 3mm Schraube in das neue Gewinde geschraubt wurde. Da der Innendurchmesser der Encoderscheibe größer als 3mm ist, konnte diese recht gut wieder mittig justiert werden:

  

Und so sieht das ganze dann wieder komplett montiert aus. auf dem letzten Bild liegt zu Testzwecken bereits die Gabellichtschranke, die dort später "irgendwie" montiert werden muss: