Saltar a contenido

Rutinas de control del radar

Esta página describe, en lenguaje operativo (no de programación), cómo el software del RCP enciende y controla el radar paso a paso. Está pensada para que alguien con experiencia operando el radar real (product expert) pueda revisar si la secuencia es correcta, aunque no lea código.

El plan del proyecto define seis rutinas de control: encendido general, encendido del transmisor, encendido del receptor analógico, encendido de la unidad de antena, movimiento de antena y posicionamiento de antena. Cada una automatiza una secuencia que, en el radar original, hacía el operador a mano desde el panel de control.

Por qué esta página existe

El plan del proyecto nombra las seis rutinas pero no fija el procedimiento interno de ninguna — eso es responsabilidad de este equipo, no algo copiado de un manual del fabricante. Cada rutina de esta página necesita revisión de alguien que conozca el procedimiento real antes de confiar en ella para algo más que pruebas contra el simulador.

Rutina 1 — Encendido general del radar

Estado: procedimiento confirmado por el product expert (ControlRoutines.md, 2026-08-20 — absorbido en radar_emulator/docs/alcance/pendientes.md PEND-27/PEND-28, ya no vive como fichero suelto en este repo) e implementado en general_power_on.py siguiendo este procedimiento. No probada contra hardware real; sin confirmar quedan solo PEND-27/PEND-28 (mapeo de canal físico del chequeo final de Cabinet Fans).

Qué revisa antes de encender

Antes de intentar el encendido, el sistema comprueba que estas cuatro condiciones estén en buen estado:

  1. Sistema en espera (standby) correcto (señal sys.standby_system_ok_status).
  2. Parámetros de línea eléctrica correctos (señal sys.line_parameters_ok_status).
  3. Condiciones ambientales correctas (señal sys.environment_ok_status).
  4. Modo remoto correcto (señal sys.remote_mode_ok_status) — confirmada por el experto.

Si cualquiera de las cuatro no está en buen estado, el sistema no envía ninguna orden al radar y reporta el intento como fallido. Mientras el radar esté encendido, las condiciones 2 y 3 (línea eléctrica, ambiente) deben seguir correctas de forma continua, no solo en el instante del encendido — una caída de cualquiera de las dos en caliente es falla, no solo precondición de arranque.

Qué hace al encender

Si las cuatro condiciones están bien, el sistema envía una orden breve de "Encender Radar" — como pulsar un botón momentáneamente, no como sostener un interruptor. Esto es así porque, según la documentación del equipo de simulación, el radar interpreta esta orden como un pulso (una presión de botón), no como un nivel sostenido: si dos órdenes opuestas ("Encender" / "Apagar") estuvieran activas a la vez, gana apagar, por seguridad.

Cómo se determina si funcionó

Después de enviar el pulso, el experto confirma que hay que esperar la activación de dos señales de confirmación directa — ya no se infiere el éxito de que las precondiciones "sigan bien":

  1. Sistema encendido (señal sys.system_on_ok_status).
  2. Ventilación de la pizarra de distribución (MDB) correcta (señal sys.mdb_fan_ok_status).

Como paso final de la rutina, se chequea además la ventilación de los tres subsistemas restantes — Tx, Rx y AU —, agregada como una sola condición:

  1. Cabinet Fans Ok (Tx + Rx + AU). En radar_emulator existe agregada como sys.cabinet_fans_ok, pero es una señal virtual interna del simulador, sin equivalente en el catálogo real — la rutina lee las cuatro señales reales por separado (los dos blowers de Tx ya implementados, más sys.rx_cabinet_fan_ok_status/sys.au_cabinet_fan_ok_status) y hace el AND ella misma, mismo criterio que la Rutina 2 con tx.interlock_ok_status. El mapeo exacto de canal físico para Rx/AU y la reconciliación de "Tx Cabinet Fan Ok Status" con la semilla existente todavía no están confirmados — ver PEND-27/PEND-28 en radar_emulator/docs/alcance/pendientes.md antes de tratar este paso como cerrado. Si el pulso y los dos chequeos anteriores salieron bien pero falla algún Cabinet Fan, la rutina reporta el resultado como interrumpido, no como fallo — el radar sí quedó encendido.

radar_emulator ya modela toda esta secuencia en un bloque sys.fsm real (state_machine, estados OFF/STARTING/ON/FAULT) con una señal de confirmación directa, sys.radar_on_status — pero es virtual, interna al simulador y sin equivalente en el catálogo real (el propio ICD confirma que no existe una señal de "radar encendido" en el hardware), así que la rutina no la lee: usa system_on_ok_status/mdb_fan_ok_status como confirmación, igual que haría contra hardware real.

Diagrama de la secuencia

flowchart TD
    A[Inicio: intento de encendido general] --> B{¿Standby OK?}
    B -- No --> F[Fallo: no se envía ninguna orden]
    B -- Sí --> C{¿Parámetros de línea eléctrica OK?}
    C -- No --> F
    C -- Sí --> D{¿Condiciones ambientales OK?}
    D -- No --> F
    D -- Sí --> R{¿Modo remoto OK?}
    R -- No --> F
    R -- Sí --> E[Enviar pulso breve: Encender Radar]
    E --> G[Esperar activación]
    G --> H{¿System On Ok y MDB Fan Ok?}
    H -- No --> F
    H -- Sí --> J{¿Cabinet Fans Ok — Tx/Rx/AU?}
    J -- No --> K[Encendido parcial: reportar falla de ventilación]
    J -- Sí --> I[Éxito: encendido general completado]

Las siguientes cinco rutinas todavía no tienen código — lo que sigue es el diseño propuesto para cada una, deducido del comportamiento del simulador del radar (radar_emulator), que hoy es la única referencia disponible del lado del equipo. Se documentan aquí, antes de programarlas, precisamente para que el experto las revise primero y no después.

Rutina 2 — Encendido del transmisor

Estado: implementada hasta "listo" (ver más abajo), probada contra el simulador del radar — core/control_routines/transmitter_power_on.py, ver spike-fase2/RESULTADO-transmitter-power-on.md. No probada contra hardware real. Es la única de las seis rutinas donde el simulador del radar sí reproduce una secuencia interna con tiempos y enclavamientos — las demás son más simples porque el simulador no les modela ese comportamiento (ver aviso al final de esta sección).

Alcance implementado: hasta 'listo', no más allá (2026-08-19)

La rutina implementada llega hasta tx.ready_status (pasos 1–4 de abajo) y se detiene ahí — no sube alta tensión ni habilita salida (pasos 5–6). El plan nombra seis rutinas, ninguna llamada "subir HV" o "empezar a radiar"; eso tiene más sentido como parte de arrancar un escaneo (Scan Controller, sin construir todavía) que como parte de un encendido que se hace una vez. Responde la pregunta que quedaba abierta más abajo con la interpretación más conservadora — sin confirmar con el experto.

Enclavamientos de seguridad que deben estar bien antes de continuar

Antes de subir alta tensión, deben estar en buen estado, todos a la vez. Son seis señales reales, no siete — "radomo cerrado" y "sistema en espera" son, en el simulador, la misma señal agregada (tx.interlock_ok_status = ant.radome_closed_status and sys.standby_system_ok_status), no dos independientes:

  1. Interlock físico del transmisor (radomo cerrado y sistema en espera correcto — una sola señal agregada, no dos).
  2. Presión de guía de onda correcta.
  3. Soplador de la cabina funcionando.
  4. Soplador del magnetrón funcionando.
  5. Secuencia de fases correcta.
  6. Ciclo de trabajo (duty cycle) dentro de límite.

Hallazgo de implementación: estas señales no las exige el simulador para encender, solo para subir HV

La transición real de "apagado" a "arrancando" en el simulador (tx.fsm) no exige ninguno de estos seis — solo la orden de encender. El simulador solo los exige mas adelante, al pedir alta tensión. La rutina implementada los chequea igual, por decisión propia del RCP, más estricta que el simulador (mismo criterio que la Rutina 1): no calentar el magnetrón sin sopladores/presión/fase correctos, aunque el simulador no lo exija todavía en ese punto. Sin confirmar con el product expert.

Secuencia propuesta

  1. Encender transmisor: se envía una orden breve "Encender Tx" (pulso, como en la Rutina 1). Arrancan sopladores y fuentes de alimentación del transmisor.
  2. Calentamiento inicial (~1,5 segundos): tiempo corto de arranque antes de pasar a calentamiento del magnetrón.
  3. Calentamiento del magnetrón (~3 minutos): el transmisor queda encendido pero no listo para alta tensión hasta que termine este tiempo de caldeo.
  4. Listo: terminado el caldeo, el transmisor queda en estado "listo", esperando la orden de alta tensión.
  5. Encender alta tensión: si en ese momento todos los enclavamientos de la lista de arriba siguen en buen estado, se envía la orden "Encender HV" y el transmisor queda con alta tensión aplicada.
  6. Habilitar salida: con una orden adicional el transmisor pasa a "radiando".
  7. Apagado: la orden "Apagar Tx" funciona desde cualquier punto de la secuencia y corta todo de inmediato — es la orden de mayor prioridad, por seguridad.
  8. Caída de un enclavamiento en caliente: si algún enclavamiento de la lista deja de estar bien mientras el transmisor tiene alta tensión o está radiando, la alta tensión se retira automáticamente (vuelve a "listo"), pero el transmisor no se apaga por completo — sigue caliente, listo para otro intento sin repetir el calentamiento.

Falla que el sistema vigila por sí mismo

Si la corriente pico del magnetrón supera un umbral, el sistema marca una falla de sobrecorriente que se queda activa (enclavada) hasta que se envíe explícitamente la orden de "reset de fallas" — no se limpia sola aunque la corriente baje.

Para el experto: revisar antes de confiar en esta rutina

  • Los tiempos de arriba (1,5 s de arranque, 3 minutos de caldeo del magnetrón) son valores de marcador de posición puestos por el equipo de simulación — el propio simulador los marca como pendientes de confirmar. ¿Cuál es el tiempo real de caldeo del magnetrón del RD100S?
  • El umbral de sobrecorriente pico del magnetrón que dispara la falla también es un valor de marcador de posición. ¿Cuál es el umbral real?
  • ¿El radomo realmente forma parte de la cadena de enclavamiento del transmisor en el RD100S, o eso es una particularidad del simulador que no aplica al radar real?
  • ¿"Encendido del transmisor" (la rutina de esta sección) debe llegar hasta "listo" nada más, o debe incluir también subir alta tensión y empezar a radiar? El plan no lo distingue — podría ser que subir HV y radiar sean parte de arrancar un escaneo, no de esta rutina.

Diagrama de estados

stateDiagram-v2
    [*] --> Apagado
    Apagado --> Arrancando: Encender Tx (pulso)
    Arrancando --> Calentando: ~1.5 s
    Calentando --> Listo: ~3 min (caldeo magnetrón)
    Listo --> AltaTension: Encender HV (si enclavamientos OK)
    AltaTension --> Radiando: Habilitar salida
    AltaTension --> Listo: cae algún enclavamiento
    Radiando --> Listo: cae algún enclavamiento
    Arrancando --> Apagado: Apagar Tx
    Calentando --> Apagado: Apagar Tx
    Listo --> Apagado: Apagar Tx
    AltaTension --> Apagado: Apagar Tx
    Radiando --> Apagado: Apagar Tx

Rutina 3 — Encendido del receptor analógico

Estado: implementada y probada contra el simulador — core/control_routines/receiver_power_on.py, ver spike-fase2/RESULTADO-receiver-power-on.md. No probada contra hardware real. El simulador no modela ninguna secuencia interna para el receptor — es una rutina simple, parecida en forma a la Rutina 1. Turn On RFE/Turn Off RFE está confirmado como par de flanco (pulso) en radar_emulator/docs/interfaces/modbus.md, sin la ambigüedad de la Rutina 4.

Hallazgo de implementación: el subsistema no tiene ningún bloque de lógica en la semilla

A diferencia de las rutinas anteriores, ninguna señal rx.* la calcula nada en radar_emulator — ni las tres fuentes de alimentación, ni rfe_on_status, ni stalo_locked_status. Probar el camino de éxito de esta rutina requirió forzarlas también por el canal WS de control, no solo la precondición.

Qué revisaría antes de encender

  • Las tres fuentes de alimentación del receptor (+15 V, −15 V, +12 V) en buen estado.

Qué haría al encender

Enviar una orden breve "Encender RFE" (pulso, mismo patrón que Rutina 1 y Rutina 2).

Cómo se determinaría el éxito

Confirmar que el front-end de recepción (RFE) queda encendido y que el oscilador local (STALO) está enganchado (locked) — sin oscilador enganchado, el receptor no puede procesar señal aunque esté "encendido".

Para el experto: revisar antes de implementar esta rutina

  • ¿Hay algún tiempo de espera entre encender el RFE y que el oscilador local se enganche, o es prácticamente inmediato? El simulador no modela esto, así que no hay ninguna pista de cuánto tardaría en el radar real.
  • ¿Hay alguna condición de enclavamiento (como en el transmisor) que deba revisarse antes de encender el receptor, o basta con las tres fuentes de alimentación?

Rutina 4 — Encendido de la unidad de antena

Estado: implementada y probada contra el simulador — core/control_routines/antenna_unit_power_on.py, ver spike-fase2/RESULTADO-antenna-unit-power-on.md. No probada contra hardware real. Con esto, las seis rutinas del plan tienen primer borrador implementado.

Decisión de implementación: nivel, no pulso

La señal atípica de más abajo (una sola orden, no un par) se resolvió tratándola como interruptor de nivel (se escribe y se deja en True, sin bajarla) — mismo criterio ya usado para ant.enable_drive_az/el_conmand en la Rutina 5: un comando único, sin contraparte de apagado, no listado en "Comandos por flanco" de radar_emulator. Sigue sin confirmar con el product expert; si el radar real la maneja como pulso, esta implementación queda mal.

Hallazgo: mismo problema que el receptor — sin lógica en la semilla

Ni ant.au_on_status ni los dos drive_{az,el}_ok_status los calcula nada en radar_emulator — mismo motivo que la Rutina 3 para forzar también las señales de éxito al probar contra el simulador, no solo la precondición.

Qué revisaría antes de encender

  • Radomo cerrado.

Qué haría al encender

Enviar la orden de encendido de la unidad de antena.

Cómo se determinaría el éxito

Confirmar que la unidad de antena queda encendida, y que los variadores de azimut y elevación reportan buen estado.

Para el experto: revisar antes de implementar esta rutina — señal atípica

A diferencia de las otras cinco rutinas, el catálogo de señales tiene una sola orden para esta ("encender/apagar unidad de antena"), no un par separado de "Encender" / "Apagar" como en encendido general, transmisor y receptor. Eso puede significar que es un interruptor de nivel (se mantiene apretado/sostenido) en vez de un pulso momentáneo como las demás — rompe el patrón de las otras rutinas y necesita confirmación explícita de cómo se opera realmente antes de programarla.

Rutina 5 — Movimiento de antena

Estado: implementada y probada contra el simulador del radar (ver spike-fase2/RESULTADO-antenna-movement.md). No probada contra hardware real. Es la primera rutina que controla algo con inercia real (la antena no cambia de velocidad instantáneamente).

Corrección sobre lo descrito más abajo (2026-08-19)

Esta sección seguía describiendo la rutina como "enviar una velocidad deseada en grados/s". Al implementarla se confirmó que la señal real del hardware (la referencia que recibe el variador) está en voltios (±10 V), no en grados/s — es una entrada analógica a un variador, igual que en el radar real. No existe hoy una ganancia real del RD100S para traducir grados/s a voltios (el simulador usa una ganancia propia marcada como pendiente de confirmar). La rutina implementada (core/control_routines/antenna_movement.py) recibe la referencia directamente en voltios y no confirma la magnitud de la velocidad alcanzada — solo el sentido de giro y que el eje efectivamente arranca o se detiene. Traducir una velocidad deseada en grados/s a esta referencia de voltios queda pendiente de esa ganancia real (PEND-RCP-07).

Qué debe estar listo antes de mover

  • La unidad de antena encendida (Rutina 4 completada).
  • El variador del eje que se va a mover (azimut o elevación) habilitado.

Qué haría al mover

Enviar una velocidad deseada al eje correspondiente. La antena acelera de forma gradual (no instantánea) hasta esa velocidad y la mantiene.

Protecciones mientras se mueve

  • Elevación tiene topes físicos de fin de carrera (aproximadamente −1,5° y 91,5° en el simulador — valores de marcador de posición pendientes de confirmar): si el eje llega a un tope, el movimiento en esa dirección se detiene solo, aunque se siga pidiendo esa velocidad.
  • Azimut no tiene tope (gira continuo en círculo), pero sí protección térmica: si el motor exige demasiada corriente (más de 30 A, valor de marcador de posición) durante demasiado tiempo seguido (5 s equivalentes), el sistema lo detiene para no dañarlo, y esa protección solo se rearma al volver a encender la unidad de antena.

Cómo se determinaría el éxito o la interrupción

Confirmar que el eje efectivamente alcanza (aproximadamente) la velocidad pedida, y detectar si se activó algún tope o la protección térmica para reportarlo como movimiento interrumpido, no como error silencioso.

Para el experto: revisar antes de implementar esta rutina

  • Los límites de elevación y el umbral de protección térmica de azimut son valores de marcador de posición del simulador. ¿Cuáles son los límites y umbrales reales del RD100S?
  • Azimut tiene protección térmica del motor modelada en el simulador; elevación no (solo fin de carrera físico, sin protección térmica de motor). ¿Es correcto que elevación no la necesite, o es un hueco del simulador que igual deberíamos cubrir en el RCP por seguridad?

Corrección (2026-08-19)

Esta sección decía antes lo contrario: que elevación tenía protección térmica y azimut no. Al verificar contra radar_emulator/config/rd100s.seed.json para implementar la guarda de seguridad de parámetros (ver más abajo) se confirmó que es al revés — el único bloque i2t de la semilla calcula ant.i2t_drive_az_status (azimut); la señal ant.i2t_drive_el_status existe en el catálogo pero no tiene ningún bloque que la calcule (sin cablear).

Rutina 6 — Posicionamiento de antena

Estado: implementada y probada contra el simulador del radar (ver spike-fase2/RESULTADO-antenna-positioning.md). No probada contra hardware real. A diferencia de las otras cinco, la rutina implementada (core/control_routines/antenna_positioning.py) no fija ningún valor propio de ganancia, tolerancia ni tiempo máximo — los exige como parámetros obligatorios de quien la llame, precisamente porque no hay ningún valor real ni siquiera aproximado (ni del simulador) que usar como default. Es la rutina más distinta de las seis: el radar solo acepta una orden de velocidad, nunca una orden de "ir a esta posición exacta" — ese lazo de control (medir dónde está, calcular hacia dónde y qué tan rápido moverse, y frenar al llegar) lo tiene que resolver el software del RCP, apoyándose en la Rutina 5. El simulador del radar no da ninguna pista de cómo debería comportarse este lazo — es diseño nuevo, no algo que se pueda deducir de él.

Qué haría, en términos generales

  1. Leer la posición actual de azimut/elevación.
  2. Calcular cuánto falta para llegar a la posición pedida.
  3. Pedir una velocidad (vía la Rutina 5) proporcional a esa distancia: rápido si falta mucho, despacio si falta poco.
  4. Cuando la posición esté dentro de un margen aceptable del objetivo, detener el movimiento.

Para el experto: esta rutina necesita definirse desde cero

  • ¿Qué tan preciso debe ser el posicionamiento final (margen de tolerancia en grados)?
  • ¿Hay un tiempo máximo esperado para posicionar, después del cual debería reportarse como fallo en vez de seguir esperando?
  • ¿El acercamiento final debe frenar de forma gradual (como se describe arriba) o el radar real tiene su propio comportamiento de frenado que deberíamos imitar?

Limitación conocida de la implementación (2026-08-19)

El control proporcional simple implementado no calcula distancia de frenado contra la aceleración limitada del eje (Rutina 5): decide "ya estoy en tolerancia" y ahí recién manda a frenar, así que puede terminar más lejos del objetivo que el margen pedido mientras el eje completa la desaceleración. Ver spike-fase2/RESULTADO-antenna-positioning.md. No se resolvió con una fórmula de frenado propia porque exigiría el valor real de aceleración del RD100S, que tampoco existe (ver Rutina 5).

Resumen de estado

Rutina Estado Complejidad frente al simulador
1. Encendido general Procedimiento confirmado por el experto e implementado sys.fsm real en el simulador (antes: sin lógica simulada)
2. Encendido del transmisor Implementada hasta "listo", probada contra simulador Secuencia con tiempos y enclavamientos ya modelada en el simulador
3. Encendido del receptor Implementada, probada contra simulador Sin lógica simulada — camino de éxito solo probado forzando señales
4. Encendido de unidad de antena Implementada, probada contra simulador Sin lógica simulada — orden tratada como nivel, no pulso (decisión sin confirmar)
5. Movimiento de antena Implementada, probada contra simulador Modelada con inercia, topes y protección térmica
6. Posicionamiento de antena Implementada, probada contra simulador No modelada en absoluto — diseño nuevo del RCP

Con esto, las seis rutinas del plan tienen primer borrador implementado y probado contra el simulador. La Rutina 1 ya tiene su procedimiento confirmado por el product expert (PEND-RCP-06, resuelto salvo el mapeo de canal de PEND-27/28 en radar_emulator); las Rutinas 2 a 6 siguen sin confirmar (PEND-RCP-07).

Trazabilidad técnica

Para quien necesite correlacionar esta página con el código: la Rutina 1 vive en src/core/control_routines/general_power_on.py, la Rutina 2 (hasta "listo", sin HV/radiar) en src/core/control_routines/transmitter_power_on.py, la Rutina 3 en src/core/control_routines/receiver_power_on.py, la Rutina 4 en src/core/control_routines/antenna_unit_power_on.py, la Rutina 5 en src/core/control_routines/antenna_movement.py (consume la guarda de límites de antena en src/core/safety_guard/) y la Rutina 6 en src/core/control_routines/antenna_positioning.py (consume la Rutina 5 en cada paso de control). La Rutina 1 ya implementa el procedimiento confirmado por el product expert (PEND-RCP-06). Las preguntas de las Rutinas 2 a 6 (incluidas las de las Rutinas 5 y 6 ya implementadas) siguen abiertas en PEND-RCP-07 — ambas en Pendientes.