base_agent/uas/model/state.py

178 lines
10 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- 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