Справочник микшеров
От стиков и гироскопа до µs на проводе: полная геометрия каждого микшера — оси крыла, смеси руля, элевоны, триммы и ограничения.
На этой странице описан слой микшера src/lib/Ornithopter/Ornithopter.cpp и система профилей OrnithopterConfig.h. Для общей архитектуры начните со
статью Архитектура
; о тайминге импульсов и диапазонах трима см.
Серво-ядро
статью.
Теги функций серво
Каждый выход каждого микшера — значение µs, записанное в _f[] и индексированное тегом ServoFunc. Теги — это транспорт: они говорят что означает сигнал, но не куда он подключён:
| Тег | Имя | Значение |
|---|---|---|
0
|
SF_NONE
|
Зарезервирован — без функции (первые PWM-слоты свободны для BOOT и I2C) |
1 / 2
|
SF_LEFT_WING / SF_RIGHT_WING
|
Передние машущие крылья (волновое ядро) |
3
|
SF_RUDDER
|
Головной/гребневой руль (волна) или килевой руль (редуктор) — смесь рыскания + крена |
4
|
SF_MOTOR
|
Газ бесколлекторного ESC (только редукторное ядро) |
5 / 6
|
SF_VTAIL_LEFT / SF_VTAIL_RIGHT
|
Поверхности V-хвоста, элевонное смешение (редукторное ядро) |
7
|
SF_ELEVATOR
|
Традиционный отдельный руль высоты (редукторные профили 6/7) |
8 / 9
|
SF_BACK_LEFT_WING / SF_BACK_RIGHT_WING
|
Задняя пара крыльев 4-крылого планера (зеркало передней пары, собственный трим) |
Профиль рантайма даёт funcMap: массив, отображающий индекс PWM-выхода → ServoFunc. Первые три слота (PWM 1…3) всегда SF_NONE — они принадлежат ремню BOOT и шине I2C — поэтому реальные серво-функции начинаются с индекса PWM 3 (комментарий в прошивке поясняет: индекс 3 = CH4, 4 = CH5, 5 = CH6).
Восемь профилей микшера
Существуют восемь профилей микшера. Профили 0–2 ведут волновое ядро (машущие крылья), профили 3–7 — редукторное ядро (мотор + хвосты):
| # | Профиль | Ядро | Сервы | funcMap (PWM 3 · 4 · 5) |
|---|---|---|---|---|
0
|
SERVO_2WING
|
волновое | 2 | Левое крыло · Правое крыло · — |
1
|
SERVO_2WING_1RUD
|
волновое | 3 | Левое крыло · Правое крыло · Руль |
2
|
SERVO_4WING
|
волновое | 4 (задняя правая разделяет зеркало задней левой) | Левое крыло · Правое крыло · Заднее левое крыло |
3
|
GEARBOX_2VTAIL_1RUD
|
редукторное | 3 | Руль · V-хвост левый · V-хвост правый |
4
|
GEARBOX_1MOT_2VTAIL
|
редукторное | 3 | Мотор · V-хвост левый · V-хвост правый |
5
|
GEARBOX_1MOT_2VTAIL_1RUD
|
редукторное | 4 (правый V-хвост разделяет левое зеркало) | Руль · Мотор · V-хвост левый |
6
|
GEARBOX_1ELE_1RUD
|
редукторное | 2 | Руль · Руль высоты · — |
7
|
GEARBOX_1MOT_1ELE_1RUD
|
редукторное | 3 | Руль · Мотор · Руль высоты |
Выбор: флаг сборки MIXER_PROFILE (устаревший ORNITHOPTER_GEARBOX=1 → профиль 5), затем переопределяется в рантайме через WebUI (setOrnithopterProfile). Проверка ядра — просто activeProfile ≥ GEARBOX_2VTAIL_1RUD.
Микширование осей крыла (волновое ядро)
Все значения каналов входят в микшеры нормализованными: _crsfToNorm линейно отображает сырое окно 172…1811 на −1…+1. Команды руления затем масштабируются слайдерами авторитета профиля (aileronScale, elevatorScale, 0–100%) на ±60° (ORNI_STEER_MAX_DEG).
Зеркальная геометрия. Сервы крыла установлены зеркально, что меняет смысл синфазных и дифференциальных членов. Поэтому код трактует элерон (крен) как синфазный — он добавляется к обоим крыльям, становясь дифференциальным физическим отклонением — а руль высоты (тангаж) как дифференциальный в коде, становясь синфазным физическим отклонением. Уравнения углов, при ORNI_NEUTRAL_ANGLE_DEG = 100° и множителе 2× только для членов отклонения:
angleLeft = NEUTRAL + (aileron + elevator + flapCentre − degL) · 2
angleRight = NEUTRAL + (aileron − elevator − flapCentre + degR) · 2
flapping: degL/R = amplitudeL/R · shapedWave(rawPhase, ferocityL/R, …)
glide: degL = degR = 0 → static glide offset takes over
degL/degR — мгновенные отклонения взмаха левого и правого крыла, каждое — произведение собственной амплитуды и волны, сформированной свирепостью. Руль высоты вверх усиливает нисходящий взмах; вниз — восходящий (асимметричная свирепость). Рыскание делит крылья двумя дополняющими способами:
- Дифференциал свирепости (
rudderFerocityRange): левое получает+свирепость, правое−свирепость— два крыла удерживаются по-разному, но сохраняют общую фазу реверса (limiarShared), поэтому повороты — чистый крутящий момент крена, а не рассинхронизация. - Дифференциал амплитуды (
rudderAmplitudeDifferential): левая амплитуда ×(1+Δ), правая ×(1−Δ) — симметричное расхождение вокруг заданного газом взмаха.
Углы ограничены 0…180° и преобразуются в импульсы настраиваемым конвертом servoMinUs…servoMaxUs (по умолчанию 988…2012): µs = min + угол·(max−min)/180, плюс трим на функцию. Смещения центра планирования/взмаха (glideAngleDeg, flappingAngleDeg, ±15°) входят как статические члены в свою ветвь — поэтому центры планирования и взмаха можно настраивать независимо для каждого профиля.
Микширование руля (оба ядра)
Микшер руля дословно общий для обоих ядер — одно уравнение, два планера:
mix = rudderNorm · rudderYawWeight + aileronNorm · rudderRollWeight
mix = clamp(mix, −1 … +1)
µs = 1500 + mix · 500 (rudder centre ± 500 µs)
+ gyroRudderCorrection (Zephyrus, when enabled)
+ servoTrimUs[SF_RUDDER]
По умолчанию: rudderYawWeight = 65%, rudderRollWeight = 35% (настраиваются в рантайме в WebUI, хранятся на бэкап). Связь крена на руле — то, что позволяет тяжелокрылому птерозавру держать координированные повороты без гимнастики с нитью рыскания; уменьшите вес крена, если головной руль слишком агрессивен в крене.
Микширование хвоста и элевонов (редуктор)
Редукторное ядро работает без состояния каждый тик. Его три субмикшера:
- Мотор —
SF_MOTOR: при вооружении газ 0…1 отображается на 1000…2000 мкс; снятие с вооружения или потеря связи форсирует минимум (мотор остановлен). - Руль — уравнение идентично разделу выше.
- Хвосты — две семьи. Классические профили (6/7) ведут отдельный руль высоты:
µs = 1500 + elevatorNorm·500 + pitchPID + trim. V-профили (3/4/5) элевонно смешивают оба канала на два хвостовых серво:
VtailLeft = 1500 + (aileron + elevator)·scale + rollPID + pitchPID + trimL
VtailRight = 1500 + (aileron − elevator)·scale − rollPID + pitchPID + trimR
scale = 500 µs; both aileron/elevator sums clamped to −1…+1 first
На редукторном ядре Zephyrus вводит обе ПИД-коррекции крена и тангажа в хвостовые сервы (крен противофазно, тангаж синфазно), каждая жёстко ограничена ±250 мкс (ZEPHYR_GEARBOX_CLAMP_US). Сбой гироскопа может поэтому покачать, но никогда не застопорит хвостовой серво.
Впрыск Зефира, триммы и failsafe
Существуют три разные точки ввода в зависимости от ядра и оси:
| Ось | Волновое ядро | Редукторное ядро |
|---|---|---|
| Руль / рыскание | gyroRudderCorrection добавляется к µs гребневого руля |
gyroRudderCorrection добавляется к µs килевого руля |
| Крен (элерон) | — (волновые крылья не несут ПИД крена) | gyroAileronCorrection, противофаза по V-хвосту, ограничено ±250 мкс |
| Тангаж (руль высоты) | — (вводится как модуляция волны в слое Zephyrus) | gyroElevatorCorrection, синфазно, ограничено ±250 мкс |
Тримы и пределы. У каждой функции есть знаковый трим на серво (servoTrimUs[tag], по умолчанию 0, ±300 мкс), добавляемый последним, и каждое значение проходит _clampServo — абсолютный защитный предел 500…2500 мкс, который выше всего. При фейлсейфе или потере связи все функции возвращаются к 1500 мкс, а редукторный мотор — к минимуму, поэтому модель всегда планирует к нейтрали.
Готовы к практическому слою? Настройка волны учебник показывает, как эти числа ощущаются со стиков, а Архитектура статья показывает, где каждый микшер сидит в конвейере.