%% Referencias de código (no se renderizan en el PNG, solo para mantenimiento futuro) %% Fase 1 (inferir dirección) -- detalle común en: %% schemes/flowcharts/common/mermaid/inferencia-direccion.mmd %% Compromiso de dirección: src/python/src/ros2/navigation/track_navigator_node.py (_commit_direction) %% src/python/src/navigation/start_measurement.py, planning/waypoints.py (plan_believed_path) %% Fase 2 (conducción) -- vigilancia de colisión/atasco, detalle común en: %% schemes/flowcharts/common/mermaid/escape-colision.mmd %% Fase 3 (vueltas) -- detalle común en: %% schemes/flowcharts/common/mermaid/conteo-vueltas.mmd %% Fase 4 (fin): core_navigator.py (_handle_finish) -- sin ParkController en Open Challenge %% - %% PRECISADO 2026-09-10. El nodo de conducción decía "ajustando la velocidad %% según el espacio libre adelante y el error de rumbo", lo cual es cierto pero %% esconde cómo funciona de verdad y por qué el robot va lento en las curvas: %% - %% EL LÍMITE DE RUMBO ES UN ESCALÓN, NO UNA RAMPA. src/config/navigation/motion/ %% heading.toml fija crawl = 1.0 rad (~57 grados) y crawl_ramp_start = 0.0, o %% sea: por debajo de 57 grados de error de rumbo no hay penalización alguna, y %% por encima la velocidad cae de golpe al suelo de arrastre. No hay término %% medio. Medido, ese corte está activo entre el 44% y el 64% de la ronda, así %% que ES el límite de velocidad que manda en el Open, por encima del espacio %% libre adelante. %% - %% SUAVIZARLO ESTÁ REFUTADO, no pendiente: convertir el escalón en rampa se midió %% sobre 128 escenarios y dio -0.00 s de media más una carrera nueva en sentido %% inverso. La rampa es un PALIATIVO porque la causa está aguas arriba: el 58% de %% los ticks apuntan a un punto objetivo que exige 0.23 m de radio de giro contra %% un mínimo físico de 0.29 m. El chasis no puede tomar la curva que se le pide, %% acumula error de rumbo, y el escalón lo frena. Arreglar el punto objetivo es %% el arreglo; suavizar el freno no lo es. %% - %% ESTADO: el Open está funcionalmente completo -- 638/640 en simulación sobre %% un checkout limpio con cero colisiones, y dos rondas limpias de 3 vueltas en %% hardware, una por sentido. El riesgo restante es de COBERTURA, no de %% capacidad: el hardware ha visto 2 arranques y la simulación varía 640. flowchart TD Start(["Inicio de la carrera
(modo ciego: sin mapa
ni dirección conocidos)"]) --> Fase1 Fase1[["Inferencia de dirección"]] --> Commit["Fija la dirección
y ubica al robot en la pista"] Commit --> StartPose["Mide con precisión
la posición de arranque"] StartPose --> PlanPath["Traza la ruta de
puntos de paso a seguir"] PlanPath --> BuildLap["Prepara el contador
de vueltas para esa ruta"] BuildLap --> Drive subgraph FASE_2["Fase 2 - Conducción normal"] Drive["Sigue la ruta trazada"] --> SpeedClear["Elige velocidad según el
espacio libre adelante:
cuanto menos hueco, más lento"] SpeedClear --> HeadCheck{"¿El error de rumbo
supera 57 grados?"} HeadCheck -- "Sí" --> Crawl["Cae de golpe al suelo
de arrastre (no es una
rampa: es un escalón)"] HeadCheck -- "No" --> Full["Mantiene la velocidad
que pidió el espacio libre:
por debajo de 57 grados
no hay penalización"] Crawl --> Watch Full --> Watch[["Vigilancia de colisión y atasco"]] Watch --> WPCheck end WPCheck{"¿Llegó al punto
de paso objetivo?"} WPCheck -- "No" --> Drive WPCheck -- "Sí, y cerró
la vuelta de la ruta" --> LapPhase LapPhase[["Conteo de vueltas"]] --> LapsDone{"¿Ya completó
las 3 vueltas?"} LapsDone -- "No" --> Drive LapsDone -- "Sí" --> Finish subgraph FASE_4["Fase 4 - Fin (sin estacionamiento)"] Finish["Se detiene por completo.
El Open Challenge no tiene
maniobra final"] end Finish --> End(["Carrera terminada"])