soniks_client.antenna¶
Управление железом и расчёт положения спутника.
Примечание
rig и rotator импортируют системный модуль Hamlib, доступный только внутри
контейнера. В документации он подменяется заглушкой.
Стратегии слежения намеренно от Hamlib не зависят — поэтому именно они покрыты тестами.
Расчёт параметров пролёта¶
Расчёт положения спутника и радиальной скорости по TLE (Skyfield).
- class soniks_client.antenna.satellite_parameters.SatelliteParametersCalculator(station_location, tle)[исходный код]¶
Базовые классы:
objectРасчёт параметров пролёта по TLE и координатам станции.
- Параметры:
station_location (dict[str, float | int])
tle (dict[str, str])
- get_position()[исходный код]¶
Вернуть текущие азимут и угол места спутника в градусах.
- Тип результата:
tuple[float, float]
- get_radial_velocity()[исходный код]¶
Вернуть радиальную скорость спутника, м/с.
Положительное значение — спутник удаляется.
- Тип результата:
float
- get_azimuths_satellite_pass(start_time, end_time, satellite_name)[исходный код]¶
Вернуть азимуты восхода, кульминации и захода для пролёта.
Окно поиска расширяется на два часа в обе стороны: сеанс мог начаться с задержкой, и AOS уже прошло, либо LOS ещё далеко за
end_time. В расширенном окне помещается несколько пролётов, поэтому берётся целая тройка событий одного пролёта, ближайшая к окну наблюдения.- Результат:
Тройка азимутов либо
None, если пролёт не найден.- Параметры:
start_time (datetime)
end_time (datetime)
satellite_name (str)
- Тип результата:
tuple[AOS, Maximum, LOS] | None
Сессии связи¶
Фоновые потоки, гоняющие вычисленные значения в железо во время прохода.
Фоновые сессии связи: слежение ротатора и доплеровская коррекция частоты.
- class soniks_client.antenna.communication_session.CommunicationSessionBase(update_interval)[исходный код]¶
Базовые классы:
Generic[T],ABCФоновая сессия, гоняющая расчётные значения в железо во время прохода.
Потомок задаёт, что именно считать и куда отправлять; базовый класс ведёт поток и его жизненный цикл.
- Параметры:
update_interval (float)
- set_session_parameters(station_location, tle)[исходный код]¶
Задать координаты станции и TLE. Во время активной сессии игнорируется.
- Результат:
False, если сессия уже активна и параметры не приняты. Потомок обязан проверить результат: иначе он перестраивает своё состояние на живой сессии в обход этой защиты.- Параметры:
station_location (dict[str, float | int])
tle (dict[str, str])
- Тип результата:
bool
- start_session()[исходный код]¶
Запустить фоновый поток сессии.
- Исключение:
NoSessionParametersError – Параметры пролёта не заданы.
- Тип результата:
None
- stop_session()[исходный код]¶
Остановить фоновый поток сессии и дождаться его завершения.
- Тип результата:
None
- class soniks_client.antenna.communication_session.RotatorTrackingSession(update_interval, rotator)[исходный код]¶
Базовые классы:
CommunicationSessionBase[tuple[float,float]]Сессия слежения поворотного устройства за спутником.
Применяет стратегию из
ANTENNA__ROTATOR__MODEи двигает антенну, только если рассогласование превысилоANTENNA__ROTATOR__THRESHOLD. По завершении всегда возвращает антенну в исходное положение.- Параметры:
update_interval (float)
rotator (RotatorController)
- set_session_parameters(station_location, tle, start_time=None, end_time=None)[исходный код]¶
Задать координаты станции и TLE. Во время активной сессии игнорируется.
- Результат:
False, если сессия уже активна и параметры не приняты. Потомок обязан проверить результат: иначе он перестраивает своё состояние на живой сессии в обход этой защиты.- Параметры:
station_location (dict[str, float | int])
tle (dict[str, str])
start_time (datetime | None)
end_time (datetime | None)
- Тип результата:
bool
- class soniks_client.antenna.communication_session.RigRXDopplerCorrectedSession(update_interval, rig)[исходный код]¶
Базовые классы:
CommunicationSessionBase[int]Сессия доплеровской коррекции частоты приёма.
Считает радиальную скорость спутника и отдаёт скорректированную частоту демону
rigctld.- Параметры:
update_interval (float)
rig (RigController)
- set_session_parameters(station_location, tle, frequency)[исходный код]¶
Задать координаты станции и TLE. Во время активной сессии игнорируется.
- Результат:
False, если сессия уже активна и параметры не приняты. Потомок обязан проверить результат: иначе он перестраивает своё состояние на живой сессии в обход этой защиты.- Параметры:
station_location (dict[str, float | int])
tle (dict[str, str])
frequency (int)
- Тип результата:
bool
Приёмное устройство¶
Управление приёмным устройством через Hamlib.
Hamlib — системный модуль, доступный только внутри контейнера.
- class soniks_client.antenna.rig.RigController(rig_ip, rig_port, model=Hamlib.RIG_MODEL_NETRIGCTL)[исходный код]¶
Базовые классы:
objectПриёмное устройство через сетевой
rigctld(Hamlib).Используется для доплеровской коррекции частоты во время прохода.
- Параметры:
rig_ip (str)
rig_port (int)
- connect()[исходный код]¶
Открыть соединение с
rigctld.- Исключение:
EquipmentConnectionError – Hamlib вернул код ошибки.
- Тип результата:
None
- disconnect()[исходный код]¶
Закрыть соединение с
rigctld.- Тип результата:
None
- property frequency: float¶
- property vfo: int¶
Текущий VFO приёмника, прочитанный при подключении.
- soniks_client.antenna.rig.get_rig_controller()[исходный код]¶
Вернуть единственный на процесс контроллер приёмника.
Раньше контроллер создавался на импорте модуля: ошибка конфигурации Hamlib роняла клиент на старте трейсбеком вместо записи в лог.
- Тип результата:
Поворотное устройство¶
Управление поворотным устройством через Hamlib.
Hamlib — системный модуль, доступный только внутри контейнера.
- class soniks_client.antenna.rotator.RotatorController(model, baud, port)[исходный код]¶
Базовые классы:
objectПоворотное устройство через Hamlib.
Создаётся только при
ANTENNA__ROTATOR__ENABLED; иначеget_rotator_controller()возвращаетNone.- Параметры:
model (str)
baud (int)
port (str)
- connect()[исходный код]¶
Открыть соединение с поворотным устройством.
- Исключение:
EquipmentConnectionError – Hamlib вернул код ошибки.
- Тип результата:
None
- disconnect()[исходный код]¶
Закрыть соединение с поворотным устройством.
- Тип результата:
None
- property position: list[float]¶
- soniks_client.antenna.rotator.get_rotator_controller()[исходный код]¶
Вернуть единственный на процесс контроллер ротатора либо
None.Раньше контроллер создавался на импорте модуля, поэтому неизвестная модель Hamlib роняла клиент на старте трейсбеком вместо записи в лог.
- Тип результата:
RotatorController | None
Стратегии слежения¶
Поведение каждого режима описано в Поворотном устройстве.
Важно
Общая угловая математика живёт в TrackingStrategy. Правки, связанные с
переходом через 0/360, делайте там, а не в конкретной стратегии.
Выбор стратегии слежения по значению ANTENNA__ROTATOR__MODE.
- soniks_client.antenna.tracking.create_tracking_strategy()[исходный код]¶
Создать стратегию слежения по
ANTENNA__ROTATOR__MODE.- Тип результата:
Контракт стратегии слежения и общая угловая математика.
Исправления, связанные с переходом через 0/360, вносите сюда, а не в конкретную стратегию — иначе они достанутся одному режиму из трёх.
- class soniks_client.antenna.tracking.base.TrackingStrategy(min_elevation, threshold)[исходный код]¶
Базовые классы:
ABCКонтракт преобразования координат спутника в команды для ротатора.
Каждая стратегия отвечает за: - подготовку к пролёту (например, решение о flip); - перевод (az_sat, alt_sat) -> (az_rot, alt_rot); - расчёт дельт между целью и текущей позицией; - решение, нужно ли двигаться.
- Параметры:
min_elevation (float)
threshold (float)
- FULL_CIRCLE = 360.0¶
- HALF_CIRCLE = 180.0¶
- abstractmethod prepare_pass(aos_az, max_az, los_az)[исходный код]¶
Подготовиться к пролёту по азимутам восхода, кульминации и захода.
- Параметры:
aos_az (float)
max_az (float)
los_az (float)
- Тип результата:
None
- abstractmethod transform_target(sat_az, sat_alt, cur_rot_az, cur_rot_alt)[исходный код]¶
Перевести координаты спутника в целевые координаты ротатора.
- Параметры:
sat_az (float)
sat_alt (float)
cur_rot_az (float)
cur_rot_alt (float)
- Тип результата:
tuple[float, float]
- abstractmethod calculate_delta(target_az, target_alt, cur_az, cur_alt)[исходный код]¶
Вернуть рассогласование по азимуту и углу места в градусах.
- Параметры:
target_az (float)
target_alt (float)
cur_az (float)
cur_alt (float)
- Тип результата:
tuple[float, float]
- needs_movement(az_delta, alt_delta)[исходный код]¶
Превысило ли рассогласование порог, при котором стоит двигать антенну.
- Параметры:
az_delta (float)
alt_delta (float)
- Тип результата:
bool
- static shortest_angular_delta(a, b)[исходный код]¶
Кратчайшая угловая разница a-b в диапазоне [-180, 180], возвращаем модуль.
- Параметры:
a (float)
b (float)
- Тип результата:
float
- static closest_equivalent(sat_az, ref_az)[исходный код]¶
Вернуть значение, эквивалентное sat_az (mod 360), ближайшее к ref_az. Нужно для режима 250: 350° при ref=-10° даст -10°.
- Параметры:
sat_az (float)
ref_az (float)
- Тип результата:
float
Стратегия слежения для обычного ротатора с азимутом 0–360°.
- class soniks_client.antenna.tracking.normal.NormalStrategy(min_elevation, threshold)[исходный код]¶
Базовые классы:
TrackingStrategyОбычный режим. Азимут 0..360, угловое расстояние — кратчайшее через 0/360.
- Параметры:
min_elevation (float)
threshold (float)
- prepare_pass(aos_az, max_az, los_az)[исходный код]¶
Подготовка не требуется.
- Параметры:
aos_az (float)
max_az (float)
los_az (float)
- Тип результата:
None
- transform_target(sat_az, sat_alt, cur_rot_az, cur_rot_alt)[исходный код]¶
Вернуть азимут спутника как есть, ограничив угол места снизу.
- calculate_delta(target_az, target_alt, cur_az, cur_alt)[исходный код]¶
Вернуть рассогласование, считая азимут по кратчайшему пути через 0/360.
Стратегия слежения с переворотом для проходов через север.
- class soniks_client.antenna.tracking.flip.FlipStrategy(min_elevation, threshold)[исходный код]¶
Базовые классы:
TrackingStrategyПереворот на 180° по азимуту и зеркалирование элевации. Решение о flip принимается один раз на весь пролёт — на основе того, проходит ли спутник через север (макс. азимут не между AOS и LOS).
- Параметры:
min_elevation (float)
threshold (float)
- prepare_pass(aos_az, max_az, los_az)[исходный код]¶
Решить, нужен ли переворот на этот пролёт. Решение не меняется до конца.
- Параметры:
aos_az (float)
max_az (float)
los_az (float)
- Тип результата:
None
- transform_target(sat_az, sat_alt, cur_rot_az, cur_rot_alt)[исходный код]¶
Вернуть целевые координаты, при перевороте — азимут+180° и зеркальный угол места.
- calculate_delta(target_az, target_alt, cur_az, cur_alt)[исходный код]¶
Вернуть рассогласование по кратчайшему пути: азимут уже в [0, 360).
- property is_flipping: bool¶
Выбран ли переворот на текущий пролёт.
Стратегия слежения для ротатора с расширенным диапазоном азимута ±250°.
- class soniks_client.antenna.tracking.range_250.Range250Strategy(min_elevation, threshold)[исходный код]¶
Базовые классы:
TrackingStrategyРотатор с жёсткими границами по азимуту [-250, 250].
Сопровождение идёт «через 0»: если спутник движется 3° -> 2° -> 1° -> 0° -> 359°, ротатор продолжает движение -1° -> -2° -> -3° (а не разворачивается на 360°).
Решение о направлении (в + или в -) принимается на каждой итерации по текущему положению ротатора: берётся значение sat_az, эквивалентное (mod 360) и ближайшее к текущему rot_az.
- Параметры:
min_elevation (float)
threshold (float)
- LOWER_LIMIT = -250.0¶
- UPPER_LIMIT = 250.0¶
- prepare_pass(aos_az, max_az, los_az)[исходный код]¶
Предупредить, если пролёт идёт около юга и может оказаться недостижимым.
- Параметры:
aos_az (float)
max_az (float)
los_az (float)
- Тип результата:
None
- transform_target(sat_az, sat_alt, cur_rot_az, cur_rot_alt)[исходный код]¶
Вернуть непрерывный азимут рядом с текущим положением, ограничив его аппаратными пределами ±250°.
- calculate_delta(target_az, target_alt, cur_az, cur_alt)[исходный код]¶
Вернуть рассогласование без приведения по модулю 360.
Обе координаты уже в одной непрерывной системе отсчёта и могут быть отрицательными.
На упоре рассогласование по азимуту обнуляется после первой отправки: ротатор в предел уже упёрся, и дальше дельта остаётся большой до конца прохода, заставляя переотправлять одну и ту же команду.