📝 Recriando um projeto de teleoperação para o FEI Portas Abertas

Em poucas palavras

Recriei, para apresentar no FEI Portas Abertas, um projeto de alunos de graduação: uma mão robótica que copia os movimentos dos meus dedos em tempo real (ou quase), usando uma webcam do notebook, uma ESP32, uma PCA9685 para controle de servomotores e o braço robótico em si. Mais do que o resultado pronto, o valor esteve em repetir o processo dos alunos, verificar se a documentação está adequada e demonstrar para alunos do ensino básico e médio como diferentes tecnologias são aplicadas.


Introdução

Como parte de um Trabalho de Conclusão de Curso que orientei, com título ATENA - Robô humanoide InMoov com teleoperação baseada em visão Computacional, um grupo de alunos de graduação construiu uma mão robótica, com base no robô InMoov, capaz de copiar em tempo real (ou quase tempo real) os movimentos de uma mão humana usando apenas uma webcam. Para apresentar o projeto no FEI Portas Abertas, resolvi refazer o caminho deles do zero: montar o mesmo hardware, rodar o mesmo software, entender cada decisão que tomaram.

Essa foi uma experiência interessante que mostra como é importante ter uma documentação adequada para que outros pesquisadores possam avaliar e reproduzir o trabalho que foi realizado.

A ideia, em uma frase

Uma webcam capta a mão de quem está operando/acenando, um script em Python no computador usa o MediaPipe Hands para medir o quanto cada dedo está dobrado, e esses ângulos viajam por um cabo serial USB até uma ESP32, que os aplica em cinco servomotores através de uma placa PCA9685.

Por que tão simples?

Foi uma escolha consciente dos alunos. O objetivo é demonstrar a teleoperação em um evento que recebe alunos do ensino médio e fundamental de diferentes escolas. Nesse contexto, a complexidade de um framework de robótica inteiro para mover o robô, como foi o caso do Trabalho de Conclusão de Curso dos alunos, seria desproporcional. Tem uma certa honestidade em manter um projeto do tamanho do problema que ele resolve.

O fluxo completo fica assim:

flowchart TB
    A[Webcam]
    B["MediaPipe Hands<br/>Python / PC"]
    C[Serial USB]
    D["ESP32<br/>MicroPython"]
    E[PCA9685]
    F["5 Servos<br/>(dedos)"]

    A --> B --> C --> D
    D -->|I2C| E --> F

Observação: Nenhuma lógica de calibração roda na ESP32: ela só recebe ângulos já prontos (0 a 180 graus) e escreve no canal certo da placa PCA9685. Toda a parte de “entender a mão humana” fica no computador, que tem maior capacidade de processamento do que o Microcontrolador.

Vejam na figura abaixo tanto a mão do operador quando do robô fechadas.

O que a webcam realmente enxerga

O MediaPipe Hands devolve um esqueleto da mão com pontos de referência (landmarks) em cada articulação. Para saber se um dedo está aberto ou fechado, o código calcula o ângulo formado entre três desses pontos - base, nó do meio e ponta. Um ângulo próximo de 180° é um dedo esticado; um ângulo bem menor é um dedo dobrado. Por exemplo, a imagem a seguir apresenta um exemplo da saída do MediaPipe Hands.

Parece simples até o polegar entrar na história. Enquanto os outros quatro dedos variam numa faixa ampla, de cerca de 40° a 160°, o polegar se move numa faixa bem mais estreita, de aproximadamente 125° a 175° - a geometria da própria mão limita quanto ele consegue “abrir” nesse tipo de medição. Usar a mesma faixa dos outros dedos para o polegar significa, na prática, ele nunca sair do estado “fechado”. Foi um daqueles lembretes de que um modelo que funciona bem para quatro dedos pode simplesmente não servir para o quinto - e que vale a pena desconfiar de generalizações.

Onde o hardware falhou e tive que corrigir

A parte de software, eu diria que é a mais simples de repetir. Não porque seja mais fácil em si, mas porque envolve um ambiente digital relativamente controlado, que segue uma lógica mais previsível do que um ambiente real.

Veja o que aconteceu quando fui replicar o projeto dos alunos: depois de montar tudo, reescrever o firmware, confirmar que a ESP32 encontrava a placa PCA9685 no barramento I2C, os servos simplesmente não se moviam. Commandos sendo enviados, respostas de “ok” chegando de volta, e nenhum movimento físico. Depois de descartar várias hipóteses de software, o problema era um pino: OE (Output Enable), na placa PCA9685 genérica usada no projeto, que não vinha aterrado internamente por padrão. Sem um jumper ligando esse pino a qualquer terra/GND da placa, o chip aceita perfeitamente os commandos I2C, mas nunca chega a gerar o sinal PWM de verdade para os servos.

Não é um problema sofisticado. É exatamente o tipo de detalhe que só aparece quando se sai da teoria e se coloca a mão (com o perdão do trocadilho) na placa. Fico feliz em admitir que não foi intuição de eletrônica que me levou até ali, foi processo de eliminação e alguma sorte de olhar para o lugar correto e pensar que aquilo era um potential problema.

Além disso, outro problema surgiu. Como fazer a movimentação adequada dos dedos utilizando fios de náilon e uma polia acoplada ao eixo do motor? É a movimentação dos fios que faz com que os dedos fechem e abram (associado a uma mola alojada nos dedos). Neste sentido, o posicionamento e tensionamento do fio são fundamentais para garantir a correta operação do mesmo. Isso fez com que eu desenvolvesse um script em MicroPython para a ESP32 a fim de conseguir movimentar cada um dos dedos de forma independente e controlada para que eu pudesse calibrar a relação entre o ângulo do servomotor e a posição do dedo.

Testando por camadas

Uma coisa que aprendi a valorizar - inclusive como professor de disciplinas ligadas a IoT - é resistir à tentação de ligar tudo de uma vez, mesmo que seja isso que os alunos quase sempre tentam fazer. Incentivo os alunos a desenvolver seus projetos passo a passo (mesmo que uma IA Generativa consiga entregar quase tudo pronto de uma vez). Por exemplo, cada camada desse projeto foi validada isoladamente antes de ir para a próxima. Seguem as fases que utilizei:

  1. Hardware puro: só a ESP32 e a PCA9685, testadas direto no Thonny, sem nenhum software de captação e processamento de imagens do computador envolvido. Apenas o envio de sinais PWM para a PCA9685.
  2. ESP32 por serial: um script que varre cada dedo de 0° a 180° e volta, confirmando canal certo, direção certa e que a comunicação serial realmente funciona. Além disso, valida a movimentação de cada dedo entre aberto e fechado.
  3. Webcam e MediaPipe, sem o hardware da mão robótica: só para ver o esqueleto da mão e os ângulos calculados na tela, permitindo validar a captação e processamento de imagens.
  4. Programa completo: só depois de validar as três camadas anteriores e mesmo assim fazendo as conexões passo a passo para garantir que a compatibilidade entre os distintos sistemas estava adequada.

Um princípio que vale além da eletrônica

Isolar variáveis não é só disciplina de laboratório. É basicamente a única forma sensata de depurar qualquer sistema com várias camadas de hardware e software se comunicando - e vale tanto para uma mão robótica quanto para um pipeline de dados de IoT em produção.

Até rodar no WSL trouxe sua própria camada de tradução: nem a webcam nem a porta serial da ESP32 aparecem automaticamente ali, e foi preciso “emprestar” os dois dispositivos do Windows via USB/IP. Isso foi algo que eu só tive que fazer uma vez para compartilhar a rede do computador com o WSL, mas não tinha feito isso com outros elementos do computador. Esse foi mais um lembrete de que, em projetos de hardware e software, o ambiente de desenvolvimento também é parte do sistema.

Demonstração no dia do evento

No dia do evento a ideia era que os visitantes pudessem realizar o movimento da mão robótica de forma remota, com a captação de imagem sendo feitas por um notebook. A ideia era apresentar rapidamente o projeto, deixar que os visitantes manipulassem a mão e explicar os conceitos por trás do projeto. Algo simples, mas que apresentava claramente o potential do trabalho.

Por que isso importa para além do hobby

Não vejo esse projeto como robótica de ponta, e não é essa a pretensão dele. O valor que enxergo é outro: é o tipo de exercício que me devolve, na prática, o que ensino em teoria nas disciplinas de IoT - sensores, atuadores, comunicação, protocolos, e principalmente a distância entre “o código funciona” e “o sistema físico responde adequadamente”. Além disso, um projeto desses serve para apresentar e “tornar real” diversos conceitos que os alunos vão ter contato ao longo da graduação.

Não sei ao certo o que outros alunos da graduação vão fazer a partir desse primeiro passo. Talvez fazer a mão reagir a estímulos distintos, talvez melhorar a estrutura física da mesma, talvez refinar o sistema de controle dos servomotores, talvez estabelecer uma comunicação sem fio entre a mão e o computador, enfim… Por enquanto, fico satisfeito em ter conseguido replicar o trabalho dos alunos, em apresentá-lo a outros alunos, e em lembrar que qualquer pessoa pode se debruçar sobre uma área de interesse e descobrir coisas novas no caminho.

Este projeto está documentado com mais detalhes técnicos (esquema de ligações, calibração, troubleshooting) no repositório do código que você pode consultar neste link.

E você?

Se você também tem uma ideia parada há anos - de robótica ou não - qual seria o menor pedaço dela que já daria para testar num fim de semana?


📚 Referências e Fontes

🔗 Conexões do Cofre

🌐 Referências Externas