Um SO-101 equilibra uma bola de pingue-pongue vendo-a apenas pela câmera de pulso
- Construtor: zecice
Um SO-101 segura uma raquete de tênis de mesa na garra e mantém uma bola de pingue-pongue equilibrada sobre ela. A câmera de pulso é o único sensor para a bola; todo o resto vem das leituras das próprias juntas do braço. O controlador foi treinado no MuJoCo e roda sem alterações no braço real, o que o autor mostra em um clipe curto no X: uma mão empurra a bola para a borda da raquete e o braço a traz de volta ao centro.
Como funciona
O pipeline do repositório tem quatro etapas. Os quadros da câmera de pulso (640x480, reduzidos para 128x96) vão para um detector por limiar de cor que encontra a bola laranja. Um pequeno estimador MLP, treinado em simulação, transforma as 3 últimas detecções na posição da bola sobre a raquete. A velocidade é uma diferença finita filtrada dessas posições. Em seguida, um controlador treinado com aprendizado por reforço (PPO) gera 5 mudanças de posição das juntas a 30 Hz. A raquete fica presa de lado em relação à câmera, então a câmera a vê de perfil e vê a bola perto de uma única coluna da imagem.
O que fez a passagem da simulação funcionar
A lição sim-to-real do autor é treinar o controlador com as falhas do sistema real desde o início, uma forma de randomização de domínio:
- Latência de controle aleatória entre 0 e 4 quadros (0 a 133 ms), com as 3 últimas ações na observação. - Ganhos de servo suaves e aleatórios, porque servos baratos cedem e atrasam. - Um estado da bola com ruído como a saída do estimador, com a velocidade calculada pelo mesmo filtro de diferenças finitas que o robô usa. Um controlador treinado com a velocidade exata falhou completamente com a velocidade derivada da câmera.
O que não funcionou também está registrado: uma política CNN de ponta a ponta sobre imagens do pulso, treinada por clonagem de comportamento e DAgger a partir do controlador PPO, ia bem em simulação, mas mal enxergava a bola real. O detector de cor simples e o pequeno estimador a substituíram.
No braço real
O hardware é um braço seguidor SO-101, uma câmera de pulso, uma raquete comum presa na garra e uma bola laranja. O braço roda com os drivers SO-101 follower e Feetech do LeRobot. O README lista o que importou no braço real:
- Ganho P dos servos em 32, em vez do padrão do LeRobot, 16, com o qual o braço cede e ignora comandos de 4 a 7 graus. O script de execução o ajusta. - Uma pose inicial nivelada: com alguns graus de inclinação a bola escapa, porque a política não tem ação integral. Cada braço grava sua própria pose inicial com um script guia incluído. - Apertar a raquete pela carga (cerca de 10%) e nunca comandar a garra totalmente fechada: um travamento aciona a proteção contra sobrecarga da Feetech e o motor sai do barramento até que a alimentação seja desligada e religada. - Medir a própria latência com o script incluído; o controlador é treinado para 0 a 4 passos extras de 33 ms.
O README também avisa que o braço se move sozinho e continua energizado depois que os scripts terminam.
Resultados e o que foi liberado
O autor relata 97.5% dos episódios equilibrados por 10 segundos em simulação randomizada, 113 de 120 em simulação com o pipeline completo da câmera, e que o braço real equilibra a bola. Os pesos treinados do controlador e do estimador estão no repositório, então todo o pipeline pode ser testado no simulador sem o braço. Treinar o controlador levou cerca de 29 milhões de passos e cerca de 2 horas em um notebook (6 núcleos de CPU para a simulação, uma GPU RTX A1000 para a rede). Foi desenvolvido no Linux; macOS e Windows não foram testados.
O código e os pesos são MIT. Os arquivos do modelo do SO-101 vêm do repositório SO-ARM100 da TheRobotStudio sob Apache-2.0, e a malha da raquete de um projeto de controle de tênis de mesa sob MIT.
Detalhes
- 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 e vídeos
- 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
- Construtor: https://github.com/zecice