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

345 lines
11 KiB
Markdown

# 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)
```cpp
void GrifoMsg_A1B6::startProtection()
{
dSymbInt.setFromUser(127); // Symbol Intensity = MAX
}
```
#### A1 - Valori di Default (linee 162-163)
```cpp
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)
```cpp
void GrifoMsg_A2B7::startProtection()
{
dSilence.setFromUser(1); // Silence = ON (1)
dStby.setFromUser(1); // Standby = ON (1)
}
```
#### A2 - Valori di Default (linee 697-698)
```cpp
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)
```cpp
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)
```cpp
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)
```cpp
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)
```cpp
//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)
```cpp
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
```python
# 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
```python
# 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
```python
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`