# Radar Startup Sequence

## Overview

Questo modulo implementa la sequenza di inizializzazione radar identica a quella utilizzata da GrifoScope, analizzata dal codice sorgente C++.

## Background - Analisi GrifoScope

### Sequenza Originale (da `g346_a1a2.cpp`)

GrifoScope all'avvio esegue:

1. **Inizializzazione Sicura** (`startProtection()`):
   ```cpp
   // A1
   dSymbInt.setFromUser(127);    // Symbol intensity massima
   dIfGain.setFromUser(127);     // IF Gain massimo
   
   // A2  
   dSilence.setFromUser(1);      // Silence ON → TX disabilitato
   dStby.setFromUser(1);         // Standby ON → Radar inattivo
   ```

2. **Attivazione** (quando utente preme "Run" e toglie Standby/Silence):
   ```cpp
   actSTBY.setActionValue(0, 1);  // Toggle: 0=OFF, 1=ON
   // Shortcut: CTRL+F1
   ```

## Campi 1553 Critici

### Messaggio A2 - Word 01 (Radar Mode Command)

| Campo | Bit | Descrizione | Valori |
|-------|-----|-------------|--------|
| **stby** | 7 | Standby control | 0=OFF (operativo), 1=ON (standby) |
| **silence** | 3 | Silence control | 0=OFF (TX abilitato), 1=ON (TX disabilitato) |
| **freeze** | 6 | Freeze selection | 0=No freeze, 1=Freeze |
| **ibit_request** | 8 | IBIT request | 0=No IBIT, 1=Request IBIT |

**Nota bit positions**: Usano `IDD_REVBIT16(n) = 15-n` dal C++

## API Python

### Funzioni Principali

#### `initialize_radar_safe_state() -> (MsgA1, MsgA2)`

Crea messaggi con configurazione sicura iniziale:
- A1: `symbol_intensity=127` (massimo)
- A2: `stby=1, silence=1, mode=NO_OPERATION`

```python
from pybusmonitor1553.core.radar_startup import initialize_radar_safe_state

msg_a1, msg_a2 = initialize_radar_safe_state()
bc.send_command(1, msg_a1)
bc.send_command(2, msg_a2)
```

#### `activate_radar_operational(...) -> MsgA2`

Crea messaggio A2 per attivazione (Standby/Silence OFF):

```python
from pybusmonitor1553.core.radar_startup import activate_radar_operational
from pybusmonitor1553.lib1553.constants import MasterMode

msg_a2 = activate_radar_operational(
    master_mode=MasterMode.RWS,
    designation_control=2,  # TWS
    range_scale=0,
    scan_width=0
)
bc.send_command(2, msg_a2)
```

#### `radar_startup_sequence(bc, ...) -> bool`

Sequenza completa automatica:

```python
from pybusmonitor1553.core.bus_controller import BusController
from pybusmonitor1553.core.radar_startup import radar_startup_sequence
from pybusmonitor1553.lib1553.constants import MasterMode

bc = BusController(rt_ip="192.168.1.100")
bc.connect()

success = radar_startup_sequence(
    bc,
    target_mode=MasterMode.RWS,
    verify_steps=True,   # Verifica con B7 ogni step
    step_delay=0.5       # 500ms tra gli step
)

if success:
    print("Radar ready!")
```

#### `quick_start_radar(...) -> BusController`

All-in-one: connette e avvia radar in una chiamata:

```python
from pybusmonitor1553.core.radar_startup import quick_start_radar

bc = quick_start_radar(
    rt_ip="192.168.1.100",
    mode=MasterMode.RWS
)

if bc:
    # Radar pronto, bc già connesso
    bc.send_command(...)
```

## Sequenza Step-by-Step

### Step 1: SAFE MODE (Power-On Protection)

```python
# Crea messaggi sicuri
msg_a1, msg_a2_safe = initialize_radar_safe_state()

# Invia al radar
bc.send_command(1, msg_a1)
time.sleep(0.1)
bc.send_command(2, msg_a2_safe)

# Stato: Radar in standby, TX disabilitato
```

### Step 2: Verifica Stato (Opzionale)

```python
msg_b7 = bc.request_data(7, MsgB7, timeout=1.0)
if msg_b7:
    print(f"Mode: {msg_b7.master_mode}")
    print(f"Valid: {msg_b7.valid_data_flag == 0}")
```

### Step 3: Attivazione Operativa

```python
msg_a2_active = activate_radar_operational(
    master_mode=MasterMode.RWS
)
bc.send_command(2, msg_a2_active)

# Stato: Radar operativo, TX abilitato
```

### Step 4: Verifica Attivazione

```python
msg_b7 = bc.request_data(7, MsgB7, timeout=1.0)
if msg_b7 and msg_b7.valid_data_flag == 0:
    print("✓ Radar OPERATIONAL")
```

## Esempi Completi

Vedi `tools/radar_startup_examples.py`:

1. **Manual Startup** - Step-by-step manuale
2. **Automatic Startup** - Usando `radar_startup_sequence()`
3. **Quick Start** - All-in-one con `quick_start_radar()`
4. **Shutdown Sequence** - Ritorno sicuro a SAFE MODE
5. **Continuous Operation** - Ciclo completo con cambio modi
6. **Error Handling** - Gestione timeout e recovery

### Esecuzione Esempi

```bash
cd tools
python radar_startup_examples.py
```

## Testing Senza Hardware

Per testare senza radar reale:

```python
# Usa localhost con simulatore RT (futuro)
bc = BusController(rt_ip="127.0.0.1", rt_port=51553)
bc.connect()

# Oppure verifica solo la creazione messaggi
msg_a1, msg_a2 = initialize_radar_safe_state()
print(f"A2 packed: {msg_a2.pack().hex()}")
```

## Logging

Il modulo usa logging standard Python:

```python
import logging

logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)

# Output:
# 2025-12-16 10:30:00 - radar_startup - INFO - Step 1: Sending SAFE MODE configuration
# 2025-12-16 10:30:01 - radar_startup - INFO - ✓ SAFE MODE messages sent
# ...
```

## Troubleshooting

### Radar non risponde a B7

```python
# Verifica connessione
if not bc.is_connected:
    bc.connect()

# Aumenta timeout
msg_b7 = bc.request_data(7, MsgB7, timeout=2.0)

# Verifica rete
bc.get_statistics()  # Controlla timeouts
```

### Startup fallisce

```python
# Prova senza verifiche intermedie
success = radar_startup_sequence(
    bc,
    verify_steps=False,  # Skip B7 checks
    step_delay=1.0       # Più tempo tra step
)

# Oppure manuale recovery
msg_a1, msg_a2 = initialize_radar_safe_state()
bc.send_command(1, msg_a1)
bc.send_command(2, msg_a2)
```

### Valori campi non corretti

```python
# Debug: stampa valori packed
msg_a2 = activate_radar_operational()
print(f"A2 word 0: 0x{struct.unpack('>H', msg_a2.pack()[0:2])[0]:04X}")

# Verifica bit positions
assert msg_a2.stby == 0, "Standby should be OFF"
assert msg_a2.silence == 0, "Silence should be OFF"
```

## Integrazione con GUI

```python
class RadarControlPanel:
    def __init__(self):
        self.bc = BusController()
        
    def on_run_button_clicked(self):
        """Equivalente al pulsante 'Run' di GrifoScope"""
        if not self.bc.is_connected:
            self.bc.connect()
        
        # Startup automatico
        success = radar_startup_sequence(self.bc)
        if success:
            self.status_label.setText("Radar OPERATIONAL")
            self.enable_controls(True)
    
    def on_standby_toggle(self):
        """Equivalente a CTRL+F1 in GrifoScope"""
        msg_a2 = MsgA2()
        msg_a2.stby = 1 if self.standby_active else 0
        self.bc.send_command(2, msg_a2)
```

## Riferimenti

- **Analisi Completa**: `doc/GrifoScope-Startup-Sequence.md`
- **ICD Reference**: `doc/ICD_DECD_FTH - GRIFO-F_TH...md`
- **C++ Source**: `cpp/GrifoScope/GrifoMCS/GADS/MCS/MCS_G346/g346/g346_a1a2.cpp`
- **Message Definitions**: `pybusmonitor1553/lib1553/messages/msg_a2.py`

## See Also

- [Bus Controller README](../pybusmonitor1553/core/README_BusController.md)
- [UDP1553 Protocol](../doc/UDP1553-Protocol-Implementation.md)
- [Message Mapping](../doc/C++-Python-Message-Mapping.md)
