Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,91 @@ async def generate_bluesky_sim_air_traffic_data_with_sensor_latency_issues(
duration: int | None = None,
) -> list[list[FlightObservationSchema]]:
"""This method generates"""
flight_observations = self.generate_bluesky_sim_air_traffic_data(config_path=config_path, duration=duration)


scn_path = config_path or self.settings.simulation_config_path
duration_s = int(duration or self.settings.simulation_duration_seconds or 30)

sensor_ids = self.settings.sensor_ids

try:
# create a list of UUIDs with at least one UUID if session_ids is empty
sensor_ids = [UUID(x) for x in sensor_ids] if sensor_ids else [uuid.uuid4()]
except ValueError as exc:
logger.error(f"Invalid sensor ID in configuration, it should be a valid UUID: {exc}")
raise
current_sensor_id = sensor_ids[0]

if not scn_path:
raise ValueError("No scenario path provided. Provide config_path or set settings.simulation_config_path.")

# ---- Init BlueSky headless ----
# detached=True prevents UI/event loop from blocking.
# Use a temporary directory for BlueSky working files to avoid polluting ~/bluesky
# BlueSky's pathfinder.init() auto-creates required subdirs (scenario, plugins, output, cache)
flight_observations: list[list[FlightObservationSchema]] = []
with tempfile.TemporaryDirectory(prefix="openutm-bluesky-") as tmp_dir:
cfg_path = os.path.join(tmp_dir, "settings.cfg")
bs.init(mode="sim", detached=True, workdir=tmp_dir, configfile=cfg_path)

# Route console output to stdout (useful for debugging stack commands)
bs.scr = ScreenDummy()
now = arrow.now()
logger.info(f"Initializing BlueSky (headless) and loading scenario: {relative_path(scn_path)} with duration {duration_s}s")

# ---- Load scenario ----
# BlueSky scenario files (like scenario/DEMO/bluesky_flight.scn) are typically loaded with IC.
# NOTE: Use absolute paths if relative paths cause issues inside Docker.
bs.stack.stack(f"IC {scn_path}")

# Ensure 1 Hz stepping; FF starts fast-time running mode, but we will still step manually.
# Some setups work fine with DT 1 and calling bs.sim.step().
bs.stack.stack("DT 1.0")

# ---- Sample data at 1 Hz for duration_s seconds ----
# Store per-aircraft series
results_by_acid: dict[str, list[FlightObservationSchema]] = {}

for t in range(1, duration_s + 1):
# Advance sim by one step (DT=1 sec)
bs.sim.step()
timestamp = now.shift(seconds=t)
timestamp_microseconds = int(timestamp.float_timestamp * 1_000_000) # microseconds

# Snapshot traffic arrays
acids: list[str] = list(getattr(bs.traf, "id", []))
lats: list[float] = _tolist(getattr(bs.traf, "lat", []))
lons: list[float] = _tolist(getattr(bs.traf, "lon", []))
alts: list[float] = _tolist(getattr(bs.traf, "alt", []))

for i, acid in enumerate(acids):
lat = float(lats[i])
lon = float(lons[i])
alt_m_or_ft = float(alts[i])

# BlueSky typically uses meters internally for alt, but some scenarios use FL/ft inputs.
# We store altitude_mm as "millimeters"; keep it consistent with your schema.
# If alt is actually feet, you can convert here: alt_m = alt_ft * 0.3048
altitude_mm = alt_m_or_ft * 1000.0
metadata = {"sensor_id": current_sensor_id} if current_sensor_id else {}

obs = FlightObservationSchema(
lat_dd=lat,
lon_dd=lon,
altitude_mm=altitude_mm,
traffic_source=0,
source_type=0,
icao_address=acid,
timestamp=timestamp_microseconds,
metadata=metadata,
)
results_by_acid.setdefault(acid, []).append(obs)

logger.debug(f"{acid:>6} lat={lat:.6f} lon={lon:.6f} alt_mm={altitude_mm:.1f}")

# Convert dict -> list[list[FlightObservationSchema]] with stable ordering
flight_observations = [results_by_acid[acid] for acid in sorted(results_by_acid.keys())]


# This method modifies the retrieved simulation data by changing the timestamp and adding latency to the observed dataset
LATENCY_PROBABILITY = 0.1 # 10% chance to have latency issues
Expand Down