跳轉到

第 6 章:遙控與飛行模式切換

本章學習目標

  • 搞懂搖桿的數值(1000~2000)怎麼變成飛機的指令
  • 看懂解鎖/上鎖油門門檻失控保護這些安全邏輯
  • 理解這台有哪些飛行模式,以及它們怎麼被選擇

搭配官方影片(下方可直接播放,需先轉檔,見第 0 章)。

📺 官方影片:遙控程式工程結構介紹(4.3)

📺 官方影片:遙控程式工作流程(4.4)


6.1 搖桿其實只是四個數字

遙控器把每個搖桿軸變成一個 1000~2000 的數字,中間是 1500

通道 變數 中立 意義
油門 Remote.thr 1000(最低) 總升力
橫滾 Remote.roll 1500 左右傾
俯仰 Remote.pitch 1500 前後傾
偏航 Remote.yaw 1500 轉頭

這些數字透過 nRF24L01(2.4G)ELRS 接收機進來,在第 1 章的 Duty_4ms 被讀取與解析。


6.2 從搖桿到「想要的角度」

RC_Analy()Mode_Controler() 把搖桿換算成姿態外環的目標(HAL/control.c):

HAL/control.c(節錄)
pidPitch.desired = -(Remote.pitch - 1500) * 0.04f * 1.50f;   // 搖桿 → 目標俯仰角
pidRoll.desired  =  (Remote.roll  - 1500) * 0.04f * 1.50f;   // 搖桿 → 目標橫滾角

帶你算一次:把橫滾桿推到 Remote.roll = 1700

\[ (1700 - 1500) \times 0.04 \times 1.5 = 200 \times 0.06 = \mathbf{12°} \]

也就是「桿子推到 1700 → 命令飛機傾斜 12 度」。推到底 2000 則是 ±30°。 這個 pidRoll.desired 正是第 4 章外環的目標值——一條完整的指揮鏈就接起來了: 你的手指 → 搖桿數字 → 目標角度(外環)→ 目標角速度(內環)→ 馬達


6.3 解鎖與上鎖:別讓它隨便就轉

馬達會傷人,所以飛控預設是「上鎖」的,要用一個特定動作才會「解鎖」。 看 remote_unlock()HAL/remote.c):

  • 解鎖:油門拉到最低 + 偏航打到右(Remote.thr<1200 && Remote.yaw>1800)→ ALL_flag.unlock = 1
  • 上鎖:油門最低 + 偏航打到左 → ALL_flag.unlock = 0,馬達立刻停。
HAL/remote.c(節錄)
if (Remote.thr < 1200 && Remote.yaw > 1800)   // 油門最低、偏航打右 → 準備解鎖
{
    // …連續滿足條件才真正解鎖,避免誤觸
    ALL_flag.unlock = 1;
}

油門門檻:解鎖 ≠ 起飛

就算解鎖了,只要油門低於約 1100,MotorControl() 仍會把四顆馬達設為 0(第 5 章看過)。 要等你主動推油門才會轉。這是一層額外保險。


6.4 失控保護(Failsafe):訊號斷了怎麼辦

如果飛到一半遙控訊號斷掉,最危險。Rc_Connect()HAL/remote.c)負責偵測並善後:

  • 收不到新資料 → 把 roll/pitch/yaw 強制回中立(1500),避免維持一個歪掉的指令。
  • 油門則緩慢遞減Remote.thr = Remote.thr - 20),讓飛機慢慢降落而不是直接斷電摔下。
HAL/remote.c(節錄)
Remote.roll  = 1500;   // 失聯 → 搖桿回中
Remote.pitch = 1500;
Remote.yaw   = 1500;
// …
Remote.thr = Remote.thr - 20;   // 油門慢慢收,緩降

這就是為什麼第 1 章的 Duty_1000ms 要統計 NRF_SSI(訊號強度)—— 系統需要知道「現在還連著嗎」,才能決定要不要觸發失控保護。


6.5 這台有哪些飛行模式

Mode_Controler() 像一個總開關,依搖桿/旗標選擇目前用哪套控制:

模式 怎麼進入 控制鏈 章節
姿態模式(預設) 一般飛行 搖桿 → 角度外環 → 角速度內環 第 4 章
定高模式 雙桿手勢切換(flag_bara 氣壓/光流高度 → 高度 PID → 油門 第 7 章
光流定點 有光流且品質夠 位置 → 速度 → 角度(三級串級) 第 8 章
特技(空翻) 特定搖桿組合 繞過角度外環,直接給大角速度 第 9 章
無頭模式 Yaw_Carefree() 把搖桿方向依機頭朝向旋轉 本章 6.6

6.6 補充:無頭模式(Headless)

新手常搞不清「機頭朝哪」。無頭模式 Yaw_Carefree()HAL/control.c)用一個旋轉矩陣, 把你的搖桿方向依照當前航向旋轉,讓「你推前,飛機就往遠離你的方向去」,不管機頭朝哪:

HAL/control.c
pidRoll.desired  = originalRoll * cosy + originalPitch * siny;   // 依 yaw 角旋轉搖桿輸入
pidPitch.desired = originalPitch * cosy - originalRoll * siny;

這正是第 3 章學的「角度」在實際應用——把指令從「機體座標」轉到「對你而言的方向」。


6.7 接收機怎麼跟飛控講話:ELRS / SBUS / CRSF

你的搖桿訊號要從遙控器「飛」到飛機、再「交給」飛控,這中間其實是兩段不同的事, 用了不同名詞,很多人會搞混。先把它們分清楚:

層次 是什麼 比喻
無線連結(ELRS、TBS Crossfire…) 訊號怎麼在空中飛:用哪個頻段、怎麼抗干擾、距離多遠 快遞公司:負責把包裹從遙控器送到飛機上的接收機
線材協議(CRSF、SBUS、PPM…) 接收機收到後,怎麼把資料交給飛控(透過一條 UART 線) 簽收單格式:接收機和飛控講好的交件格式

逐一解釋:

  • ELRS(ExpressLRS):一套開源、超低延遲、超遠距離的無線連結系統(2.4G 或 900MHz)。 便宜、社群大,是近幾年 FPV 圈最紅的選擇。它屬於「快遞公司」那一層——管訊號飛得多快多遠。
  • CRSF(Crossfire 協議):接收機↔飛控之間的串列協議,TBS 發明、ELRS 也用它。 雙向(能把電量等遙測傳回遙控器)、低延遲、一包最多 16 通道。ELRS 接收機通常就是用 CRSF 跟飛控講話。
  • SBUS:Futaba 發明的串列協議,同樣是接收機↔飛控之間用的,一包 16 通道、訊號反相。 歷史悠久、超多接收機支援(Frsky、Futaba…)。和 CRSF 是「同一層、不同廠牌」的東西。

這台飛機用在哪?

你手上這台同時支援兩種遙控:配套遙控器走 nRF24L01(自訂 2.4G);也能綁 ELRS 接收機。 程式 ELRS/ELRS.c 就是在解析 CRSF 協議——透過 USART3、420000 baud、用 DMA 收 26 位元組的封包:

ELRS/ELRS.c(節錄)
if (packet[0] == CRSF_ADDRESS_FLIGHT_CONTROLLER       // 0xC8:這包是給「飛控」的
 && packet[2] == CRSF_FRAMETYPE_RC_CHANNELS_PACKED)   // 0x16:這包是「遙控通道」資料
{
    rcChannels[i] = bitBuffer & 0x07FF;   // 每 11 位元解出一個通道值(0~2047)
}

之後 CRSF_Connect() 把這些通道值換算回第 6.1 節那個 1000~2000 範圍,接進和 nRF24L01 一模一樣的控制鏈

如果你要自己做一架飛機,會用什麼?

現在主流、CP 值最高的組合是:

推薦:ELRS(連結)+ CRSF(協議)

買一個 ELRS 發射模組(或內建 ELRS 的遙控器)+ 一顆 ELRS 接收機, 接收機用 2 條訊號線(UART 的 TX/RX)+ 電源 接到飛控,飛控設定收 CRSF。 延遲低、距離遠、又便宜,是目前 DIY 的首選。

SBUS 是比較傳統的選擇(手上有 Frsky/Futaba 接收機時用);PPM 更老、通道少,現在很少用了。

💡 一句話記法:ELRS 管「訊號怎麼飛過來」,CRSF / SBUS 管「接收機怎麼把資料交給飛控」。 兩者是不同層、要搭配使用——例如「ELRS 連結 + CRSF 協議」。


6.8 動手驗證

  • 不裝槳,開上位機,推各搖桿看 Remote.thr/roll/pitch/yaw 數值是否 1000~2000、中立 1500。
  • 做解鎖手勢,看 ALL_flag.unlock 變 1;做上鎖手勢看它回 0。
  • 解鎖後不推油門,確認馬達不轉(油門門檻保險)。
  • 把接收機關掉/走遠,觀察是否觸發失控保護(搖桿回中、油門遞減)。

6.9 思考題

  • 用 6.2 的公式,Remote.pitch = 1350 對應幾度?方向是前傾還是後仰?(注意負號)
  • 用自己的話說明「ELRS」和「CRSF」差在哪、為什麼要分兩層。
  • 若你想讓這台飛得更遠,該換「連結」那一層還是「協議」那一層?
  • 為什麼「解鎖」要用「油門最低 + 偏航打邊」這種刻意的組合,而不是按一個鍵?
  • 失控保護為什麼是「油門慢慢收」而不是「立刻關馬達」?兩種做法各有什麼風險?

6.10 本章對應的原始碼

檔案 看什麼
HAL/remote.c RC_Analy()Rc_Connect()(失控保護)、remote_unlock()(解鎖)
HAL/control.c Mode_Controler()(模式選擇)、Yaw_Carefree()(無頭)
HARDWARE/nrf24l01.cELRS/ELRS.c 兩種接收機的底層收發

下一章:第一個「自動」功能——放開油門也能自己維持高度氣壓定高