器人:RK3566與15電機(jī)的高集成嵌入式設(shè)計(jì))
1. 25厘米的鴨子憑什么在Github刷屏這一陣子刷Github trending一只鴨子吸引了我的注意。準(zhǔn)確說(shuō)是一個(gè)嵌入式機(jī)器人項(xiàng)目外觀被做成了鴨子造型整機(jī)只有25cm高重量壓到800g以內(nèi)卻在這么小的身板里塞進(jìn)一顆RK3566和15個(gè)電機(jī)。最開(kāi)始我以為又是那種拍個(gè)視頻就扔在那里吃灰的網(wǎng)紅demo但點(diǎn)進(jìn)去看了倉(cāng)庫(kù)里的代碼、電路圖和裝配說(shuō)明越看越覺(jué)得這項(xiàng)目的完成度不低。很多做嵌入式的人看到這種項(xiàng)目的反應(yīng)都是好家伙RK3566這顆芯片通常拿來(lái)做帶HDMI顯示的開(kāi)發(fā)板再不濟(jì)也是跑Linux的迷你主機(jī)怎么會(huì)被塞進(jìn)一只玩偶鴨子里面但這恰恰是這個(gè)項(xiàng)目最吸引我的地方。RK3566是瑞芯微主打能效比的一顆四核A55處理器主頻最高1.8GHz帶Mali-G52 GPU和獨(dú)立的NPU算力雖然比不了旗艦芯片但做機(jī)器人主控綽綽有余。15個(gè)電機(jī)意味著鴨子有15個(gè)自由度對(duì)應(yīng)不同身體部位的運(yùn)動(dòng)所以在體積受限的前提下RK3566的算力可以用在圖像識(shí)別、語(yǔ)音交互、運(yùn)動(dòng)規(guī)劃這些真正需要“思考”的任務(wù)上而不是單純?nèi)WM發(fā)波。更讓我覺(jué)得有意思的是這個(gè)項(xiàng)目把很多矛盾集中在一個(gè)很小的空間里要輕、要小、要多個(gè)執(zhí)行器、要強(qiáng)算力、還要能跑得動(dòng)Linux系統(tǒng)。這些條件的組合讓它在同類項(xiàng)目中顯得非常另類。如果說(shuō)以前我們看慣了“樹(shù)莓派小車(chē)”和“STM32四軸飛行器”那這只鴨子就是一次在算力與機(jī)械自由度之間找平衡的嘗試。而對(duì)于想入門(mén)嵌入式Linux、機(jī)器人控制、小型機(jī)械結(jié)構(gòu)的開(kāi)發(fā)者來(lái)說(shuō)這個(gè)項(xiàng)目的可參考價(jià)值其實(shí)比很多成熟產(chǎn)品還要高。1.1 這不是玩具而是一個(gè)嵌入式全家桶有人可能會(huì)想15個(gè)電機(jī)聽(tīng)起來(lái)很多但大多數(shù)玩具鴨子不也能扭頭扇翅膀嗎區(qū)別在于普通玩具用的是機(jī)械聯(lián)動(dòng)電機(jī)就一個(gè)或者兩個(gè)所有動(dòng)作都是固定的凸輪軌跡。這個(gè)項(xiàng)目里的15個(gè)電機(jī)每一個(gè)都是獨(dú)立控制的相當(dāng)于每個(gè)運(yùn)動(dòng)關(guān)節(jié)都有專門(mén)的驅(qū)動(dòng)通道。從頸部的擺動(dòng)到翅膀的抬升從尾巴的翹起到腿部的前進(jìn)后退在控制層面是完全解耦的。這種設(shè)計(jì)帶來(lái)的第一個(gè)問(wèn)題就是電機(jī)驅(qū)動(dòng)電路的數(shù)量和體積。15路電機(jī)如果要全部由RK3566直接驅(qū)動(dòng)顯然不現(xiàn)實(shí)。RK3566沒(méi)有那么多硬件PWM引腳即使有足夠引腳驅(qū)動(dòng)電流也不夠。所以項(xiàng)目中大概率采用了“主控電機(jī)驅(qū)動(dòng)MCU”的分層架構(gòu)。RK3566只算決策不碰執(zhí)行細(xì)節(jié)通過(guò)串口或USB把“頭部往左轉(zhuǎn)30度”“左翅膀抬到40度”這類高層指令發(fā)給下位機(jī)具體PWM周期、占空比、舵機(jī)速度曲線都由下位機(jī)來(lái)處理。如果往深里想這種架構(gòu)其實(shí)和現(xiàn)代自動(dòng)駕駛的域控制器方案如出一轍主計(jì)算單元做感知與規(guī)劃MCU做底層執(zhí)行控制中間通過(guò)通信協(xié)議握手。只不過(guò)我們平時(shí)看到的工業(yè)級(jí)方案動(dòng)輒幾百瓦功耗而這只鴨子把整套系統(tǒng)縮到了800g以內(nèi)使得它更像一個(gè)可以放在桌面上隨便玩的機(jī)器人。1.2 從倉(cāng)庫(kù)結(jié)構(gòu)看項(xiàng)目的完整度我在翻代碼的時(shí)候發(fā)現(xiàn)作者對(duì)倉(cāng)庫(kù)的整理非常克制。每個(gè)目錄的命名基本都能直接看出作用固件源碼、PCB設(shè)計(jì)文件、3D打印模型、上位機(jī)調(diào)試工具各自分得清清楚楚。熟悉開(kāi)源硬件項(xiàng)目的朋友都知道很多項(xiàng)目火起來(lái)往往是因?yàn)橐曨l效果炸裂但點(diǎn)進(jìn)倉(cāng)庫(kù)發(fā)現(xiàn)資料亂成一團(tuán)連個(gè)像樣的README都沒(méi)有。這個(gè)鴨子項(xiàng)目至少在分享意識(shí)上是到位的它甚至把BOM表物料清單和裝配步驟都整理成了markdown文檔這一點(diǎn)非常拉好感。作者還提供了一個(gè)調(diào)試用的上位機(jī)界面讓我很意外。雖然只是簡(jiǎn)單的滑塊和儀表盤(pán)但配合一些主流的圖形界面框架可以實(shí)現(xiàn)實(shí)時(shí)調(diào)參。這也讓我意識(shí)到15個(gè)自由度的小型機(jī)器人在調(diào)試階段如果沒(méi)有一個(gè)好用的實(shí)時(shí)控制界面光靠燒錄固件來(lái)試錯(cuò)效率會(huì)低得離譜。2. 拆掉外殼看布局15個(gè)電機(jī)的分配藝術(shù)先說(shuō)結(jié)論15個(gè)電機(jī)聽(tīng)著多但分到每個(gè)身體部位之后其實(shí)不算奢侈。我自己拿這個(gè)數(shù)推了一下大致可以這么分配左右兩條腿共用4個(gè)電機(jī)左右翅膀各2個(gè)、合計(jì)4個(gè)脖子和頭部轉(zhuǎn)動(dòng)2個(gè)尾巴上下或左右擺動(dòng)1個(gè)嘴巴開(kāi)合1個(gè)眼睛或眼皮活動(dòng)1到2個(gè)剩下2到3個(gè)可能會(huì)分配給身體前傾后仰或者內(nèi)部懸掛重心調(diào)節(jié)。每一路關(guān)節(jié)只要多一點(diǎn)自由度的組合整體看起來(lái)就會(huì)自然很多。不過(guò)真正難的不是數(shù)量而是如何在25cm的高度內(nèi)讓這些電機(jī)互不干涉并且整體重量不超。這需要設(shè)計(jì)者每一個(gè)電機(jī)都親自選型不能只圖力矩大。我見(jiàn)過(guò)不少人做的桌面機(jī)器人為了追求扭矩直接上20kg級(jí)別的金屬舵機(jī)結(jié)果整個(gè)設(shè)備動(dòng)起來(lái)和挖掘機(jī)一樣動(dòng)作遲滯還有很大的聲音。這個(gè)項(xiàng)目針對(duì)鴨子這種小型仿生對(duì)象電機(jī)選型應(yīng)該偏向小型金屬齒輪舵機(jī)扭矩?zé)o需太大關(guān)鍵是重量輕、反應(yīng)速度快。2.1 驅(qū)動(dòng)方案為什么不能全用RK3566 GPIO這里我想多聊一點(diǎn)硬件分工。RK3566運(yùn)行Linux系統(tǒng)Linux不是實(shí)時(shí)操作系統(tǒng)進(jìn)程調(diào)度可能隨時(shí)被中斷如果直接讓Linux內(nèi)核去控制PWM波形的起始結(jié)束時(shí)間一旦系統(tǒng)負(fù)載升高或者某個(gè)后臺(tái)進(jìn)程搶占了CPU電機(jī)控制就會(huì)出現(xiàn)明顯抖頓。對(duì)于鴨子這種需要連續(xù)平滑動(dòng)作的機(jī)器人來(lái)說(shuō)稍有卡頓就會(huì)原形畢露看起來(lái)一點(diǎn)都不自然。所以最合理的做法是給RK3566配一顆MCU協(xié)處理器專門(mén)負(fù)責(zé)生成15路PWM信號(hào)。RK3566通過(guò)USB或者UART與MCU通信。底層MCU內(nèi)部跑一個(gè)實(shí)時(shí)循環(huán)定時(shí)刷新每一路PWM的占空比。RK3566下發(fā)的指令不是原始PWM值而是目標(biāo)角度和運(yùn)動(dòng)時(shí)間。MCU自己負(fù)責(zé)將角度值插值成一條平滑的軌跡簡(jiǎn)單說(shuō)就是“規(guī)劃在Linux執(zhí)行在MCU”。這種分工既保證了控制帶寬又讓上層應(yīng)用可以專注于視覺(jué)、語(yǔ)音、路徑規(guī)劃等復(fù)雜任務(wù)。在這個(gè)項(xiàng)目中上層到下層之間的通信協(xié)議設(shè)計(jì)尤為關(guān)鍵。如果每幀只傳角度數(shù)據(jù)15路角度加上校驗(yàn)和數(shù)據(jù)量并不大串口115200波特率完全足夠。作者在倉(cāng)庫(kù)中定義了一套簡(jiǎn)潔的幀格式幀頭、指令類型、通道編號(hào)、目標(biāo)值、校驗(yàn)位一目了然。這種設(shè)計(jì)的好處是即使后續(xù)把鴨子換成貓、狗或者其他機(jī)器人形態(tài)這套通信協(xié)議依然可以復(fù)用。2.2 結(jié)構(gòu)件選材與減重細(xì)節(jié)800g以內(nèi)的裸機(jī)重量限制意味著結(jié)構(gòu)件不能全用鋁合金板或厚厚的亞克力否則光外殼和支架就要占掉一大半重量。更常見(jiàn)的做法是關(guān)鍵受力部位比如腿部關(guān)節(jié)和電機(jī)固定座使用PLA或者PETG材質(zhì)的3D打印件內(nèi)部填充率控制在20%到30%之間外殼部分用輕薄的ABS塑料片或者光固化打印的薄殼外面再做打磨與噴漆手感也不會(huì)差太多。同時(shí)還要注意重心的分布。25cm的小鴨子如果整個(gè)頭部塞了一堆攝像頭和麥克風(fēng)頭部比重過(guò)大站立時(shí)就會(huì)前傾。所以我在看項(xiàng)目圖的時(shí)候特意觀察了身體中后部是否預(yù)留了放電池的空間。把鋰電池和電機(jī)驅(qū)動(dòng)板放在胸腔偏后的位置可以有效壓低重心讓鴨子在站立狀態(tài)下的自穩(wěn)能力更強(qiáng)。別看這個(gè)細(xì)節(jié)小對(duì)多關(guān)節(jié)機(jī)器人的運(yùn)動(dòng)表現(xiàn)影響非常直接。重心高一點(diǎn)走起來(lái)就是搖搖晃晃像紙片人重心低一點(diǎn)動(dòng)作才能顯得扎實(shí)。3. 軟件怎么讓這只鴨子“活”起來(lái)如果說(shuō)硬件是骨肉那軟件就是靈魂。這個(gè)項(xiàng)目讓我覺(jué)得很有學(xué)習(xí)價(jià)值的地方不只是結(jié)構(gòu)設(shè)計(jì)而是它的軟件架構(gòu)并沒(méi)有走捷徑。作者沒(méi)有簡(jiǎn)單寫(xiě)一個(gè)跑馬燈程序讓鴨子按順序動(dòng)關(guān)節(jié)而是把姿態(tài)生成、動(dòng)作插值、指令下發(fā)、反饋修正這幾層分得很清楚。3.1 步態(tài)控制從四足退化到雙足的策略鴨子走路和人類走路有本質(zhì)區(qū)別人走路時(shí)軀干基本保持豎直靠雙腿交替向前擺動(dòng)鴨子走路時(shí)軀干會(huì)左右搖擺走路步伐比我們想象的更依賴重心轉(zhuǎn)移。作者首先在計(jì)算機(jī)上建了一個(gè)簡(jiǎn)化模型把鴨子簡(jiǎn)化為一個(gè)軀干加兩條腿和兩個(gè)翅膀的剛體系統(tǒng)先仿真重心位置隨時(shí)間的變化再把仿真的軌跡輸出為每個(gè)電機(jī)角度的變化曲線。初始版本的步態(tài)代碼大概率是離線生成的也就是預(yù)先算好一組“走一步”的關(guān)節(jié)角度序列然后存成表。這樣做的優(yōu)點(diǎn)是控制簡(jiǎn)單、開(kāi)發(fā)難度低缺點(diǎn)是非常死板遇到地面不平或者被推一下就很難恢復(fù)平衡??磦}(cāng)庫(kù)更新記錄作者后期加了簡(jiǎn)單的姿態(tài)反饋比如在軀干上裝了一個(gè)IMU慣性測(cè)量單元讀取鴨子的俯仰和橫滾角然后對(duì)步伐周期或關(guān)節(jié)角度做小幅補(bǔ)償。這種做法在機(jī)器人領(lǐng)域叫“開(kāi)環(huán)步態(tài)閉環(huán)穩(wěn)定修正”比純開(kāi)環(huán)進(jìn)了一大步但又不至于引入復(fù)雜的模型預(yù)測(cè)控制非常適合這個(gè)體積級(jí)別的機(jī)器人項(xiàng)目。如果你也想復(fù)刻一只類似的仿生機(jī)器人我建議第一版不用急著做動(dòng)態(tài)平衡先把開(kāi)環(huán)步態(tài)調(diào)自然讓鴨子能平穩(wěn)走兩米不摔跤再考慮要不要引入IMU做閉環(huán)。一上來(lái)就上全狀態(tài)反饋控制大概率會(huì)被非線性摩擦和舵機(jī)響應(yīng)延遲搞到頭大。3.2 動(dòng)作層與邏輯層的解耦我特別注意到項(xiàng)目里有一個(gè)行為狀態(tài)機(jī)的概念作者它的實(shí)現(xiàn)不算復(fù)雜但足夠靈活。比如當(dāng)鴨子檢測(cè)到面前有障礙物時(shí)狀態(tài)機(jī)會(huì)從“閑逛”切換到“觀察”觀察狀態(tài)下會(huì)調(diào)用一組頭部和眼部的電機(jī)組合動(dòng)作然后再?zèng)Q定是轉(zhuǎn)向還是后退。這些狀態(tài)之間的切換是通過(guò)在Linux側(cè)跑一個(gè)輕量級(jí)的事件循環(huán)來(lái)實(shí)現(xiàn)的每隔幾十毫秒讀取一次傳感器數(shù)據(jù)判斷當(dāng)前狀態(tài)再生成對(duì)應(yīng)的動(dòng)作指令隊(duì)列。做這個(gè)設(shè)計(jì)的時(shí)候作者沒(méi)有把傳感器數(shù)據(jù)處理和電機(jī)動(dòng)作邏輯混在同一個(gè)模塊里。傳感器數(shù)據(jù)統(tǒng)一發(fā)布到消息隊(duì)列動(dòng)作模塊只訂閱結(jié)果。這種思路和機(jī)器人的發(fā)布訂閱范式很像雖然在高算力平臺(tái)上有更復(fù)雜的通信框架可以用但在這只鴨子上用只有幾千行的純代碼實(shí)現(xiàn)反而能保證系統(tǒng)的確定性和低延遲我覺(jué)得這就是嵌入式項(xiàng)目中“好鋼用在刀刃上”的體現(xiàn)。3.3 PID調(diào)節(jié)與實(shí)時(shí)性驗(yàn)證雖然底層MCU負(fù)責(zé)了PWM輸出但15個(gè)電機(jī)的角度閉環(huán)仍然需要處理。常見(jiàn)的舵機(jī)內(nèi)部帶有電位器反饋可以近似看作一個(gè)位置閉環(huán)系統(tǒng)但它的動(dòng)態(tài)響應(yīng)是固定的我們不能直接調(diào)PID。為了避免舵機(jī)之間響應(yīng)速度不一致導(dǎo)致的動(dòng)作畸形作者在MCU層面加入了統(tǒng)一的速度規(guī)劃意思是每個(gè)動(dòng)作指令都附帶一個(gè)期望運(yùn)動(dòng)時(shí)間MCU不直接把目標(biāo)角度一步到位而是將它拆分成許多小步進(jìn)按固定的時(shí)間間隔逐步逼近目標(biāo)值。這種做法相當(dāng)于在外部加了一層控制環(huán)能有效抹平不同舵機(jī)的個(gè)體差異。在調(diào)試時(shí)作者用了一套簡(jiǎn)單的可視化工具把15路電機(jī)的目標(biāo)角度和實(shí)際反饋角度實(shí)時(shí)繪制成曲線類似邏輯分析儀抓波形那樣。打開(kāi)開(kāi)關(guān)后鴨子每次做動(dòng)作曲線都會(huì)立即反映有沒(méi)有過(guò)沖或者滯后。如果你自己復(fù)刻也可以在串口上每隔20ms輸出一組角度值然后用常用的串口繪圖工具來(lái)看曲線不用專門(mén)去買(mǎi)顯示屏。這樣一套流程下來(lái)對(duì)PID或者速度曲線參數(shù)該怎么調(diào)心里會(huì)非常清楚。4. 供電系統(tǒng)800克極限里的最后一公里很多小型機(jī)器人項(xiàng)目會(huì)在機(jī)械結(jié)構(gòu)和代碼上花盡心思卻在供電上翻車(chē)。相信我80%的“為什么一通電就重啟”“為什么電機(jī)一動(dòng)作屏幕就閃爍”的問(wèn)題最后都能追溯到供電系統(tǒng)設(shè)計(jì)不合理。這只鴨子的供電設(shè)計(jì)雖然沒(méi)有采用特別高端的方案但在小型化、輕量化方面有不少值得抄作業(yè)的地方。4.1 電池選型與安裝位置在800g的限重里電池必須精打細(xì)算。目前常見(jiàn)的2S鋰電池單顆重量大約在80g到120g之間容量在800mAh到1500mAh左右??紤]到RK3566在跑Linux時(shí)峰值功耗可能達(dá)到5W以上加上15個(gè)電機(jī)的平均功耗整機(jī)平均功率大概在15W到25W之間待機(jī)時(shí)可以低一些但跑動(dòng)作時(shí)瞬間功耗會(huì)波動(dòng)較大。如果用2S電池7.4V供電1500mAh的容量理論上可以提供11Wh左右的能量但實(shí)際可用容量要打折大概夠這只鴨子連續(xù)活躍運(yùn)行30到50分鐘。電池的安裝位置也很講究。很多復(fù)刻者會(huì)順手把電池放在鴨子肚子正中間看著挺穩(wěn)實(shí)際上走路時(shí)重心在身體中部會(huì)晃動(dòng)。這個(gè)項(xiàng)目更合理的做法是把電池盡量放在身體重心偏下的位置甚至可以把電池平放在腹部靠近腿部的位置讓轉(zhuǎn)動(dòng)慣量更小動(dòng)作響應(yīng)更敏捷。還有一點(diǎn)要注意電池與主板之間必須用帶自鎖的XH2.54或者XT30接插件千萬(wàn)不能用杜邦線直接懟在電池上否則大幅度動(dòng)作時(shí)線頭松脫引發(fā)斷電輕則重啟重則飛線短路。4.2 電機(jī)瞬時(shí)電流與壓降15個(gè)電機(jī)同時(shí)啟動(dòng)瞬間的電流總和相當(dāng)可觀。小型舵機(jī)堵轉(zhuǎn)電流可以達(dá)到1A以上即便正常轉(zhuǎn)動(dòng)時(shí)平均電流只有200到400mA15個(gè)一起動(dòng)也可能在瞬間拉到5到8A。如果電源提供的電流能力不足或者線纜內(nèi)阻過(guò)大電壓就會(huì)被瞬間拉低導(dǎo)致RK3566在低電壓下觸發(fā)上電復(fù)位整個(gè)系統(tǒng)直接重啟。為了應(yīng)對(duì)這個(gè)問(wèn)題常見(jiàn)的方案是加一個(gè)大容量的穩(wěn)壓電容比如在電源入口并聯(lián)2到3個(gè)470uF到1000uF的電解電容或者用一個(gè)超級(jí)電容模塊來(lái)吸收電流尖峰。電容不能解決所有問(wèn)題但可以明顯緩解瞬時(shí)壓降。更好的方案是隔離供電把RK3566和電機(jī)驅(qū)動(dòng)模塊分別用獨(dú)立的DC-DC降壓電路電機(jī)電源直接從電池獲取主控電源經(jīng)過(guò)一顆5V的LDO或者DC-DC來(lái)穩(wěn)壓。這樣即使電機(jī)把電壓拉得很低只要不低于主控電路的最低輸入電壓Linux系統(tǒng)就不會(huì)崩。另外選用輸出電流足夠的大功率穩(wěn)壓芯片也很重要。RK3566本身需要多路供電但通常開(kāi)發(fā)板上已經(jīng)集成了電源管理芯片外部只需要給它提供一路5V或12V即可。如果在自制底板時(shí)復(fù)用PMIC參考設(shè)計(jì)要特別留意每路電源的紋波抑制尤其是在電機(jī)啟動(dòng)瞬間的電磁干擾下電源紋波可能變得很臟。這時(shí)候可以用示波器去抓一下各路電源的電壓毛刺如果發(fā)現(xiàn)有超過(guò)200mV的尖峰就需要在布局上減少電機(jī)線與電源線的平行走線或加LC濾波。4.3 電源管理休眠與喚醒嵌入式Linux項(xiàng)目的另外一個(gè)容易被忽略的點(diǎn)是低功耗管理。鴨子不可能一直滿負(fù)荷工作長(zhǎng)時(shí)間待機(jī)時(shí)如果電機(jī)驅(qū)動(dòng)板和主控一起通電電會(huì)掉得飛快。較好的做法是在不活動(dòng)時(shí)讓RK3566進(jìn)入淺休眠狀態(tài)或降頻模式同時(shí)下位機(jī)MCU也進(jìn)入低功耗睡眠只保留一個(gè)定時(shí)喚醒的周期或者紅外觸發(fā)器。一旦檢測(cè)到有人靠近或用手拍它MCU立刻喚醒RK3566完成重啟或快速恢復(fù)。這個(gè)項(xiàng)目在喚醒策略上做得比較務(wù)實(shí)因?yàn)镽K3566從深度睡眠中喚醒的延遲比較明顯如果每次喚醒都要等Linux系統(tǒng)完整重啟用戶體驗(yàn)會(huì)非常糟糕。更合適的是讓系統(tǒng)在空閑時(shí)掛起一部分外設(shè)保留內(nèi)核在內(nèi)存中運(yùn)行類似鼠標(biāo)移動(dòng)喚醒電腦那樣從淺睡眠快速恢復(fù)。在嵌入式Linux下可以通過(guò)內(nèi)核的suspend到內(nèi)存與RTC鬧鐘喚醒來(lái)實(shí)現(xiàn)結(jié)合GPIO外部中斷也可以做到。但要留意并非所有底層驅(qū)動(dòng)都支持suspend/resume如果發(fā)現(xiàn)喚醒后傳感器或藍(lán)牙模塊異常那就要根據(jù)自己的外設(shè)情況做狀態(tài)恢復(fù)處理。5. 從0到1復(fù)刻一只鴨子流程與建議如果你看完前面這些內(nèi)容已經(jīng)心癢難耐想自己也做一只鴨子那我基于對(duì)項(xiàng)目的理解幫你梳理一下從開(kāi)始的復(fù)刻流程。整個(gè)過(guò)程大概分硬件準(zhǔn)備、結(jié)構(gòu)裝配、軟件調(diào)試三大塊中間會(huì)有不少在你沒(méi)實(shí)際動(dòng)手前根本想不到的坑。5.1 硬件采購(gòu)哪些必須買(mǎi)好的哪些可以平替核心主控板建議直接選擇現(xiàn)成的RK3566開(kāi)發(fā)板體積盡量選緊湊型最好是核心板底板的形式。市面上常見(jiàn)的RK3566核心板尺寸通常只有幾十毫米見(jiàn)方重量也不大非常適合塞進(jìn)鴨子身體。底板可以自己畫(huà)也可以選用官方設(shè)計(jì)的通用底板但要注意底板的大小和接口方向是否影響安裝在鴨子的內(nèi)部骨架里。電機(jī)部分關(guān)鍵參數(shù)是扭矩、尺寸和重量。15個(gè)電機(jī)里腿部受力最大的位置需要扭矩大一些至少選2.5kg/cm以上的金屬舵機(jī)尾部和嘴巴這種輕微活動(dòng)的位置用1.3kg/cm的塑料齒輪舵機(jī)就夠了。盡量統(tǒng)一電機(jī)驅(qū)動(dòng)信號(hào)線和電源線的接口免得裝好后分不清哪個(gè)是哪路。在預(yù)算允許的情況下買(mǎi)帶金屬輸出軸的舵機(jī)比塑料軸耐用很多尤其是鴨子走路時(shí)腳的沖擊會(huì)反復(fù)傳導(dǎo)到舵機(jī)輸出軸塑料軸很容易被打滑。結(jié)構(gòu)件要么直接用倉(cāng)庫(kù)里的3D打印文件要么自己畫(huà)適配的板件。如果你沒(méi)有3D打印機(jī)可以在網(wǎng)上找代打印服務(wù)PLA材料就夠價(jià)格也不高。需要注意的是打印時(shí)的層高和填充率不要太低否則螺柱位置容易裂開(kāi)。組裝時(shí)不要急著上螺絲卡死建議先用手捏住相關(guān)關(guān)節(jié)試一下轉(zhuǎn)動(dòng)角度是否被干涉。5.2 軟件編譯與系統(tǒng)燒錄RK3566跑的主系統(tǒng)大概率是某個(gè)定制化的Linux鏡像作者可能基于Buildroot或者Debian裁剪。作為復(fù)刻者你需要先在電腦上克隆源碼倉(cāng)庫(kù)然后安裝交叉編譯工具鏈。這里的坑通常出現(xiàn)在環(huán)境依賴上不同Ubuntu版本對(duì)老版本工具鏈的兼容性不一樣如果你在編譯過(guò)程中遇到莫名其妙的頭文件找不到建議直接用倉(cāng)庫(kù)文檔推薦的Docker鏡像或者指定發(fā)行版版本能省掉大量時(shí)間。燒錄系統(tǒng)時(shí)最好用支持USB燒錄的開(kāi)發(fā)板工具或者按官方教程制作一張快速啟動(dòng)的SD卡。第一次啟動(dòng)往往顯示不出畫(huà)面或者串口日志里卡在某一段這時(shí)候不要慌先把串口調(diào)試線接好看內(nèi)核日志結(jié)束在哪里再查對(duì)應(yīng)外設(shè)的驅(qū)動(dòng)配置。我自己的經(jīng)驗(yàn)是很多人做這類Linux單板機(jī)器人最后卡住的不是代碼邏輯而是某個(gè)外設(shè)的設(shè)備樹(shù)配置沒(méi)有打開(kāi)。比如某個(gè)舵機(jī)驅(qū)動(dòng)板掛在I2C總線上設(shè)備樹(shù)里沒(méi)定義對(duì)應(yīng)地址和節(jié)點(diǎn)系統(tǒng)就永遠(yuǎn)掃不到設(shè)備電機(jī)自然一動(dòng)不動(dòng)。5.3 常見(jiàn)問(wèn)題與排查思路根據(jù)我踩過(guò)類似項(xiàng)目坑的經(jīng)驗(yàn)幾個(gè)高頻問(wèn)題你一定要提前有數(shù)。第一上電后RK3566反復(fù)重啟大概率是電源電壓跌落導(dǎo)致。先不要查軟件拿萬(wàn)用表量電機(jī)啟動(dòng)瞬間的供電電壓如果掉到4.5V以下趕緊加大電容或改隔離供電。第二多個(gè)舵機(jī)之間互相串?dāng)_比如轉(zhuǎn)動(dòng)腿的時(shí)候翅膀也跟著抖。這通常不是電機(jī)的機(jī)械問(wèn)題而是PWM信號(hào)線上有電源干擾或者是舵機(jī)電源回流到了主控板的地線??梢試L試在電機(jī)電源和主控電源之間加共地電感或把舵機(jī)信號(hào)線用雙絞線繞一下。第三手臂或者腿的動(dòng)作反了。如果你發(fā)現(xiàn)鴨子在調(diào)姿時(shí)越調(diào)越亂那就先檢查一下輸入到每個(gè)舵機(jī)的角度極性。很多舵機(jī)支持正向和反向安裝同樣給50%的占空比轉(zhuǎn)動(dòng)方向可能完全相反。調(diào)試時(shí)不要一張嘴就改程序先用上位機(jī)單獨(dú)控制某一通道確認(rèn)正方向后再在代碼里把偏移量記下來(lái)。第四IMU數(shù)據(jù)抖動(dòng)導(dǎo)致姿態(tài)誤判。在步態(tài)閉環(huán)修正中如果IMU的數(shù)據(jù)沒(méi)有經(jīng)過(guò)濾波加速度計(jì)的震動(dòng)噪聲會(huì)讓鴨子誤以為自己傾斜了從而做出奇怪的補(bǔ)償動(dòng)作。建議先用低通濾波或簡(jiǎn)單的互補(bǔ)濾波把分軸的角度算平滑再送給狀態(tài)機(jī)。6. 我從中得到的幾條經(jīng)驗(yàn)這個(gè)項(xiàng)目最讓我有收獲的不是RK3566有多強(qiáng)也不是15個(gè)電機(jī)有多炫而是它在產(chǎn)品化思維上的平衡術(shù)。做一個(gè)能動(dòng)的鴨子不難做一個(gè)能穩(wěn)定走、能交互、還不超重的鴨子難的是每一個(gè)環(huán)節(jié)都做到剛剛好用。我最贊同的一點(diǎn)是它對(duì)通信協(xié)議和狀態(tài)機(jī)的簡(jiǎn)化。很多開(kāi)發(fā)者看到一個(gè)機(jī)器人有15個(gè)電機(jī)第一反應(yīng)就是上ROS、寫(xiě)各種復(fù)雜節(jié)點(diǎn)但實(shí)際效果未必比一個(gè)幾KB狀態(tài)機(jī)好。這個(gè)項(xiàng)目讓我重新意識(shí)到嵌入式項(xiàng)目的核心不在于用多前沿的框架而在于搞懂每一層之間傳遞什么數(shù)據(jù)、什么時(shí)候傳遞、缺失了怎么辦。通信幀短小、狀態(tài)清晰、反饋及時(shí)比堆砌一堆抽象層有用得多。如果你只是想體驗(yàn)一下做小型機(jī)器人的樂(lè)趣不一定要完全復(fù)刻這只鴨子。你可以先拆出它的結(jié)構(gòu)設(shè)計(jì)思路用一塊更便宜的開(kāi)發(fā)板加4到6個(gè)舵機(jī)做一個(gè)只會(huì)點(diǎn)頭的小鳥(niǎo)機(jī)器人。等你理解了一個(gè)動(dòng)作從規(guī)劃到執(zhí)行的完整鏈路再回來(lái)挑戰(zhàn)15個(gè)電機(jī)的鴨子和RK3566就會(huì)發(fā)現(xiàn)難度沒(méi)有想象中那么高。我始終覺(jué)得這種“小體量、高集成”的項(xiàng)目才是讓嵌入式愛(ài)好者成長(zhǎng)最快的東西。