База на глиссере
База управления на глиссере
Цель занятия: обучающиеся реализуют приём команд и микшер на наземной технике, проверяют поведение при потере связи и переносят эту логику на летающий аппарат.
Глиссер даёт ту же цепочку управления, что и дрон — приём команд, микширование, воздействие на движители, поведение при потере связи, — но отлаживается на земле. Ошибка в коде здесь означает, что аппарат остановился или поехал не туда, а не что он упал с высоты.
Что общего у глиссера и дрона
| Звено | Глиссер | Квадрокоптер |
|---|---|---|
| Приём команд | CRSF от ELRS-приёмника | То же самое |
| Разбор протокола | Тот же конечный автомат, тот же CRC | То же самое |
| ARM-тумблер | Разрешение движения | Разрешение вращения винтов |
| Микшер | Каналы → мощность двух движителей | Каналы → обороты четырёх моторов |
| Failsafe | Стоп при потере связи | Снятие газа / возврат домой |
| Выход | ШИМ на драйвер | ШИМ или DShot на ESC |
Отличается только микшер и последствия ошибки. Всё остальное переносится буквально, вплоть до строк кода.
Микшер: от каналов к движителям
Микшер — функция, превращающая команды пилота в мощности отдельных движителей. Для двух движителей (танковая схема, skid-steer):
Логика простая: едем прямо — обоим одинаково; поворачиваем — одному добавляем, другому убавляем.
// Каналы приходят в диапазоне 1000..2000, центр 1500
int thr = rx.getChannel(CH_THROTTLE); // 1000..2000
int yaw = rx.getChannel(CH_YAW); // 1000..2000
// Переводим в знаковый диапазон -255..255
int drive = map(thr, 1000, 2000, -255, 255);
int turn = map(yaw, 1000, 2000, -255, 255);
int left = constrain(drive + turn, -255, 255);
int right = constrain(drive - turn, -255, 255);
motors.set(left, right);constrain здесь не украшение. При полном газе и полном руле сумма даёт 510
— вдвое больше максимума. Без ограничения значение переполнится или уедет в
драйвер как мусор. Приём тот же, что в регуляторе линии у робота: выход
контура всегда ограничивается диапазоном исполнительного устройства.Мёртвая зона
Стики почти никогда не возвращаются ровно в 1500. Без мёртвой зоны глиссер будет медленно ползти при отпущенных стиках.
const int DEADZONE = 30; // микросекунд вокруг центра
int applyDeadzone(int value, int center = 1500, int dz = DEADZONE) {
if (abs(value - center) < dz) return center;
return value;
}Тот же приём понадобится на дроне: там «ползёт» превращается в «уводит».
Микшер квадрокоптера — для сравнения
Чтобы связь была наглядной, вот тот же принцип для четырёх моторов:
Та же идея: общая составляющая (газ) плюс разностные (наклоны и разворот). Знаки при рыскании чередуются по диагонали — потому что разворот создаётся разбалансом реактивных моментов пар винтов, вращающихся в разные стороны.
ARM: движение только по разрешению
const int ARM_THRESHOLD_US = 1700;
bool armed = rx.getChannel(CH_ARM) > ARM_THRESHOLD_US;
motors.setArmed(armed);
if (!armed) {
motors.set(0, 0); // не armed — движители обесточены, что бы ни было на стиках
return;
}Порог 1700 (а не 1500) выбран так, чтобы случайное дрожание около центра не включало моторы: тумблер должен быть уверенно в верхнем положении.
Failsafe и двухуровневая защита
В ERLS_Rover реализованы два независимых уровня:
- Тумблер ARM — осознанное решение оператора. Работает мгновенно.
- Таймаут связи — автоматика. Нет пакетов 500 мс → каналы в безопасные значения, газ в минимум, движение прекращается.
Уровни независимы намеренно: отказ одного не отменяет другой. Оператор может выключить ARM при живой связи; автоматика остановит аппарат, даже если оператор ничего не успел сделать.
Практика занятия
Собрать цепочку и увидеть каналы
Приёмник подключён, дамп каналов идёт в консоль. Убеждаемся, что стики двигают нужные числа — это предыдущая тема.
Написать микшер
Реализуем drive/turn → left/right с constrain и мёртвой зоной. Проверяем
без движителей: выводим рассчитанные мощности в консоль и двигаем стики.
Подключить движители и проверить направления
Частая ошибка — движитель крутится не в ту сторону. Лечится либо перестановкой проводов, либо знаком в коде. Записываем, что именно сделали.
Проверить ARM
Тумблер вниз — стики не действуют вообще. Тумблер вверх — управление работает. Проверяется многократно, это ключевая защита.
Проверить failsafe
Выключаем пульт при работающих движителях. Аппарат должен остановиться в пределах полусекунды. Это обязательная проверка, а не факультатив.
Диагностика
| Симптом | Причина | Что делать |
|---|---|---|
| Ползёт при отпущенных стиках | Нет мёртвой зоны или сбит центр | Добавить deadzone, откалибровать стики |
| Поворачивает не в ту сторону | Перепутаны движители или знак | Поменять местами в микшере |
| При полном газе руль не работает | Насыщение: drive уже 255 | Ограничить газ или масштабировать сумму |
| Дёргается на полном ходу | Просадка питания под нагрузкой | Проверить аккумулятор и сечение проводов |
| Не останавливается при выключении пульта | Failsafe не реализован или не проверяется таймаут | Вернуться к таймауту 500 мс |
Приёмка занятия
- Микшер написан самостоятельно, ограничение диапазона объяснено.
- ARM работает: при выключенном тумблере движители не реагируют ни на что.
- Failsafe проверен выключением пульта при работающих движителях.
- Обучающийся объясняет, какие строки перенесутся на квадрокоптер без изменений, а какие придётся заменить.