Control de brazo robótico multi-articulado vía USB Serial o Bluetooth SPP, con interfaz gráfica en Python (CustomTkinter), firmware ESP32 y app Android companion.
- Conexión dual: Puerto serie USB (CP2102/CH340) o Bluetooth SPP
- Control manual: Sliders individuales por servo con botones de ajuste fino (±10°)
- Secuencias: Grabación, edición y reproducción de movimientos con interpolación suave
- Keyframe compression: Reduce grabaciones largas a posturas clave automáticamente
- Mando Xbox: Control por joysticks analógicos (XInput en Windows)
- PSMove: Control por movimiento con Sony PlayStation Move (orientación + tracking 3D)
- Wiimote: Control por movimiento con Nintendo Wiimote (orientación + sensor IR)
- Paro de emergencia: Botón y atajo
Ctrl+E— envía HOME al instante - Auto-reconexión Bluetooth: Reintenta hasta 3 veces si la conexión se pierde
- App Android companion: Escanea, conecta y controla desde un teléfono
- Módulo de IA (Ollama local): Control por voz, visión por cámara y agente autónomo con tool-calling
- Sistema de visión (YOLO): Detección de objetos en tiempo real, localización 3D y pipeline de agarre
- Barra de estado: Información en tiempo real de conexión, DOF y comandos
- Configurable: Hasta 6 servos, pines asignables, calibración por test
# 1. Crear un entorno virtual (recomendado)
python -m venv .venv
# 2. Instalar dependencias DENTRO del entorno
.venv\Scripts\pip install -r requirements.txt
# 3. Ejecutar la app con el entorno
.venv\Scripts\python main.pyNotas Windows:
sounddevicetrae PortAudio incorporado (no se instala nada extra). Bluetooth SPP: empareja el Brazo-Robotico en Configuración → Bluetooth; Windows lo expone como puerto COM virtual ("Standard Serial over Bluetooth link") y la app lo detecta automáticamente en modo Bluetooth. Si falta el driver del adaptador USB-UART (CP2102/CH340), instálalo desde el sitio del fabricante.
# 1. Crear un entorno virtual (recomendado: el Python de Debian es "managed")
python3 -m venv --system-site-packages .venv
# --system-site-packages reutiliza cv2/customtkinter/numpy ya instalados
# 2. Instalar dependencias DENTRO del entorno
.venv/bin/pip install -r requirements.txt
# 3. Ejecutar la app con el entorno
.venv/bin/python main.pySi omites el venv y usas el Python del sistema (Debian/Ubuntu),
pip installfallará con externally-managed-environment (PEP 668). Para voz necesitas además la librería del sistema:sudo apt install libportaudio2.
# Instalar dependencias Bluetooth
sudo apt install libbluetooth-dev
pip install pybluez wiimote.py
# Emparejar Wiimote: presionar 1+2 o botón SYNC
# La app detectará automáticamente el Wiimote# Compilar psmoveapi desde fuente
git clone https://github.com/thp/psmoveapi.git
cd psmoveapi
mkdir build && cd build
cmake ..
make
# Configurar udev rules (Linux)
sudo cp contrib/99-psmove.rules /etc/udev/rules.d/
sudo udevadm control --reload-rules
# Para pairing via Bluetooth:
./psmove pair # Conectar PSMove por USB primeroEn Windows,
psmoveapi.dll(compilado con MSVC o MinGW) debe estar en%USERPROFILE%\psmoveapi\buildo accesible víaPSMOVEAPI_LIBRARY_PATH.
# 1. Instalar Ollama (servicio local): https://ollama.com/download (Windows/macOS/Linux)
# 2. Descargar modelos (cuantizados, ligeros para equipos limitados)
ollama pull llama3.2:3b # texto / agente
ollama pull llama3.2-vision # visión por cámara (multimodal, opcional)
# 3. Dependencias de sistema (solo Linux, captura de micrófono)
sudo apt install libportaudio2
# 4. Dependencias pip
pip install ollama sounddevice faster-whisper # o: pip install -r requirements.txt
# Nota: en equipos muy limitados usa el modelo STT 'tiny'/'base' y solo vozpip install ultralytics # trae torch CPU
python scripts/detect_demo.py # Etapa 1: detección en vivo
python scripts/localize_demo.py # Etapa 2: detección + punto 3D del brazo
python scripts/grasp_demo.py --port /dev/ttyUSB0 # Etapa 3: agarrar objeto (Linux)
python scripts/grasp_demo.py --port COM3 # Etapa 3: agarrar objeto (Windows)Nota: PSMove requiere conexión Bluetooth para acceder a sensores. USB solo permite LED y rumble.
- Arduino IDE o PlatformIO
- Placa:
ESP32 Dev Module - Librería:
BluetoothSerial
- MIT App Inventor 2
- Importar
android/Robotic_Arm_Control.aiay generar APK
# En Arduino IDE: abrir arduino/robotic_arm/robotic_arm.ino
# Seleccionar placa: ESP32 Dev Module
# Uploadpython main.py # Windows: .venv\Scripts\python main.py | Linux: .venv/bin/python main.py- USB: Seleccionar puerto (ej.
COM3en Windows,/dev/ttyUSB0en Linux) y pulsar Conectar - Bluetooth: Cambiar a modo Bluetooth, seleccionar Brazo-Robotico y conectar
- Linux: usa
bluetoothctl/rfcomm (requieresudono interactivo o permisos) - Windows: empareja el ESP32 en Configuración y selecciona su puerto COM virtual
- Linux: usa
- Arrastrar sliders o usar botones ±10
- Grabar secuencias con el botón 🔴 Grabar
- Reproducir con ▶ Reproducir
- En Windows, conectar mando Xbox para control analógico
- Usar PSMove o Wiimote para control por movimiento
- Asegurarse de que Ollama está corriendo:
ollama serve(osystemctl start ollama) - Pulsar 🧠 IA en la barra superior (abre la ventana del asistente)
- Elegir modo:
- Comando rápido (sin IA): órdenes directas y sin latencia (indicado en equipos muy limitados)
- Agente IA: el modelo planifica y ejecuta movimientos con herramientas
- Escribir la orden o usar 🎙 Hablar (requiere micrófono + faster-whisper)
- Activar 📷 Ver escena para que el modelo analice la cámara antes de actuar
Ejemplos de órdenes: derecha, izquierda poco, sube, abre la pinza, ve al punto 20 15 40, ve a home, detener.
- Conectar el brazo (USB o BT) y abrir la cámara (panel Conexión).
- En la ventana 🧠 IA pulsar 🎯 Agarrar (agarra el objeto más cercano), o pedirle al agente: "Agarra el vaso" / "Recoge el cubo rojo".
- El LLM interpreta la intención y genera la tool
grasp(label); el pipeline (detector → localizador → ejecutor) hace el movimiento real.
Requiere
ultralyticsy un objeto cuyo tamaño esté enLocalizer.DEFAULT_KNOWN_SIZES(o añádelo). La profundidad se estima por tamaño aparente (cámara monocular).
robotic_arm_control/
├── main.py # Punto de entrada de la app
├── requirements.txt # Dependencias Python
├── android/
│ └── Robotic_Arm_Control.aia # App Android (MIT App Inventor)
├── arduino/
│ └── robotic_arm/
│ ├── robotic_arm.ino # Firmware ESP32
│ └── robotic_arm.ino.test # Test de Bluetooth sin PWM
├── core/
│ ├── bluetooth_manager.py # Gestión de conexión Bluetooth
│ ├── serial_manager.py # Gestión de conexión serie USB
│ ├── robot_arm.py # Modelo del brazo robótico
│ ├── sequence.py # Reproductor de secuencias
│ ├── motion_controller.py # Interfaz base para motion controllers
│ ├── psmove_controller.py # Control por PS Move Motion Controller
│ ├── wiimote_controller.py # Control por Nintendo Wiimote
│ ├── xinput_controller.py # Control por mando Xbox (Windows)
│ └── ai/ # Módulo de IA (Ollama + voz + visión)
│ ├── ollama_client.py # Cliente Ollama (chat, visión, tool-calling)
│ ├── audio_capture.py # Captura de micrófono (sounddevice)
│ ├── speech_to_text.py # STT con faster-whisper
│ ├── commands.py # Ruta rápida de órdenes por voz/texto
│ └── arm_agent.py # Agente autónomo (tools sobre RobotArm)
├── core/vision/ # Sistema de visión artificial (YOLO)
│ ├── detector.py # Detector YOLO (bbox + clase + conf)
│ ├── localizer.py # Pixel → 3D (profundidad por tamaño)
│ └── grasper.py # Pipeline de agarre (planner + ejecutor)
├── gui/
│ ├── app.py # Ventana principal y orquestación
│ ├── connection_frame.py # Panel de conexión
│ ├── control_frame.py # Panel de control de servos
│ ├── controller_frame.py # Panel del mando Xbox
│ ├── motion_controller_frame.py # Panel de control por movimiento
│ ├── sequence_frame.py # Panel de secuencias
│ ├── configurator_frame.py # Ventana de configuración DOF/pines
│ ├── camera_frame.py # Vista previa de la cámara
│ └── ai_dialog.py # Ventana emergente del asistente IA
├── utils/
│ ├── config_manager.py # Persistencia de configuración
│ └── theme.py # Paleta de colores (oscuro/claro)
└── tests/
├── test_aia_blocks.py # Validación de bloques App Inventor
├── test_inverse_kinematics.py # Tests de cinemática inversa
├── test_psmove_controller.py # Tests de PSMove
└── test_ai_commands.py # Tests de la ruta rápida de IA
Reglas del protocolo:
- Todo comando enviado por el cliente debe terminar con LF (
\n, 0x0A) - Toda respuesta del ESP32 siempre termina con LF (
\n, 0x0A) - El ESP32 descarta buffers incompletos tras 500ms de inactividad
El ESP32 acepta comandos tanto por Serial USB como por Bluetooth SPP:
| Comando | Respuesta | Descripción |
|---|---|---|
PING |
PONG |
Verificación de conexión |
CHECK |
CHECKED |
Health-check periódico |
STATUS |
STATUS OK <n> <a0> <a1> ... |
Estado: n=servos, aN=ángulos actuales |
<id> <angulo> |
OK servo <id> -> <angulo> deg |
Mover servo (-90 a 90) |
CONFIG <n> <p0> <p1> ... |
CONFIG OK - <n> servos en pines: ... |
Reconfigurar DOF |
Nota: las respuestas de error siguen el formato Error: <descripcion> y también terminan con LF.
| Entrada | Servo | Descripción |
|---|---|---|
| Pitch (inclinación) | Servo 1 (Hombro) | Inclinación hacia adelante/atrás |
| Roll (rotación) | Servo 0 (Base) | Rotación izquierda/derecha |
| Yaw (giro eje Z) | Servo 4 (Inclinación muñeca) | Giro del mando como volante |
| Trigger | Servo 5 (Pinza) | Apertura de la pinza |
| ▲ Triangle | Home | Posición inicial |
| ● Circle | Guardar postura | Guardar postura actual |
| ✕ Cross | Agregar postura | Agregar a secuencia |
| ▶ Start | Play/Stop | Reproducir/secuencia |
| ■ Select | Stop | Detener reproducción |
| Entrada | Servo | Descripción |
|---|---|---|
| Pitch (inclinación) | Servo 1 (Hombro) | Inclinación hacia adelante/atrás |
| Roll (rotación) | Servo 0 (Base) | Rotación izquierda/derecha |
| IR X | Servo 3 (Rotación muñeca) | Posición horizontal del cursor |
| IR Y | Servo 4 (Inclinación muñeca) | Posición vertical del cursor |
| A | Home | Posición inicial |
| B | Guardar postura | Guardar postura actual |
| 1 | Agregar postura | Agregar a secuencia |
| + | Play/Stop | Reproducir/secuencia |
| - | Stop | Detener reproducción |
| D-pad | Servos 2,5 | Ajuste fino ±3° |
python -m pytest # Suite completa
python tests/test_aia_blocks.pyValida que los bloques del archivo .aia usen métodos reales de App Inventor (BluetoothClient, Notifier) y que las variables globales sean consistentes.
El proyecto se realizó con un brazo robótico potenciado por 5 servomotores Hextronik HX5010 y 2 servomotores Hextronik HXT12K, montados en una estructura de acrílico
Este proyecto cuenta con una Licencia MIT.
Este proyecto utiliza las siguientes librerías de terceros:
| Librería | Licencia | Uso |
|---|---|---|
| wiimote.py | MIT | Control por Nintendo Wiimote |
| psmoveapi | BSD | Control por PlayStation Move |
| CustomTkinter | MIT | Interfaz gráfica |
| pyserial | BSD | Conexión serie USB |
| Ultralytics YOLO | AGPL-3.0 | Detección de objetos |
| faster-whisper | MIT | Transcripción de voz (STT) |
| sounddevice | MIT | Captura de micrófono |
Agradecimientos totales a los respectivos equipos de las librerías
Software y Firmware realizado por YacaloX, Hardware donado por Rafael Rojas Niño