base_agent/uas/model/state.py

178 lines
10 KiB
Python
Raw Normal View History

2026-06-18 03:28:14 +00:00
# -*- coding: utf-8 -*-
"""
装备状态基类 + 各域子类
BaseState 公共状态基类dataclass
AircraftState 飞行器状态
GroundState 地面车辆/机器狗状态
RadarState 雷达状态
"""
from __future__ import annotations
import copy
import dataclasses
from dataclasses import dataclass, field
from enum import Enum
from typing import Any, Dict, List
# ─────────────────────────────────────────────────────────────────
# 飞行阶段枚举
# ─────────────────────────────────────────────────────────────────
class FlightPhase(Enum):
GROUND = "GROUND" # 地面停放
TAKEOFF = "TAKEOFF" # 起飞滑跑
CLIMB = "CLIMB" # 爬升
CRUISE = "CRUISE" # 巡航
DESCENT = "DESCENT" # 下降
APPROACH = "APPROACH" # 进近
LAND = "LAND" # 着陆
# ─────────────────────────────────────────────────────────────────
# 公共状态基类
# ─────────────────────────────────────────────────────────────────
@dataclass
class BaseState:
"""
装备公共状态基类
每次 step(dt) 后生成新的状态快照不可变frozen 语义
子类通过新增字段扩展特有状态
"""
# ── 时间 ──────────────────────────────────────────────────────
timestamp: float = 0.0 # 仿真绝对时刻(秒)
elapsed_time: float = 0.0 # 自启动累计时长(秒)
# ── 位置 ──────────────────────────────────────────────────────
latitude: float = 0.0 # 纬度WGS-84
longitude: float = 0.0 # 经度WGS-84
altitude: float = 0.0 # 高度MSL
# ── 姿态 ──────────────────────────────────────────────────────
heading: float = 0.0 # 航向角(度,真北顺时针)
pitch: float = 0.0 # 俯仰角(度,抬头为正)
roll: float = 0.0 # 横滚角(度,右滚为正)
# ── 速度 ──────────────────────────────────────────────────────
speed: float = 0.0 # 地速m/s
acceleration: float = 0.0 # 切向加速度m/s²
# ── 生命周期 ──────────────────────────────────────────────────
lifecycle: str = "CREATED" # LifecycleState.value
# ── 扩展 ──────────────────────────────────────────────────────
extra: Dict[str, Any] = field(default_factory=dict)
sub_states: List["BaseState"] = None
# ── 属性 ──────────────────────────────────────────────────────
@property
def position(self) -> tuple:
return (self.latitude, self.longitude, self.altitude)
# ── 序列化 ────────────────────────────────────────────────────
def to_dict(self) -> Dict[str, Any]:
return dataclasses.asdict(self)
@classmethod
def from_dict(cls, d: Dict[str, Any]) -> "BaseState":
valid = {f.name for f in dataclasses.fields(cls)}
return cls(**{k: v for k, v in d.items() if k in valid})
def copy_with(self, **kwargs) -> "BaseState":
obj = copy.copy(self)
for k, v in kwargs.items():
setattr(obj, k, v)
return obj
def __repr__(self) -> str:
return (f"{self.__class__.__name__}("
f"t={self.timestamp:.1f}s, "
f"pos=({self.latitude:.4f},{self.longitude:.4f},"
f"{self.altitude:.0f}m), "
f"hdg={self.heading:.1f}°, "
f"spd={self.speed:.1f}m/s, "
f"lc={self.lifecycle})")
# ─────────────────────────────────────────────────────────────────
# 飞行器状态
# ─────────────────────────────────────────────────────────────────
@dataclass
class AircraftState(BaseState):
"""飞行器完整状态"""
# ── 飞行阶段 ──────────────────────────────────────────────────
phase: str = FlightPhase.GROUND.value
# ── 飞行动力学 ────────────────────────────────────────────────
airspeed: float = 0.0 # 空速m/s
vertical_speed: float = 0.0 # 垂直速度m/s上升为正
bank_angle: float = 0.0 # 坡度角(度)
turn_rate: float = 0.0 # 转弯角速度(°/s
# ── 燃油 ──────────────────────────────────────────────────────
fuel_remaining: float = 0.0 # 剩余油量(升/千克)
fuel_percent: float = 100.0 # 剩余油量百分比
# ── 航线进度 ──────────────────────────────────────────────────
route_progress: float = 0.0 # 航线完成进度0.0~1.0
segment_index: int = -1 # 当前航段索引
# -- 风向
wind_direction: float = 0.0
wind_speed: float = 0.0
# ─────────────────────────────────────────────────────────────────
# 地面装备状态(车辆 / 机器狗)
# ─────────────────────────────────────────────────────────────────
@dataclass
class GroundState(BaseState):
"""地面装备状态(车辆 / 机器狗通用)"""
# ── 地形 ──────────────────────────────────────────────────────
slope_deg: float = 0.0 # 当前坡度(度)
road_type: str = "road" # road / offroad / track
# ── 运动 ──────────────────────────────────────────────────────
is_stopped: bool = True # 是否静止
odometer_m: float = 0.0 # 里程计(米)
# ── 电量(机器狗)────────────────────────────────────────────
battery_percent: float = 100.0 # 电量百分比
# ── 航线进度 ──────────────────────────────────────────────────
route_progress: float = 0.0
segment_index: int = -1
# ─────────────────────────────────────────────────────────────────
# 雷达状态
# ─────────────────────────────────────────────────────────────────
@dataclass
class RadarState(BaseState):
"""雷达装备状态"""
# ── 扫描 ──────────────────────────────────────────────────────
current_azimuth: float = 0.0 # 当前扫描方位角(度)
scan_elevation: float = 0.0 # 当前扫描仰角(度)
scan_cycles: int = 0 # 累计扫描圈数
# ── 跟踪 ──────────────────────────────────────────────────────
is_tracking: bool = False # 是否处于跟踪模式
tracked_count: int = 0 # 当前跟踪目标数
tracked_targets: List[str] = field(default_factory=list)
# ── 工作状态 ──────────────────────────────────────────────────
is_transmitting: bool = False # 是否发射
power_output_kw: float = 0.0 # 当前发射功率kW