アーキテクチャ:カーネルとデータフロー
CRSFストリームが羽ばたきと尾になる仕組み:モジュール境界、2つのミキサーカーネル、リンク断でも翼竜を生かす状態機械。
信号経路
PteronautOS は ExpressLRS 4.x のフォークで、受信機の「PWM パススルー」末尾を専用の飛行制御レイヤーに置き換えました。データ経路は意図的に短く保たれています:
CRSF radio link
│ 2.4 GHz SX1280
▼
rx_main / CRSF decoder → ChannelData[] (raw 172…1811 µs-window values)
▼
Ornithopter::update() → _readChannels() → voice* fields
▼ kernel select: activeProfile ≥ GEARBOX_2VTAIL_1RUD ?
_computeServoMixer() OR _computeGearboxMixer()
▼
_f[] (indexed by ServoFunc tag, µs)
▼
PWM output stage → funcMap channels → wing / rudder / motor servos
4 つの構造上のアイデアが機体を安定させ、コードを小さく保ちます:
- チャンネルは早い段階で正規化されます。 172–1811 の CRSF ウィンドウ内の生値はすべて −1…+1(
_crsfToNorm)またはパーセントに一度だけ写像され、その単位だけがミキサーを流れます — マジック定数の繰り返しはありません。 -
出力は固定ではなくタグ付けされます。 ミキサーは
_f[ServoFunc]に書き込みます。タグがどの物理 PWM 出力を駆動するかは、後でプロファイルのfuncMapが決めます — 参照: ミキサー・リファレンス .モデルの配線を変えても、ミキサーの計算には一切触れません。 - カーネルはコンパイル時のファミリーであり、実行時の選択です。 波形フラッパーとギアボックス・コントローラーはどちらもバイナリ内にあり、アクティブなプロファイルが毎更新ティックでカーネルを選びます。
- フェイルセーフはイベントではなく状態です。 リンク断、ベンチモード、スティック上書きは
update()内の明示的なゲートなので、無線が沈黙している間サーボが暴走することはありません。
2つのカーネル:波形とギアボックス
カーネルとは、正規化されたチャンネルをサーボ機能の µs へ変えるブロックです。PteronautOS にはミキサー・プロファイル番号で区別される 2 つのファミリーがあります:
| ファミリー | プロファイル | アクチュエータ | モデル原型 |
|---|---|---|---|
| 波形(サーボ)カーネル | 0 SERVO_2WING · 1 SERVO_2WING_1RUD · 2 SERVO_4WING | 羽ばたき翼サーボ(2–4)、冠舵 | ダイレクトドライブ・サーボのオーニソプター — 古典的な PteronautOS |
| ギアボックス・カーネル | 3 GEARBOX_2VTAIL_1RUD · 4 GEARBOX_1MOT_2VTAIL · 5 GEARBOX_1MOT_2VTAIL_1RUD · 6 GEARBOX_1ELE_1RUD · 7 GEARBOX_1MOT_1ELE_1RUD | モーター ESC、V テールまたはエレベーター + ラダー | ギア駆動/モーター駆動フラッパーと一般的な尾翼面 |
選択は update() 内の単一テスト PROFILE_IS_GEARBOX(activeProfile ≥ 3)で行われます。プロファイル自体は実行時の値です:ビルドフラグ MIXER_PROFILE から始まり(旧 ORNITHOPTER_GEARBOX=1 は今もプロファイル 5 にマップ)、WebUI から setOrnithopterProfile() でライブ切替できます — 再フラッシュなしで新しい機体へ照準を移せます。プロファイルは全部で 8 つ。正確な funcMap レイアウトはミキサー・リファレンスに表でまとめられています。
波形カーネル(サーボ羽ばたき)
波形カーネルは、ほとんどの人が「PteronautOS」と呼ぶものです:2 つの翼サーボが位相連続の振動を実行し、その形は毎サイクル彫琢されます。その解剖:
- ヒステリシス付きフラップゲート。 フラッピングに入るにはスロットルがフラップ閾値(既定の生値 ≈303、PWM 等価 ≈1.08 ms)を越える必要があります。閾値 − 50 のヒステリシス未満でのみ抜けるため、境界のスロットルが翼をチャタリングさせることはありません。
- 周波数。 FlappingOscillator は実経過時間(µs クロック、dt 上限 100 ms)で進みます。ケイデンス目標は、プロファイルの
throttleFrequencyMixにより CH6 フラップ周波数チャンネルとスロットルを 0.5 Hz…flapBaseFreq/10 の範囲で混ぜます。 - 振幅。 サーボ速度上限に対するスロットルの割合
ampMax = degPerSec / (2·f)(degPerSec = 60°/servoSpeed_ms)、乗算前に 55° でハードキャップ。したがって振幅は高周波で自然に崩れます — 翼がサーボの能力以上を求めることはありません。 - 猛度(フェロシティ)。 ダウンストローク(パワー)とアップストローク(回復)の猛度はストロークごとに成形され、エレベーターで非対称に変調され(引き起こしはダウンストロークを、押し込みはアップストロークを強める)、スロットル結合も加わり、形状関数の前に 0…8 へ制限されます。
- ヨー差動。 ラダーは左右逆相の猛度(
rudderFerocityRange)と左右逆相の振幅(rudderAmplitudeDifferential)を加えますが、ストローク反転位相は翼の間で 共有されたままです — 旋回の効きは非同期の翼ではなく非対称なドウェルから生まれます。 - 幾何と出力。 成形された −1…+1 の波は度へスケールされ、エルロン/エレベーター操舵(±60° の効き × スケール)に対してミックスされ、グライド/フラップ中心トリムでオフセットされ、0…180° にクランプされた後、構成可能な
servoMinUs…servoMaxUs包絡線(既定 988…2012)を通じて関数別トリム付きで µs へ変換されます。 - グライド分岐。 フラップ閾値未満ではオシレーターが減衰し、翼は静的なグライド角を保ちます — ベンチおよび発進に理想的な状態です。
ギアボックスカーネル(モーター+尾翼)
ギアボックス・カーネルは純粋な羽ばたきをモーター駆動系 + 一般的な尾翼面と交換します。モーターは連続回転するため、このカーネルはティックごとにステートレスで — オシレーターはなく — 代わりに:
- スロットル(アーム時)を 1000…2000 µs の ESC コマンド(
SF_MOTOR)へマップし、ディスアーム時はアイドル; - 尾翼をミックスします:V テールプロファイルはエレボン混合(エルロン+エレベーター / エルロン−エレベーター)を、古典的プロファイルは独立したエレベーター面を使います;
- Zephyrus(有効時)が ロール・ピッチ PID 補正を尾翼サーボへ注入できるようにし、±250 µs(
ZEPHYR_GEARBOX_CLAMP_US)に制限してセンサーのグリッチでサーボが停止しないようにします; - 波形カーネルと同じラダーミキサーと µs/トリム/クランプ包絡線を維持します。
1 つのオーニソプター機体が両方の性格を持てます:波形カーネルで羽ばたき発進し、ギアボックスで巡航する — 実行時プロファイル切替は update() 内のその 1 行です。
状態:リンク・ベンチ・フェイルセーフ
update() は WiFi/サーボループから固定 ~10 ms のケイデンスで呼ばれ、ミキサー実行前に 3 つのフラグをゲートします:
| 状態 | 条件 | 挙動 |
|---|---|---|
| 通常飛行 | linkUp + アームチャンネル有効 | カーネル出力全体がスティックに追従します |
| ベンチ/パネルモード | benchMode(WebUI パネル、RC リンクなし) |
中立スティックが注入され、スロットルはフラップ閾値未満に保持 — グライド + トリムの編集がライブで見えます |
| スティック上書き | stickOverride(仮想チャンネル) |
ファームウェア注入のチャンネル値が CRSF を完全に置き換えます(サーボ掃引、テスト) |
| フェイルセーフ | リンク喪失(onLinkDown / enterFailsafe) |
全機能が 1500 µs に中央化され、オシレーターリセット、モーター → 最小;CRSF パケット喪失も RX レベルで中央化されます |
喪失時中央化の挙動は意図的に 2 層へ重複させています:CRSF スタックがチャンネルデータをフェイルセーフし、Ornithopter 層が 幾何(振動状態を含む)をフェイルセーフします。したがって死んだ無線は、滑空可能で操縦可能な機体を残します — 決して暴れる機体ではありません。
ソースマップ
| モジュール | パス | 責務 |
|---|---|---|
| Ornithopter レイヤー |
src/lib/Ornithopter/
|
カーネル選択、ミキサー計算、波形オシレーター、プロファイル、トリム |
| 飛行プロファイルと定数 |
src/lib/Ornithopter/OrnithopterConfig.h
|
MixerProfile 列挙、ServoFunc タグ、funcMap、すべての数値デフォルト |
| オシレーター/形状 |
src/lib/Ornithopter/OrnithopterWaveform.h
|
位相積分、猛度成形、反転ロジック |
| Zephyrus(オプション) |
src/lib/Zephyrus/
|
MPU6050 + Mahony AHRS、デュアル PID、冠/尾翼補正 |
| PWM 出力段 |
src/lib/ServoOutput/devServoOutput.cpp
|
CRSF ティックに同期して µs を書き込みます |
| WebUI 設定 |
src/lib/WIFI/devWIFI.cpp
|
実行時プロファイル + チューニング永続化(/pteronautos) |
1 つ下の層 — 数値が正確にどの波形を生み、各プロファイルが関数を PWM 出力へどう配線するか — は ミキサー・リファレンス にあり、サーボタイミング包絡線は サーボカーネル に記載されています。