實(shí)戰(zhàn):視覺反饋與PID控制的工程實(shí)現(xiàn))
簡介2017年全國大學(xué)生電子設(shè)計(jì)競賽B題滾球控制系統(tǒng)的完整工程代碼包面向參加電賽或?qū)W習(xí)嵌入式視覺控制的學(xué)生與開發(fā)者。系統(tǒng)以O(shè)penMV攝像頭追蹤小球位置通過藍(lán)牙將坐標(biāo)發(fā)送至STM32控制端結(jié)合PID算法驅(qū)動電機(jī)實(shí)現(xiàn)滾球控制覆蓋圖像處理、無線通信與閉環(huán)控制等關(guān)鍵環(huán)節(jié)。壓縮包共254個文件約8.76MB主要包括Keil工程文件uvproj/uvopt、C語言源碼與頭文件c/h、編譯生成的目標(biāo)文件與匯編o/axf/s、燒錄固件hex以及腳本和備份文件bat/bak目錄結(jié)構(gòu)便于直接打開工程查看或重新編譯。目前已有1810人學(xué)習(xí)下載適合希望快速上手完整賽題方案、參考硬件驅(qū)動與圖像識別代碼、梳理PID控制流程的參賽者和嵌入式愛好者。1. 題面回顧與整體方案選型1.1 這一題到底在考什么2017年電賽B題“滾球控制系統(tǒng)”題面核心一句話概括讓一個金屬小球在一個可雙向傾斜的平板上穩(wěn)定到指定位置并能沿給定軌跡運(yùn)動。聽起來像玩具實(shí)際做起來是集機(jī)械、視覺、控制、嵌入式于一身的綜合題。先說清楚系統(tǒng)工作邏輯平板繞X軸和Y軸兩個方向傾斜小球受重力分量驅(qū)動在平板上滾動??刂葡到y(tǒng)需要實(shí)時獲取小球的位置坐標(biāo)和期望位置求偏差通過控制算法計(jì)算出平板應(yīng)該傾斜的角度再由舵機(jī)或電機(jī)驅(qū)動平板動作形成閉環(huán)。整個過程對實(shí)時性要求很高典型的視覺反饋閉環(huán)系統(tǒng)。從當(dāng)年參賽隊(duì)伍的方案分布來看大致分三類方案類型視覺方案主控方案優(yōu)缺點(diǎn)A類OpenMV攝像頭模塊STM32F4系列開發(fā)快視覺端獨(dú)立處理串口通信適合趕時間B類普通攝像頭上位機(jī)圖像處理上位機(jī)STM32圖像處理靈活但需要多設(shè)備聯(lián)調(diào)現(xiàn)場穩(wěn)定性考驗(yàn)大C類攝像頭直連高性能MCU樹莓派/全志等嵌入式Linux算力強(qiáng)可跑復(fù)雜算法但功耗和實(shí)時性要平衡我當(dāng)年采用的是A類方案OpenMV做圖像識別輸出小球坐標(biāo)STM32做主控跑PID控制算法驅(qū)動舵機(jī)改變平板角度。這套方案最大的好處是視覺和控制解耦調(diào)試時可以分別驗(yàn)證不用一上來就面對“全鏈路不工作”的噩夢。1.2 系統(tǒng)構(gòu)成與機(jī)械結(jié)構(gòu)要點(diǎn)整個系統(tǒng)拆開看核心模塊就四個視覺檢測模塊、主控計(jì)算模塊、執(zhí)行機(jī)構(gòu)模塊、機(jī)械平臺結(jié)構(gòu)。機(jī)械結(jié)構(gòu)是我第一個踩坑的地方。平板和底座之間必須用萬向節(jié)或者類似結(jié)構(gòu)連接確保平板能以中心為支點(diǎn)做兩個自由度的旋轉(zhuǎn)。很多隊(duì)伍用兩個舵機(jī)疊加的云臺結(jié)構(gòu)一個舵機(jī)控制俯仰一個控制橫滾下面一個舵機(jī)要馱著另一個舵機(jī)結(jié)構(gòu)重量大容易產(chǎn)生機(jī)械抖動。我當(dāng)時的做法是底座固定一個數(shù)字舵機(jī)通過連桿結(jié)構(gòu)驅(qū)動平板繞X軸旋轉(zhuǎn)另一個舵機(jī)垂直安裝驅(qū)動平板繞Y軸旋轉(zhuǎn)。這樣兩個舵機(jī)都固定在底座上平板上的負(fù)載很小轉(zhuǎn)動慣量低響應(yīng)快得多。連桿結(jié)構(gòu)需要自己用3D打印或者鋁合金件加工精度要求挺高如果連桿虛位大了控制死區(qū)會讓你懷疑人生。機(jī)械部分的經(jīng)驗(yàn)總結(jié)第一舵機(jī)選型至少用20kg級別的數(shù)字舵機(jī)金屬齒輪不然平板帶球運(yùn)行時根本穩(wěn)不住第二所有連接件盡量用軸承減少摩擦阻力第三平板的平面度非常關(guān)鍵如果平板本身是翹的PID參數(shù)調(diào)到天邊也救不回來。2. 代碼工程結(jié)構(gòu)與數(shù)據(jù)流設(shè)計(jì)2.1 代碼模塊劃分的底層邏輯寫這套代碼最大的體會是競賽代碼和平時練手的例程完全是兩碼事。平時寫代碼追求“能跑”競賽代碼追求“在規(guī)定的幾十秒內(nèi)穩(wěn)定跑完整個賽程”。所以代碼結(jié)構(gòu)設(shè)計(jì)的第一步不是急著寫邏輯而是先把數(shù)據(jù)流理清楚。我的代碼整體分三大模塊視覺模塊OpenMV端、通信協(xié)議層、控制執(zhí)行模塊STM32端。視覺模塊負(fù)責(zé)的事情比較純粹通過攝像頭采集圖像識別小球位置把坐標(biāo)算出來。OpenMV上的Micropython代碼簡單直接就是初始化傳感器、設(shè)置閾值、找色塊、計(jì)算重心。通信協(xié)議層是最容易被低估的部分。因?yàn)镺penMV和STM32通過串口通信數(shù)據(jù)幀格式必須自己定。我定義的數(shù)據(jù)幀是幀頭0xAA 數(shù)據(jù)長度 數(shù)據(jù)位X坐標(biāo)、Y坐標(biāo)、標(biāo)志位 校驗(yàn)位。X和Y坐標(biāo)各占兩個字節(jié)先高后低這樣可以在一次傳輸里同時傳遞坐標(biāo)和當(dāng)前狀態(tài)??刂茍?zhí)行模塊是STM32端的核心包含三個子模塊串口解析、期望軌跡生成、PID控制器。數(shù)據(jù)流向 攝像頭采集 - OpenMV圖像處理 - 小球坐標(biāo)(x,y) - 串口協(xié)議幀 - STM32串口中斷接收 - 數(shù)據(jù)校驗(yàn)解析 - 與期望坐標(biāo)(x_ref, y_ref)求偏差 - PID計(jì)算 - 舵機(jī)PWM輸出 - 平板傾斜 - 小球滾動 - 攝像頭再次采集閉環(huán)理清數(shù)據(jù)流之后寫代碼就變成填空了。每個模塊的輸入輸出都明確測試的時候可以單獨(dú)喂數(shù)據(jù)驗(yàn)證不用每次都要整個系統(tǒng)跑起來。2.2 控制周期與任務(wù)調(diào)度設(shè)計(jì)控制系統(tǒng)的實(shí)時性是所有代碼設(shè)計(jì)中優(yōu)先級最高的一件事。我的系統(tǒng)采用的是固定控制周期設(shè)計(jì)核心控制環(huán)運(yùn)行在5ms定時器中斷中也就是200Hz的控制頻率。這個頻率怎么定的主要考慮因素有三個舵機(jī)響應(yīng)速度數(shù)字舵機(jī)典型響應(yīng)時間在50ms到200ms級別控制頻率太高意義不大、OpenMV的幀率實(shí)際穩(wěn)定跑30fps左右即大約33ms一幀新數(shù)據(jù)、PID微分項(xiàng)的噪聲敏感性頻率太高會放大噪聲。這里有個重要的實(shí)際經(jīng)驗(yàn)控制周期和視覺數(shù)據(jù)的到達(dá)周期是不匹配的200Hz的控制率但視覺數(shù)據(jù)只有30Hz左右。如果直接把上一幀坐標(biāo)用在控制里小球可能已經(jīng)跑出去很遠(yuǎn)了控制必然滯后。我的做法是在主控里做坐標(biāo)緩存和外推預(yù)測當(dāng)收到最新一幀坐標(biāo)時記錄該幀的時間戳控制環(huán)計(jì)算時讀取最近一幀坐標(biāo)并乘以一個根據(jù)實(shí)際調(diào)試得出的速度修正系數(shù)相當(dāng)于簡單預(yù)測了小球在當(dāng)前時刻的位置。這個優(yōu)化看似不起眼實(shí)測對系統(tǒng)穩(wěn)定性的提升非常大。整個任務(wù)的調(diào)度結(jié)構(gòu)主循環(huán)非阻塞 while(1) { 處理串口接收數(shù)據(jù)幀中斷環(huán)形緩沖區(qū) 更新期望軌跡點(diǎn)根據(jù)任務(wù)狀態(tài)機(jī) 非實(shí)時狀態(tài)刷新OLED顯示、按鍵掃描 } 定時器中斷5ms 讀取最近狀態(tài)緩存 計(jì)算PID輸出 更新舵機(jī)PWM占空比狀態(tài)機(jī)也是很關(guān)鍵的設(shè)計(jì)。賽題有多個任務(wù)定點(diǎn)停留、直線運(yùn)動、圓周運(yùn)動等。我把這些做成一個簡單的枚舉狀態(tài)機(jī)主循環(huán)根據(jù)狀態(tài)決定當(dāng)前執(zhí)行的軌跡類型定時器中斷只負(fù)責(zé)執(zhí)行“位置偏差-PID-輸出”這條固定流水線不關(guān)心現(xiàn)在跑什么軌跡。這樣軌跡切換的時候控制環(huán)完全不需要改動。3. 核心算法模塊拆解與代碼實(shí)現(xiàn)3.1 圖像處理從像素到坐標(biāo)OpenMV端識別小球最常用的是色塊識別函數(shù)find_blobs()。但直接調(diào)用API只能拿到一個色塊的矩形框我們需要的是小球在圖像中的具體中心坐標(biāo)。小球一般選擇橙色或者紅色和白色平板背景對比度高閾值設(shè)置也相對容易。圖像處理的幾個關(guān)鍵點(diǎn)第一ROI區(qū)域裁剪。平板在攝像頭視野內(nèi)是固定區(qū)域我直接在初始化時獲取平板四個角的圖像坐標(biāo)設(shè)為ROI。只在這個區(qū)域內(nèi)做色塊查找能大幅減少誤識別也能提高幀率。第二用色塊的中心作為小球位置。blob.cx()和blob.cy()返回的是色塊中心對小圓球來說這和球心位置偏差很小可以接受。但如果小球快速運(yùn)動圖像會有運(yùn)動模糊色塊區(qū)域會拉長這時候取中心點(diǎn)會有幾個像素的誤差在控制上體現(xiàn)為幾毫米的偏差。解決方法是適當(dāng)增大曝光時間換取更亮更清晰的圖像或者改用邊緣檢測加灰度重心法。第三多目標(biāo)干擾處理。如果賽場環(huán)境有其他橙紅色物體混進(jìn)ROIfind_blobs會返回多個結(jié)果。我加了面積和圓度雙重過濾條件只保留面積在合理區(qū)間且圓度接近1的目標(biāo)。核心代碼片段import sensor, image, time from pyb import UART sensor.reset() sensor.set_pixformat(sensor.RGB565) sensor.set_framesize(sensor.QVGA) sensor.skip_frames(time2000) sensor.set_auto_gain(False) # 關(guān)閉自動增益防止亮度變化導(dǎo)致閾值漂移 sensor.set_auto_whitebal(False) uart UART(3, 115200, timeout_char1000) THRESHOLD (30, 80, 20, 80, 30, 80) # 橙色小球LAB閾值 ROI (60, 40, 200, 120) # 平板區(qū)域需要根據(jù)實(shí)際標(biāo)定 while True: img sensor.snapshot() blobs img.find_blobs([THRESHOLD], roiROI, pixels_threshold20, area_threshold20) if blobs: # 面積過濾 圓度過濾 best_blob max(blobs, keylambda b: b.area()) if best_blob.area() 100 and best_blob.roundness() 0.5: x best_blob.cx() y best_blob.cy() # 組幀發(fā)送幀頭 0xAAX高字節(jié)X低字節(jié)Y高字節(jié)Y低字節(jié)校驗(yàn) data bytearray([0xAA, x 8, x 0xFF, y 8, y 0xFF, (x ^ y) 0xFF]) uart.write(data)這里特別提一下自動增益和自動白平衡這是新手最容易忽略的坑。如果不關(guān)閉當(dāng)環(huán)境亮度或者小球位置變化時攝像頭的增益會自己調(diào)整同樣的顏色在不同時刻測出的閾值完全不一致導(dǎo)致時而識別不到、時而誤識別。調(diào)好一次閾值后固定參數(shù)是最穩(wěn)妥的做法。3.2 坐標(biāo)映射圖像坐標(biāo)到物理坐標(biāo)的標(biāo)定攝像頭拿到的是圖像像素坐標(biāo)幾百x幾百但PID控制需要的是平板上的物理坐標(biāo)或者歸一化坐標(biāo)。如果直接用像素坐標(biāo)做控制鏡頭畸變在邊緣區(qū)域會造成很大的控制誤差小球在平板中間穩(wěn)了到邊緣就明顯跑偏。我采用的方案是四點(diǎn)標(biāo)定法在平板的四個角各做一個標(biāo)記記錄它們在圖像中的像素坐標(biāo)同時知道它們的物理坐標(biāo)比如定義平板中心為原點(diǎn)長寬方向上歸一化到-100到100。用透視變換把圖像坐標(biāo)轉(zhuǎn)換到物理坐標(biāo)。數(shù)學(xué)上這是一個單應(yīng)性變換矩陣求解問題。四個點(diǎn)對可以求解8個自由度的單應(yīng)矩陣。OpenMV的庫函數(shù)里沒有直接封裝透視變換的API我是在STM32端實(shí)現(xiàn)的坐標(biāo)解算。事先在電腦上用Python離線算出變換矩陣系數(shù)固化在代碼常量里。// STM32端簡化實(shí)現(xiàn)假設(shè)已通過標(biāo)定得到系數(shù) a0~a7 // 物理坐標(biāo)X_phys (a0*x_img a1*y_img a2) / (a6*x_img a7*y_img 1) // Y_phys (a3*x_img a4*y_img a5) / (a6*x_img a7*y_img 1) float x_phys (a0*x a1*y a2) / (a6*x a7*y 1); float y_phys (a3*x a4*y a5) / (a6*x a7*y 1);標(biāo)定的操作要注意幾點(diǎn)四個標(biāo)定點(diǎn)盡量覆蓋整個平板區(qū)域不要集中在中間否則外推邊緣誤差很大標(biāo)定時平板必須處于水平狀態(tài)每次挪動攝像頭或者平板位置后需要重新標(biāo)定。這個矩陣的關(guān)鍵作用不只是矯正畸變還能把圖像坐標(biāo)系的原點(diǎn)對齊到平板中心讓控制變量的物理意義更清晰。3.3 PID控制位置環(huán)加前饋控制算法的核心是一個雙通道PIDX軸和Y軸獨(dú)立控制。最樸素的想法就是兩個獨(dú)立的PID分別把小球拉向目標(biāo)坐標(biāo)。但實(shí)際跑起來你會發(fā)現(xiàn)純位置PID在小球接近目標(biāo)時會反復(fù)震蕩難以穩(wěn)定。原因在于小球是無自平衡能力的對象沒有阻尼平板一傾斜就加速它相當(dāng)于一個二階積分環(huán)節(jié)位置PID要穩(wěn)住這種對象本質(zhì)上需要靠微分項(xiàng)的阻尼作用。單純調(diào)大比例增益會出現(xiàn)極限環(huán)震蕩調(diào)大微分項(xiàng)會放大噪聲。我的解決方案是位置式PID加微分先行并加入速度前饋typedef struct { float kp, ki, kd; float integral; float last_err; float target; } PID_t; float PID_Update(PID_t *pid, float measured, float dt) { float err pid-target - measured; pid-integral err * dt; // 積分限幅 if (pid-integral 300) pid-integral 300; if (pid-integral -300) pid-integral -300; float derivative (measured - pid-last_measured) / dt; // 微分先行的關(guān)鍵 float output pid-kp * err pid-ki * pid-integral - pid-kd * derivative; pid-last_err err; pid-last_measured measured; return output; }微分先行和標(biāo)準(zhǔn)PID的區(qū)別在于微分項(xiàng)作用于被控量小球位置的變化率而不是偏差的變化率。這樣目標(biāo)值突變比如從點(diǎn)A切換到點(diǎn)B時微分項(xiàng)不會產(chǎn)生巨大的沖擊系統(tǒng)不會猛地抖一下。速度前饋是這樣加的當(dāng)執(zhí)行圓軌跡或直線軌跡時目標(biāo)點(diǎn)本身在運(yùn)動小球的期望速度不為零。單純的位置PID輸出的是把小球拉向目標(biāo)點(diǎn)的力但如果目標(biāo)點(diǎn)本身在移動就相當(dāng)于一直在追一個動點(diǎn)。我的做法是根據(jù)期望軌跡計(jì)算出目標(biāo)點(diǎn)的運(yùn)動速度乘以一個前饋系數(shù)加到輸出上。這個前饋系數(shù)只有純位置PID輸出的一半左右但對軌跡跟蹤精度的提升很明顯跟蹤圓形軌跡的半徑誤差能縮小到一個很小的范圍。4. 調(diào)試實(shí)戰(zhàn)從能跑到跑穩(wěn)的完整鏈條4.1 分步調(diào)試法先開環(huán)后閉環(huán)拿到代碼的第一件事我強(qiáng)烈建議先做開環(huán)測試不要一上來就跑閉環(huán)。第一步測試視覺鏈路。把OpenMV單獨(dú)上電在OLED或者串口輸出里看小球坐標(biāo)是否連續(xù)、平滑坐標(biāo)在平板不同位置是否和預(yù)想一致。這個環(huán)節(jié)最容易發(fā)現(xiàn)的是圖像閾值問題、標(biāo)定矩陣用錯的問題、串口通信丟幀的問題。第二步測試舵機(jī)執(zhí)行鏈路。用STM32直接發(fā)不同脈寬的PWM信號觀察平板傾斜方向是否正確、響應(yīng)是否靈敏。這里注意舵機(jī)的脈寬范圍和旋轉(zhuǎn)方向同一型號的舵機(jī)不同批次可能反著轉(zhuǎn)直接寫死很容易翻車。第三步純P控制測試。把KI和KD設(shè)為0只保留比例項(xiàng)從很小的KP開始加。觀察小球在平板上是否被“推”向目標(biāo)如果有來回震蕩就降低KP如果響應(yīng)太慢就增大一點(diǎn)。純P能讓小球穩(wěn)定在一個范圍內(nèi)就算是第一步成功。第四步逐步加D和I。先加微分項(xiàng)壓制震蕩再加積分項(xiàng)消除靜差。積分項(xiàng)一定要限幅這一點(diǎn)前面代碼里已經(jīng)體現(xiàn)了。4.2 現(xiàn)場調(diào)試的實(shí)戰(zhàn)經(jīng)驗(yàn)比賽現(xiàn)場和實(shí)驗(yàn)室環(huán)境差別很大燈光的位置、亮度完全不一樣攝像頭看到的畫面可能和調(diào)參時完全不同。這是每年電賽翻車最多的地方。我當(dāng)時的做法是在OpenMV初始化時加入一個閾值自動適配邏輯。上電后先讀取當(dāng)前環(huán)境光下的圖像取ROI區(qū)域內(nèi)最亮和最暗的像素值范圍結(jié)合預(yù)設(shè)的色差偏移動態(tài)生成閾值。這個邏輯只在上電時執(zhí)行一次運(yùn)行期間閾值不變化避免圖像處理在循環(huán)中自適應(yīng)帶來的不確定抖動。還有現(xiàn)場電磁干擾問題。舵機(jī)是強(qiáng)干擾源大電流變化會通過電源線影響主控和攝像頭。我的做法是每個模塊獨(dú)立供電舵機(jī)用單獨(dú)的7.4V電池主控和攝像頭用5V電源通過光耦隔離或者是至少用共地加粗導(dǎo)線來緩解。實(shí)測下來如果共用一個電源舵機(jī)啟動瞬間電壓跌落非常明顯攝像頭畫面會閃甚至直接重啟。4.3 PID參數(shù)整定的實(shí)用技巧PID參數(shù)整定很多人喜歡用試湊法一頓亂調(diào)最后調(diào)出來的系統(tǒng)可能剛好能過測試但稍微換個環(huán)境就垮了。我建議采用臨界比例度法的思路來做系統(tǒng)性的參數(shù)整定。做法先只保留比例項(xiàng)逐步增大KP直到系統(tǒng)出現(xiàn)等幅震蕩記錄此時的KP值為Ku震蕩周期為Tu。然后根據(jù)經(jīng)驗(yàn)公式計(jì)算初始參數(shù)再在這組參數(shù)附近微調(diào)。當(dāng)年調(diào)試出來的參數(shù)大概在一個范圍內(nèi)但不同機(jī)械結(jié)構(gòu)的系統(tǒng)差異很大——比如我后期換了一組舵機(jī)參數(shù)就必須重新調(diào)。給一個參考方向比例系數(shù)一般在2到8之間微分系數(shù)在比例系數(shù)的5到10倍之間積分系數(shù)很小主要用來消除靜態(tài)誤差調(diào)大了很容易引發(fā)低頻震蕩。在整定過程中有兩個細(xì)節(jié)值得特別留意。一個是在線修改參數(shù)的功能調(diào)試時用按鍵或者串口命令實(shí)時調(diào)整參數(shù)比重新燒錄程序快太多了。另一個是用OLED實(shí)時顯示PID的各個環(huán)節(jié)的值定位問題快比如看到輸出一直頂?shù)缴舷薜∏蚣y絲不動基本可以判斷是機(jī)械卡死而不是PID參數(shù)問題。5. 高頻故障與排查手冊5.1 常見故障速查表現(xiàn)象可能原因優(yōu)先級排查項(xiàng)小球靜止時來回震蕩微分項(xiàng)過小阻尼不足增大KD檢查微分項(xiàng)是否有效小球偏向一側(cè)無法居中積分項(xiàng)過小時有靜差或機(jī)械零點(diǎn)偏了檢查平板水平度增加KI小球跑飛完全不受控坐標(biāo)映射錯誤或舵機(jī)方向反了先檢查跟蹤的坐標(biāo)是否正確再看PWM方向攝像頭找不到小球閾值不對、光照變化、小球顏色被反光顯示二值化圖像確認(rèn)關(guān)閉自動增益控制反應(yīng)明顯遲鈍控制周期太長或串口丟幀嚴(yán)重檢查串口波特率確認(rèn)幀校驗(yàn)機(jī)制是否有效舵機(jī)嗡嗡響且發(fā)燙控制頻率過高或輸出抖動頻繁降低控制頻率輸出加死區(qū)5.2 獨(dú)家避坑經(jīng)驗(yàn)寫代碼時最大的一個教訓(xùn)串口中斷接收里千萬不要做耗時操作。我早期在串口中斷處理里直接解析數(shù)據(jù)并更新PID目標(biāo)值結(jié)果導(dǎo)致中斷函數(shù)執(zhí)行時間太長主循環(huán)被阻塞得厲害。正確做法是中斷里只把數(shù)據(jù)扔進(jìn)環(huán)形緩沖區(qū)在主循環(huán)里做解析。還有一個我花了一整天才解決的詭異問題小球在某一個特定位置附近總是出現(xiàn)規(guī)律性偏轉(zhuǎn)。排查到最后發(fā)現(xiàn)是攝像頭支架的共振造成的。攝像頭固定在一個較長的金屬支架上舵機(jī)工作時支架產(chǎn)生高頻微振動導(dǎo)致圖像坐標(biāo)周期性漂移。后來把攝像頭支架加粗加固后問題徹底消失。調(diào)試時建議把重要數(shù)據(jù)通過串口打印或者無線模塊發(fā)到電腦上做成實(shí)時曲線。很多隊(duì)伍在實(shí)驗(yàn)室里看OLED上的數(shù)字變化完全看不出趨勢。我在筆記本上用匿名上位機(jī)或者直接用Python的matplotlib做實(shí)時繪圖把小球的實(shí)際軌跡畫出來調(diào)試效率提升非常明顯。5.3 功能擴(kuò)展思路如果這套系統(tǒng)想繼續(xù)深入做有兩個方向很值得擴(kuò)展。一個是把控制算法升級為串級PID結(jié)構(gòu)內(nèi)環(huán)控制平板角速度外環(huán)控制小球位置響應(yīng)速度會有質(zhì)的提升。另一個是在軌跡規(guī)劃上下功夫賽題要求畫圓或走直線時目前的簡單逐點(diǎn)逼近方案在高速下精度有限可以考慮前瞻加軌跡插值讓運(yùn)動更順滑。比賽的代碼就是這樣一套東西從原理到落地每一步都有坑每一步也都有收獲。希望這篇內(nèi)容能幫到準(zhǔn)備電賽的朋友們特別是那些正在為B題代碼頭疼的隊(duì)友們。調(diào)試的時候保持耐心分模塊去驗(yàn)證不要指望一次點(diǎn)亮剩下來的事情就交給時間和手感了。本文還有配套的精品資源點(diǎn)擊獲取