86 lines
2.9 KiB
Python
86 lines
2.9 KiB
Python
"""
|
||
航段数据结构
|
||
独立为单独文件,供 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})"
|
||
)
|