In diesem Artikel möchte ich die Entstehungsgeschichte meines Glockenspiel-Roboters mit euch teilen. Das Coding zum Roboter findet sich auf Github. Hier verlinkt findet ihr eine ungeschnittene Aufnahme vom letzten Stand des Roboters:

Ungeschnittene Aufnahme des Glockenspielers

Inhaltsverzeichnis

  1. Die Inspiration
  2. Mein selbstgestecktes Ziel
  3. Die ersten Ideen
  4. Zwei Bewegungen mit einer Achse
  5. Adios Wippe, hallo zweiter Arm
  6. Die erste Programmierung
  7. Ein vollständiges Lied
  8. Mehrere Lieder organisieren

Hinweis: Dieser Artikel ist noch in Arbeit. Ich wollte bereits diesen vorläufigen Stand für das Wintergatan-Meetup 2023 online stellen.


Die Inspiration

Im Januar 2022 bin ich auf Youtube über dieses Video des Kanals TechNewRobot gestolpert. Dort spielt ein Lego-Roboter souverän ein klassisches Lied (Bach Menuett in G-Dur) auf einem Glockenspiel.

Ansicht des Roboters von oben
„Lego mindstorms robot playing Bach…“ – by TechNewRobot

Besonders faszinierend finde ich die elegante Umsetzung: Die Schlägel sitzen auf zwei parallelen zum Instrument verlaufenden Schienen, auf denen sie per Seilzug bewegt werden. Jeder Schlitten umfasst ein Schlagwerk mit Motor. Durch deren Konstruktion ist nur eine halbe Motorumdrehung ohne Richtungswechsel für sehr kräftige Schläge notwendig:

Blick auf den Roboter entlang des Xylophons - mit den beiden Schlägeln links und rechts davon.
Frontansicht

Ferner muss so relativ wenig Masse bewegt werden – was gegenüber komplett fahrenden Robotern schnellere Lieder ermöglicht. Und durch die gradlinige Schlittenbewegung wird jeder Klangstab genau in der Mitte getroffen – was ohne Umherfahren schwierig ist.

Mein selbstgestecktes Ziel

Ich habe mir dieses Video immer und immer und immer wieder angeschaut – einfach wundervoll! Doch was mir auffiel: Um die „zuschlagenden“ Motoren auf ihren Schlitten schnell zur richtigen Note zu fahren, braucht es die Kraft von vier Motoren. Ließe sich dieser Kraftaufwand vermeiden?

Und warum muss sich der Roboter überhaupt so sehr der Form des Instruments anpassen? Könnte sich das Instrument nicht dem Roboter anpassen?

Man könnte doch auch zum Beispiel die Klangstäbe um den Roboter herum anordnen. Wie es unter anderem in diesem Video von faian000re zu sehen ist:

„Presentation of the xylophone robot“ – by faian000re

Bisher schien niemand die „Schlagkraft“ aus dem genannten Lego-Video mit solch einer kreisförmigen Anordnung kombiniert zu haben. Natürlich gibt es bereits andere, echt beeindruckende Glockenspielroboter da draußen. Aber eben keine kreisrunden lautstarken aus Lego.

Mein Glockenspiel auf Otto.de

Die Idee faszinierte mich. Und so kam es dann, dass ich mir Ende Februar 2022 bei Otto ein Glockenspiel bestellte. Es war der Beginn meiner mehrmonatigen Reise an die Grenzen meiner mechanischen, musikalischen und informationstechnischen Fähigkeiten, die ich hier mit euch teilen möchte.

Die ersten Ideen

Eines war mir direkt klar: Wenn ich die Klangstäbe schon frei anordne, dann sollen sie einen Kreis bilden. Denn es gibt keine elegantere Form als einen Kreis (Hexagons einmal ausgenommen).

Auf dieser Grundlage entstand der erste greifbare Entwurf…

… verbunden mit der rein ästhetischen Frage, wie die Klangstäbe später angeordnet sein sollten. Eine Entscheidung von absolut niedriger Priorität … aber sie regt die Fantasie an.

Das große Problem wurde aber schon jetzt ersichtlich: Wie soll der notwendige Elefant an Mechanik in den kleinen Porzellanladen in der Mitte passen? Von den keulenförmigen NXT-Motoren ganz zu schweigen.

Idee #1: Wie wäre es mit einer Konstruktion, bei der jeder Klangstab seinen eigenen Schlägel fest verbaut bekommt? Dieser wäre per Angelsehne oder ähnlichem mit der eigentlichen Mechanik „unter der Oberfläche“ verbunden. Das Problem, schnell die richtige Note anzusteuern, ließe sich so an eine Stelle verlagern, an der mehr Platz für dessen Lösung ist.

Meine damaligen Skizzen zu der Idee

… ein wesentlicher Bestandteil wäre dann wohl aber ähnlich der Konstruktion aus diesem Video aufgebaut – nur in Kreisform.

„Self-Playing LEGO Xylophone“ – by Kevin Darke

Ja, aber: Möchte ich wirklich ein Dutzend Angelsehnen (oder ähnliches) quer durch die Mitte meines Modells spannen? Ein Zerlegen des Roboters für den Transport wäre damit unmöglich. Und wartbar klingt das auch nicht. Hmm … also weiter überlegen.

Deshalb Idee #2: Inspiriert von einem meiner Lieblings-Youtuber habe ich mir sehr eine Lösung mit Murmeln gewünscht. So würde die Schwerkraft das Problem mit der Schlagkraft übernehmen. Die Mechanik müsste „nur“ gefallene Murmeln durch die Mitte wieder nach nach oben „pumpen“ (zum Beispiel so) und in die richtige Richtung fallen lassen.

Idee für ein Murmel-Reservoir je Klangstab

Hier ein Beispiel aus dem Video „legophone“ von hugolinvh, wie so eine Konstruktion grob aussehen könnte:

legophone by hugolinvh

Ja, aber: All das würde wohl viel mehr Probleme schaffen als überwinden. Hunderte lose Murmeln auf engstem Raum dazu zu bewegen, genau zur richtigen Zeit an die richtige Stelle zu rollen … schwierig. Besser wäre, wenn alle Bestandteile mechanisch direkt verbunden wären.

Damit zu Idee #3: In der Mitte des Kreises wird eine Wippe aufgehangen, die an beiden Enden Schlägel befestigt hat. Daran werden zwei Motoren angeschlossen. Der eine dreht die komplette Wippe so, dass ein Ende auf die gewünschte Note zeigt. Der andere Motor kippt die Wippe derart, dass das richtige Ende auf die Note schlägt. Um beide Drehungen durch die gleiche Achse in der Mitte zu leiten wollte ich das abgebildete „Turntable“-Bauteil und zwei dieser 90°-Zahnrädern verwenden.

Damalige Skizzen und Bauteile für die Wippen-Idee

Diese Idee empfand ich als vielversprechend. Mit nur zwei Motoren könnte ich damit schnell jede beliebige Note schlagen. Mehr als eine Viertel Drehung der Wippe sollte nie zur nächsten Note fehlen. Keine Schnüre, keine Murmeln, keine losen Bauteile, durchgängige mechanische Verbindungen.

Das sollte doch funktionieren … … oder nicht?

Zwei Bewegungen mit einer Achse

Entsprechend dieser Idee habe ich zunächst versucht, zwei Drehbewegungen um dem gleichen Mittelpunkt herum zu erzeugen. Dabei kam folgender Motorblock heraus. Ein Motor dreht den schwarzen Außenrand des „Turntable“-Teils, der andere Motor dreht eine Achse in dessen Mitte.

Nachteil hiervon: Die äußere Drehachse lässt sich deutlich schwerer verlängern als die innere. Ergo müssten die Schlägel nahe am klobigen Motorblock liegen. Es wäre sehr viel praktischer, wenn man beide Bewegungen mit einer einzigen Technik-Achse übertragen bekäme.

Als einzige weiterer Bewegungsfreiraum einer rotierenden Achse fiel mir nur Heben/Senken ein. Ergo habe ich einen Prototypen genau dafür gebaut: Ein Motor dreht die Achse, der andere hebt und senkt sie.

So kann der Motorblock beliebig weit von der Wippe entfernt sein. Zudem lassen sich auf diese Art und Weise die beiden Bewegungen direkt auf die Wippe übertragen, ohne zusätzliche Zahnräder. Damit wurde die Konstruktion simpler als ursprünglich gedacht.

Dieser Aufbau schien soweit zu funktionieren. Nach einigem Umbauten konnte der Prototyp einen der (relativ schweren) Klangstäbe tragen, sodass ein paar manuelle Tests möglich waren. Hier ein Video davon.

Es war sehr schwer, manuell die Noten hörbar zu treffen. Erste Zweifel an diesem Mechanismus kamen in mir auf. Es bräuchte sehr kurze, kräftige Bewegungen anstelle der kontinuierlichen Drehung des Motors.

Adios Wippe, hallo zweiter Arm

Im Laufe des Junis 2022 wollte ich den Zuschlagmechanismus verbessern. Zur gleichen Zeit fand ich auch ein Glasgefäß in einem sehr coolen Gebrauchtwarenhaus und habe mir fortan das Ziel gesetzt, dass der Mechanismus am Ende in dieses Glas passen muss.

Iterationen des Wipp-Mechanismus

Mir wurde langsam klar, dass eine „Wippe“ (also zwei verbundene Schlägel) nicht funktionieren werden. Um die Noten hörbar zu treffen, muss der Schlag per Gummizug verstärkt werden. Dieser würde jedoch die Wippe permanent aus ihrem Gleichgewicht drücken – und das auch noch irgendwie in beide Richtungen gleichzeitig (blaue Pfeile). Es braucht aber dieses Gleichgewicht, wenn die Wippe zu einer anderen Note rotiert (grüne Pfeile).

Die Widersprüche bei einer Wippe

Letztendlich konnte ich es per Gummizug nur ins Gleichgewicht ziehen. Weshalb der Roboter unterm Strich immer nach oben schlagen wollte. Mir wollte keine andere Lösung einfallen. Darum habe ich mich dafür entschieden, lieber zwei voneinander unabhängige Schlägel zu bauen. Ein paar Experimente in LeoCAD zeigten, dass das grundsätzlich ins Glas passen müsste.

Das Glas hat fast perfekte Legomaße…
… und laut LeoCAD passen auch vier Motoren hinein.

So entstand ein kleiner Mechanismus aus zwei gestapelten Motoren, der sehr gut funktionierte. Zusammen mit einem zweiten, spiegelverkehrt gebauten ergab sich ein sehr kompakter Motorblock, der perfekt ins Glas passte.

Motorblock inklusive Schlägeln

Mit einigen Umbauten ließen sich an diesem Block dann auch die Halterung für die Klangstäbe befestigen. Jeder Klangstab wird auf zwei Schnipsgummis in der Schwebe gehalten, damit die Note klar und ungedämpft klingt. Ferner wird je ein 3/4-Pin mit eingespannt um ein Verrutschen zu vermeiden. Das Gesamtgewicht der 16 Klangstäbe (ca. 1,2kg) wird primär vom Glas getragen.

Klangstäbe auf Schnipsgummis

Anfang Juli 2022 war es dann soweit: Vor mir stand ein – rein mechanisch betrachtet – funktionsfähiger Roboter. Nun musste ihm „nur“ noch Leben eingehaucht werden.

Die erste Programmierung

Die Programmierung des Roboters wollte ich auf keinen Fall grafisch in der von LEGO mitgelieferten Umgebung durchführen. Dort werden für jede Anweisung Blöcke per Drag-n-Drop in ein Gitter gezogen und anschließend per Formularen konfiguriert. Das ist zwar für Kinder als Einstieg gut, aber für größere Vorhaben extrem aufwändig und unübersichtlich.

Screenshot aus der NXT-G Programmieroberfläche

Der ursprüngliche Plan war die Nutzung des EVShield v2 von mindsensors.com (absolut keine Kaufempfehlung!). Das ist ein Board, welches zusammen mit einem Arduino Uno den Lego-NXT als „Gehirn“ des Roboters ersetzt. Zur Programmierung habe ich sowohl VSCode als auch die Arduino IDE ausprobiert. Anfangs sah das auch vielversprechend aus…

Je tiefer ich aber einstieg, desto mehr wurde mir die unausgereifte Programmierbibliothek des EV3-Shields zum Verhängnis (hier zu finden). Die Motoren ließen sich nur sehr ungenau steuern. Zum Beispiel hier beim Zeigen auf jede Note:

Manchmal machten die Motoren auch komplett willkürliche Bewegungen, die das Programm nicht ansatzweise vorgab. Beispiel:

Mir wurde schnell klar, dass ich mit diesen Problemen niemals ordentlich ein Lied spielen könnte. Ergo musste ich doch die originalen NXT-Steine als Steuerzentrale nutzen und programmieren. Die große Frage war: Wie?

Zum Glück fand ich Bricx Command Center – eine Software, über das auch ältere Lego-Hardware normal programmiert werden kann (Homepage). Leider wurde es seit Jahren nicht mehr weiter entwickelt. Doch ich habe es in einer virtuellen Windows-7-Maschine auf meinem Linuxrechner zum Laufen bekommen, sodass ich mich dennoch für diese Option entschied.

Über eine eigens entwickelte Sprache namens NXC – Not eXactly C, sprich: fast wie die Programmiersprache C – lassen sich hier alle Funktionen des NXT nutzen. Die Sprache ist zwar etwas eigen, aber hat sehr verständliche Tutorials und eine gute Dokumentation.

Da ein NXT-Baustein nur drei Motoren steuern kann, brauchte es zwei NXTs für die vier Motoren. Ergo war irgendeine Art von Kommunikation zwischen den NXTs nötig. Eine direkte Kommunikation per Kabel habe ich nicht zum Laufen bekommen. Die einzige Alternative war Bluetooth, was dafür aber umso besser funktionierte. Mit regelmäßigen Pings (alle 100ms bei mir) bleibt die Verbindung zudem auch nach längerer Inaktivität sehr performant.

Bluetooth-Kommunikation in NXC

Anschließend habe ich die Aufteilung der Logik auf die NXTs vorgenommen.

Der sekundäre NXT ist nur für das Schlagen auf die Klangstäbe zuständig. Ferner kalibiert er die beiden Motoren, die dies tun. All das geschieht nur auf Befehl via Bluetooth hin. Von selbst macht der Sekundäre NXT nichts.

Der primäre NXT übernimmt die komplette Steuerung. Auf ihm sind alle Lieder gespeichert. Er dreht die Schlägel zur richtigen Zeit zu den entsprechenden Noten, und gibt dem sekundären NXT anschließend den Befehl zum Schlag mit dem richtigen Schlägel.

Durch diese Aufteilung sind alle weiteren Anpassungen nur auf dem primären NXT durchzuführen. Ich brauche mich also, sobald die Bluetoothverbindung und die Steuerbefehle einmal programmiert sind, nie wieder mit dem zweiten NXT zu befassen.

Über diese Aufteilung konnte ich recht schnell Fortschritte machen und hatte Anfang Juli diese Methode der Kalibrierung zum Laufen gebracht: Die Arme werden in die gleiche Richtung gedreht, bis sie gegen den jeweils anderen stoßen. Dieser Punkt wird anschließend als Nullpunkt gesetzt, von dem aus der Winkel zu den Noten gemessen wird.

Ein vollständiges Lied

Nach diesen grundlegenden Funktionen wollte ich dem Roboter ein erstes Lied beibringen. Schon von Anfang an hatte ich hierfür die Spieluhr von „Davy Jones“ aus „Fluch der Karibik“ im Sinn. Sie hat einen ähnlichen Klang wie mein Glockenspiel.

Da ich selbst kein Instrument spiele und auch Noten nicht flüssig lesen kann, habe ich mir ein freies Notensatzprogramm namens MuseScore installiert. Anschließend kann man eine passende MIDI-Datei damit öffnen und kann die Noten bearbeiten und automatisch beschriften lassen.

MuseScore mit angepassten Noten zu Davy Jones

Da der Glockenspiel-Roboter nur 16 Noten hat, müssen häufig einzelne Noten oder komplette Lieder verschoben („transponiert“) werden, damit sie für den Roboter in Reichweite liegen. In MuseScore kann man sich diese Änderungen direkt anhören und auch Noten rot hervorheben lassen, die außerhalb einer bestimmten Spanne liegen. Super praktisch!

Zurück zur Programmierung: Dort wollte ich ein einheitliches Format für dieses und zukünftige Lieder. Deshalb habe ich mir eine eigene „Notation“ für die Steuerung des Roboters während eines Liedes überlegt. Jedes Lied ist ein zweidimensionales Byte-Array. Es besteht aus Zeilen mit folgenden drei Angaben:

NOTE: Gibt an, welcher der zwei Schlägel sich zu diesem Zeitpunkt an welcher Note befinden soll.

Wo sich welche Note physisch befindet ist über eine Liste von Winkelangaben je Schlägel hinterlegt. Index 0 ist die Ausgangsstellung nach dem Kalibrieren.

HIT: Gibt an, ob keiner, einer oder beide Schlägel zuschlagen sollen. „Keiner“ kann für Ausweichmanöver oder vorausschauende Routenplanung sinnvoll sein.

PAUSE: Gibt an, wie lange mit dem Befehl in der nächsten Zeile zu warten ist. Die Konstanten orientieren sich an der Dauer von Pausen/Noten aus der Musik (Triolen wurden erst viel später für ein anderes Lied hinzugefügt).

So startete ich schließlich mit dem Coding für „Davy Jones“. Die Kommentare rechts sind die Taktnummern. Ohne sie wurde es schnell zu unübersichtlich – denn ja, ich habe das manuell runtergeschrieben, nicht generiert.

Viele Messungen, Anpassungen, Performanceverbesserungen und Frickeleien später konnte der Roboter das Lied fließend spielen.

Mehrere Lieder organisieren

… Fortsetzung des Artikels ist noch in Arbeit …