SXXXXXXX_PyBusMonitor1553/doc/GrifoScope-Startup-Sequence.md
2025-12-17 07:59:30 +01:00

11 KiB

GrifoScope Startup Sequence Analysis

Obiettivo

Identificare la sequenza di inizializzazione che GrifoScope esegue per preparare il radar all'operatività, da replicare in PyBusMonitor1553.

Analisi Codice C++

1. Inizializzazione Messaggi A1/A2 (Startup Protection)

File: cpp/GrifoScope/GrifoMCS/GADS/MCS/MCS_G346/g346/g346_a1a2.cpp

A1 - Radar Settings (GrifoMsg_A1B6::startProtection() - linea 10-12)

void GrifoMsg_A1B6::startProtection()
{
    dSymbInt.setFromUser(127);  // Symbol Intensity = MAX
}

A1 - Valori di Default (linee 162-163)

dSymbInt.setFromUser(127);      // Symbol Intensity = 127 (massimo)
dIfGain.setFromUser(127);       // IF Gain = 127 (massimo)
dAltBlock.setFromUser(McsG346AltBlock::NORMAL);  // Altitude Block = NORMAL

A2 - Radar Operation Command (GrifoMsg_A2B7::startProtection() - linee 414-416)

void GrifoMsg_A2B7::startProtection()
{
    dSilence.setFromUser(1);    // Silence = ON (1)
    dStby.setFromUser(1);       // Standby = ON (1)
}

A2 - Valori di Default (linee 697-698)

dSilence.setFromUser(1);   // Silence = ON (1) - Trasmettitore disabilitato
dStby.setFromUser(1);      // Standby = ON (1) - Radar in standby

2. Campi 1553 ICD

File: cpp/GrifoScope/GrifoSdkEif/pub/TH/th_b1553_icd.h

Standby Selection (linee 417-424)

enum stby_selection_t
{
  STBY_OFF,  // 0 = Radar operativo
  STBY_ON    // 1 = Radar in standby
};

typedef idd_boolfield_u16_t<IDD_REVBIT16(8), stby_selection_t> stby_field_t;

Posizione: Word A2-01, bit 8 (reversed: bit 7 in Python 0-based)

Silence Selection (linee 428, 443, 457)

typedef bool silence_selection_t;

typedef idd_bitfield_u16_t<IDD_REVBIT16(12), 1, silence_selection_t> silence_field_t;

union rdr_mode_command_word_t {
    ...
    silence_field_t silence;  // reserved
    ...
};

Posizione: Word A2-01, bit 12 (reversed: bit 3 in Python 0-based)

Valori:

  • 0 = Silence OFF → Trasmettitore abilitato
  • 1 = Silence ON → Trasmettitore disabilitato (modalità sicura)

3. Controlli GUI

File: cpp/GrifoScope/GrifoMCS/GADS/MCS/MCS_G346/g346/mcs_g346.cpp (linee 1199-1204)

QAction* qStby=new QAction(&wb.mainWindow());
qStby->setShortcut(QKeySequence(Qt::CTRL+Qt::Key_F1));  // CTRL+F1
qStby->setStatusTip("STBY!");
qStby->setText("STBY");
AdsWidgetsManager::mapAction(theMsg->A2B7.actSTBY, *qStby);

Shortcut: CTRL+F1 per toggle STBY

File: cpp/GrifoScope/GrifoMCS/GADS/MCS/MCS_G346/g346/grifocmddock.cpp (linee 32-33)

//ui->tb_ads_silence->setVisible(false);
ui->tb_ads_silence->setEnabled(false);  // Silence button DISABILITATO

Nota: Il pulsante Silence è disabilitato nell'interfaccia GUI. Questo suggerisce che il controllo Silence potrebbe essere gestito automaticamente o non utilizzato nel sistema G346.

4. Azioni Toggle (linee 514-516)

actSTBY.setObjectName("act_STBY");
actSTBY.attachTo(&dStby);
actSTBY.setActionValue(0, 1);  // 0=OFF, 1=ON

Sequenza di Startup Radar

Fase 1: Inizializzazione Sicura (Power-On)

Al primo avvio, GrifoScope imposta:

Messaggio A1 (Radar Settings):

  • symbol_intensity = 127 (massimo)
  • if_gain = 127 (massimo)
  • altitude_block = NORMAL
  • Tutti gli altri campi ai valori di default (tipicamente 0)

Messaggio A2 (Radar Operation):

  • stby = 1 (STBY_ON) → Radar in standby
  • silence = 1 (ON) → Trasmettitore disabilitato
  • master_mode = 0 o valore precedente
  • designation_control = NOT_VALID (7 per 3 bit)

Fase 2: Attivazione ("Run" → Rimozione Standby/Silence)

Quando l'operatore preme "Run" e rimuove Standby/Silence:

Messaggio A2 modificato:

  • stby = 0 (STBY_OFF) → Radar operativo
  • silence = 0 (OFF) → Trasmettitore abilitato
  • master_mode = RWS (o altro modo selezionato)
  • Altri parametri operativi come range, scan, etc.

Messaggio A1 (può essere aggiornato con valori operativi):

  • target_history = valore desiderato (es. 3)
  • symbol_intensity = valore desiderato
  • Frequency channel, gains, etc.

Campi Python Mapping

Messaggio A1 (msg_a1.py)

Già implementati:

  • symbol_intensity - BitField(0, 0, 7)
  • if_gain - BitField(1, 0, 7)
  • target_history - BitField(0, 8, 3)
  • ground_reject_vel_high - BitField(0, 15, 1)
  • frequency_channel - BitField(1, 8, 6)

Mancante:

  • altitude_block - BitField (word 0, bits da verificare)

Messaggio A2 (msg_a2.py)

Già implementati:

  • master_mode - EnumField(0, 0, 4, MasterMode)
  • designation_control - EnumField(0, 4, 3, DesignationControl)
  • priority_target_number - BitField(2, 0, 6)
  • range_scale - EnumField(1, 0, 4, RangeScale)
  • scan_width - EnumField(1, 4, 3, ScanWidth)
  • velocity_scale - EnumField(1, 7, 2, VelocityScale)

Mancanti (CRITICI per startup):

  • stby - BitField(0, 7, 1) # IDD_REVBIT16(8) = bit 7
  • silence - BitField(0, 3, 1) # IDD_REVBIT16(12) = bit 3
  • freeze - BitField(0, 6, 1) # IDD_REVBIT16(9) = bit 6
  • ibit_request - BitField(0, 8, 1) # IDD_REVBIT16(7) = bit 8

Implementazione Python Raccomandata

1. Completare msg_a2.py

# In pybusmonitor1553/lib1553/messages/msg_a2.py

# Word 0 - Radar Mode Command (rdr_mode_command_word_t)
master_mode = EnumField(0, 0, 4, MasterMode)
designation_control = EnumField(0, 4, 3, DesignationControl)
stby = BitField(0, 7, 1)          # NUOVO - Standby control
ibit_request = BitField(0, 8, 1)   # NUOVO - IBIT request
freeze = BitField(0, 6, 1)         # NUOVO - Freeze selection
stop_powerup = BitField(0, 5, 1)   # NUOVO - Reserved
reserved_11 = BitField(0, 11, 1)   # NUOVO - Emergency/reserved
silence = BitField(0, 3, 1)        # NUOVO - Silence control (trasmettitore)
sar_exec = BitField(0, 13, 1)      # NUOVO - SAR execution type

2. Creare Funzione Startup

# In pybusmonitor1553/core/radar_startup.py

def initialize_radar_safe_state() -> tuple[MsgA1, MsgA2]:
    """
    Crea messaggi A1/A2 con valori di startup sicuri (Standby + Silence ON).
    
    Questa è la configurazione iniziale che GrifoScope usa al power-on
    per proteggere il radar.
    
    Returns:
        (msg_a1, msg_a2): Messaggi pronti per l'invio
    """
    # A1: Radar Settings - valori di default sicuri
    msg_a1 = MsgA1()
    msg_a1.symbol_intensity = 127          # Massimo (startup protection)
    msg_a1.if_gain = 127                   # Massimo
    msg_a1.target_history = 0              # Default
    msg_a1.ground_reject_vel_high = 0      # Default
    msg_a1.frequency_channel = 0           # Default
    # ... altri campi a 0
    
    # A2: Radar Operation - SAFE MODE
    msg_a2 = MsgA2()
    msg_a2.master_mode = MasterMode.NO_OPERATION  # 0
    msg_a2.designation_control = DesignationControl.NOT_VALID  # 7
    msg_a2.stby = 1                        # STANDBY ON
    msg_a2.silence = 1                     # SILENCE ON (TX disabilitato)
    msg_a2.freeze = 0                      # No freeze
    msg_a2.ibit_request = 0                # No IBIT
    # ... altri campi a valori di default
    
    return msg_a1, msg_a2


def activate_radar_operational() -> MsgA2:
    """
    Crea messaggio A2 per attivare il radar (rimuove Standby e Silence).
    
    Questa è l'operazione che l'utente fa in GrifoScope premendo "Run" 
    e disattivando Standby/Silence.
    
    Returns:
        msg_a2: Messaggio A2 con radar pronto all'operatività
    """
    msg_a2 = MsgA2()
    msg_a2.stby = 0                        # STANDBY OFF
    msg_a2.silence = 0                     # SILENCE OFF (TX abilitato)
    msg_a2.master_mode = MasterMode.RWS    # Modo operativo (es. RWS)
    msg_a2.designation_control = DesignationControl.TWS  # Modo designation
    msg_a2.freeze = 0
    msg_a2.ibit_request = 0
    # ... configurare altri parametri operativi
    
    return msg_a2


def radar_startup_sequence(bc: BusController):
    """
    Esegue la sequenza completa di startup del radar.
    
    Replicata da GrifoScope:
    1. Invia A1/A2 con valori sicuri (Standby + Silence ON)
    2. Attende conferma dal radar (B6/B7)
    3. Rimuove Standby e Silence
    4. Configura modo operativo
    
    Args:
        bc: BusController connesso al radar
    """
    import time
    
    # Step 1: Invia configurazione sicura
    print("Step 1: Inizializzazione radar (SAFE MODE)")
    msg_a1, msg_a2 = initialize_radar_safe_state()
    bc.send_command(1, msg_a1)
    time.sleep(0.1)
    bc.send_command(2, msg_a2)
    time.sleep(0.5)  # Attendi stabilizzazione
    
    # Step 2: Verifica stato radar
    print("Step 2: Verifica stato radar")
    msg_b7 = bc.request_data(7, MsgB7, timeout=1.0)
    if msg_b7:
        print(f"  Radar status: mode={msg_b7.master_mode}, stby={msg_b7.standby_status}")
    else:
        print("  WARNING: Nessuna risposta da B7")
    
    # Step 3: Attiva radar (rimuovi Standby/Silence)
    print("Step 3: Attivazione radar (Standby/Silence OFF)")
    msg_a2_active = activate_radar_operational()
    bc.send_command(2, msg_a2_active)
    time.sleep(0.5)
    
    # Step 4: Verifica attivazione
    print("Step 4: Verifica attivazione")
    msg_b7 = bc.request_data(7, MsgB7, timeout=1.0)
    if msg_b7:
        print(f"  Radar active: mode={msg_b7.master_mode}, RF={msg_b7.rf_radiation}")
        if msg_b7.standby_status == 0 and msg_b7.rf_radiation:
            print("  ✓ Radar OPERATIVO")
        else:
            print("  ⚠ Radar non completamente attivo")
    
    print("Startup sequence completata")

3. Esempio Utilizzo

from pybusmonitor1553.core.bus_controller import BusController
from pybusmonitor1553.core.radar_startup import radar_startup_sequence

# Connetti al radar
bc = BusController(rt_ip="192.168.1.100")
bc.connect()

# Esegui sequenza startup
radar_startup_sequence(bc)

# Ora il radar è pronto per comandi operativi
# ... invio comandi A2 per cambiare modo, range, etc.

bc.disconnect()

Note Implementative

Bit Position Conversion (IDD_REVBIT16)

Formula C++: IDD_REVBIT16(pos) = 15 - pos

Esempi:

  • IDD_REVBIT16(8) → bit 7 in Python (stby)
  • IDD_REVBIT16(12) → bit 3 in Python (silence)
  • IDD_REVBIT16(9) → bit 6 in Python (freeze)
  • IDD_REVBIT16(7) → bit 8 in Python (ibit_request)

Verificare con B7 (Radar Status Tellback)

Campi B7 da controllare:

  • standby_status → deve essere 0 quando operativo
  • rf_radiation → deve essere 1 quando TX attivo
  • master_mode → deve corrispondere al comando A2
  • designation_mode → deve corrispondere al comando A2

Riferimenti

  • ICD Header: cpp/GrifoScope/GrifoSdkEif/pub/TH/th_b1553_icd.h
  • Implementazione A1/A2: cpp/GrifoScope/GrifoMCS/GADS/MCS/MCS_G346/g346/g346_a1a2.cpp
  • GUI Controls: cpp/GrifoScope/GrifoMCS/GADS/MCS/MCS_G346/g346/mcs_g346.cpp
  • Python Messages: pybusmonitor1553/lib1553/messages/msg_a2.py