Исходный код soniks_client.antenna.tracking.flip
"""Стратегия слежения с переворотом для проходов через север."""
from core.configs import logger
from soniks_client.antenna.tracking.base import TrackingStrategy
[документация]
class FlipStrategy(TrackingStrategy):
"""
Переворот на 180° по азимуту и зеркалирование элевации.
Решение о flip принимается один раз на весь пролёт — на основе
того, проходит ли спутник через север (макс. азимут не между AOS и LOS).
"""
_AZ_OFFSET = 180.0
_FLIP_BORDER_ELEV = 90.0
def __init__(self, min_elevation: float, threshold: float) -> None:
super().__init__(min_elevation, threshold)
self._is_flip: bool = False
[документация]
def prepare_pass(self, aos_az: float, max_az: float, los_az: float) -> None:
"""Решить, нужен ли переворот на этот пролёт. Решение не меняется до конца."""
self._is_flip = self._is_flip_required(aos_az, max_az, los_az)
logger.info("[FlipStrategy] flip на пролёт: %s", self._is_flip)
[документация]
def calculate_delta(self, target_az, target_alt, cur_az, cur_alt):
# В flip-режиме азимут уже в [0, 360), кратчайший путь корректен
"""Вернуть рассогласование по кратчайшему пути: азимут уже в [0, 360)."""
return (
self.shortest_angular_delta(target_az, cur_az),
abs(target_alt - cur_alt),
)
def _is_flip_required(self, aos: float, max_: float, los: float) -> bool:
"""True, если пролёт пересекает север (азимут проходит через 0/360).
Сырое сравнение ``aos < max_ < los`` работало только пока пролёт не
пересекал 0/360 на одном из участков: пролёт 10° -> 20° -> 350°
пересекает север между кульминацией и заходом, но выглядел
возрастающим и flip не включался.
Азимуты разворачиваются в непрерывную последовательность общим
хелпером базового класса; север пересечён, если развёрнутый путь
вышел за пределы [0, 360).
"""
unwrapped_max = self.closest_equivalent(max_, aos)
unwrapped_los = self.closest_equivalent(los, unwrapped_max)
path = (aos, unwrapped_max, unwrapped_los)
return min(path) < 0.0 or max(path) >= self.FULL_CIRCLE
@property
def is_flipping(self) -> bool:
"""Выбран ли переворот на текущий пролёт."""
return self._is_flip