One process per drone: seeded patrol kinematics, sensor streams at realistic rates, detection events, hot current/ blocks sealed into Hive-partitioned Parquet, and the compact UDP state broadcast with peer RSSI derivation. Scales via docker compose --scale.
69 lines
2.3 KiB
Python
69 lines
2.3 KiB
Python
"""Runtime configuration, resolved once from the environment."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import socket
|
|
import time
|
|
import uuid
|
|
from dataclasses import dataclass, field
|
|
|
|
|
|
def _default_drone_id() -> str:
|
|
"""Stable per-container id: works with `docker compose up --scale`."""
|
|
return os.environ.get("DRONE_ID") or f"dr-{socket.gethostname()[-4:]}"
|
|
|
|
|
|
def _default_flight_id() -> str:
|
|
"""Short time-sortable partition alias; canonical UUIDv7 kept separately."""
|
|
return os.environ.get("FLIGHT_ID") or time.strftime(
|
|
"%Y%m%dT%H%MZ", time.gmtime()
|
|
) + "-" + uuid.uuid4().hex[:4]
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class Config:
|
|
drone_id: str = field(default_factory=_default_drone_id)
|
|
flight_id: str = field(default_factory=_default_flight_id)
|
|
flight_uuid: str = field(default_factory=lambda: str(uuid.uuid4()))
|
|
|
|
data_dir: str = field(default_factory=lambda: os.environ.get("DATA_DIR", "./data"))
|
|
seed: int = field(default_factory=lambda: int(os.environ.get("SEED", "42")))
|
|
|
|
# Simulation pacing
|
|
duration_s: float = field(
|
|
default_factory=lambda: float(os.environ.get("DURATION_S", "120"))
|
|
)
|
|
speedup: float = field(
|
|
default_factory=lambda: float(os.environ.get("SPEEDUP", "1.0"))
|
|
)
|
|
|
|
# Sensor rates (Hz, simulated time)
|
|
imu_hz: float = field(default_factory=lambda: float(os.environ.get("IMU_HZ", "50")))
|
|
baro_hz: float = 1.0
|
|
temp_hz: float = 0.2
|
|
battery_hz: float = 0.5
|
|
detection_rate_hz: float = field(
|
|
default_factory=lambda: float(os.environ.get("DETECTION_HZ", "0.05"))
|
|
)
|
|
|
|
# State broadcast
|
|
state_hz: float = field(
|
|
default_factory=lambda: float(os.environ.get("STATE_HZ", "5"))
|
|
)
|
|
udp_port: int = field(default_factory=lambda: int(os.environ.get("UDP_PORT", "47000")))
|
|
broadcast_addr: str = field(
|
|
default_factory=lambda: os.environ.get("BROADCAST_ADDR", "255.255.255.255")
|
|
)
|
|
|
|
# Patrol area (meters, local mission frame)
|
|
area_size_m: float = field(
|
|
default_factory=lambda: float(os.environ.get("AREA_SIZE_M", "400"))
|
|
)
|
|
cruise_alt_m: float = field(
|
|
default_factory=lambda: float(os.environ.get("CRUISE_ALT_M", "60"))
|
|
)
|
|
cruise_speed_ms: float = field(
|
|
default_factory=lambda: float(os.environ.get("CRUISE_SPEED_MS", "12"))
|
|
)
|