Skip to content

Verhalten

Thomas Euler edited this page Aug 30, 2020 · 37 revisions

In der Konfigurationsdatei hexbug_config.py können weitere "Verhaltensweisen" aktiviert werden. Folgende Verhalten sind derzeit implementiert:

Hinweis: Diese Verhalten benötigen gegebenenfalls weitere Sensoren oder andere Erweiterungen.

"Look at blob"

Drawing

Dieses Verhalten benötigt eine kleine Wärmebildkamera vom Typ AMG88xx ("GRID-Eye IR 8x8 thermal camera"), die z.B. bei Adafruit als Breakout verfügbar ist. Diese Kamera liefert 8x8 Pixel-Wärmebilder mit bis zu 10 Hz, wobei jeder Pixel einen Temperaturwert repräsentiert. Basierend auf einem Treiber von Adafruit, kann der Roboter diese Bilder auslesen und zur Navigation verwenden.

Die Bildverarbeitung auf dem ESP32 unter Python läuft langsam. Um zu demonstrieren, welche Möglichkeiten es gibt, dies zu beschleunigen, gibt es drei Versionen des Codes zur Blob-Detektion:

  • blob.py ist in Python geschrieben und benötigt keine Änderungen an der Firmware. Diese Version wird automatisch genommen, wenn ulab, eine an numpy angelehnte Mathematik-Bibliothek für Array-Berechnungen unter MicroPython, nicht geladen werden kann.

  • blob_ulab.py ist ebenfalls in Python geschrieben, verwendet aber zur Beschleunigung der Berechnungen Funktionen aus ulab und benötigt damit eine erweiterte Firmware, in die ulab eingebunden wurde.

  • blob_ulab2.py schleißlich verwendet spezielle, in C geschriebene Funktionen zum Filtern und zur Blob-Detektion, die in ulab eingebunden wurden (siehe hier).

In allen drei Fällen werden in einem Wärmebild "Objekte" erkannt und deren Position und Größe zurück geliefert. Damit ist es dem Roboter möglich, die Kamera auf den größten "blob" im Blickfeld auszurichten. Dies ist im Video zu sehen; die Kamera folgt der Bewegung des heißen Teebechers. Im Hintergrund wird das Wärmebild, dass der Roboter "sieht" angezeigt. Es wird gleichzeitig über MQTT-Telemetrie an den PC übermittelt; die Detektion der "blobs" läuft aber autonom auf dem ESP32.

Hinweis: Es gibt sicherlich bessere Verfahren, Blobs zu detektieren und auch der Python bzw. C-Code ist nicht optimal. Hier geht es nur darum, welche Geschwindigkeitsvorteile man durch die verschiedenen Lösungen erreichen kann.

Das momentan implementierte Verhalten besteht darin, dass der Roboter in regelmäßigen Abständen anhält, sich in Richtung der größten Wärmequelle ausrichtet und dann weiterläuft (Video).

Das Breakout-Board wird am Sensorarm des Roboters montiert; dazu gibt es eine Adapterplatte (siehe unten). Diese ist um 25° abgewinkelt, damit die Kamera horizontal nach vorne ausgerichtet ist, wenn der Sensorarm die IR-Distanzsensoren zur Hinderniserkennung schräg auf den Boden richtet. Diese Adapterplatte wird einfach zwischen dem Sensorhalter und der Aufnahme für den (oder die) Distanzsensor(en) montiert. In diesem Beispiel trägt der Sensorarm drei kleinere Distanzsensoren; diese Erweiterung ist hier erläutert.

Drawing

Das Verhalten lässt sich über Konstanten in hexbug_config.py steuern:

DO_FOLLOW_BLOB   = const(1)    # 1=enabled
BLOB_ROUNDS      = const(30)   # In behavour, how many rounds to look for blobs
BLOB_MIN_AREA    = const(5)    # # of pixels
BLOB_MIN_PROB    = const(50)   # [%]
BLOB_MIN_XY_OFFS = 0.1
BLOB_FILTER      = [[0.0625,0.125,0.0625], # Gaussian smooth, None=disable filtering
                    [0.125, 0.25, 0.125 ],
                    [0.0625,0.125,0.0625]]
BLOB_MIN_N_SD    = 0.5
BLOB_TSF         = const(2)    # Turn speed factor, increase to follow faster
BLOB_YSTEP       = const(4)    # maximal yaw step
BLOB_SPIN_MS     = const(50)   # Spin duration when following

"Find light"

Wenn aktiviert, steuert der Roboter auf die hellste Lichtquelle zu. Dazu vergleicht er die Ausgabewerte zweier Lichtsensoren und dreht sich bevorzugt auf die Seite mit dem höheren Helligkeitswert. Als Lichtsensoren können zwei Photodioden verwendet werden, die seitlich am Sensorarm angebracht sind und durch eine Abschirmung überwiegend das Licht auf der jeweiligen Seite messen.

Drawing

Die Photodioden werden über eine einfache Schaltung an zwei der A/D-Wandler-Eingänge angeschlossen. Dabei wird eine lichtabhängige Spannung über einen Spannungsteiler mit einem relativ hochohmigen Arbeitswiderstand gemessen. Die Ausgangsspannung ist linear proportional zur Lichtleistung.

Die hier verwendeten Photodioden sind vom Typ SFH 203 und für Licht im Wellenlängenbereich von 400 bis 1100 nm empfindlich.

Das Verhalten wird in hexbug_config.py folgendermaßen kontrolliert:

DO_FIND_LIGHT    = const(0)    # 1=enabled
AI_CH_LIGHT_R    = const(3)
AI_CH_LIGHT_L    = const(2)

Ein Wert von 1 in DO_FIND_LIGHT aktiviert das Verhalten. Die Nummern der analogen Eingänge (Pins) müssen in AI_CH_LIGHT_R und AI_CH_LIGHT_R gesetzt werden.

"Take a nap"

Wenn dieses Verhalten aktiviert ist, schaltet sich der Roboter von Zeit zu Zeit ab. Dieses Verhalten demonstriert die Verwendung der Schlafmodi (deepsleep, lightsleep) des ESP32. Um zu "schlafen", schaltet der Roboter die 5V-Versorgung des Boards ab und versetzt sich in einen Schlafmodus (derzeit mit lightsleep). Nach einer zufälligen Anzahl von Sekunden, wacht er wieder auf und läuft weiter.

DO_TAKE_NAPS     = const(0)    # =probability ([‰]) to activate behaviour
NAP_FROM_S       = const(5)    # range of random numbers to sleep ...
NAP_TO_S         = const(50)   # ... in [s]

Der Wert von DO_TAKE_NAPS wird in Promille angegeben; ein Wert von 0 schaltet das Verhalten aus. Die Konstanten NAP_FROM_S und NAP_TO_S legen den Bereich der Zufallswerte für die Schlafzeit fest (random.randint(NAP_FROM_S, NAP_TO_S)).

Um das Board abschalten zu können, muss ein 5V-Spannungsregler mit Shutdown-Pin (U1V11F5, siehe Bauteile unter "Optional") verwendet und die Konstante USE_POWER_SHD auf den Wert 1 gesetzt werden.

"Look around"

Von Zeit zu Zeit "schaut" der Roboter umher, während die LED gelb pulsiert. Dieses Verhalten hat keinen weiteren Nutzen, außer dass es den Roboter "lebendiger" wirken lässt. Die Häufigkeit, mit der das Verhalten aufgerufen wird, kann man über die Konstante DO_LOOK_AROUND in hexbug_config.py steuern:

DO_LOOK_AROUND   = const(30)   # =probabilty ([‰]) to activate behaviour

Der Wert wird in Promille angegeben; ein Wert von 0 schaltet das Verhalten aus.

Weiter zu Sensoren etc.