Ein SO-101 balanciert einen Tischtennisball und sieht ihn nur durch die Handgelenkkamera
- Erbauer: zecice
Ein SO-101 hält einen Tischtennisschläger im Greifer und hält einen Tischtennisball darauf im Gleichgewicht. Die Handgelenkkamera ist sein einziger Sensor für den Ball; alles andere stammt aus den eigenen Gelenkmesswerten des Arms. Der Regler wurde in MuJoCo trainiert und läuft unverändert auf dem echten Arm, was der Builder in einem kurzen Clip auf X zeigt: Eine Hand schiebt den Ball zum Rand des Schlägers, und der Arm bringt ihn zurück in die Mitte.
So funktioniert es
Die Pipeline im Repository hat vier Stufen. Bilder der Handgelenkkamera (640x480, verkleinert auf 128x96) gehen an einen Farbschwellen-Detektor, der den orangefarbenen Ball findet. Ein kleiner MLP-Schätzer, in der Simulation trainiert, macht aus den letzten 3 Detektionen die Position des Balls auf dem Schläger. Die Geschwindigkeit ist eine gefilterte finite Differenz dieser Positionen. Ein mit Reinforcement Learning (PPO) trainierter Regler gibt dann 5 Änderungen der Gelenkpositionen mit 30 Hz aus. Der Schläger ist hochkant zur Kamera eingespannt, sodass die Kamera ihn von der Seite sieht und den Ball nahe einer einzigen Bildspalte.
Was den Sprung aus der Simulation möglich machte
Die Sim-to-Real-Lehre des Builders lautet, den Regler von Anfang an mit den Schwächen des echten Systems zu trainieren, eine Form der Domain Randomization:
- Regelungslatenz zufällig über 0 bis 4 Frames (0 bis 133 ms), mit den letzten 3 Aktionen in der Beobachtung. - Weiche, zufällig gewählte Servoverstärkungen, weil billige Servos durchhängen und nachlaufen. - Ein verrauschter Ballzustand wie die Ausgabe des Schätzers, dessen Geschwindigkeit mit demselben Finite-Differenzen-Filter berechnet wird, den der Roboter verwendet. Ein Regler, der auf der exakten Geschwindigkeit trainiert wurde, versagte vollständig mit der aus der Kamera abgeleiteten Geschwindigkeit.
Auch was nicht funktionierte, ist festgehalten: Eine End-to-End-CNN-Policy auf Handgelenkbildern, trainiert per Behavior Cloning und DAgger vom PPO-Regler, war in der Simulation in Ordnung, sah den echten Ball aber kaum. Der einfache Farbdetektor und der kleine Schätzer haben sie ersetzt.
Auf dem echten Arm
Die Hardware ist ein SO-101-Follower-Arm, eine Handgelenkkamera, ein normaler Tischtennisschläger im Greifer und ein orangefarbener Ball. Der Arm läuft über die SO-101-Follower- und Feetech-Treiber in LeRobot. Das README nennt, was auf dem echten Arm wichtig war:
- Servo-P-Verstärkung 32 statt LeRobots Standardwert 16, bei dem der Arm durchhängt und Befehle von 4 bis 7 Grad ignoriert. Das Run-Skript setzt sie. - Eine waagerechte Ausgangspose: Ein paar Grad Neigung, und der Ball rollt weg, weil die Policy keinen Integralanteil hat. Jeder Arm nimmt seine eigene Ausgangspose mit einem mitgelieferten Hilfsskript auf. - Den Schläger nach Last zudrücken (etwa 10%) und den Greifer nie ganz schließen lassen: Ein Blockieren löst den Feetech-Überlastschutz aus, und der Motor fällt vom Bus, bis die Stromversorgung aus- und wieder eingeschaltet wird. - Die eigene Latenz mit dem mitgelieferten Skript messen; der Regler ist für 0 bis 4 zusätzliche Schritte von 33 ms trainiert.
Das README warnt außerdem, dass sich der Arm selbstständig bewegt und nach dem Ende der Skripte unter Strom bleibt.
Ergebnisse und was veröffentlicht ist
Der Builder berichtet 97.5% der Episoden 10 Sekunden lang balanciert in randomisierter Simulation, 113 von 120 in der Simulation mit der vollständigen Kamera-Pipeline, und dass es auf dem echten Arm balanciert. Die trainierten Gewichte von Regler und Schätzer liegen im Repository, sodass sich die ganze Pipeline ohne Arm im Simulator ausprobieren lässt. Das Training des Reglers dauerte etwa 29 Millionen Schritte und etwa 2 Stunden auf einem Laptop (6 CPU-Kerne für die Simulation, eine RTX-A1000-GPU für das Netz). Entwickelt wurde unter Linux; macOS und Windows sind ungetestet.
Code und Gewichte stehen unter MIT. Die SO-101-Modelldateien stammen aus dem SO-ARM100-Repository von TheRobotStudio unter Apache-2.0, das Schlägermodell aus einem Tischtennis-Regelungsprojekt unter MIT.
Details
- arm: SO-101 follower
- task: Balancing a ping-pong ball on a table-tennis paddle held in the gripper
- posted: 5 November 2026 (video), repository opened 8 November 2026
- licence: MIT (code and weights); SO-101 model files Apache-2.0; paddle mesh MIT
- sensing: Wrist camera only for the ball, plus the arm's joint readings
- weights: Controller and estimator released in the repository
- training: MuJoCo with randomised latency (0-133 ms), soft servos and noisy ball state
- framework: LeRobot (SO-101 follower, Feetech drivers), MuJoCo 3.17
- controller: PPO policy, 5 joint-position changes at 30 Hz
- difficulty: Advanced
- perception: Colour-threshold detector and a small MLP estimator trained in simulation
Fotos und Videos
- zecice/so101-pingpong-balance: The simulation, PPO training, detector and estimator, real-arm loop and pretrained weights, with a README covering what made sim-to-real work and what mattered on the real arm.
- The real arm balancing the ball: The builder's clip of the SO-101 keeping the ball on the paddle while a hand pushes it towards the edge.
Links
- Erbauer: https://github.com/zecice