Algio-1452's picture
States Changes made so Model Knows that the Model has been cleared to land
09f96df
Raw
History Blame Contribute Delete
7.7 kB
from pydantic import BaseModel, Field
from typing import Optional
class Wind(BaseModel):
heading: int = Field(ge=0, lt=360, description="Wind heading in degrees (0-359)")
speed: int = Field(ge=0, le=100, description="Wind speed in knots")
@classmethod
def example(cls) -> "Wind":
return cls(heading=270, speed=15)
class Position(BaseModel):
segment: str = Field(
description="Direction segment: North, North-East, East, South-East, South, South-West, West, North-West"
)
distance: float = Field(ge=0, description="Distance from airport center in km")
altitude: int = Field(ge=0, description="Current altitude in feet")
target_altitude: int = Field(ge=0, description="Target altitude in feet")
@classmethod
def example(cls) -> "Position":
return cls(
segment="North-East", distance=12.5, altitude=5000, target_altitude=3000
)
class Motion(BaseModel):
heading: float = Field(
ge=0, lt=360, description="Current heading in degrees (0-359)"
)
target_heading: float = Field(
ge=0, lt=360, description="Target heading in degrees (0-359)"
)
speed: int = Field(ge=0, le=600, description="Current speed in knots")
target_speed: int = Field(ge=0, le=600, description="Target speed in knots")
@classmethod
def example(cls) -> "Motion":
return cls(heading=285.0, target_heading=270.0, speed=250, target_speed=210)
class Intent(BaseModel):
state: str = Field(
description="Aircraft state: ENROUTE, ENROUTE_CLEARED, HOLDING, APPROACH, LANDING, GO_AROUND, TAXIING, CRASHED"
)
assigned_runway: Optional[str] = Field(
default=None, description="Assigned runway ID"
)
distance_to_threshold: Optional[float] = Field(
default=None, ge=0, description="Distance to runway threshold in km"
)
next_waypoint: str = Field(description="Next waypoint or STAR name")
@classmethod
def example(cls) -> "Intent":
return cls(
state="APPROACH",
assigned_runway="27L",
distance_to_threshold=8.5,
next_waypoint="JUTES",
)
class Separation(BaseModel):
closest_traffic: Optional[str] = Field(
default=None, description="Callsign of closest aircraft"
)
distance: Optional[float] = Field(
default=None, ge=0, description="Distance to closest traffic in km"
)
conflict_risk: str = Field(description="Conflict risk level: none, medium, high")
@classmethod
def example(cls) -> "Separation":
return cls(closest_traffic="UAL456", distance=5.2, conflict_risk="medium")
class TimingStats(BaseModel):
total_time_active_sec: float = Field(
ge=0, description="Total time aircraft has been active in seconds"
)
time_in_current_state_sec: float = Field(
ge=0, description="Time spent in current intent state in seconds"
)
historical_times: dict[str, float] = Field(
default_factory=dict, description="Historical times for each intent state"
)
@classmethod
def example(cls) -> "TimingStats":
return cls(
total_time_active_sec=125.5,
time_in_current_state_sec=32.0,
historical_times={"ENROUTE": 45.0, "HOLDING": 30.0, "APPROACH": 18.5},
)
class SafetyMetrics(BaseModel):
separation_warnings_triggered: int = Field(
ge=0, description="Number of separation warnings triggered"
)
closest_proximity_km: Optional[float] = Field(
default=None, ge=0, description="Closest proximity to any aircraft in km"
)
@classmethod
def example(cls) -> "SafetyMetrics":
return cls(separation_warnings_triggered=2, closest_proximity_km=3.5)
class AirportStatus(BaseModel):
active_runways: list[str] = Field(
default_factory=list, description="List of active runway IDs"
)
runway_occupancy: dict[str, Optional[str]] = Field(
default_factory=dict,
description="Map of runway ID to occupying aircraft callsign",
)
wind: Wind
@classmethod
def example(cls) -> "AirportStatus":
return cls(
active_runways=["27L", "27R"],
runway_occupancy={"27L": "AAL123", "27R": None},
wind=Wind.example(),
)
class AircraftObservation(BaseModel):
callsign: str = Field(description="Unique aircraft identifier (e.g., AAL123)")
position: Position
motion: Motion
intent: Intent
alerts: list[str] = Field(
default_factory=list, description="Active alerts: low_fuel, critical_emergency"
)
separation: Separation
timing_stats: Optional[TimingStats] = Field(
default=None, description="Timing and state duration metrics"
)
safety_metrics: Optional[SafetyMetrics] = Field(
default=None, description="Safety-related metrics"
)
command_rejections: list[str] = Field(
default_factory=list, description="List of command rejections"
)
severity_index: float = Field(
default=1.0, ge=1.0, description="Severity index for emergency or conflicts"
)
@classmethod
def example(cls) -> "AircraftObservation":
return cls(
callsign="AAL123",
position=Position.example(),
motion=Motion.example(),
intent=Intent.example(),
alerts=["low_fuel"],
separation=Separation.example(),
timing_stats=TimingStats.example(),
safety_metrics=SafetyMetrics.example(),
command_rejections=["SPEED command rejected: below minimum"],
severity_index=1.0,
)
class Metrics(BaseModel):
simulation_time: float = Field(
ge=0, description="Elapsed simulation time in seconds"
)
planes_landed: int = Field(ge=0, description="Total aircraft successfully landed")
planes_active: int = Field(ge=0, description="Number of currently active aircraft")
@classmethod
def example(cls) -> "Metrics":
return cls(simulation_time=1850.5, planes_landed=3, planes_active=7)
class ATCObservation(BaseModel):
airport_status: AirportStatus
aircraft: list[AircraftObservation] = Field(default_factory=list)
metrics: Metrics
@classmethod
def example(cls) -> "ATCObservation":
return cls(
airport_status=AirportStatus.example(),
aircraft=[AircraftObservation.example()],
metrics=Metrics.example(),
)
class ATCAction(BaseModel):
commands: list[str] = Field(
default_factory=list,
description="List of ATC commands (e.g., ['ATC VECTOR AAL123 270'])",
)
thought: Optional[str] = Field(
default=None, description="Chain-of-thought reasoning for the commands"
)
@classmethod
def example(cls) -> "ATCAction":
return cls(
commands=["ATC VECTOR AAL123 270", "ATC ALTITUDE AAL123 3000"],
thought="The aircraft AAL123 is deviating from the approach path. Vectoring to heading 270 to re-align with the ILS.",
)
class ATCState(BaseModel):
episode_id: Optional[str] = Field(
default=None, description="Unique episode identifier"
)
step_count: int = Field(ge=0, description="Current step number in the episode")
task_name: str = Field(description="Name of the current task/scenario")
cumulative_reward: float = Field(description="Accumulated reward for the episode")
@classmethod
def example(cls) -> "ATCState":
return cls(
episode_id="ep_001",
step_count=42,
task_name="KJFK Approach Control",
cumulative_reward=156.7,
)