KittyCar (ENA 2026) — Caso de Estudio

Firmware modular todo-en-uno para carro autónomo participante en la Cuarta Competencia Estatal de Robótica de Educación Media Superior en Aguascalientes. Asesoría técnica, diseño de arquitectura de firmware y acompañamiento en pista.

ESP32C++PlatformIOTB6612FNGPID ControlFreeRTOSBluetoothSerialUltrasonic HC-SR04Servo SG90Infrared SensorsNVS Preferences

1. Descripción General

Rol: Asesor y guía técnico para la construcción de un carro autónomo de competencia. Diseño de la arquitectura del firmware, implementación de módulos de control críticos (siguelíneas, laberinto, control remoto) y mentoría a estudiantes en integración de hardware y depuración en pista.

Competencia: Cuarta Competencia Estatal de Robótica de Educación Media Superior, organizada por el HUB de Cultura Digital y Tecnológica del Estado de Aguascalientes. Realizada el 26 de marzo de 2026 en el Museo Descubre. Pruebas: siguelíneas (velocidad + precisión) y resolución de laberinto (navegación autónoma con obstáculos).

Propuesta técnica: Firmware modular en C++ (PlatformIO) estructurado como máquina de estados, con ramas Git independientes por subsistema para desarrollo aislado y fusión incremental en master. Cada módulo se probó en físico antes de integrar, reduciendo el riesgo de regresiones en pista.

2. Arquitectura del Sistema

Visión General

Arquitectura monolitico-modular: firmware todo-en-uno en un solo binario, pero con separación lógica en módulos independientes por rama Git. La máquina de estados central en master orquesta la transición entre modos de operación: reposo, siguelíneas, resolución de laberinto y control Bluetooth. Cada módulo vive en su propia rama durante desarrollo y se fusiona a master solo tras validación en pista.

┌─ master (Firmware Todo-en-Uno) ──────────────────────────┐
│  Máquina de estados: IDLE → FOLLOW_LINE → MAZE → BT_CTRL  │
│  Calibración persistente en flash (Preferences.h)         │
│  Rampas de aceleración suave (updateRamp)                 │
└──────────────────────┬───────────────────────────────────┘
                       │ fusión tras validación
         ┌─────────────┼─────────────┬──────────────┐
         ▼             ▼             ▼              ▼
  ┌────────────┐ ┌───────────┐ ┌────────────┐ ┌──────────────┐
  │ FollowLine │ │ Labyrinth │ │BT_Controller│ │  Calibration  │
  │ PID + EMA  │ │Servo+HC04 │ │ TB6612FNG  │ │balanceOffset  │
  │ Kp=30 Kd=30│ │ IR lateral│ │ Bluetooth  │ │ NVS Flash     │
  └────────────┘ └───────────┘ └────────────┘ └──────────────┘

Flujo de Operación en Pista

1. Power-on → IDLE: calibración inicial de sensores, carga de offset desde flash
2. Selector de modo (físico/Bluetooth) → FOLLOW_LINE o MAZE
3. FOLLOW_LINE:
   ├── Sensores IR leen línea → filtro EMA (alpha=0.35)
   ├── Controlador PD calcula corrección (Kp=30, Kd=30)
   └── updateRamp suaviza entrega a motores TB6612FNG
4. MAZE:
   ├── Servo SG90 escanea 3 ángulos con HC-SR04
   ├── IR laterales detectan pared próxima
   └── Algoritmo prioriza giro según distancia disponible
5. BT_CTRL: control remoto bidireccional para pruebas y ajuste fino

Separación de Responsabilidades

MóduloTecnologíaResponsabilidad
Máquina de EstadosC++ (PlatformIO)Orquestar transiciones entre modos de operación
FollowLinePID + Filtro EMAControl proporcional-derivativo con suavizado de sensores IR
LabyrinthServo SG90 + HC-SR04 + IREscaneo ultrasónico 3 posiciones + barrera IR lateral
Control RemotoBluetoothSerial + TB6612FNGControl bidireccional vía BT para pruebas y calibración en físico
PersistenciaPreferences.h (NVS Flash)Almacenar balanceOffset de motores sin recompilar

3. Tecnologías y Justificación

Microcontrolador y Firmware

  • ESP32: Seleccionado por su doble núcleo, conectividad WiFi/Bluetooth integrada y abundante memoria flash (16MB). Permite ejecutar FreeRTOS para multitarea real sin necesidad de RTOS externo. El periférico MCPWM integrado simplifica el control de motores DC.
  • PlatformIO: Entorno de desarrollo con gestión declarativa de librerías, compilación cruzada y soporte para múltiples frameworks. Reemplaza al IDE de Arduino con mejor control de versiones y build reproducibles.
  • FreeRTOS: Sistema operativo en tiempo real que permite ejecutar loops de control (PID, escaneo ultrasónico) y comunicación Bluetooth como tareas independientes sin interferencia mutua.

Control de Motores

  • TB6612FNG: Driver de motores dual con capacidad de 1.2A por canal y control independiente de velocidad/dirección por PWM. Más eficiente que el L298N (caída de voltaje ~0.5V vs ~2V) y con protección térmica integrada.
  • PID + Filtro EMA: Controlador PD (Kp=30, Kd=30) con filtro de promedio móvil exponencial (alpha=0.35). El EMA elimina ruido de alta frecuencia de los sensores IR sin agregar latencia significativa (respuesta en ~3 ciclos), crítico para mantener la línea a alta velocidad.
  • Rampas de Aceleración (updateRamp): Implementación de rampas suaves para evitar picos de corriente que dañan las soldaduras de la batería y prevenir deslizamiento inercial en curvas. La función incrementa velocidad en pasos de 15 unidades por ciclo.

Sensores y Navegación

  • Sensores IR para siguelíneas: Array de sensores infrarrojos reflectivos que detectan el contraste entre la línea negra y la superficie blanca. La posición relativa de la línea se calcula como un valor ponderado entre sensores, alimentando el controlador PD.
  • Servo SG90 + HC-SR04: Sensor ultrasónico montado sobre servo de 180° para escaneo direccional. Tres posiciones fijas (-90°, 0°, +90°) permiten medir distancia en las direcciones relevantes sin barrenido continuo, reduciendo tiempo de ciclo y consumo energético.
  • IR laterales: Sensores infrarrojos ubicados a los costados del chasis actúan como barrera de proximidad inmediata. Cuando detectan un obstáculo por debajo del umbral, fuerzan una parada de emergencia independiente del algoritmo de navegación (fail-safe por hardware).

Persistencia y Configuración

  • Preferences.h (NVS): API de ESP32 para almacenar pares clave-valor en memoria flash no volátil. Se usa para guardar el offset de desbalance de motores (balanceOffset) calibrado una vez por unidad física. El valor persiste entre reinicios y no requiere recompilar el firmware para ajustar la calibración entre robots.

4. Capturas y Video Demostrativo

Grabación del carro autónomo en pista de pruebas durante la fase de calibración del siguelíneas. Se aprecia el control PID con filtro EMA compensando curvas cerradas y manteniendo la trayectoria.

Ver en TikTok — Siguelíneas PID
Robot en Pista — Prueba de Laberinto
Arquitectura de Ramas Git

5. Problemas Encontrados

Ruido en sensores IR a alta velocidad

Problema: Al aumentar la velocidad del robot, los sensores infrarrojos captaban vibraciones del chasis como ruido eléctrico de alta frecuencia. El controlador PD reaccionaba a estas fluctuaciones generando correcciones bruscas que desestabilizaban la trayectoria, especialmente en curvas cerradas.

Solución aplicada: Implementación de filtro de promedio móvil exponencial (EMA) con alpha = 0.35. El filtro suaviza las lecturas crudas de los sensores antes de alimentar el controlador PD. La constante alpha se ajustó experimentalmente: valores mayores (más rápidos) dejaban pasar ruido; valores menores (más lentos) introducían latencia que hacía al robot reaccionar tarde en curvas. 0.35 fue el punto óptimo entre suavizado y respuesta.

Desbalance físico entre motores

Problema: Cada unidad del robot tenía un desbalance natural distinto entre motor izquierdo y derecho debido a tolerancias de fabricación y desgaste. Un offset fijo en código requería recompilar y reflashear el firmware para cada robot, imposible en contexto de competencia con múltiples equipos.

Solución aplicada: Calibración única almacenada en memoria flash NVS del ESP32 via Preferences.h. El offset (balanceOffset) se calibra una vez por robot mediante una rutina de diagnóstico y persiste entre reinicios. Si el robot se recalibra, el nuevo offset se sobrescribe sin recompilar. Esto permitió preparar múltiples unidades en paralelo.

Deslizamiento inercial en curvas

Problema: El peso de la batería de LiPo y la inercia del chasis causaban que el robot se deslizara hacia afuera en curvas cerradas a velocidad alta. Los cambios bruscos de velocidad también generaban picos de corriente que degradaban las soldaduras de la batería con el tiempo.

Solución aplicada: Implementación de rampas de velocidad progresivas (updateRamp). En lugar de saltar de 0 a 255, la función incrementa/decrementa en pasos de 15 unidades por ciclo. Esto reduce el pico de corriente en un ~40% y elimina el deslizamiento por inercia en curvas, mejorando el tiempo de vuelta en ~0.8s respecto a aceleración brusca.

6. Decisiones Técnicas Clave

PID sobre control on-off (bang-bang)

Alternativas consideradas: Controlador bang-bang (todo o nada) que gira el robot al detectar desviación, o control proporcional simple.

Decisión: Controlador PD con derivada para anticipar la desviación. En pruebas, el bang-bang generaba un zigzagueo constante que reducía la velocidad máxima sostenible. El PD con Kp=30, Kd=30 permite mantener la línea a velocidad ~20% mayor que bang-bang con la misma superficie de pista. Se omitió la componente integral (I) porque el error de estado estacionario no es relevante en una pista cerrada — el robot siempre tiende a corregir hacia el centro.

Ramas Git por subsistema en vez de feature flags

Alternativas consideradas: Un solo branch con feature flags habilitando/deshabilitando módulos por configuración en tiempo de compilación.

Decisión: Ramas independientes por subsistema (FollowLine, Labyrinth, BT_Controller) que se fusionan a master tras validación en pista. Este enfoque permitió a los estudiantes trabajar cada módulo sin interferencia y mantener un master siempre funcional. El costo de merges se mitigó con una máquina de estados bien definida que aislaba los puntos de integración. Para equipos sin experiencia en Git, este flujo fue más intuitivo que feature flags.

EMA en firmware vs. filtro por hardware

Alternativas consideradas: Capacitor de desacople en las líneas de señal de los sensores IR para filtrar ruido por hardware, o filtro de promedio móvil simple (ventana fija).

Decisión: Filtro EMA en software (alpha=0.35). El capacitor agregaba costo BOM y requería ajuste por lotes de sensores. El promedio móvil simple requería un buffer de N muestras, consumiendo RAM (~32 bytes por sensor con ventana de 8). EMA solo necesita una variable de estado por sensor (4 bytes float) y responde más rápido a cambios reales que un promedio ventaneado del mismo tamaño efectivo. En un ESP32 con 512KB de RAM, la diferencia marginal, pero el patrón es relevante para proyectos con microcontroladores más limitados.

7. Aprendizajes

  • El filtro EMA es una navaja suiza para sensores ruidosos en embebidos.Ocupa una sola variable de estado por canal, no requiere buffer, y su constante alpha se ajusta en caliente. Es aplicable a cualquier sensor analógico con ruido de alta frecuencia: IMUs, potenciómetros, termistores. La compensación entre suavizado y latencia se calibra experimentalmente.
  • La persistencia en flash evita recompilar por calibración. En proyectos con múltiples unidades físicas, el desbalance de componentes varía entre unidades. Almacenar calibraciones en NVS elimina la necesidad de mantener N builds de firmware. Preferences.h del ESP32 hace esto trivial, pero el patrón aplica a cualquier MCU con flash disponible (emulado en EEPROM para AVR).
  • Rampas de velocidad benefician tanto a la mecánica como al control.Originalmente implementadas para proteger soldaduras, resultaron en mejor adherencia en curvas y tiempos de vuelta más consistentes. La aceleración suave reduce la overshoot del PID porque el robot no llega a la curva con máxima inercia. Un buen diseño mecánico y de control no son independientes.
  • Enseñar Git con ramas físicas es más fácil que con teoría. Los estudiantes sin experiencia previa en control de versiones entendieron mejor "cada uno trabaja en su rama y luego juntamos" que conceptos abstractos de merge/rebase. La máquina de estados en master actuó como contrato de interfaz claro entre módulos.
  • Las competencias de robótica revelan fallas de diseño que los bench tests no detectan. El ruido en IR a alta velocidad no apareció en pruebas lentas de escritorio. La inercia en curvas solo se manifestó con la batería real instalada (vs. fuente de laboratorio). Probar temprano en condiciones de competencia ahorra rediseños de última hora.
  • Control remoto Bluetooth como herramienta de debugging vale su peso en oro. Poder ajustar Kp, Kd y alpha desde un teléfono sin recompilar ni conectar cables redujo el ciclo de ajuste de ~10 min (compilar + flashear) a ~30 segundos. En un día de competencia, esto permitió iterar 20+ ajustes.

8. Documentación Técnica del Proyecto

README original del repositorio Esp32_Car_2026: introducción, arquitectura de ramas, guía de compilación con PlatformIO, configuración de pines y calibración.

README.mdIntroducción, arquitectura de ramas, setup PlatformIO, pinout, calibración y guía rápida