157 lines
5.3 KiB
Markdown
157 lines
5.3 KiB
Markdown
# 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.
|