Saltar a contenido
← Volver a OPRobots.org

Scripts: Perfiles de Giro

Sistema de generación de perfiles de giro con aceleración angular sinusoidal (jerk limitado) para el robot micromouse. Produce trayectorias suaves que minimizan el deslizamiento y el estrés mecánico.

Característica Detalle
Script principal scripts/turn-profiles/turn-profiles.ipynb
Biblioteca scripts/turn-profiles/micromouse_sinusoidal_turn_profiles_aux.py (346 líneas)
Scripts auxiliares verify_profiles.py, deep_analysis.py, analyze_all_pairs.py, test_new_exit.py
Dependencias Python ≥ 3.10, NumPy, Pandas, Matplotlib, Jupyter
Salida Structs C con parámetros de giro → se copian a move.c

Arquitectura

micromouse_sinusoidal_turn_profiles_aux.py
│
├── Maze               — dimensiones de celda (0.18m) y poste (0.012m)
├── RobotPhysics       — masa (0.070 kg), inercia, ancho (0.0702m), ω_max (40 rad/s)
├── Line               — recta definida por punto de referencia (x,y) y ángulo
├── TurnProfile        — perfil básico con DataFrame de trayectoria
├── SlalomTurnProfile  — perfil con líneas de entrada/salida + visualización
├── turn_profile()     — genera perfil de ω sinusoidal (3 fases)
├── complete_profile() — integra ω → posición, ángulo, fuerzas
├── complete_slalom_profile() — alinea con líneas de entrada/salida del laberinto
├── turn_shift()       — calcula desplazamiento para alinear perfil
└── Simulator          — orquesta la generación: slalom() e inplace()

Sistema de Coordenadas

Las coordenadas se definen en unidades de celda relativas al poste (escaladas por maze.cell = 0.18m):

                Norte (0, +0.5)
                    |
Oeste (-0.5, 0) ----+---- (+0.5, 0) Este
                    |
                Sur (0, -0.5)
  • (0, 0) = centro del poste
  • Ángulos: 0 = Este, π/2 = Norte, π = Oeste, 3π/2 = Sur

Perfil de Velocidad Angular

Cada giro tiene 3 fases con aceleración sinusoidal:

         ω_max  ───────────────
               ╱                ╲
             ╱                    ╲
    0  ─────                        ─────
    |--transition--|----arc----|--transition--|
Fase Ecuación
Transición entrada ω(t) = ω_max · sin(t/transition · π/2)
Arco constante ω(t) = ω_max
Transición salida ω(t) = ω_max · cos(t/transition · π/2)

Tipos de Giro

Tipo Ángulo Entry Exit Radio (m)
MOVE_90 90° (0, -.5, 0) (.5, 0, π/2) 0.135
MOVE_180 180° (0, -.5, 0) (0, .5, π) 0.090
MOVE_TO_45 45° (0, -.5, 0) (.5, 0, π/4) 0.120
MOVE_TO_135 135° (0, -.5, 0) (0, .5, 3π/4) 0.07456
MOVE_45_TO_45 90° (0, -.5, π/4) (0, .5, 3π/4) 0.06364
MOVE_FROM_45 45° (0, -.5, π/4) (.5, 0, π/2) 0.120
MOVE_FROM_45_180 135° (0, -.5, π/4) (0, .5, π) 0.07456

Estrategias de Velocidad

Estrategia v_90 v_180 v_TO_45 v_TO_135 v_45to45 Uso
EXPLORE 0.800 Exploración del laberinto
NORMAL 1.696 1.350 1.644 1.118 0.955 Carrera conservadora
MEDIUM 1.932 1.575 1.865 1.305 1.114 Carrera media
FAST 2.220 1.800 2.146 1.491 1.273 Competición
SUPER 2.490 2.025 2.404 1.678 1.432 Máxima segura
HAKI 2.745 2.250 2.647 1.864 1.591 Límite físico

Parámetros de Salida (Struct C)

struct turn_params {
    float start;              // Distancia entrada (mm, con signo)
    float end;                // Distancia salida (mm, con signo)
    uint16_t linear_speed;    // Velocidad lineal (mm/s)
    float max_angular_speed;  // ω_max (rad/s)
    float transition;         // Duración transición (ms)
    float arc;                // Duración arco (ms)
    int8_t sign;              // +1 derecha, -1 izquierda
};

Convención de signos de .start y .end

Signo .start .end
Negativo El perfil empieza antes del sensing point (reduce el tramo recto previo) El perfil termina después del sensing point (reduce el tramo recto posterior)
Positivo El perfil empieza después del sensing point (alarga el tramo recto previo) El perfil termina antes del sensing point (alarga el tramo recto posterior)

Scripts Auxiliares

Script Propósito
verify_profiles.py Verifica simetría de MOVE_180, correspondencia TO_135↔FROM_45_180, y TO_45↔FROM_45
deep_analysis.py Trazado paso a paso del proceso de generación de perfiles
analyze_all_pairs.py Análisis de los 49 pares de giros posibles, gaps físicos, y distancias
test_new_exit.py Evalúa el cambio de geometría de MOVE_180 (exit antiguo vs nuevo)

Flujo de Trabajo

flowchart TD
    A[Definir/ajustar perfiles en notebook] --> B[Ejecutar notebook]
    B --> C[verify_profiles.py]
    C --> D{¿Pares correctos?}
    D -->|Sí| E[Copiar structs C a move.c]
    D -->|No| F[deep_analysis.py]
    F --> A
    E --> G[analyze_all_pairs.py]

Problemas Conocidos

Ver 17-known-issues.md para los issues del subsistema de movimiento (MV-XX). Issues específicos de los scripts:

ID Descripción Estado
MOVE_180: asimetría en .start/.end (exit antiguo en (.5, 0, π) causaba ratio 3.64×) ✅ Corregido — exit cambiado a (0, .5, π)
TO_135 / FROM_45_180: referencia de salida incorrecta ((.5, 0, 3π/4)(0, .5, 3π/4)) ✅ Corregido
turn_shift() no funciona con líneas paralelas (afecta a giros de 180°) ⚠️ Limitación de diseño — requiere shift manual
Error residual de ~2.55 mm en MOVE_180 por desplazamiento no exacto de 180 mm ⚠️ Aceptable para la aplicación

Documento generado el 2026-06-25. Ver también Movimiento, Cinemática, Control PID.