# target_simulator

A brief description of target_simulator.

## Features
- Feature 1
- Feature 2

## Getting Started
...

## Contributing
...

## License
...


## Note: debug GUI vs simulation command behaviour

The project provides two different code paths for sending target update commands:

- Debug GUI (SFP Packet Inspector / Simple Target Sender):
	- When you press "Send Target" from the debug window, the GUI sends a
		`tgtset` command that includes state qualifiers such as `/s` (active),
		`/t` (traceable) and `/r` (restart) if the corresponding checkboxes are set.
	- This behaviour is intentional: the debug UI is meant for manual testing and
		for explicitly toggling target flags.

- Runtime Simulation:
	- The simulation engine and continuous updates use `tgtset` commands that
		contain only the positional/kinematic parameters (range, azimuth, velocity,
		heading, altitude) and do not include the state qualifiers. This avoids
		unintentionally changing target lifecycle flags during normal simulation.

Why this matters
- Historically the code used `tgtinit` in some debug flows. `tgtinit` sets
	some different internal parameters (for example `heading_start`) and can
	change target motion in unintended ways. To preserve correct simulation
	behaviour, the debug window now sends `tgtset` + qualifiers while the
	simulation keeps sending `tgtset` without qualifiers.

Where to look in the code
- Debug GUI sender: `target_simulator/gui/sfp_debug_window.py` (`_on_send_target`).
- Command builders: `target_simulator/core/command_builder.py` (`build_tgtset_from_target_state`, `build_tgtset_selective`, `build_tgtinit`).
- Settings: debug file names and options are in `settings.json` (section `debug`) and `target_simulator/config.py` contains defaults.

If you want the debug UI to exactly mimic runtime behaviour, uncheck the
Active/Traceable/Restart checkboxes before sending, or use the runtime APIs to
send `tgtset` without qualifiers.

## Debug logging (attivazione localizzata)

Il progetto utilizza il modulo `logging` di Python con logger a livello di
modulo (per esempio `target_simulator.analysis.simulation_state_hub`). In
diversi punti del codice è stato standardizzato l'uso di `logger =
logging.getLogger(__name__)` e aggiunto un helper `temporary_log_level`
in `target_simulator/utils/logger.py` per attivare temporaneamente livelli di
log più verbosi.

Di seguito alcuni esempi rapidi per attivare/disattivare il DEBUG solo per la
parte del codice che ti interessa analizzare.

### Attivare DEBUG per un modulo (a runtime)

Apri una shell Python o esegui lo snippet nel tuo script/main e imposta il
livello del logger del modulo che vuoi investigare.

Esempio — abilitare DEBUG solo per lo state hub:

```python
import logging
logging.getLogger('target_simulator.analysis.simulation_state_hub').setLevel(logging.DEBUG)
```

Per tornare a INFO (o disattivare DEBUG):

```python
logging.getLogger('target_simulator.analysis.simulation_state_hub').setLevel(logging.INFO)
```

I nomi dei logger corrispondono ai path dei moduli. Esempi utili:

- `target_simulator.analysis.simulation_state_hub`
- `target_simulator.gui.sfp_debug_window`
- `target_simulator.gui.ppi_display`
- `target_simulator.gui.payload_router`
- `target_simulator.core.sfp_transport`

### Attivare DEBUG solo per un blocco di codice (temporaneo)

Usa il context manager `temporary_log_level` fornito in
`target_simulator.utils.logger`:

```python
from logging import getLogger
from target_simulator.utils.logger import temporary_log_level

mod_logger = getLogger('target_simulator.gui.payload_router')

with temporary_log_level(mod_logger, logging.DEBUG):
	# dentro questo blocco il logger è DEBUG
	router.process_some_payload(...)   # esempio
# All'uscita il livello viene ripristinato automaticamente
```

### Debug ancora più granulare — child logger e filtri

Per messaggi molto verbosi puoi creare child logger o usare `extra` + `Filter`:

Child logger:

```python
base = logging.getLogger('target_simulator.analysis.simulation_state_hub')
diag = base.getChild('diagnostics')  # 'target_simulator.analysis.simulation_state_hub.diagnostics'
diag.setLevel(logging.DEBUG)
diag.debug("dettagli diagnostici: ...")
```

Esempio di filtro basato su `extra`:

```python
class ExtraKeyFilter(logging.Filter):
	def __init__(self, key, allowed_values):
		super().__init__()
		self.key = key
		self.allowed = set(allowed_values)
	def filter(self, record):
		return getattr(record, self.key, None) in self.allowed

handler = logging.StreamHandler()
handler.addFilter(ExtraKeyFilter('topic', ['diagnostic']))
logging.getLogger('target_simulator').addHandler(handler)

# Emetti:
logging.getLogger('target_simulator.analysis.simulation_state_hub').debug("...", extra={'topic':'diagnostic'})
```

### Esecuzione rapida da PowerShell

Esempio per aprire REPL con PYTHONPATH corretto (Windows PowerShell):

```powershell
$env:PYTHONPATH='C:\src\____GitProjects\target_simulator'
python
# dentro REPL eseguire i comandi logging mostrati sopra
```

Oppure eseguire un singolo comando:

```powershell
$env:PYTHONPATH='C:\src\____GitProjects\target_simulator'; python -c "import logging; logging.getLogger('target_simulator.gui.payload_router').setLevel(logging.DEBUG); print('DEBUG enabled')"
```

Se vuoi, possiamo aggiungere un piccolo pannello nella GUI per controllare i
livelli dei logger a runtime; fammi sapere se preferisci questa opzione.
