# target_simulator/analysis/simulation_archive.py import os import json import time from datetime import datetime from typing import Dict, List, Any, Tuple from target_simulator.core.models import Scenario # Definisci la struttura per uno stato registrato RecordedState = Tuple[float, float, float, float] # (timestamp, x_ft, y_ft, z_ft) class SimulationArchive: """ Gestisce la raccolta dei dati per una singola esecuzione di simulazione e la salva su file. """ ARCHIVE_FOLDER = "archive_simulations" def __init__(self, scenario: Scenario): """ Inizializza una nuova sessione di archivio per un dato scenario. """ self.start_time = time.monotonic() self.scenario_name = scenario.name self.scenario_data = scenario.to_dict() # Struttura dati per contenere gli eventi registrati, indicizzati per target_id # self.recorded_data[target_id]['simulated'] = [(ts, x, y, z), ...] # self.recorded_data[target_id]['real'] = [(ts, x, y, z), ...] self.recorded_data: Dict[int, Dict[str, List[RecordedState]]] = {} self._ensure_archive_directory() def _ensure_archive_directory(self): """Crea la directory principale dell'archivio se non esiste.""" if not os.path.exists(self.ARCHIVE_FOLDER): try: os.makedirs(self.ARCHIVE_FOLDER) except OSError as e: print(f"Errore nella creazione della directory di archivio: {e}") def add_simulated_state( self, target_id: int, timestamp: float, state: Tuple[float, ...] ): """Aggiunge uno stato simulato all'archivio.""" if target_id not in self.recorded_data: self.recorded_data[target_id] = {"simulated": [], "real": []} full_state: RecordedState = (timestamp, state[0], state[1], state[2]) self.recorded_data[target_id]["simulated"].append(full_state) def add_real_state( self, target_id: int, timestamp: float, state: Tuple[float, ...] ): """Aggiunge uno stato reale (dal server) all'archivio.""" if target_id not in self.recorded_data: self.recorded_data[target_id] = {"simulated": [], "real": []} full_state: RecordedState = (timestamp, state[0], state[1], state[2]) self.recorded_data[target_id]["real"].append(full_state) def save(self) -> str: """ Salva l'archivio completo della simulazione in un file JSON. Il nome del file รจ generato dal timestamp e dal nome dello scenario. Ritorna: Il percorso del file salvato. """ end_time = time.monotonic() archive_content = { "metadata": { "scenario_name": self.scenario_name, "start_timestamp_utc": datetime.utcnow().isoformat(), "duration_seconds": end_time - self.start_time, }, "scenario_definition": self.scenario_data, "simulation_results": self.recorded_data, } ts_str = datetime.now().strftime("%Y%m%d_%H%M%S") safe_scenario_name = "".join( c for c in self.scenario_name if c.isalnum() or c in (" ", "_") ).rstrip() filename = f"{ts_str}_{safe_scenario_name}.json" filepath = os.path.join(self.ARCHIVE_FOLDER, filename) try: with open(filepath, "w", encoding="utf-8") as f: json.dump(archive_content, f, indent=4) print(f"Archivio di simulazione salvato in: {filepath}") return filepath except IOError as e: print(f"Errore durante il salvataggio dell'archivio di simulazione: {e}") return ""