base_agent/uas/model/wind.py

64 lines
2.6 KiB
Python
Raw Normal View History

2026-06-18 03:28:14 +00:00
import math
from typing import Tuple
# ══════════════════════════════════════════════════════════════════════
# 风场模型(保持不变,略)
# ══════════════════════════════════════════════════════════════════════
class WindField:
"""风场模型(同前版本,此处省略重复代码)"""
def __init__(self):
self._uniform_dir: float = 0.0
self._uniform_spd: float = 0.0
self._layers: list = []
def set_uniform(self, direction_deg: float, speed_ms: float):
self._uniform_dir = direction_deg % 360.0
self._uniform_spd = max(0.0, speed_ms)
def add_layer(self, altitude_m: float,
direction_deg: float, speed_ms: float):
from dataclasses import dataclass as _dc
@_dc
class _L:
altitude_m: float
wind_dir_deg: float
wind_speed_ms: float
self._layers.append(
_L(altitude_m, direction_deg % 360.0, max(0.0, speed_ms))
)
self._layers.sort(key=lambda x: x.altitude_m)
def get_wind(self, altitude_m: float) -> Tuple[float, float]:
if not self._layers:
return self._uniform_dir, self._uniform_spd
if altitude_m <= self._layers[0].altitude_m:
lo = self._layers[0]
return lo.wind_dir_deg, lo.wind_speed_ms
if altitude_m >= self._layers[-1].altitude_m:
hi = self._layers[-1]
return hi.wind_dir_deg, hi.wind_speed_ms
lo_idx, hi_idx = 0, len(self._layers) - 1
while hi_idx - lo_idx > 1:
mid = (lo_idx + hi_idx) // 2
if self._layers[mid].altitude_m <= altitude_m:
lo_idx = mid
else:
hi_idx = mid
lo, hi = self._layers[lo_idx], self._layers[hi_idx]
dh = hi.altitude_m - lo.altitude_m
t = (altitude_m - lo.altitude_m) / dh if dh > 0 else 0.0
spd = lo.wind_speed_ms * (1-t) + hi.wind_speed_ms * t
d = hi.wind_dir_deg - lo.wind_dir_deg
if d > 180.0: d -= 360.0
if d < -180.0: d += 360.0
return (lo.wind_dir_deg + d * t) % 360.0, spd
def get_wind_vector(self, altitude_m: float) -> Tuple[float, float]:
wd, ws = self.get_wind(altitude_m)
wt = math.radians((wd + 180.0) % 360.0)
return ws * math.sin(wt), ws * math.cos(wt)