:無人機(jī)串級PID調(diào)參全流程詳解)
把一臺無人機(jī)從零調(diào)到能穩(wěn)定懸停最磨人的就是PID參數(shù)。最近我又把整套流程走了一遍從ROS仿真環(huán)境搭起來到Gazebo里跑PX4 SITL再到真機(jī)上做室內(nèi)懸停和航線機(jī)動(dòng)前前后后重刷了好幾版參數(shù)。這篇筆記就把我的調(diào)參過程和思路完整記錄下來不只是參數(shù)表還會(huì)把串級PID的內(nèi)外環(huán)邏輯、控制頻率怎么定、仿真的參數(shù)為什么不能直接上真機(jī)這些關(guān)鍵點(diǎn)都拆開講。這篇筆記適合兩類人。一類是剛接觸無人機(jī)飛控知道PID是啥但不知道從哪里下手調(diào)的初學(xué)者另一類是ROS已經(jīng)裝好想在仿真里先跑通整套流程再做真機(jī)的玩家。文章會(huì)涉及一些PX4和QGroundControl的具體操作但只要照著順序往下走不需要太深的前置知識也能跟得上。真機(jī)調(diào)參有風(fēng)險(xiǎn)我一般建議先花兩天把仿真流程走熟再上真機(jī)否則一次炸機(jī)就夠你心疼很久了。1. 搭建ROS無人機(jī)仿真環(huán)境從安裝到起飛1.1 系統(tǒng)與ROS版本怎么選先交代我用的環(huán)境Ubuntu 20.04 ROS Noetic。選Noetic而不是ROS 2的Humble主要原因是PX4、MAVROS這一整套無人機(jī)生態(tài)在ROS 1下面最成熟網(wǎng)上能查到的資料也最多。如果你是零基礎(chǔ)不建議一上來就追新版本先把ROS 1這條鏈路跑通后面再遷移ROS 2會(huì)輕松很多。無人機(jī)飛控這個(gè)東西最怕的不是功能不夠新而是你踩了個(gè)坑發(fā)現(xiàn)社區(qū)里根本沒人跟你踩過同一個(gè)坑。ROS安裝本身沒什么難度就是依賴關(guān)系比較折磨人。網(wǎng)上教程很多我直接用了社區(qū)里很流行的魚香ROS一鍵安裝腳本。這個(gè)腳本在入門圈子里用的人非常多能自動(dòng)處理依賴關(guān)系、初始化rosdep裝完之后創(chuàng)建工作空間、編譯packages基本不會(huì)卡在一些莫名其妙的系統(tǒng)庫問題上。手動(dòng)安裝當(dāng)然也可以但新手很容易卡在rosdep update和依賴缺失那一步一卡就是一整天。我的態(tài)度是工具順手就行一鍵安裝不丟人關(guān)鍵是裝完之后你得清楚自己裝了什么、工作空間怎么組織、source的是哪個(gè)setup文件。另外提一句如果你是Windows用戶又不想搞雙系統(tǒng)可以用虛擬機(jī)或者WSLWindows Subsystem for Linux跑Ubuntu但要注意USB設(shè)備的透傳問題。調(diào)真機(jī)時(shí)需要把飛控通過USB連到地面站虛擬機(jī)里要設(shè)置USB直通WSL的話要配合usbipd-win這類工具。最省心的方案還是雙系統(tǒng)雖然來回重啟麻煩一點(diǎn)但不會(huì)遇到設(shè)備識別不了這種玄學(xué)問題。1.2 PX4 SITL Gazebo仿真環(huán)境搭建仿真環(huán)境我選的是PX4 SITLSoftware In The Loop加Gazebo。SITL的意思是飛控代碼跑在電腦上不連接任何真實(shí)硬件Gazebo提供一個(gè)虛擬的三維世界和飛機(jī)模型。這樣做的好處非常直接你把參數(shù)調(diào)炸了大不了重啟一下仿真真實(shí)飛機(jī)不會(huì)給你表演自由落體。搭建步驟大概是先拉取PX4-Autopilot源碼然后用它自帶的make px4_sitl gazebo命令啟動(dòng)仿真再裝好QGroundControl地面站以下簡稱QGC。啟動(dòng)之后Gazebo里會(huì)默認(rèn)出現(xiàn)一架四旋翼QGC連接后能看到傳感器數(shù)據(jù)和飛行狀態(tài)。第一次起飛前記得在QGC里把飛行模式切到Stabilized或者Position模式這兩個(gè)模式一個(gè)靠飛控穩(wěn)姿態(tài)一個(gè)再疊加位置控制都比手動(dòng)模式安全得多。啟動(dòng) PX4 SITL 仿真 make px4_sitl gazebo # 另開終端啟動(dòng)地面站 QGroundControl.AppImage可能有朋友要問為什么不直接在真機(jī)上調(diào)因?yàn)檎鏅C(jī)調(diào)參第一步是先驗(yàn)證傳感器方向、電機(jī)轉(zhuǎn)向這些環(huán)節(jié)任何一個(gè)小錯(cuò)誤就是炸機(jī)。仿真里沒有物理接線問題你能把全部注意力放在參數(shù)的變化如何影響飛機(jī)響應(yīng)這一件事上。等仿真里對調(diào)參手感有感覺了上真機(jī)再對照著試效率會(huì)高很多。2. 搞懂PID算法位置式、增量式和串級的關(guān)系2.1 位置式PID與增量式PID的本質(zhì)區(qū)別寫代碼之前先把PID的兩種常見離散形式講清楚。位置式PID的表達(dá)式是u(k) Kp * e(k) Ki * sum(e(j)) Kd * (e(k) - e(k-1))它輸出的是執(zhí)行機(jī)構(gòu)的絕對控制量比如直接給電機(jī)的油門值。這里有個(gè)經(jīng)典問題積分項(xiàng)會(huì)把歷史誤差一直累加一旦執(zhí)行機(jī)構(gòu)達(dá)到飽和比如油門已經(jīng)推到100%這個(gè)累積值還在繼續(xù)漲等誤差反向后要花很長時(shí)間才能退出來表現(xiàn)出來就是飛機(jī)低頭之后猛地回彈一下。這就是積分飽和。增量式PID算的是兩次控制量之間的差值delta_u(k) Kp*(e(k)-e(k-1)) Ki*e(k) Kd*(e(k)-2*e(k-1)e(k-2))注意這個(gè)式子里沒有累加項(xiàng)只關(guān)心當(dāng)前和前兩步的誤差變化。好處是控制器輸出是增量不存在積分飽和問題而且就算某一次計(jì)算有誤也只是改變量錯(cuò)了不會(huì)直接給一個(gè)很大的絕對值。飛控里很多位置環(huán)和速度環(huán)會(huì)用增量式的思路配合限幅使用控制起來更穩(wěn)。這兩種形式本質(zhì)上是同一套PID控制思想的不同實(shí)現(xiàn)區(qū)別在于輸出絕對值和輸出增量。無人機(jī)的角速度環(huán)和姿態(tài)環(huán)通常用位置式的變種再配合積分限幅和防積分飽和邏輯把這些邏輯搞清楚你調(diào)參時(shí)看到MC_ROLLRATE_I這個(gè)參數(shù)就不會(huì)一頭霧水了。2.2 無人機(jī)串級PID結(jié)構(gòu)內(nèi)環(huán)外環(huán)的作用無人機(jī)跟普通電機(jī)調(diào)速最大的區(qū)別在于它需要同時(shí)控制角度和角速度這就引出了串級PID。串級的意思就是兩個(gè)PID控制器串聯(lián)起來外層控制器先算出一個(gè)期望值內(nèi)層控制器再去跟蹤這個(gè)期望值。拿橫滾軸舉例。外環(huán)姿態(tài)環(huán)的輸入是期望橫滾角比如遙控器給15度指令它輸出一個(gè)期望橫滾角速度內(nèi)環(huán)角速度環(huán)的輸入就是這個(gè)期望角速度同時(shí)反饋陀螺儀測出來的真實(shí)角速度經(jīng)過PID計(jì)算后輸出給電機(jī)混控器一個(gè)控制量。外環(huán)每算一次相當(dāng)于給內(nèi)環(huán)布置一次任務(wù)內(nèi)環(huán)再高頻地執(zhí)行這些任務(wù)。有人會(huì)問為什么這么麻煩一個(gè)PID直接把角度控制住不行嗎這里就是串級PID的精髓所在。如果只用單環(huán)控制角度遇到外部擾動(dòng)時(shí)比如一陣側(cè)風(fēng)、一個(gè)槳葉打滑角速度會(huì)突變但角度的反饋?zhàn)兓鋵?shí)很滯后??刂破饕冉嵌认绕瞬胖廊バ拚@時(shí)候飛機(jī)早就晃起來了。加上角速度內(nèi)環(huán)之后陀螺儀能立刻感知角速度變化在擾動(dòng)還沒來得及變成明顯角度偏差之前就把它壓住。所以內(nèi)環(huán)是快環(huán)負(fù)責(zé)對抗擾動(dòng)外環(huán)是慢環(huán)負(fù)責(zé)跟隨目標(biāo)角度。內(nèi)外環(huán)的時(shí)間間隔或者說控制頻率也是按這個(gè)分工來設(shè)計(jì)的。2.3 內(nèi)外環(huán)控制頻率怎么定串級PID的分工決定了內(nèi)外環(huán)的執(zhí)行頻率必須分開。內(nèi)環(huán)處理角速度角速度變化非??焖钥刂祁l率要高一般要到幾百赫茲的量級外環(huán)處理角度角度的變化相對滯后幾十赫茲到一百赫茲就夠用了。這種快內(nèi)環(huán)慢外環(huán)的結(jié)構(gòu)在控制領(lǐng)域叫時(shí)間尺度分離是飛控設(shè)計(jì)里非常經(jīng)典的思想。實(shí)際在PX4里控制器是在不同調(diào)度模塊里跑的各個(gè)模塊的運(yùn)行頻率由固件決定。調(diào)參時(shí)你不一定需要去改這些頻率但心里要清楚你調(diào)的每一個(gè)P、I、D參數(shù)是給哪個(gè)環(huán)路的、這個(gè)環(huán)路的反饋來自哪個(gè)傳感器、這個(gè)傳感器更新速率有多少。把這條鏈路理清楚后面調(diào)參就不會(huì)瞎試。比如你發(fā)現(xiàn)飛機(jī)繞橫滾軸高頻振動(dòng)第一反應(yīng)應(yīng)該是去看角速度環(huán)的參數(shù)而不是去改姿態(tài)環(huán)因?yàn)檫@種高頻問題只有內(nèi)環(huán)的響應(yīng)速度才能背鍋。3. 無人機(jī)PID調(diào)參實(shí)操記錄從內(nèi)環(huán)到外環(huán)3.1 調(diào)參前的準(zhǔn)備與Checklist不管仿真還是真機(jī)調(diào)參前必須把這幾件事檢查完我列個(gè)清單傳感器校準(zhǔn)加速度計(jì)、陀螺儀、磁力計(jì)在QGC里按向?qū)ё咭槐檫b控器搖桿映射檢查通道方向、行程大小要跟飛控預(yù)期一致飛行模式切換通道確認(rèn)能穩(wěn)定切到Stabilized/Position/手動(dòng)真機(jī)還需要檢查螺旋槳方向、電機(jī)轉(zhuǎn)向、電調(diào)校準(zhǔn)、電池電壓、機(jī)架重心在PX4里橫滾、俯仰、偏航三軸的PID參數(shù)是分開的。橫滾和俯仰基本對稱所以我先調(diào)橫滾軸調(diào)通之后直接把參數(shù)復(fù)制給俯仰軸偏航軸單獨(dú)處理。注意找對參數(shù)名橫滾角速度環(huán)在QGC參數(shù)列表里是MC_ROLLRATE_P、MC_ROLLRATE_D姿態(tài)環(huán)是MC_ROLL_P別和偏航的MC_YAW_*搞混了。ArduPilot固件的參數(shù)命名完全不同但調(diào)參順序和思路是一樣的。一個(gè)小提醒把參數(shù)列表里能改的都截圖備份特別是默認(rèn)值。調(diào)參過程中你一定會(huì)改亂幾次有備份才能快速回滾。我用了一個(gè)笨辦法每調(diào)一組參數(shù)就在筆記本上記一次包括改了多少、現(xiàn)象是什么、結(jié)論是什么。這種原始記錄比任何調(diào)參軟件都好用。3.2 角速度內(nèi)環(huán)調(diào)參步驟先調(diào)內(nèi)環(huán)這是整個(gè)調(diào)參過程的地基。原則是先把I和D參數(shù)置為0只保留P。P從一個(gè)很小的值開始加以我這臺350mm軸距四旋翼為例從0.05開始每調(diào)一檔加0.02到0.03然后用遙控器打一個(gè)快速橫滾指令再回中觀察飛機(jī)角速度對指令的跟隨情況。什么是合適的P理想狀態(tài)是角速度快速跟上指令沒有明顯過沖和振蕩。P太小飛機(jī)響應(yīng)很肉指令執(zhí)行得拖拖拉拉P合適跟手、干脆。繼續(xù)加P直到飛機(jī)出現(xiàn)肉眼可見的高頻抖振甚至電機(jī)發(fā)出嗡嗡的抖動(dòng)聲這時(shí)候已經(jīng)到臨界點(diǎn)了。往回退一點(diǎn)在臨界值基礎(chǔ)上打個(gè)7折到8折作為P的最終值。接下來加D。D的作用是抑制角速度變化率能壓住高頻抖振但加太大反而會(huì)放大傳感器噪聲讓抖動(dòng)更明顯。我習(xí)慣從0開始每次加0.001這樣的小步長觀察高頻噪聲是否安靜下來加到臨界點(diǎn)再退一些。最后調(diào)II用來消除靜態(tài)誤差比如飛機(jī)一直朝某個(gè)方向緩慢偏轉(zhuǎn)通常說明I不夠或者傳感器沒校準(zhǔn)。I從0開始按0.01左右步長加加到飛機(jī)懸停時(shí)姿態(tài)穩(wěn)定不漂再稍微退一點(diǎn)。這里整理一份我調(diào)橫滾內(nèi)環(huán)的記錄方便你理解每次只動(dòng)一個(gè)變量是什么意思調(diào)試輪次修改參數(shù)現(xiàn)象結(jié)論第1輪MC_ROLLRATE_P0.05I/D為0打桿響應(yīng)很慢飛機(jī)動(dòng)作遲緩P太小繼續(xù)加大第2輪P0.10響應(yīng)改善但指令回中后仍有小幅度余搖P偏大但接近臨界區(qū)第3輪P0.08響應(yīng)利落基本無高頻抖動(dòng)暫定P0.08第4輪P0.08D0.003高頻段明顯更安靜D有效保持第5輪I0.02懸停時(shí)漂移減輕回中更穩(wěn)I合適保持3.3 姿態(tài)外環(huán)調(diào)參步驟內(nèi)環(huán)調(diào)好后外環(huán)就簡單了因?yàn)樗举|(zhì)上是在給內(nèi)環(huán)下指令。外環(huán)P從默認(rèn)值開始觀察角度對指令的跟隨。如果角度過沖大、來回?cái)[說明外環(huán)P太大如果角度響應(yīng)慢半拍、打桿后飛機(jī)要過一會(huì)才反應(yīng)過來說明外環(huán)P太小。外環(huán)一般不需要太強(qiáng)的I因?yàn)榉€(wěn)態(tài)誤差主要由內(nèi)環(huán)的I來處理外環(huán)加太多I反而容易引起低頻振蕩。調(diào)外環(huán)時(shí)有幾個(gè)容易踩的坑。第一個(gè)內(nèi)環(huán)參數(shù)在調(diào)外環(huán)期間絕對不要再動(dòng)否則你沒法判斷問題到底出在哪個(gè)環(huán)。第二個(gè)觀察角度響應(yīng)時(shí)不要盯著飛機(jī)本身而是看期望角度和實(shí)際角度之間的偏差我在真機(jī)上就很難用肉眼準(zhǔn)確判斷所以要么靠手感要么直接看日志曲線。第三個(gè)如果改了外環(huán)P之后飛機(jī)出現(xiàn)周期性擺頭頻率不高但一直不停多半是外環(huán)P太大或者內(nèi)環(huán)響應(yīng)本來就偏慢這時(shí)候先降低外環(huán)P試試。我實(shí)際調(diào)參時(shí)走過彎路剛開始覺得外環(huán)P好理解就急著調(diào)外環(huán)結(jié)果內(nèi)環(huán)P本來就偏大外環(huán)怎么調(diào)都振。后來老老實(shí)實(shí)回到內(nèi)環(huán)把內(nèi)環(huán)參數(shù)重新壓住外環(huán)一次就調(diào)通了。所以請記住這個(gè)順序內(nèi)環(huán)穩(wěn)定是一切的前提。3.4 用飛行日志分析參數(shù)效果光靠肉眼和手感不夠每次試飛后把日志導(dǎo)出來看很有必要。QGC自帶日志分析界面能畫出角速度、姿態(tài)角、PWM輸出等關(guān)鍵曲線。我最關(guān)注的是兩項(xiàng)一是角速度曲線里有沒有高頻鋸齒狀振動(dòng)二是姿態(tài)角曲線在階躍指令后的超調(diào)量和收斂時(shí)間。仿真里看曲線更方便因?yàn)榄h(huán)境沒有風(fēng)控制量不會(huì)有大毛刺。真機(jī)日志里角速度曲線如果高頻段有一條細(xì)細(xì)的抖動(dòng)帶很可能是傳感器噪聲被D放大要考慮降低D或者調(diào)整濾波參數(shù)。注意不是所有抖動(dòng)都是PID參數(shù)問題電機(jī)軸承磨損、槳葉不平衡同樣會(huì)產(chǎn)生高頻振動(dòng)這時(shí)候調(diào)PID只會(huì)越調(diào)越亂先換槳、做動(dòng)平衡再回來看日志才是正路。4. 調(diào)參中遇到的坑常見問題與排查技巧4.1 高頻抖振問題高頻抖振是入坑PID調(diào)參最常見的現(xiàn)象表現(xiàn)為飛機(jī)懸停時(shí)電機(jī)聲音發(fā)緊、機(jī)身輕微發(fā)抖。調(diào)試思路是按順序排除先把D調(diào)小或者清零如果抖振明顯消失問題出在D或傳感器噪聲如果還在再把P降下來試。要是P和D都降了還在抖就該去檢查槳葉、電機(jī)動(dòng)平衡以及機(jī)架有沒有共振點(diǎn)了。我用過一個(gè)偏方把無人機(jī)拿在手里加油門到不同油門位置感受不同轉(zhuǎn)速下的機(jī)身振動(dòng)。有些機(jī)架的共振點(diǎn)恰好落在懸停油門附近產(chǎn)生的抖動(dòng)跟PID無關(guān)。這類機(jī)械問題不解決你再怎么調(diào)參數(shù)都沒用反而會(huì)把參數(shù)壓得特別低導(dǎo)致飛機(jī)手感變得很遲鈍。4.2 響應(yīng)慢、漂移和震蕩問題響應(yīng)慢多數(shù)是外環(huán)P偏小也有可能是遙控器通道的輸入曲線設(shè)置太鈍在QGC里檢查搖桿輸入值是否跟實(shí)際桿量一致。漂移問題優(yōu)先檢查重心和傳感器校準(zhǔn)然后再考慮I是否足夠不要上來就猛加I那會(huì)把傳感器零偏也一并校正成控制量。震蕩和抖振不一樣震蕩的表現(xiàn)是飛機(jī)像呼吸一樣周期性擺動(dòng)頻率較低常見原因是外環(huán)P過大或者內(nèi)外環(huán)頻率比例不合適。內(nèi)環(huán)響應(yīng)太慢的時(shí)候外環(huán)還按原來的頻率控制就會(huì)出現(xiàn)外環(huán)給的任務(wù)內(nèi)環(huán)跟不上飛機(jī)慢悠悠地晃。這種情況先把內(nèi)環(huán)P和D加到位再回頭調(diào)整外環(huán)。這里可以做個(gè)小速查表現(xiàn)象可能原因優(yōu)先排查順序飛機(jī)高頻抖動(dòng)D過大、P過大、傳感器噪聲、機(jī)械振動(dòng)1. 先降D 2. 再降P 3. 查槳葉/電機(jī)低頻角度震蕩外環(huán)P過大、內(nèi)環(huán)響應(yīng)慢1. 降外環(huán)P 2. 增強(qiáng)內(nèi)環(huán)響應(yīng)持續(xù)漂移重心偏、傳感器未校準(zhǔn)、I不足1. 查重心 2. 校準(zhǔn) 3. 加I響應(yīng)遲緩?fù)猸h(huán)P過小、搖桿曲線太鈍1. 加外環(huán)P 2. 查搖桿輸入4.3 仿真與真機(jī)參數(shù)差異的處理仿真里調(diào)好的參數(shù)直接搬到真機(jī)上大概率要翻車。仿真模型的電機(jī)響應(yīng)、空氣動(dòng)力學(xué)、傳感器噪聲都是理想化的真機(jī)上有濾波延遲、電調(diào)響應(yīng)延遲、電池壓降、結(jié)構(gòu)共振等各種額外因素同樣一組參數(shù)在真機(jī)上表現(xiàn)會(huì)差很多。我的經(jīng)驗(yàn)是仿真參數(shù)只作為真機(jī)調(diào)參的起點(diǎn)P、I、D先按仿真值的0.6到0.8倍填入再重新按內(nèi)環(huán)到外環(huán)的順序微調(diào)這樣比從零開始能快不少。還有個(gè)更隱蔽的問題就是電池電壓。仿真里電池電壓恒定不變真機(jī)上新電池和舊電池的懸停油門差異很大電壓下降后電機(jī)響應(yīng)變軟原來合適的P可能就不夠用了。所以我調(diào)參時(shí)一般固定用同一組電池電量保持在一個(gè)區(qū)間內(nèi)避免電壓因素混進(jìn)來干擾判斷。另外溫度對電調(diào)和電機(jī)的響應(yīng)也有影響冬天和夏天的手感不一樣這些變量都要在調(diào)參記錄里寫上不然隔幾天你會(huì)發(fā)現(xiàn)參數(shù)自己變了。4.4 真機(jī)調(diào)試避坑清單最后再給一份更實(shí)操的真機(jī)避坑清單這些都是我用真金白銀換來的教訓(xùn)真機(jī)第一次上電前務(wù)必把螺旋槳卸下來做電機(jī)轉(zhuǎn)向測試。飛控加電后每路電機(jī)輸出方向必須在固件里確認(rèn)好否則一旦裝槳起飛飛機(jī)直接翻身調(diào)參時(shí)一定要在空曠無人的室內(nèi)或者在帶防護(hù)網(wǎng)的場地里進(jìn)行。飛機(jī)失控后的動(dòng)能不是開玩笑的系留繩在初步測試時(shí)也值得加裝每次只改一個(gè)參數(shù)改完記錄改亂了能回滾。別貪快一次改三四個(gè)參數(shù)出了問題你根本不知道是誰的鍋電池電壓和電量在試飛前檢查好電壓偏低會(huì)導(dǎo)致油門手感變化容易被誤判成參數(shù)問題。飛控的低電壓報(bào)警別關(guān)它在關(guān)鍵時(shí)刻能救命飛控的減震處理很重要特別是把飛控直接裝在碳纖維板上的機(jī)架高速振動(dòng)通過結(jié)構(gòu)傳導(dǎo)到陀螺儀日志里全是噪聲再怎么調(diào)參都白搭這次調(diào)參最大的收獲我覺得倒不是最終那組參數(shù)而是把先內(nèi)環(huán)后外環(huán)每次只動(dòng)一個(gè)變量用日志而不是感覺來判斷這三個(gè)原則真正刻進(jìn)了肌肉記憶。以前調(diào)小車的PID感覺差不多了就收工但無人機(jī)這種強(qiáng)耦合、高動(dòng)態(tài)的系統(tǒng)每一步都糊弄不得。現(xiàn)在再讓我調(diào)一個(gè)新機(jī)架心里就很有底了無非是按這套流程重新走一遍快的話半天就能出一組能飛的參數(shù)。下一步我打算給這臺飛機(jī)加上視覺感知模塊做點(diǎn)簡單的目標(biāo)跟蹤飛行讓飛機(jī)不只是穩(wěn)定懸停還能跟著目標(biāo)走到時(shí)候再繼續(xù)分享新的踩坑經(jīng)歷。