Adicione Interação por Voz ao Seu SO-ARM10x com reSpeaker Flex
Visão geral

O controlador de voz LeRobot SO-ARM permite controlar um braço robótico SO-ARM100 usando comandos de voz naturais alimentados por IA. O sistema combina detecção de palavra de ativação, Groq Whisper speech-to-text, compreensão de linguagem com LLaMA 3 e Orpheus text-to-speech para criar uma experiência robótica totalmente interativa e mãos livres. Construído sobre o framework LeRobot, ele é executado em sistemas Ubuntu x86 e dispositivos NVIDIA Jetson usando um array de microfones USB ReSpeaker para entrada de voz. Os usuários podem criar poses personalizadas do braço, gestos e gatilhos conversacionais para construir interações robóticas inteligentes para pesquisa, educação e desenvolvimento em robótica.
Hardware Necessário
| SO-ARM101 | reSpeaker Flex XVF3800 Circular | reComputer Super J4012 |
|---|---|---|
![]() | ![]() | ![]() |
Como Funciona
You speak → Wake word detected → Audio recorded → Whisper STT → LLaMA LLM → Orpheus TTS speaks back → SO-ARM100 moves
Serviços Necessários
| Serviço | Finalidade | Custo |
|---|---|---|
| Groq | Whisper STT, LLaMA LLM, Orpheus TTS | Nível gratuito é suficiente |
Parte 1 — Instalar o LeRobot
Instalar o Miniforge
Para Jetson (ARM64):
wget https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-Linux-aarch64.sh
chmod +x Miniforge3-Linux-aarch64.sh
./Miniforge3-Linux-aarch64.sh
source ~/.bashrc
Para x86 Ubuntu 22.04:
wget "https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-$(uname)-$(uname -m).sh"
bash Miniforge3-$(uname)-$(uname -m).sh
source ~/.bashrc
conda init --all
Criar o Ambiente Conda
conda create -y -n lerobot python=3.10
conda activate lerobot
Clonar e Instalar o LeRobot
git clone https://github.com/KasunThushara/lerobot
conda install ffmpeg -c conda-forge
cd lerobot
pip install -e ".[feetech]"
Parte 2 — Configurar os Braços
Configurar IDs dos Motores
Cada servo precisa de um ID exclusivo atribuído antes da montagem. Siga o guia oficial: Configure the Motors
Montar os Braços
Siga o tutorial de montagem para o SO-ARM100: Assembly Guide
Encontrar as Portas USB
Conecte cada braço e execute este utilitário para identificar qual porta pertence a qual braço:
lerobot-find-port
Execute-o uma vez por braço (conecte um de cada vez). Anote os caminhos das portas — normalmente /dev/ttyACM0 e /dev/ttyACM1.
Calibrar Ambos os Braços
A calibração mapeia valores brutos do motor para posições normalizadas. Siga o guia para ambos os braços, líder e seguidor: Calibration Guide
O arquivo de calibração será salvo automaticamente em:
~/.cache/huggingface/lerobot/calibration/robots/so_follower/<your_arm_id>.json
Parte 3 — Configurar o Controlador de Voz
cd ~/lerobot/examples/voice_arm
Instalar Dependências
# System dependency required for PyAudio
sudo apt-get install -y portaudio19-dev
pip install -r requirements.txt
Baixar o Modelo de Palavra de Ativação
Baixa o modelo pré-treinado "Hey Jarvis" do openwakeword em ~/.openwakeword/:
python download_model.py
Encontrar o Índice do Seu Microfone
Conecte seu ReSpeaker Flex e então execute:
python list_mics.py
Exemplo de saída:
Available audio INPUT devices:
[0] bcm2835 Headphones (rate=44100Hz)
[1] ReSpeaker 4 Mic Array (rate=16000Hz)
[2] USB PnP Sound Device (rate=16000Hz)
Anote o número de índice ao lado do seu ReSpeaker — esse é o seu MIC_INDEX.
Configurar o Projeto
cp config.env.example config.env
nano config.env
No mínimo, atualize estes dois valores:
# Your Groq API key (required) — get one free at console.groq.com
GROQ_API_KEY=gsk_xxxxxxxxxxxxxxxxxxxxxxxx
# The number from list_mics.py
MIC_INDEX=1
Parte 4 — Definir as Ações do Seu Braço
Etapa 1 — Ler as Posições Atuais das Juntas
Mova fisicamente o braço para uma pose que você deseja salvar e então execute:
python read_positions.py
O script imprime valores normalizados das juntas em tempo real enquanto você move o braço. Quando estiver satisfeito com a pose, pressione Ctrl+C e a posição final será impressa para você copiar.
Etapa 2 — Adicionar a Pose em robot_arm.py
Abra robot_arm.py e encontre o dicionário ACTION_MAP. Adicione sua pose:

"my_custom_pose": _pose(**{
"shoulder_pan.pos": 20.0,
"shoulder_lift.pos": 40.0,
"elbow_flex.pos": 60.0,
"wrist_flex.pos": -30.0,
"gripper.pos": 80.0,
}),
Para gestos animados (como um aceno), use uma lista de poses — cada etapa é executada com ARM_GESTURE_DELAY entre elas:
"wave_hi": [
_pose(**{"shoulder_lift.pos": -70.0, "wrist_flex.pos": 60.0, ...}),
_pose(**{"shoulder_lift.pos": -70.0, "wrist_flex.pos": -60.0, ...}),
_HOME, # return to neutral
],
Etapa 3 — Atualizar o Prompt de Sistema do LLM em llm.py
Adicione sua nova ação à lista de ações válidas e às regras de gatilho para que o LLM saiba sobre ela:

Valid actions:
my_custom_pose = describe what it does
Trigger rules:
- "your trigger phrase" → my_custom_pose
Executar o Controlador de Voz
Certifique-se de que seu ambiente conda esteja ativo e então:
conda activate lerobot
python pipeline.py
Você deverá ver:
======================================================
SO100 Arm Voice Controller — Ready
Wake word : hey jarvis
LLM model : llama-3.1-8b-instant
STT model : whisper-large-v3-turbo
TTS voice : autumn
Arm port : /dev/ttyACM0 id='my_awesome_follower_arm'
======================================================
[WakeWord] Listening for 'hey jarvis' ...
Agora diga "Hey Jarvis" e dê um comando!
Exemplos de Comandos de Voz
| Você diz | O que acontece |
|---|---|
| "Hey Jarvis, open the gripper" | O gripper abre totalmente |
| "Hey Jarvis, grab it" | O gripper fecha |
| "Hey Jarvis, go to pick up mode" | O braço se move para a pose de agarrar |
| "Hey Jarvis, can you turn around" | A base gira para o lado |
| "Hey Jarvis, wave at the camera" | O braço acena e retorna à posição neutra |
| "Hey Jarvis, go home" | Todas as juntas retornam à posição neutra |
Visão Geral dos Arquivos do Projeto
examples/voice_arm/
├── pipeline.py # Main entry point — orchestrates the full flow
├── robot_arm.py # SO100 arm controller — add your poses here
├── llm.py # LLM prompt — add your voice triggers here
├── wakeword.py # Listens for "Hey Jarvis" in a background thread
├── audio_recorder.py # Records audio after wake word fires
├── stt.py # Sends audio to Groq Whisper → returns text
├── tts.py # Sends reply to Groq Orpheus → plays audio
├── config.py # Loads all settings from config.env
├── config.env.example # Template — copy to config.env and fill in
├── read_positions.py # Helper: read live joint positions for tuning poses
├── list_mics.py # Helper: find your MIC_INDEX
└── download_model.py # Downloads the openwakeword model files
Referência de Configuração
| Variável | Padrão | Descrição |
|---|---|---|
GROQ_API_KEY | (required) | Sua chave de API Groq |
WAKEWORD_MODEL | hey jarvis | Frase de palavra de ativação |
MIC_INDEX | 1 | Índice de dispositivo PyAudio |
WAKEWORD_THRESHOLD | 0.5 | Sensibilidade de detecção (0.0–1.0) |
WAKEWORD_COOLDOWN | 2 | Segundos entre novos disparos |
RECORDING_SECONDS | 3 | Quanto tempo gravar após a palavra de ativação |
LLM_MODEL | llama-3.1-8b-instant | Modelo Groq LLM |
STT_MODEL | whisper-large-v3-turbo | Modelo Groq Whisper |
TTS_VOICE | autumn | Voz para saída de fala |
ARM_PORT | /dev/ttyACM0 | Porta USB do braço seguidor |
ARM_ID | my_awesome_follower_arm | ID do braço (corresponde ao nome do arquivo de calibração) |
ARM_MOVE_DELAY | 1.5 | Segundos de espera após um movimento de pose |
ARM_GESTURE_DELAY | 0.4 | Segundos entre etapas da sequência de gestos |
Solução de problemas
Falha na instalação do PyAudio Instale primeiro a biblioteca de sistema PortAudio:
sudo apt-get install -y portaudio19-dev
A palavra de ativação nunca é acionada
Execute list_mics.py novamente e confirme que MIC_INDEX corresponde ao seu ReSpeaker. Tente reduzir WAKEWORD_THRESHOLD para 0.3. Fale claramente a cerca de 1 metro do microfone.
O braço não se move após um comando
Verifique se ARM_PORT está correto (lerobot-find-port). Confirme se o arquivo de calibração existe em ~/.cache/huggingface/lerobot/calibration/robots/so_follower/<ARM_ID>.json.
O braço se move para a posição errada
Os valores de pose padrão em ACTION_MAP são estimativas iniciais. Execute read_positions.py, mova fisicamente o braço para a pose desejada e copie os valores exibidos para robot_arm.py.
Erros de TTS / STT
Verifique novamente GROQ_API_KEY em config.env. O nível gratuito do Groq tem limites de taxa — aguarde alguns segundos entre comandos se encontrar erros.
O áudio é reproduzido, mas soa distorcido
No Raspberry Pi, defina a saída de áudio para o dispositivo correto via raspi-config → System Options → Audio.
Créditos
Feito com:
- LeRobot — framework de robótica open-source da Hugging Face
- SO-ARM100 — braço robótico open-source de baixo custo da Seeed Studio
- openwakeword — detecção local de palavra de ativação
- Groq — Whisper STT, LLaMA LLM e Orpheus TTS ultrarrápidos
- ReSpeaker Flex — matriz de microfones USB


