""" 航段数据结构 独立为单独文件,供 flight_route.py 和外部模块引用 """ from __future__ import annotations from dataclasses import dataclass from typing import TYPE_CHECKING if TYPE_CHECKING: from uas.route.waypoint import Waypoint @dataclass class RouteSegment: """ 直线航段(两个程序转弯之间的直线飞行段) 坐标说明: start_lat/lon → 本段实际起点(上一转弯出口 或 第一个航路点) end_lat/lon → 本段实际终点(下一转弯 TIP 或 最后一个航路点) wp_from/to → 对应的逻辑航路点(用于高度/速度约束查询) """ # ── 逻辑航路点引用 ── wp_from: "Waypoint" # 起始逻辑航路点 wp_to: "Waypoint" # 终止逻辑航路点 # ── 实际飞行起终点坐标(含 TIP 修正)── start_lat: float # 实际起点纬度(度) start_lon: float # 实际起点经度(度) end_lat: float # 实际终点纬度(度) end_lon: float # 实际终点经度(度) # ── 几何参数 ── distance: float # 水平距离(米) bearing: float # 初始方位角(度,真北顺时针) # ── 时间参数 ── t_start: float # 航段起始时刻(秒) t_end: float # 航段结束时刻(秒) duration: float # 飞行时长(秒) # ── 速度参数 ── v_start: float # 起点速度(m/s) v_end: float # 终点速度(m/s) acceleration: float # 匀加速度(m/s²) # ── 高度参数 ── alt_start: float # 起点高度(米,MSL) alt_end: float # 终点高度(米,MSL) # ── 衍生属性 ── @property def vertical_speed(self) -> float: """平均垂直速度(m/s)""" if self.duration < 1e-6: return 0.0 return (self.alt_end - self.alt_start) / self.duration @property def avg_speed(self) -> float: """平均地速(m/s)""" return (self.v_start + self.v_end) / 2.0 @property def is_climb(self) -> bool: return self.alt_end > self.alt_start + 10 @property def is_descent(self) -> bool: return self.alt_end < self.alt_start - 10 @property def is_level(self) -> bool: return abs(self.alt_end - self.alt_start) <= 10 def __str__(self) -> str: phase = "爬升" if self.is_climb else ("下降" if self.is_descent else "平飞") return ( f"Seg[{self.wp_from.identifier}→{self.wp_to.identifier}] " f"{self.distance/1000:.3f}km / {self.bearing:.1f}° / " f"{self.duration:.1f}s / " f"{self.v_start:.1f}→{self.v_end:.1f}m/s / " f"{self.alt_start:.0f}→{self.alt_end:.0f}m ({phase})" )