Firmware, Bluetooth-Brücke und Agent-Skill für den KOSMOS-Proxi: einmal flashen, danach hört der Roboter über Bluetooth LE auf Textbefehle. Was die Befehle schickt, ist ihm egal — ein Skript, ein curl, oder ein KI-Agent, der aus "mach mal was Lustiges" eine Choreografie baut. firmware/ MakeCode-Projekt (TypeScript) und fertige .hex für V1 und V2 bridge/ BLE-Brücke und HTTP-API, einzige Abhängigkeit ist bleak agent/ Skill-Definition: Alltagssprache -> Befehle tools/ Quelltext aus .hex extrahieren, Musik-Tabellen prüfen docs/ Protokoll, Einrichtung, Hardware, Lizenzen Zwei Dinge, die sonst nirgends stehen und in docs/HARDWARE.md dokumentiert sind: die Pin-Belegung des Roboters ist nicht öffentlich, sie wurde aus den mitgelieferten .hex-Dateien rekonstruiert (tools/hex_source.py holt sie heraus). Und der Ton braucht zwingend eine ganzzahlige Frequenz sowie Pin P0 — sonst kracht der Lautsprecher, der Aufruf hängt und die Bluetooth- Verbindung stirbt. Am echten Roboter durchgetestet: Verbindung, Sensoren, Display, 41 Sekunden Musik am Stück, alle Bewegungsrichtungen, Musik und Fahren gleichzeitig, Tanzfiguren, Not-Stopp mitten in der Bewegung, Autostart nach Neustart. MIT-Lizenz. Die Hardware-Extension stammt von kaku111 (TobbieII) und die Notendaten aus pxt-microbit, beide ebenfalls MIT — siehe THIRD-PARTY-NOTICES.
8.1 KiB
name, description
| name | description |
|---|---|
| proxi-control | Steuert den Proxi-Roboter. Nutze diesen Skill, wenn jemand will, dass Proxi etwas tut — laufen, tanzen, sich umschauen, ein Gesicht zeigen, etwas sagen, Hindernisse suchen. |
Proxi steuern
Proxi ist ein kleiner zweibeiniger Roboter mit einem micro:bit als Kopf. Du schickst ihm Textbefehle über die Brücke und übersetzt damit, was der Mensch in Alltagssprache will.
Befehle senden
Du brauchst keine Dateien und kein Python. Die Brücke läuft als Dienst auf
dem Raspberry Pi und ist über HTTP erreichbar — curl genügt.
Die Adresse der Brücke steht in der Umgebungsvariablen PROXI_URL:
PROXI="${PROXI_URL:?PROXI_URL ist nicht gesetzt — Adresse der Proxi-Brücke, z.B. http://proxi.local:8080}"
Ist sie nicht gesetzt, sag das dem Menschen, statt eine Adresse zu raten. Sie hängt davon ab, wo die Brücke läuft — typisch ist der Hostname des Raspberry Pi plus Port 8080, notfalls dessen IP-Adresse.
Ein einzelner Befehl:
curl -sX POST $PROXI/command \
-H 'Content-Type: application/json' \
-d '{"command":"MOVE:FWD:1000"}'
Mehrere am Stück — die Brücke arbeitet sie der Reihe nach ab, inklusive der
WAIT-Pausen. So schickst du Choreografien:
curl -sX POST $PROXI/commands \
-H 'Content-Type: application/json' \
-d '{"commands":["FACE:HAPPY","MELODY:FUNK","TURN:LEFT:400","WAIT:450","TURN:RIGHT:400","WAIT:450","STOP"]}'
Nachsehen, ob Proxi überhaupt da ist:
curl -s $PROXI/status # {"connected": true, ...}
Steht dort "connected": false, ist Proxi ausgeschaltet oder außer Reichweite.
Sag das dem Menschen, statt Befehle ins Leere zu schicken — die Brücke
verbindet sich von selbst, sobald er eingeschaltet wird.
Nicht selbst starten
proxi_bridge.py brauchst du nicht und sollst du nicht aufrufen. Das Skript
liegt auf dem Pi und läuft dort bereits als Dienst. Eine zweite Instanz würde
scheitern: Bluetooth LE erlaubt nur eine Verbindung zum Roboter, und die
hält der Dienst. Alles läuft über HTTP.
Was Proxi kann
| Befehl | Wirkung |
|---|---|
MOVE:FWD[:ms] / MOVE:BWD[:ms] / MOVE:STOP |
laufen |
TURN:LEFT[:ms] / TURN:RIGHT[:ms] / TURN:STOP |
Oberkörper drehen |
DANCE[:n] / STAMP[:n] / SHAKE[:n] |
tanzen, aufstampfen, Kopf schütteln |
FACE:<name> / FACE:RAW:z0:z1:z2:z3:z4 |
Gesicht zeigen |
TEXT:<text> |
Text über das Display laufen lassen |
MELODY:<name> / TONE:<hz>[:ms] |
Musik und Töne |
SENSOR:ALL / SENSOR:IR_L / SENSOR:IR_R |
Sensoren lesen |
CLEAR / STOP / PING / STATUS |
System |
Die vollständige Liste aller Namen für FACE und MELODY steht in
docs/PROTOCOL.md. Rate keine Namen — nimm einen aus
der Liste oder frag nach.
Regeln
Es gibt keine Geschwindigkeit. Die Motoren können nur an oder aus. Alles, was du steuerst, ist die Dauer. "Langsam" gibt es nicht — "kurz" schon. Erfinde keinen Speed-Parameter.
Realistische Zeiten. Grobe Anhaltspunkte, jeder Untergrund ist anders:
| Was | Dauer |
|---|---|
| ein, zwei Schritte | 800–1500 ms |
| durchs Zimmer | 4000–6000 ms |
| Vierteldrehung | ~700 ms |
| halbe Drehung | ~1400 ms |
Zwischen Bewegungen WAIT:<ms> setzen. Bewegungsbefehle kommen sofort mit
OK zurück und laufen dann weiter — ohne Pause überschreibt der nächste
Befehl die noch laufende Bewegung, und Proxi zuckt nur. WAIT ist eine Pause in
der Brücke, kein Befehl an den Roboter. Immer etwas länger als die Bewegung
davor:
MOVE:FWD:1200
WAIT:1400
TURN:LEFT:700
WAIT:900
Immer mit STOP enden, wenn eine Bewegungsfolge fertig ist.
Ohne Dauer stoppt eine Bewegung nach 10 Sekunden von selbst. Nutze :0 nur,
wenn wirklich bis auf Weiteres gefahren werden soll — und dann mit einem klaren
STOP danach.
Lauf- und Drehmotor sind unabhängig. Beide zusammen ergibt eine Kurve:
MOVE:FWD:0 plus TURN:LEFT:800.
Für Choreografien: MOVE und TURN laufen parallel zur Musik, DANCE,
STAMP und SHAKE nicht. Die drei Figuren teilen sich mit MELODY und
TEXT denselben Arbeiter und kommen deshalb erst dran, wenn die Melodie
fertig ist — bei MELODY:NYAN also 16 Sekunden später.
Soll zur Musik getanzt werden, bau die Schritte aus MOVE und TURN:
Wackeln ist TURN:LEFT:220 / TURN:RIGHT:220 im Wechsel, Stampfen
MOVE:FWD:200 / MOVE:BWD:200, eine Kurve MOVE:FWD:0 plus TURN.
DANCE und Co. gehören vor oder nach die Melodie, nicht mittenrein.
Ein fertiges Beispiel liegt in bridge/nyan-dance.txt.
Aber immer nur ein Klang. Ein neues MELODY oder TONE bricht das ab, was
gerade läuft. Soll eine Melodie ausklingen, gib ihr mit WAIT Zeit, bevor der
nächste Ton kommt.
Kleine Choreografie
Auf "Proxi, freu dich!":
{"commands": [
"FACE:FABULOUS",
"MELODY:POWERUP",
"STAMP:2", "WAIT:1200",
"TURN:LEFT:600", "WAIT:800",
"TURN:RIGHT:1200", "WAIT:1400",
"TURN:LEFT:600", "WAIT:800",
"DANCE:2", "WAIT:1500",
"FACE:HEART",
"STOP"
]}
Eine Choreografie zur Musik bauen
Das ist die Königsdisziplin — und es gibt ein paar Regeln, ohne die es
auseinanderfällt. Geschickt wird eine Choreografie als eine einzige Liste an
POST /commands, mit WAIT als Taktgeber dazwischen.
Getanzt wird mit MOVE und TURN, nicht mit DANCE. Nur die beiden
laufen wirklich parallel zur Musik.
Melodien reihen sich von selbst aneinander. Schickst du MELODY:B,
während A noch läuft, startet B nahtlos danach. So baust du mehrteilige
Stücke.
Rechne mit den Laufzeiten. So lange spielt jede Melodie:
| ~0,5–1 s | BADING JUMPUP JUMPDOWN POWERUP POWERDOWN |
| ~2,5–3,5 s | WAWAWAWAA PUNCHLINE RINGTONE BADDY ENTERTAINER FUNERAL |
| ~4 s | DADADUM FUNK |
| ~8 s | CHASE WEDDING PRELUDE |
| ~12 s | BIRTHDAY BLUES |
| ~16 s | ODE NYAN |
WAIT ist rund 150 ms kürzer als die Bewegung davor — so lange braucht
die Brücke selbst zwischen zwei Befehlen. Ohne diesen Abzug läuft der Tanz
der Musik davon.
Tanzschritte bestehen aus drei Bausteinen:
Wackeln TURN:LEFT:220 / TURN:RIGHT:220 im Wechsel
Stampfen MOVE:FWD:200 / MOVE:BWD:200 im Wechsel
Kurve MOVE:FWD:0 + TURN währenddessen, danach MOVE:STOP
Kurze Zeiten wirken hektisch, lange gemütlich. Genau daraus entsteht Rhythmus.
Ein vollständiges Beispiel (vier Teile, 30 Sekunden) steht kommentiert in
bridge/bigdance.txt im Repo. Die Zeilen dort sind genau die Liste, die an
POST /commands geht — Zeilen mit # sind Kommentare und werden weggelassen.
Jeder Abschnitt bekommt ein eigenes Gesicht — das macht aus einer Bewegungsfolge eine Aufführung.
Gleich viel vorwärts wie rückwärts, dann bleibt Proxi ungefähr da, wo
er losgetanzt ist. Und am Ende immer STOP.
Sensoren nutzen
SENSOR:IR_L und SENSOR:IR_R liefern 0–1023, höher heißt näher.
Am Gerät gemessen: freie Sicht 5–15, Hand in etwa 10 cm 200–600, direkt davor
bis ~980. Ab 400 steht etwas im Weg — das entspricht ungefähr einer Handbreit.
Proxi kann kein Licht messen. Der Helligkeitssensor sitzt hinter einer getönten Scheibe und ist deshalb nicht angeschlossen. Sag nicht, Proxi könne sehen, ob es hell oder dunkel ist — er kann es nicht.
Soll Proxi einem Hindernis ausweichen, fahr in kurzen Etappen und miss dazwischen, statt blind eine lange Strecke zu setzen:
SENSOR:ALL -> SENSOR:ALL:IR_L=12,IR_R=640,...
rechts ist was -> nach links ausweichen
TURN:LEFT:700
WAIT:900
MOVE:FWD:1200
WAIT:1400
SENSOR:ALL
Wenn nichts passiert
Kommt OK zurück, aber Proxi bewegt sich nicht: SENSOR:PWR abfragen. Steht da
0, ist Proxis Schalter aus (der micro:bit hängt dann nur am USB-Strom). Sag
das dem Menschen, statt weiter Fahrbefehle zu schicken.
Sicherheit
Proxi fährt auf dem Boden herum, oft mit einem Kind daneben.
- Keine Dauerfahrten ohne Zeitlimit
- Nach jeder Folge
STOP - Taste A am Roboter ist der Not-Stopp und geht immer, auch ohne Verbindung
- Wenn jemand "Stopp" sagt: sofort
STOPschicken, Nachfragen kommen danach