第 3 章:姿態解算 —— 從感測器到「現在歪幾度」¶
本章學習目標
- 理解為什麼「光有陀螺」或「光有加速度」都算不準角度
- 看懂互補濾波怎麼把兩者的優點合起來(含帶你算一次)
- 認識真實程式用的升級版:四元數 + Mahony 互補濾波(對應
MATH/imu.c) - 用上位機看 roll/pitch 波形,親眼看到「漂移」與「修正」
搭配官方影片:第 1 章已嵌入的 4.2 飛控程式工作流程,本章對應其中 GetAngle() 那一步。
3.1 兩個感測器,各有脾氣¶
第 2 章我們拿到了乾淨的陀螺和加速度。現在要回答飛機最關心的問題:「我現在傾斜幾度?」 你可能會想,那兩個感測器各算各的不就好了?問題是兩個都有缺點:
-
陀螺儀像一個反應超快、但講越久越離譜的人。 它量的是「轉動速度」,把速度對時間積分就能得到角度——瞬間很準、反應飛快。 但只要有一丁點零偏沒扣乾淨,積分會把它一直累加,幾秒後角度就「越飄越偏」(這叫漂移 drift)。
-
加速度計像一個誠實、但手會抖的人。 靜止時它只感受到地心引力,所以能算出「哪邊是下」,長期不會漂。 但飛機一震動、一加速,它就被干擾得亂跳,短期雜訊很大,沒辦法單獨用。
一句話:陀螺短期準、長期漂;加速度長期準、短期抖。 它倆的缺點剛好相反——這就是合作的契機。
3.2 互補濾波:讓兩人「互補」¶
互補濾波的點子很單純:
大部分時間相信反應快的陀螺,但每一次都偷偷把答案往誠實的加速度挪一點點。
這樣既保有陀螺的靈敏,又靠加速度「長期不漂」的特性,慢慢把陀螺的漂移拉回來。寫成公式:
其中 α 介於 0~1,越接近 1 越信任陀螺。它由一個「時間常數」τ 決定:\( \alpha = \dfrac{\tau}{\tau + \Delta t} \)。
帶你算一次¶
用這台飛機真實的姿態任務週期 Δt = 0.006s(第 1 章的 Duty_6ms),取 τ = 0.5s:
假設上一刻角度 θ = 10.00°、陀螺現在量到 ω = 20°/s、加速度反推的角度 θ_acc = 9.5°:
- 陀螺預測:10.00 + 20 × 0.006 = 10.12°
- 融合:0.9881 × 10.12 + (1 − 0.9881) × 9.5 = 9.9996 + 0.1131 = 10.11°
結果幾乎跟著陀螺(10.12,反應快),但被加速度往 9.5 拉回了 0.01°。 一次只拉 0.01° 好像沒用? 但這個 6ms 任務每秒做 167 次,這「每次一點點」累積起來, 就足以持續抵消陀螺的漂移——這就是互補濾波的精髓。
把 α 改小會怎樣?
若 α 從 0.988 降到 0.9(更信加速度),同樣數字算出來是 0.9×10.12 + 0.1×9.5 = 10.06°, 更靠近加速度、修正更快——但也更容易被加速度的抖動帶歪。這就是調參的取捨。
3.3 真實程式更聰明:四元數 + Mahony¶
上面的一維互補濾波是為了讓你抓到直覺。真實飛機是 3D 的(同時有 roll/pitch/yaw),
直接用「歐拉角」算會遇到一個叫萬向鎖(Gimbal Lock)的麻煩,數學上也不漂亮。
所以這份韌體(MATH/imu.c 的 GetAngle())用的是工業界常見的做法:
用「四元數」表示姿態,再用「Mahony 互補濾波」更新它。
別被名詞嚇到——它的精神跟 3.2 節一模一樣:相信陀螺積分,再用加速度量到的「重力方向誤差」去修正。 我們對著程式看這個對應關係:
把這六步對回 3.2 的直覺:
| 互補濾波(1D 直覺) | Mahony(程式實作) |
|---|---|
| 「加速度算的角度 θ_acc」 | ① + ② 用四元數推重力、和加速度比,得到方向誤差 |
| 「往加速度挪一點」的比例 (1−α) | ④ 裡的 Kp = 0.8(比例修正) |
| 長期把漂移拉回 | ③ 的 Ki = 0.0003 積分項(慢慢修零偏) |
| 「上一刻角度 + 陀螺轉的量」 | ⑤ 用陀螺積分四元數 |
所以四元數版到底好在哪?
- 沒有萬向鎖,任何姿態都能正確表示(飛特技翻滾也不會算爆)。
- 用叉積自然地在 3D 裡算出「重力方向誤差」,比逐軸算歐拉角乾淨。
Kp / Ki就是你調「信陀螺 vs 信加速度」的旋鈕,跟 1D 的 α 是同一回事。
3.4 動手驗證(用 ANO 上位機看波形)¶
- 開上位機,畫出
roll、pitch。把飛控慢慢傾斜到約 45° 再回正,看數值是否跟著動、回正歸零。 - 快速晃一下再放回水平:看姿態角會不會「跟得上又不亂跳」——這就是 Kp/Ki 調得好的表現。
- 觀察 yaw(航向):讓飛控靜止不動,過一兩分鐘看 yaw 有沒有慢慢漂。 會漂是正常的——因為這台沒有磁力計,yaw 只能靠陀螺積分,長期一定漂(正好印證 3.1 節)。
3.5 思考題¶
- 把
KpDef從 0.8 調大到 3.0,姿態角的反應會更快還是更慢?可能帶來什麼壞處?(對照 3.2 的「α 改小」) - 為什麼 roll/pitch 可以靠加速度修正、不會長期漂,yaw 卻會?(提示:地心引力能幫你定義「上下」,但能幫你定義「東南西北」嗎?)
- 第 2 章若校準沒做好、陀螺零偏沒扣乾淨,對應到本章 ⑤ 的積分,會看到什麼現象?
3.6 本章對應的原始碼¶
| 檔案 | 看什麼 |
|---|---|
MATH/imu.c |
GetAngle():四元數 + Mahony 互補濾波,本章重點 |
HAL/attitude_process.c |
姿態相關的上層處理 |
MATH/myMath.c |
Q_rsqrt() 快速平方根倒數、atan2/asin 等工具 |
下一章:有了準確的姿態角,飛機怎麼「把自己擺回想要的角度」? 這就要進入飛控的心臟——串級 PID 控制(對應官方影片 5.5)。