# Поворотное устройство По умолчанию ротатор выключен — станция работает с неподвижной антенной. Раздел нужен, только если у вас есть поворотное устройство. ## Подключение Штатная схема — через контейнер `rotctld` из состава Hamlib. Клиент не общается с портом напрямую: он отправляет команды сетевому демону `rotctld`, а тот уже говорит с железом. **1. Раскомментируйте секцию `rotctld` в `docker-compose.yml`:** ```yaml rotctld: image: librespace/hamlib:4.5.4 container_name: rot user: '9999' read_only: true environment: MODEL: '1' SET_CONF: 'min_az=0,max_az=360,min_el=0,max_el=180' device_cgroup_rules: - 'c 188:* rwm' restart: unless-stopped command: rotctld stop_grace_period: 1s ``` `MODEL` — номер модели Hamlib вашего контроллера, а **не** значение `ANTENNA__ROTATOR__MODEL`. Список: [Hamlib Wiki](https://github.com/Hamlib/Hamlib/wiki/Supported-Rotators) или `rotctl -l` внутри контейнера. `SET_CONF` задаёт физические пределы вашей механики — приведите их к реальности. Правило cgroup `c 188:* rwm` даёт доступ к USB-serial переходникам (`/dev/ttyUSB*`). Если контроллер подключён по Ethernet, оно не нужно. **2. Настройте `.env`:** ```ini ANTENNA__ROTATOR__ENABLED=True ANTENNA__ROTATOR__MODEL=ROT_MODEL_NETROTCTL ANTENNA__ROTATOR__PORT=rotctld:4533 ANTENNA__ROTATOR__MODE=Normal ANTENNA__ROTATOR__THRESHOLD=4 ANTENNA__ROTATOR__MIN_ELEVATION=0 ``` `ROT_MODEL_NETROTCTL` означает «ходить в сетевой `rotctld`» — это и есть схема выше. Прямое подключение (`ANTENNA__ROTATOR__PORT=/dev/ttyUSB0` плюс конкретная модель, например `ROT_MODEL_GS232`) тоже работает, но тогда сервис `rotctld` не нужен, а устройство надо пробросить в контейнер клиента. ## Режимы слежения `ANTENNA__ROTATOR__MODE` выбирает стратегию пересчёта координат спутника в команды ротатора. Все три реализованы в [`src/soniks_client/antenna/tracking/`](../development/architecture.md#слежение-за-спутником). ### Normal Азимут 0–360°, угол места 0–90°. Кратчайший путь считается «через 0/360», то есть от 350° к 10° ротатор идёт вперёд на 20°, а не назад на 340°. Подходит большинству станций. Слабое место — проход через север: спутник пересекает 0°/360°, и ротатору приходится перемотать полный круг, теряя несколько секунд приёма. ### Flip Для проходов через север. Один раз в начале прохода стратегия решает, нужен ли переворот: он нужен, если максимальный азимут **не** лежит между азимутами восхода (AOS) и захода (LOS) — признак того, что траектория пересекает север. Если переворот нужен, ротатор наводится на **азимут + 180°**, а угол места зеркалится: `180° − угол`. Спутник на 30° над горизонтом — антенна смотрит на 150°, то есть «через голову» назад. Требует механику с диапазоном угла места до 180°. Решение принимается на весь проход целиком и в середине не меняется. ### 250 Для ротаторов с расширенным диапазоном азимута ±250° и защитой от перекручивания кабеля. Слежение непрерывное «через 0»: когда спутник идёт 3° → 2° → 1° → 0° → 359°, ротатор продолжает движение в ту же сторону, в −1° → −2° → −3°, вместо разворота на 360°. Направление выбирается на каждой итерации по текущему положению ротатора: берётся значение азимута, эквивалентное по модулю 360° и ближайшее к текущему. На границах ±250° цель жёстко ограничивается, в лог идёт предупреждение. ```{note} Режим предупредит в логе, если максимальный азимут прохода попадает в 170–190° (проход около юга). Для ротатора с границами ±250° такая траектория может оказаться недостижимой. ``` ## Общие параметры * **`ANTENNA__ROTATOR__THRESHOLD`** (по умолчанию `4.0`) — команда на поворот отправляется, только если рассогласование по азимуту или углу места больше этого значения в градусах. Уменьшение даёт более плавное сопровождение, но чаще дёргает механику; увеличение бережёт привод ценой точности. * **`ANTENNA__ROTATOR__MIN_ELEVATION`** (по умолчанию `0.0`) — ротатор не опускается ниже этого угла места. Ставьте выше нуля, если антенну задевает мачта, крыша или другое препятствие. * **`OBSERVATION__ROTATOR_UPDATE_INTERVAL`** (по умолчанию `3` с) — период пересчёта положения. По окончании прохода ротатор возвращается в положение (0°, 0°). Если вместо этого нужна парковка в зенит, включите `ROT_PARK=True` — тогда скрипт `rotor-park.sh` отправит `P 180 90` после наблюдения. ## Проверка ```bash docker compose up -d docker compose logs -f rot # демон rotctld поднялся? docker compose exec soniks-client bash -c 'echo "p" | nc -w 1 rotctld 4533' ``` Последняя команда запрашивает текущее положение. Ответ из двух чисел означает, что связка клиент → `rotctld` → контроллер работает. Во время прохода в логе клиента видно выбранную стратегию — например, `[FlipStrategy] flip на пролёт: True`.