Problemas Conocidos
Fecha de análisis: 2026-06-11
Última actualización: 2026-08-25
Total: 64 issues — 10 críticos, 24 moderados, 30 leves
Última revisión: 2026-08-25 (commits aa1e633..2bbbe13)
Issues nuevos: 17 (HW-01..HW-05, SW-01..SW-03, SP-01..SP-09)
Issues corregidos: 0
Issues actualizados: 0
Correcciones Recientes ✅
| ID |
Fecha |
Descripción |
| SS-01 |
2026-06-11 |
Desbordamiento de tabla LUT — añadido bounds checking |
| SS-02 |
2026-06-11 |
Análisis de timing: margen 97x, fallo improbable |
| SS-03 |
2026-06-11 |
Filtro mediana N=3 + EMA adaptativo (α=0.2/0.6, umbral 10mm) |
| SS-07 |
2026-06-11 |
Threshold raw corregido con ley 1/d² (factor 1.5× distancia) |
| SS-15 |
2026-06-11 |
Checksum aditivo (complemento a 2) en EEPROM + warning_eeprom |
🔴 Críticos (10 issues)
Floodfill
FF-01 — Estado insuficiente en el BFS para modo TIME_BASED
| Archivos | floodfill.c:340 |
| Descripción | El floodfill almacena un único float por celda. En TIME_BASED, el coste de transición depende del estado (dirección + count). Un camino con tiempo ligeramente superior pero mejor dirección se descarta. |
| Impacto | Alto — puede no encontrar la ruta óptima global. |
| Mitigación | Condición >= permite caminos con mismo tiempo pero distinto estado. |
| Solución | Ampliar estado a floodfill[celda][direccion] o usar A*. |
FF-02 — Desbordamiento de la cola de prioridad ✅ CORREGIDO
| Archivos | floodfill.h:64-68, floodfill.c:358-387 |
| Descripción | La cola tenía capacidad fija de MAZE_CELLS (256 slots) con head/tail acumulativos. Con la relajación >= de los modos no-BASIC, un mismo update_floodfill() puede encolar bastante más de 256 veces (medido: TIME hasta ~624; DIAGONAL hasta ~14 000 en exploración de laberinto vacío). El push #257 escribía sobre head/tail (offset 4096) → SIGSEGV o floodfill incompleto. |
| Impacto | Alto — corrupción de memoria y caída del simulador. En robot normalmente no se disparaba porque el laberinto cargado de EEPROM reduce los reencolados, pero era UB latente. |
| Solución | Capacidad ampliada a MAZE_CELLS × 8 (2048 slots, 32 KB) mediante CELLS_QUEUE_CAPACITY y guardas de capacidad en queue_push()/queue_pop(). Se conserva la condición >= (necesaria para estados con distinta orientación en diagonales encadenadas). TIME queda con ~3× de margen; DIAGONAL puede saturar la cola en exploración de laberinto vacío, pero la guarda evita la corrupción y el floodfill sigue siendo completo. |
FF-03 — Penalización de giro ausente en transición ortogonal→ortogonal
| Archivos | floodfill.c:515-520 |
| Descripción | El caso from_orthogonal && to_orthogonal no verifica si la dirección cambió. |
| Impacto | Bajo en práctica (cubierto por otros casos del switch). |
Sensores
SS-01 — Desbordamiento de tabla LUT ✅ CORREGIDO
| Solución | Añadido bounds checking: if (ln_index >= LOG_LINEARIZATION_TABLE_SIZE) ln_index = LOG_LINEARIZATION_TABLE_SIZE − 1. |
SS-02 — Pérdida de conversiones ADC ✅ CORREGIDO
| Solución | Análisis de timing confirmó margen 97x. Sin riesgo real. |
SS-03 — Sin filtrado de lecturas ADC ✅ CORREGIDO
| Solución | Añadido: mediana N=3 + EMA adaptativo. |
Movimiento
MV-01 — PID sin anti-windup (6 integradores)
| Archivos | control.c:392-451 |
| Descripción | Los 6 integradores acumulan error sin clamping. Tras saturación, overshoot masivo. |
| Impacto | Alto — inestabilidad severa. |
| Solución | Implementar clamping condicional (back-calculation o conditional integration). |
MV-02 — move_inplace_turn() siempre gira a la izquierda
| Archivos | move.c:126-143 |
| Descripción | MOVE_BACK, MOVE_BACK_WALL y MOVE_BACK_STOP tienen sign = −1 fijo. |
| Impacto | Medio-Alto — desviación sistemática en exploración. |
MV-03 — lsm6dsr_read_gyro_z_raw() depende de auto-incremento SPI no verificado
| Archivos | lsm6dsr.c:66-73 |
| Descripción | Asume que IF_INC está habilitado para leer ZL+ZH consecutivos. |
| Impacto | Medio — datos incorrectos si IF_INC no está configurado. |
| Archivos | lsm6dsr.c:48-59 |
| Descripción | Solo transfieren 1 byte independientemente del parámetro len. |
| Impacto | Medio — frágil ante cambios de la librería LSM6DSR. |
🟡 Moderados (24 issues)
Floodfill
FF-04 — total_time incorrecto en tabla de pesos
| Descripción | total_time incorrecto en tabla de pesos (primera celda contada 2×). |
| Impacto | Bajo. |
FF-05 — Índice incorrecto en mmsim_get_estimated_time()
| Descripción | mmsim_get_estimated_time() usa índice incorrecto (off-by-one). |
| Impacto | Medio. |
FF-06 — Modelo de penalización de giro inexacto
| Descripción | Modelo de penalización de giro inexacto (asume deceleración completa). |
| Impacto | Medio. |
FF-07 — Orientación inicial no considerada al planificar
| Descripción | Floodfill no considera orientación inicial del robot al planificar. |
| Impacto | Medio. |
Sensores
| Descripción | Fórmula con posible división por ~0. |
| Estado | NO APLICA. |
SS-05 — Parámetro c negativo (mitigado)
| Descripción | Parámetro c negativo (mitigado). |
| Estado | NO APLICA. |
SS-06 — Filtro EMA sustituido por adaptativo
| Descripción | Filtro EMA sustituido por adaptativo en SS-03. |
| Estado | NO APLICA. |
SS-07 — Umbral raw corregido con ley 1/d² ✅ CORREGIDO
| Descripción | Umbral raw corregido con ley 1/d² (factor 1.5× distancia). |
SS-08 — Crosstalk óptico potencial
| Descripción | Crosstalk óptico potencial. |
| Estado | NO APLICA. |
SS-09 — Umbrales cableados en get_side_sensors_error()
| Descripción | Umbrales cableados en get_side_sensors_error(). |
| Estado | NO APLICA. |
| Descripción | Fórmula no validada contra datasheet (validada empíricamente). |
| Estado | NO APLICA. |
SS-15 — Sin validación de datos EEPROM ✅ CORREGIDO
| Descripción | Sin validación de datos EEPROM. Corregido con checksum aditivo (complemento a 2) + warning_eeprom. |
Movimiento
MV-05 — Distancia de frenada usa velocidad ideal
| Descripción | Distancia de frenada usa velocidad ideal, no real. |
| Impacto | Medio. |
MV-06 — Filtros independientes en velocidad angular
| Descripción | Velocidad angular con filtros independientes (desfase entre canales). |
| Impacto | Bajo-Medio. |
MV-07 — PI con 4 decimales
| Descripción | PI con 4 decimales (error 0.003%). |
| Impacto | Bajo. |
| Descripción | Fórmulas move_inplace_turn() no cinemáticamente exactas. |
| Impacto | Medio. |
MV-09 — Degradación de giro solo hacia abajo
| Descripción | Degradación de giro solo hacia abajo. |
| Impacto | Medio. |
MV-10 — Posible inconsistencia de signos en control angular
| Descripción | Posible inconsistencia de signos en control angular. |
| Impacto | Alto potencial. |
MV-11 — move_straight() negativo no comprueba wall loss
| Descripción | move_straight() negativo no comprueba wall loss. |
| Impacto | Bajo. |
Hardware
HW-01 — Esquemático y PCB desincronizados
| Archivos | pcb_files/kicad_project/ZoroBot3.kicad_sch, pcb_files/kicad_project/ZoroBot3.kicad_pcb |
| Descripción | El commit ced009d añade la SRAM 23AA04M al esquemático (SRAM1 + RRAM1 + CSRAM1 + net NSS_SRAM) y elimina los amplificadores de corriente AD8418, pero el PCB no se ha actualizado: la SRAM no está colocada y los footprints AD8418AWBZ_1/_2 siguen presentes. El diff del PCB en ese commit es solo migración de formato KiCad 8→10 (198 footprints idénticos). |
| Impacto | Medio-Alto — fabricar la placa en este estado produciría un PCB sin SRAM y con amplificadores sin función; riesgo de olvido si no se sincroniza antes de fabricar. |
| Mitigación | Ninguna — el desfase es silencioso hasta exportar gerbers. |
| Solución | Ejecutar Update PCB from Schematic y recolocar/rutear las piezas nuevas y huérfanas antes de la próxima fabricación. |
HW-02 — Lectura de corriente sin amplificador front-end
| Archivos | pcb_files/kicad_project/ZoroBot3.kicad_sch (nets CURR_SEN_MI/CURR_SEN_MD) |
| Descripción | El commit ced009d anunciaba "añadir lectura de corriente" pero elimina los amplificadores AD8418 y los shunts (SHUNT_MI/SHUNT_MD). Los canales ADC CH14/CH15 (PC4/PC5) quedan conectados sin shunt ni etapa de ganancia, por lo que no miden corriente utilizable. |
| Impacto | Medio — la lectura de corriente de motores queda inoperativa; los canales ADC quedan sin señal útil. |
| Mitigación | Ninguna — el firmware no usa estos canales actualmente. |
| Solución | Rediseñar el front-end (p. ej. reinsertar AD8418 con shunt, o un amplificador de nueva generación) o eliminar los canales y su documentación. |
HW-03 — Diodo de protección del ventilador de succión ausente
| Archivos | pcb_files/kicad_project/ZoroBot3.kicad_sch, ZoroBot3.kicad_pro |
| Descripción | El commit ced009d menciona un "diodo en succión" pero ningún fichero guardado contiene ese diodo: D14 solo existe como designador fantasma en used_designators del proyecto KiCad. El ventilador queda sin diodo de libre circulación/protección. |
| Impacto | Medio — picos de tensión inducidos por el motor del ventilador pueden dañar el MOSFET de control (Q1). |
| Mitigación | Ninguna en el diseño actual. |
| Solución | Añadir el diodo al esquemático (en paralelo con el ventilador, cátodo a positivo) y propagar a PCB/BOM. |
Scripts Python
SP-01 — Dependencias de los scripts sin declarar
| Archivos | scripts/turn-profiles/*.py, scripts/turn-profiles/*.ipynb, scripts/sensors-profiles/sensors-profiles.ipynb |
| Descripción | Los scripts importan numpy, matplotlib y pandas (y scipy.optimize en sensors-profiles) sin que exista ninguna declaración de dependencias en el repo: no hay requirements.txt ni pyproject.toml en la raíz ni en scripts/ (los únicos requirements son de docs y solo contienen mkdocs). Un entorno limpio falla con ModuleNotFoundError y no queda registro del contrato de runtime. |
| Impacto | Medio — los scripts no son reproducibles en una máquina nueva. |
| Solución | Añadir un requirements.txt (numpy, pandas, matplotlib, scipy) en scripts/ o en la raíz y referenciarlo en los README de los scripts. |
SP-02 — Imports dependientes del directorio de trabajo
| Archivos | scripts/turn-profiles/aux/verify_profiles.py:9, aux/deep_analysis.py:7, aux/analyze_all_pairs.py:10, aux/test_new_exit.py:14, turn-profiles.ipynb (celda 2) |
| Descripción | Los cuatro scripts auxiliares hacen sys.path.insert(0, '.') e importan la biblioteca principal: solo funciona si el CWD es exactamente scripts/turn-profiles/. El notebook tiene la misma dependencia oculta (importa el módulo sin manipular el path). Desde cualquier otro directorio falla con ModuleNotFoundError sin diagnóstico útil. |
| Impacto | Medio — scripts frágiles ante la forma de invocación. |
| Solución | Derivar la ruta del módulo desde __file__ (p. ej. sys.path.insert(0, str(Path(__file__).resolve().parent.parent))) o empaquetar el módulo; documentar el requisito de CWD en el notebook. |
🟢 Leves (30 issues)
Floodfill
FF-08 — Código inalcanzable tras return en switches
| Descripción | Código inalcanzable tras return en switches. |
FF-09 — #pragma GCC diagnostic ignora -Wswitch
| Descripción | #pragma GCC diagnostic ignora -Wswitch. |
FF-10 — time_penalty retorna 0 si init_speed >= speed
| Descripción | time_penalty retorna 0 si init_speed >= speed. |
FF-11 — get_direction_value() devuelve 0 para diagonales
| Descripción | get_direction_value() devuelve 0 para diagonales. |
FF-12 — Sesgo direccional en floodfill_run()
| Descripción | Sesgo direccional en floodfill_run() (NORTH siempre gana empates). |
FF-13 — cells_to_max_speed puede exceder el buffer de pesos
| Descripción | cells_to_max_speed puede exceder FLOODFILL_MAX_WEIGHTS_COUNT. |
Sensores
SS-11 — update_side_sensors_leds() con código repetitivo
| Descripción | update_side_sensors_leds() con código repetitivo. |
| Estado | NO APLICA. |
SS-12 — all_sensors_take_values() bucle infinito (debug)
| Descripción | all_sensors_take_values() bucle infinito (debug). |
| Estado | NO APLICA. |
SS-13 — Flag sensors_taking_values nunca a false
| Descripción | Flag sensors_taking_values nunca a false. |
| Estado | NO APLICA. |
SS-14 — División entera en calibración
| Descripción | División entera en calibración (error ±1 sobre ~2000). |
| Estado | NO APLICA. |
Movimiento
MV-12 — avg_micrometers/avg_millimeters nunca actualizadas
| Descripción | avg_micrometers/avg_millimeters nunca actualizadas (código muerto). |
MV-13 — volatile innecesario en variables de control PID
| Descripción | volatile innecesario en variables de control PID. |
MV-14 — Expresión redundante true && en move_arc_turn()
| Descripción | Expresión redundante true && en move_arc_turn(). |
MV-15 — Número mágico 1.75f en move_back()
| Descripción | Número mágico 1.75f en move_back(). |
MV-16 — Parámetros start/end negativos sin validación de rango
| Descripción | Parámetros start/end negativos sin validación de rango. |
MV-17 — check_wall_loss_correction() solo paredes laterales
| Descripción | check_wall_loss_correction() solo paredes laterales. |
MV-18 — Frecuencia acoplada rígidamente a SysTick = 16 kHz
| Descripción | Frecuencia acoplada rígidamente a SysTick = 16 kHz. |
MV-19 — Wrap-around de timer de encoders (verificado correcto ✅)
| Descripción | Wrap-around de timer de encoders (verificado correcto ✅). |
Hardware
HW-04 — BOM desactualizado
| Archivos | pcb_files/gerbers/bom.csv (+ designators.csv, positions.csv) |
| Descripción | El BOM generado es anterior al rango revisado: lista los AD8418 eliminados del esquemático y no incluye SRAM1/RRAM1/CSRAM1 (23AA04M, 10 kΩ, 100 nF). |
| Impacto | Bajo — pedido de componentes incorrecto si se usa el BOM sin regenerar. |
| Solución | Regenerar el BOM desde el esquemático actual (export BOM de KiCad) cuando el diseño se estabilice. |
HW-05 — SRAM sin soporte en firmware
| Archivos | source_code/ (sin driver); pcb_files/kicad_project/ZoroBot3.kicad_sch (SRAM1) |
| Descripción | La SRAM 23AA04M-I/ST (4 Mbit) está conectada al bus SPI3 compartido con CS dedicado en PB12 (pull-up 10 kΩ), pero no existe driver ni inicialización en el firmware. PB12 está libre en el código actual. |
| Impacto | Bajo — la SRAM no es utilizable hasta añadir el driver. |
| Solución | Implementar driver SPI (modo byte) con CS en PB12 e integrar el uso previsto de la SRAM. |
Arquitectura Software
SW-01 — Comentarios de setup_spi() incorrectos
| Archivos | setup.c:328-332 |
| Descripción | El comentario documenta CPHA 0 ("los datos de entrada se capturan en el flanco ascendente") pero el código usa SPI_CR1_CPHA_CLK_TRANSITION_1 (CPHA 1, captura en el segundo flanco). Además los comentarios de frecuencia mezclan PCLK1 = 36 MHz con 84 MHz para el cálculo del divisor SPI. |
| Impacto | Bajo — riesgo de configuraciones erróneas en cambios futuros guiados por el comentario. |
| Solución | Corregir el comentario al valor real del registro (CPHA 1) y unificar las frecuencias de reloj citadas. |
SW-02 — setup_spi_low_speed() código muerto
| Archivos | setup.c:375-378 |
| Descripción | La función setup_spi_low_speed() está definida pero nunca se llama en todo el firmware. |
| Impacto | Bajo — mantenibilidad. |
| Solución | Eliminarla o usarla donde corresponda. |
SW-03 — openocd_reset.cfg referencia STM32F401
| Archivos | openocd_reset.cfg |
| Descripción | El comentario sobre flash de banco único menciona "STM32F401"; el target real es un STM32F405 (también de banco único, por lo que el comportamiento descrito es correcto). |
| Impacto | Bajo — confusión al leer la configuración. |
| Solución | Cambiar el comentario a STM32F405. |
Scripts Python
SP-03 — ValueError sin mensaje en perfiles slalom infeasibles
| Archivos | scripts/turn-profiles/micromouse_sinusoidal_turn_profiles_aux.py:299, aux/test_new_exit.py:199-200 |
| Descripción | Cuando un perfil slalom es infeasible, se lanza raise ValueError sin mensaje. El capturador en test_new_exit.py imprime turn_shift failed (lines parallel) - {e} con mensaje vacío, atribuyendo la causa a líneas paralelas cuando en realidad es la comprobación de velocidad angular de la transición. |
| Impacto | Bajo — diagnóstico engañoso. |
| Solución | raise ValueError(f'transition-only angular velocity {max_angular_velocity_transition:.3f} < required {max_angular_velocity:.3f}'). |
SP-04 — except Exception genérico oculta bugs como fallos de estrategia
| Archivos | scripts/turn-profiles/aux/test_new_exit.py:232 |
| Descripción | El except Exception as e exterior del bucle de estrategias imprime ERROR - {e} y hace continue. Cualquier error de programación real (KeyError, NaN, typo) dentro del try se reporta como fallo de la estrategia de shift, sin traceback ni re-raise. El except ValueError interno (líneas 194-201) ya cubre el caso esperado. |
| Impacto | Bajo — bugs reales se ocultan como resultados legítimos del análisis. |
| Solución | Eliminar el except Exception exterior, o re-lanzar tras imprimir con traceback.print_exc(). |
SP-05 — Código muerto y comentado sin explicación
| Archivos | scripts/turn-profiles/aux/test_new_exit.py:82, micromouse_sinusoidal_turn_profiles_aux.py:288 |
| Descripción | Línea muerta errónea en test_new_exit.py:82 (usa la columna y en vez de x, marcada como "wrong, let me recalc", nunca usada — el cálculo correcto sigue en 85-86) y fórmula comentada en la biblioteca (línea 288) sin explicación de por qué se sustituyó. |
| Impacto | Bajo — mantenibilidad; la línea errónea induciría a error si se reactivara. |
| Solución | Eliminar la línea 82 y el comentario de la 288 (o documentar el motivo de la sustitución). |
SP-06 — Encoding corrupto en verify_profiles.py
| Archivos | scripts/turn-profiles/aux/verify_profiles.py |
| Descripción | El archivo contiene 1428 bytes de ? literales donde debería haber ✓/✗/═/acentos: "Script de verificaci??n", separadores "????????", y los marcadores pass/fail muestran "???" en ambas ramas. El veredicto del script — su función principal — queda ilegible. |
| Impacto | Bajo — el lector debe inferir el resultado de los ratios numéricos. |
| Solución | Reescribir los caracteres (✓/✗, ═, verificación) y verificar la codificación UTF-8 al guardar. |
SP-07 — Clasificación "PERPENDICULAR" errónea en analyze_all_pairs.py
| Archivos | scripts/turn-profiles/aux/analyze_all_pairs.py:297-306 |
| Descripción | Tras normalizar los ángulos a [0, π/2], el código clasifica como perpendiculares los pares con abs(angle_between - π/4) < 0.01. Las líneas perpendiculares difieren π/2 (90°), no π/4: pares a 45° se etiquetan "PERPENDICULAR", alimentando el razonamiento de PART 4 sobre qué pares de giro necesitan tramo recto intermedio. |
| Impacto | Bajo — decisiones de diseño basadas en salida incorrecta. |
| Solución | is_perpendicular = abs(angle_between - π/2) < 0.01. |
SP-08 — Notebook de turn-profiles con 3 MB de figuras y títulos con mojibake
| Archivos | scripts/turn-profiles/turn-profiles.ipynb (celdas 7, 9, 11, 13, 15, 17) |
| Descripción | 42 figuras PNG de 1600×1600 embebidas en el notebook (3.06 MB total) y 36 títulos con la secuencia "º" (mojibake del carácter °): p. ej. plot_trajectory(title = "90º NORMAL"). El notebook pesa 3.1 MB, renderiza lento y los títulos guardados están corruptos. |
| Impacto | Bajo — repo inflado y salida degradada. |
| Solución | Reducir a dpi=80-100 o guardar figuras en images/ y referenciarlas; reemplazar º por °. |
SP-09 — Structs de calibración solo en stdout, sin artefacto diffable
| Archivos | scripts/sensors-profiles/sensors-profiles.ipynb (celda 8) |
| Descripción | Los coeficientes a/b/c que deben aterrizar en sensors.c se emiten solo como salida impresa de la celda 8. No existe artefacto en fichero ni comprobación contra los valores commitados en el firmware: cambiar ACTIVE_DATASETS o los rangos de ajuste modifica silenciosamente los structs emitidos sin dejar rastro diffable. |
| Impacto | Bajo — las constantes del firmware pueden derivar del análisis sin detectarse. |
| Solución | Hacer que la celda 8 escriba a un fichero (p. ej. generated/sensors_calibration.h) o afirme igualdad con los valores del firmware; añadir nota de orden de ejecución. |
Resumen por Prioridades
| Prioridad |
Cantidad |
Issues |
| 🔴 Críticos |
10 |
FF-01..03, SS-01..03, MV-01..04 |
| 🟡 Moderados |
24 |
FF-04..07, SS-04..10/15, MV-05..11, HW-01..03, SP-01..02 |
| 🟢 Leves |
30 |
FF-08..13, SS-11..14, MV-12..19, HW-04..05, SW-01..03, SP-03..09 |
| TOTAL |
64 |
|
Documento actualizado el 2026-08-25. El registro de issues se mantiene en este mismo documento, con anchors estables (#xx-NN) para referencias cruzadas desde el resto de la documentación.