習(xí)機器人完整部署指南)
Microduck 是那種第一眼看上去像玩具、實際玩法很深的 25cm 級強化學(xué)習(xí)機器人。我手頭這臺從英偉達(dá) GPU 上的仿真訓(xùn)練開始最終讓它跑在 RK3566 實機上中間橫跨了強化學(xué)習(xí)算法調(diào)試、模型導(dǎo)出、邊緣端部署、電機驅(qū)動和一堆本該避免但繞不開的坑。這篇文章就記錄整個部署過程適合正在折騰 Microduck 的玩家、準(zhǔn)備把強化學(xué)習(xí)策略從 PC 搬到嵌入式平臺的研究生或工程師也適合只想知道 RK3566 這類開發(fā)板到底能不能跑強化學(xué)習(xí)策略的朋友。1. 項目背景與整體方案選型1.1 Microduck 是什么25cm 尺寸帶來的設(shè)計約束Microduck 是一個開源的小型強化學(xué)習(xí)機器人項目整體尺寸只有 25cm 級別常見的說法也叫它“玩具尺寸四足”或者“桌面級足式機器人”。體積小帶來的好處是場地要求低、危險系數(shù)低可以在桌面上直接做實驗但代價也很明顯可用電池容量小電機扭矩小主控板尺寸小散熱條件差。這就直接決定了你在選主控芯片、電機驅(qū)動、通信總線的時候不能照著大型機器人的思路來。很多玩機器人的人一上來就想著用高性能工控機或者 Jetson Orin 這類平臺做端側(cè)推理但 Microduck 這種尺寸根本塞不下這么大的板子功耗也不現(xiàn)實。我最初試過用 Jetson Nano 做推理平臺結(jié)果電池掉電速度驚人而且發(fā)熱嚴(yán)重最后只能放棄。真正適合這種體積的是一塊像 RK3566 這種小尺寸、低功耗、帶一點點 NPU 算力的核心板。25cm 尺寸還有一個隱含約束結(jié)構(gòu)件大多是 3D 打印的重量控制不嚴(yán)格轉(zhuǎn)動慣量分布不均勻。這意味著你在 GPU 仿真環(huán)境里練出來的策略如果不在仿真階段做好域隨機化到了實機上大概率站都站不穩(wěn)。所以這個尺寸的機器人項目反而是對“仿真到實機遷移”要求最嚴(yán)苛的一類。1.2 為什么選擇英偉達(dá) GPU RK3566 這套組合訓(xùn)練端選擇英偉達(dá) GPU不需要太多解釋。強化學(xué)習(xí)尤其是 PPO 這類策略梯度算法動輒需要跑幾十萬到幾百萬個 step沒有 GPU 加速的 Isaac Gym 或 MuJoCo光靠 CPU 仿真訓(xùn)練一個能走的四足策略可能要幾天甚至一周根本沒法迭代。用 RTX 4090 這類消費級卡配合 GPU 版仿真器能把訓(xùn)練時間壓縮到幾小時這就是選英偉達(dá) GPU 的核心原因。部署端選擇 RK3566則是從成本、功耗、算力三個維度權(quán)衡的結(jié)果。RK3566 是瑞芯微推出的一款四核 Cortex-A55 處理器帶 0.6TOPS 左右的 NPU功耗通常能做到一兩瓦左右板子也夠小非常契合 Microduck 的限制條件。很多人會糾結(jié)它算力不如樹莓派 5但實際做部署時你會發(fā)現(xiàn)強化學(xué)習(xí)策略網(wǎng)絡(luò)往往是一個很小的 MLP多層感知機幾百到一兩千個參數(shù)CPU 跑也只要幾毫秒NPU 反而不是重點。真正的問題是 RK3566 上的軟件生態(tài)、系統(tǒng)鏡像、外設(shè)接口是否穩(wěn)定可靠這才是我選擇它之后花大量時間踩坑的地方。所以整套鏈路用一句話總結(jié)英偉達(dá) GPU 負(fù)責(zé)把策略訓(xùn)出來RK3566 負(fù)責(zé)把策略跑起來中間通過模型導(dǎo)出和推理框架把兩者連接起來。1.3 完整部署鏈路概覽在動工之前我先在紙上把整條鏈路畫了一遍避免做到一半才發(fā)現(xiàn)方案不閉環(huán)。我的最終鏈路是在 PC 上用 GPU 仿真環(huán)境MuJoCo 或 Isaac Gym構(gòu)建 Microduck 的四足動力學(xué)模型。用 PPO 或其變體算法訓(xùn)練控制策略同時設(shè)計獎勵函數(shù)增加域隨機化。訓(xùn)練完成后把 PyTorch 權(quán)重導(dǎo)出為 ONNX 格式。對 ONNX 模型做精簡去掉不必要的算子適配邊緣端推理框架。在 RK3566 上部署推理代碼接好電機驅(qū)動通過串口或者總線把動作指令下發(fā)到電機模塊。實機調(diào)試修正關(guān)節(jié)方向、控制頻率、延時補償?shù)葐栴}。這條鏈路本身不算復(fù)雜但每一步都有不少隱藏問題。尤其是從第 4 步到第 6 步很多做算法的人不太熟悉硬件側(cè)的操作很容易卡住。后面我會按這個順序把每個階段的實操細(xì)節(jié)拆開來講。2. 強化學(xué)習(xí)訓(xùn)練階段的關(guān)鍵環(huán)節(jié)2.1 訓(xùn)練環(huán)境搭建從 MuJoCo 到 Isaac Gym 的選擇我在訓(xùn)練階段先用了 MuJoCo因為它的物理引擎精度高而且完全免費開源社區(qū)里也有不少四足機器人模型可以直接導(dǎo)入。但真正開始大規(guī)模并行采樣時我發(fā)現(xiàn) MuJoCo 的 GPU 加速能力在配置上有點繁瑣雖然它支持 GPU 批量仿真但對一個剛開始接觸這個項目的人來說還是有點門檻。后面我換了 Isaac Gym這個環(huán)境最大的優(yōu)勢是可以直接在 GPU 上大規(guī)模并行多個機器人實例一次性采樣幾千個環(huán)境訓(xùn)練效率比單環(huán)境仿真高很多。Microduck 這種 25cm 小機器人在 Isaac Gym 里可以同時跑幾千個實例配合 RTX 4090 的話訓(xùn)練一個能穩(wěn)定行走的 PPO 策略大概只需要一兩個小時到半天具體取決于獎勵函數(shù)設(shè)計得有多復(fù)雜。當(dāng)然 Isaac Gym 也有缺點。首先它的官方支持已經(jīng)逐步轉(zhuǎn)向新的 Isaac Lab 框架舊版環(huán)境安裝時和 CUDA、PyTorch 版本的兼容性問題比較多其次在 Isaac Gym 里要精確復(fù)現(xiàn) Microduck 的物理尺寸、電機特性、關(guān)節(jié)阻尼需要自己調(diào)整模型參數(shù)并不是導(dǎo)入一個 URDF 就萬事大吉。如果你和我一樣用的是社區(qū)里現(xiàn)成的 Microduck 模型文件一定要檢查關(guān)節(jié)角度的正負(fù)方向以及電機最大扭矩是否和實機一致。我的建議是如果你只想快速驗證控制邏輯用 MuJoCo 就夠了如果你要大量訓(xùn)練、頻繁迭代策略直接上 Isaac Gym 或 Isaac Lab別猶豫。2.2 狀態(tài)空間、動作空間與獎勵設(shè)計錯誤獎勵的處理很多人第一次訓(xùn)練強化學(xué)習(xí)機器人時失敗的原因不在算法而在狀態(tài)空間和動作空間定義不合理。Microduck 這種四足機器人我最開始用的狀態(tài)向量是機身線速度3 維、角速度3 維機身朝向的四元數(shù)4 維四條腿的關(guān)節(jié)角度假設(shè)每條腿 3 個電機共 12 維關(guān)節(jié)角速度12 維上一個動作12 維這樣加起來大概 46 維對于 MLP 策略網(wǎng)絡(luò)來說完全夠用。動作空間是 12 維的關(guān)節(jié)目標(biāo)位置也就是每個電機期望轉(zhuǎn)到哪個角度具體的力矩由底層的 PID 控制器去實現(xiàn)。這里有一個很關(guān)鍵的設(shè)計思路強化學(xué)習(xí)策略不直接輸出電流或力矩而是輸出目標(biāo)位置由電機驅(qū)動板自帶的 PID 閉環(huán)去跟蹤。這樣做的好處是策略在高層面做邏輯決策底層的力控制和頻率控制交給更可靠的嵌入式系統(tǒng)去處理可以避免策略在完全沒有約束的情況下輸出極端的力矩指令導(dǎo)致電機過載。熱詞里提到“基于強化學(xué)習(xí)的 PID 控制”其實就是這個方向的一個變體你可以讓強化學(xué)習(xí)實時調(diào)節(jié) PID 參數(shù)也可以讓強化學(xué)習(xí)輸出目標(biāo)軌跡PID 去跟蹤兩種方式都有人在用。獎勵設(shè)計是訓(xùn)練階段最容易踩坑的地方尤其是熱詞里提到的“強化學(xué)習(xí)遇到錯誤獎勵”。我在 Microduck 項目里遇到過兩次比較典型的錯誤獎勵問題。第一次是獎勵項數(shù)值量級失衡我把前進(jìn)速度獎勵設(shè)成 1.0而朝向一致性的懲罰只有 0.01結(jié)果訓(xùn)練出來的策略瘋狂亂跑即使方向偏離很大也能獲得高總獎勵。第二次是稀疏獎勵陷阱能量懲罰設(shè)置得太重策略干脆待著不動因為任何動作都會增加能量消耗不動反而能拿到更高的累計獎勵。處理錯誤獎勵的核心思路是每次只檢查單一獎勵項的貢獻(xiàn)而不是只看總獎勵曲線。我會在訓(xùn)練時把各個獎勵分量單獨記錄成日志觀察前進(jìn)速度分量是否正常上升、電能懲罰是否失控、朝向誤差是否有收斂趨勢。如果某個分量始終抖動劇烈多半就是該項的系數(shù)太高或者目標(biāo)函數(shù)和策略行為之間存在沖突。實踐中比較好用的做法是先用簡單獎勵跑通比如只給前進(jìn)速度獎勵和存活獎勵跑一個能走但姿勢怪異的策略再逐步加上姿態(tài)穩(wěn)定性、能耗項、關(guān)節(jié)限位懲罰。2.3 從仿真到實機的域隨機化Microduck 這類小機器人實機部署最大的敵人是仿真環(huán)境和真實物理環(huán)境的差異。我在仿真里跑得再漂亮拿到實機上一開機大多數(shù)情況是原地抽搐、翻車、甚至直接把電機堵轉(zhuǎn)。原因無外乎摩擦系數(shù)不一樣、重心位置有偏差、電機響應(yīng)延遲高、關(guān)節(jié)阻尼不匹配。域隨機化是目前解決這個問題最實用、也最容易落地的手段。我的具體做法是在每一次環(huán)境重置的時候隨機化機身質(zhì)量、質(zhì)心偏移、腿部摩擦系數(shù)、關(guān)節(jié)阻尼、電機扭矩上限、控制延時這幾個參數(shù)隨機區(qū)間大概設(shè)置在機器人真實參數(shù)的百分之二十左右。比如 Microduck 的實際重量是 0.6kg我就在 0.5kg 到 0.7kg 之間隨機采樣。這里要特別提醒一點控制延時是一個很容易被忽略但影響巨大的隨機化參數(shù)。實機從讀取傳感器到真正驅(qū)動電機整個鏈路通常有幾十毫秒的延遲如果你的訓(xùn)練環(huán)境里沒有加延時模擬策略就會對動作效果產(chǎn)生錯誤的時序關(guān)聯(lián)推斷。我的做法是在訓(xùn)練環(huán)境的每一步里隨機插入 10 到 50 毫秒的延遲讓策略學(xué)會在不確定性下保持穩(wěn)定這樣實機部署時策略的魯棒性會好很多。2.4 GPU 訓(xùn)練中的算力配置與超參數(shù)訓(xùn)練超參數(shù)這一塊我直接說我在 Microduck 項目里用到的、實測有效的配置。PPO 算法actor 網(wǎng)絡(luò)和 critic 網(wǎng)絡(luò)都是兩層 MLP每層 256 個神經(jīng)元激活函數(shù)用 ReLU。學(xué)習(xí)率初始為 3e-4訓(xùn)練過程中逐步衰減到 3e-5。batch size 設(shè)為 2048minibatch 為 128clip 參數(shù) 0.2GAE 的 lambda 取 0.95折扣因子 gamma 取 0.99。在 Isaac Gym 里我同時跑 4096 個環(huán)境實例每個實例都是獨立的 Microduck 機器人用 RTX 4090 訓(xùn)練時單次迭代差不多需要 2 到 3 秒。通常跑到 3000 到 5000 步迭代時策略已經(jīng)能走出比較像樣的步態(tài)總體訓(xùn)練時間大概在一到三個小時取決于你是否同時做大量的域隨機化。要注意的是訓(xùn)練日志最好每 50 次迭代就記錄一次到本地避免中途崩潰丟了全部進(jìn)度。3. 模型導(dǎo)出與邊緣端適配3.1 從 PyTorch 模型到 ONNX / RKNN 的轉(zhuǎn)換流程訓(xùn)練完成后你手里的是一組 PyTorch 的權(quán)重。這時候不能直接把權(quán)重丟給 RK3566因為嵌入式端大概率不會裝完整的 PyTorch更常見的是用 ONNX Runtime 或者 RKNN 工具鏈做推理。我的第一步是把 actor 網(wǎng)絡(luò)單獨提取出來保存成 ONNX 格式。轉(zhuǎn)換過程沒那么玄乎核心代碼如下import torch import torch.nn as nn class Actor(nn.Module): def __init__(self, obs_dim, act_dim): super().__init__() self.net nn.Sequential( nn.Linear(obs_dim, 256), nn.ReLU(), nn.Linear(256, 256), nn.ReLU(), nn.Linear(256, act_dim), nn.Tanh() ) def forward(self, obs): return self.net(obs) actor Actor(obs_dim46, act_dim12) actor.load_state_dict(torch.load(microduck_actor.pth)) actor.eval() dummy_input torch.randn(1, 46) torch.onnx.export( actor, dummy_input, microduck_actor.onnx, input_names[obs], output_names[action], dynamic_axes{obs: {0: batch_size}, action: {0: batch_size}}, opset_version12 )這里我把輸入輸出動態(tài) batch 打開了方便在板端推理時每次只輸入一個樣本。opset_version 建議選 11 到 13 之間太高的版本有些嵌入式推理框架支持不完整。導(dǎo)出后用onnx.checker.check_model驗證一下整體結(jié)構(gòu)再打印一遍網(wǎng)絡(luò)層確認(rèn)沒有出現(xiàn)奇怪的算子。如果執(zhí)意要用 RK3566 的 NPU那么接下來還需要用 RKNN-Toolkit2 把 ONNX 模型轉(zhuǎn)成 RKNN 格式。這個過程我踩過一個明顯的坑rknn-toolkit2 的版本必須和開發(fā)板上運行的 RKNPU 驅(qū)動版本對齊否則轉(zhuǎn)換出來的模型在板上加載時會出現(xiàn)版本不匹配的報錯。我最后用的是 rknn-toolkit2 1.6.0 配合板端 1.6 驅(qū)動才穩(wěn)定跑起來。3.2 RK3566 硬件資源限制下的量化與算子裁剪RK3566 的 NPU 理論算力有 0.6TOPS聽起來還能用但實際上它支持的算子種類有限尤其是一些動態(tài)形狀、循環(huán)、稀疏操作很可能會出現(xiàn)轉(zhuǎn)換失敗。好在一個 MLP 策略網(wǎng)絡(luò)只有全連接層、ReLU、Tanh 這類基礎(chǔ)算子算是在 RKNN 支持的范圍內(nèi)所以轉(zhuǎn)換成功率還算高。不過這里有一個非?,F(xiàn)實的問題量化。RK3566 的 NPU 對浮點模型直接支持有限更常見的是轉(zhuǎn)成 INT8 定點運算。我在量化后先小范圍測試了一下理論上 INT8 量化對 MLP 這種小網(wǎng)絡(luò)的影響應(yīng)該很小但實測下來量化后的策略在實機上偶爾會出現(xiàn)關(guān)節(jié)方向微小抖動后續(xù)排查是 tanh 輸出層的數(shù)值精度有損失導(dǎo)致策略輸出和原始浮點版本有輕微偏差。解決辦法是盡量保留輸出層為浮點層或者讓 actor 網(wǎng)絡(luò)輸出之前接一個線性層不強制走 INT8 量化。如果你和我一樣最終決定用 CPU 跑 ONNX Runtime那可以完全避開量化的問題。對于 Microduck 的運動控制頻率常用的控制循環(huán)是 50Hz 到 100Hz也就是說每 10 到 20 毫秒要跑一次推理。這個 MLP 網(wǎng)絡(luò)在 RK3566 的四個 A55 內(nèi)核上單次推理只需要 2 到 5 毫秒CPU 完全跑得動NPU 反而不一定更穩(wěn)。由此可見“必須用 NPU”是很多人對嵌入式 AI 的誤解。在 RK3566 上部署強化學(xué)習(xí)策略最重要的評估指標(biāo)是端到端延遲是否滿足控制頻率而不是硬件上有沒有 NPU。如果 CPU 能滿足實時性優(yōu)先用 CPU 推理能省去大量算子兼容性調(diào)試時間。3.3 推理框架選型ONNX Runtime CPU 還是 RKNN我在 RK3566 上對比過兩張方案ONNX RuntimeCPU和 RKNNNPU。ONNX Runtime 的優(yōu)勢是部署簡單直接安裝 prebuilt wheel 就能跑不依賴 NPU 驅(qū)動而且對 PyTorch 導(dǎo)出的 ONNX 模型兼容性好。缺點是占用的內(nèi)存稍微多一點但 Microduck 控制程序本身很小完全沒問題。如果走 RKNN 通道最大的優(yōu)勢是 NPU 可以騰出 CPU 資源給其他任務(wù)比如運動學(xué)解算、傳感器處理等。但對于我這種小規(guī)模 MLP 網(wǎng)絡(luò)NPU 的加速效果并不明顯反而因為模型轉(zhuǎn)換、量化精度、驅(qū)動版本匹配這些事增加了大量時間成本。如果你只是復(fù)制我的做法我建議直接走 ONNX Runtime CPU先把整個控制系統(tǒng)跑通后面有余力再考慮優(yōu)化 NPU 推理。在板端運行 ONNX Runtime 的代碼思路也很清晰import onnxruntime as ort import numpy as np sess ort.InferenceSession(microduck_actor.onnx, providers[CPUExecutionProvider]) # 每一控制周期構(gòu)造 obsshape 為 (1, 46) obs np.random.randn(46).astype(np.float32).reshape(1, 46) input_name sess.get_inputs()[0].name action sess.run(None, {input_name: obs})[0].reshape(-1) print(action)這里有個細(xì)節(jié)要注意輸入數(shù)據(jù)必須用np.float32不能是 float64否則 ONNX Runtime 會報類型不匹配。我在第一次跑的時候吃了這個虧整個程序報錯后我查了半天最后才發(fā)現(xiàn)是輸入數(shù)據(jù)格式問題。4. RK3566 實機部署與調(diào)試實錄4.1 系統(tǒng)鏡像與設(shè)備識別問題泰山派識別到 RK3566 但是是 ADB 設(shè)備硬件調(diào)試的第一步是讓 RK3566 開發(fā)板正常啟動并可以被電腦訪問。我用的是泰山派TaisanPi的 RK3566 核心板板卡本身支持 USB、串口、以太網(wǎng)但第一次上電時就被電腦識別成了一個 ADB 設(shè)備而不是常規(guī)的串口或者網(wǎng)絡(luò)設(shè)備這讓我折騰了一晚上。所謂“泰山派識別到 RK3566 但是是 ADB 設(shè)備”意思是開發(fā)板通過 USB 連接到電腦后lsusb識別到的設(shè)備 ID 指向 Android Debug Bridge而不是一個普通的 USB 以太網(wǎng)卡或者串口設(shè)備。出現(xiàn)這個問題的根本原因是板卡上電后進(jìn)入了燒錄模式或者出廠固件自帶的 ADB 服務(wù)在跑這時候你是沒法正常進(jìn)入系統(tǒng)的。很多剛?cè)胧?RK3566 的朋友都會卡在這一步。我的解決方法是這樣的首先用瑞芯微官方的 RKDevTool 燒錄工具進(jìn)入 MaskROM 模式重新燒寫一個干凈的系統(tǒng)鏡像。具體操作是先按住板子上的恢復(fù)鍵再上電讓板子進(jìn)入燒錄模式隨后在 RKDevTool 里燒入一個 Debian 或者 Ubuntu 的鏡像不要用出廠自帶的 Android 鏡像。燒寫成功后重新上電連接 USB 轉(zhuǎn)串口模塊登錄系統(tǒng)把 USB 設(shè)備模式改回普通 USB Device 或者直接禁用 ADB問題就解決了。如果你只是想在 Linux 系統(tǒng)里用 USB 通信記得檢查一下內(nèi)核是否加載了對應(yīng)的 USB gadget 驅(qū)動必要時寫一個 systemd 服務(wù)來啟動設(shè)備模式配置腳本。4.2 串口 / 外設(shè)對接與電機控制RK3566 實機跑起來之后下一步就是把控制信號發(fā)到電機。Microduck 的電機一般是 12V 的串行總線舵機比如常見的 LX-16A、ST3215 這類走半雙工 UART 通信。我在系統(tǒng)中用/dev/ttyS4串口和電機的轉(zhuǎn)換板通信波特率出廠默認(rèn)是 115200注意每條指令幀的 ID 和校驗位不能寫錯通過 UART 調(diào)用電機的角度位置控制指令??刂祁l率的選擇上我一開始跑 200Hz也就是 5ms 一發(fā)指令結(jié)果電機驅(qū)動板響應(yīng)不過來串口數(shù)據(jù)大量積壓關(guān)節(jié)明顯抖動。后來調(diào)低到 100Hz單次指令間隔 10ms推理、控制、通信都能在時間片里完成機器人走起來才穩(wěn)定。這里想提醒各位千萬不要盲目追求高控制頻率總線舵機的內(nèi)部 PWM 刷新頻率通常是 50 到 250Hz一串指令發(fā)得再快電機跟不上也是白搭。電機控制之外還要處理機身慣性測量單元IMU。我用的是一款常見的九軸 IMU通過 I2C 接口讀取加速度和角速度數(shù)據(jù)再把姿態(tài)四元數(shù)作為狀態(tài)輸入的一部分。IMU 數(shù)據(jù)的實時性會影響強化學(xué)習(xí)策略的輸入質(zhì)量我把 IMU 讀取放在一個獨立線程里讓它以 500Hz 的頻率刷數(shù)據(jù)然后控制主線程每 10ms 取一次最新的傳感器數(shù)據(jù)。4.3 部署后效果驗證與性能調(diào)優(yōu)實機部署成功不代表著能走好。我第一次把策略部署上去后Microduck 能站起來但邁步時明顯一瘸一拐而且頻繁往一側(cè)偏。排查下來主要有三個問題一個是左右腿的關(guān)節(jié)方向在仿真和實機上不一致等于策略在給反方向指令另一個是 IMU 數(shù)據(jù)有噪聲策略輸入不穩(wěn)定第三個是控制線程和推理線程沒有做好同步導(dǎo)致推理輸出動作時使用的傳感器數(shù)據(jù)已經(jīng)是舊數(shù)據(jù)。針對這三點我做的修正分別是在實機上逐個關(guān)節(jié)校驗電機方向?qū)懸粋€簡單的腳本讓每個關(guān)節(jié)轉(zhuǎn)到目標(biāo)角度確認(rèn)轉(zhuǎn)向與仿真模型一致對 IMU 數(shù)據(jù)加一個輕量級的低通濾波比如一階 RC 濾波減少高頻噪聲把控制循環(huán)改成“先讀取當(dāng)前傳感器數(shù)據(jù)再推理再下發(fā)指令”的嚴(yán)格順序執(zhí)行避免多線程競態(tài)。實測下來經(jīng)過這些修正后 Microduck 的行走穩(wěn)定性提升明顯單次連續(xù)行走距離能穩(wěn)定保持在十米以上。當(dāng)然這只是一個基本目標(biāo)后續(xù)還有轉(zhuǎn)向、越障、摔倒恢復(fù)等更復(fù)雜的控制目標(biāo)都需要進(jìn)一步訓(xùn)練和部署調(diào)試。5. 實踐中的典型問題與排查方法5.1 設(shè)備識別失敗快速排查清單RK3566 板卡設(shè)備識別問題在實際項目中出現(xiàn)的概率極高尤其當(dāng)你第一次刷機或者更換系統(tǒng)鏡像的時候。我根據(jù)自己的經(jīng)歷整理了一張快速排查表遇到問題可以直接照著查?,F(xiàn)象可能原因解決辦法USB 連接電腦識別為 ADB 設(shè)備板卡進(jìn)入燒錄模式或 Android 系統(tǒng)殘留按住恢復(fù)鍵進(jìn)入 MaskROM 模式用 RKDevTool 燒錄 Linux 鏡像串口無輸出登錄串口和調(diào)試串口共用同一路 UART配置錯誤檢查系統(tǒng)/boot下的uEnv.txt或config.txt確認(rèn) console 映射的串口號系統(tǒng)啟動后 USB 無法模擬串口內(nèi)核未啟用 USB gadget 驅(qū)動檢查/boot內(nèi)核模塊加載配置啟用g_serial或g_ether驅(qū)動識別到 RK3566 但無法燒錄USB 線纜不適合數(shù)據(jù)傳輸換一根短的高質(zhì)量 USB 數(shù)據(jù)線有些充電線不能傳數(shù)據(jù)板卡頻繁重啟電源供電不足使用 5V/3A 以上的適配器避免用電腦 USB 口直接供電設(shè)備識別問題大多數(shù)可以通過重新燒錄和檢查 USB 線纜解決真正卡住人的往往是不斷嘗試各種粗糙方案卻忽略了系統(tǒng)鏡像本身就是錯的。5.2 模型轉(zhuǎn)換失敗 / 精度下降我在從 PyTorch 導(dǎo)出 ONNX、再從 ONNX 轉(zhuǎn) RKNN 的過程中遇到過的錯誤類型基本是三類算子不支持、版本不匹配、動態(tài) shape 引起的問題。算子不支持時你需要在導(dǎo)出端修改網(wǎng)絡(luò)結(jié)構(gòu)把不支持的層用等價的基礎(chǔ)算子替換或者干脆重置為 CPU 推理。版本不匹配則是我在前面提過的rknn-toolkit2 和板端 RKNPU 驅(qū)動版本必須一致。動態(tài) shape 的問題更隱蔽很多 RKNN 模型要求 batch size 固定為 1如果你在導(dǎo)出時保留了動態(tài) batch轉(zhuǎn)換后可能無法加載。解決辦法是重新導(dǎo)出固定 batch 為 1。精度下降方面前面提過 INT8 量化后輸出層 tanh 受到一些影響。我驗證精度的方法是先在 PC 上隨機生成幾百組輸入比較 PyTorch 原模型和板端推理模型的輸出差異計算最大絕對誤差和均方根誤差。對于 MLP 策略網(wǎng)絡(luò)合理的誤差范圍在 0.01 到 0.05 左右如果誤差超過 0.1策略在實機上的表現(xiàn)很可能出現(xiàn)明顯退化。5.3 實機抖動、策略失效、獎勵信號異常實機抖動和策略失效是強化學(xué)習(xí)機器人部署中最讓人頭痛的問題。抖動的原因通常有幾個傳感器噪聲過大、控制頻率和電機響應(yīng)不匹配、控制輸出的動作指令變化太劇烈、關(guān)節(jié)連桿存在間隙。我的處理思路是先把控制頻率固定到 100Hz然后在動作指令上增加一個低通濾波比如每次只更新目標(biāo)角度的百分之三十讓關(guān)節(jié)運動更平滑。雖然這會稍微犧牲響應(yīng)速度但穩(wěn)定性提升立竿見影。策略失效則要區(qū)分是實機輸入不對還是模型本身泛化能力不足。實機輸入不對通常體現(xiàn)在觀測向量的維度、順序、單位與訓(xùn)練時不一致比如仿真里用的是弧度實機上讀出來的是角度制數(shù)那就需要做轉(zhuǎn)換。如果策略本身泛化能力不足則只能回頭補訓(xùn)練增加更多域隨機化參數(shù)或者在實機上收集數(shù)據(jù)后做離線強化學(xué)習(xí)微調(diào)比如用 IQL離線強化學(xué)習(xí)來校正當(dāng)前策略。獎勵信號異常多數(shù)是訓(xùn)練階段的問題。如果你在訓(xùn)練過程中發(fā)現(xiàn) total reward 在上升但在某一次迭代后驟降然后恢復(fù)得很慢很可能是某個隨機異常的仿真步進(jìn)導(dǎo)致策略崩潰。解決方法是加載之前的備份權(quán)重減小學(xué)習(xí)率同時檢查是否有環(huán)境重置時出現(xiàn)非法狀態(tài)。獎勵曲線出現(xiàn)“先升后降”的走勢時不要急著加大獎勵系數(shù)先看各項子獎勵的貢獻(xiàn)變化往往能發(fā)現(xiàn)某些項在反復(fù)震蕩。6. 寫在最后Microduck 的擴展方向與個人經(jīng)驗Microduck 這個項目真正跑通之后我在 PC 端訓(xùn)練的效率并沒有提升多少反而是 RK3566 這個嵌入式平臺的部署經(jīng)驗讓我對“強化學(xué)習(xí)機器人落地”這件事有了完全不同的理解。很多人總以為難點在算法但實際調(diào)試中傳感器對齊、關(guān)節(jié)方向、控制頻率、模型數(shù)值精度這些“瑣事”才是最耗費時間的部分。如果后續(xù)要繼續(xù)擴展我個人比較想嘗試的方向是離線強化學(xué)習(xí)比如先搜集 Microduck 在實機上自主跑動的大量數(shù)據(jù)再用 IQL 這類算法離線訓(xùn)練策略這樣可以進(jìn)一步縮小仿真和實機的差距。另外也可以在平臺上做更復(fù)雜的任務(wù)比如目標(biāo)跟隨、避障、小斜坡越障這些都需要重新設(shè)計獎勵函數(shù)和訓(xùn)練設(shè)置。最后分享一個小技巧不管是用 ONNX Runtime 還是 RKNN部署前一定要在 PC 上先做輸出一致性校驗不要直接燒到板子上再改。我一開始就是圖快模型轉(zhuǎn)完直接丟 RK3566結(jié)果各種莫名抖動后來回到 PC 上做差分測試才發(fā)現(xiàn)是量化精度的問題。多花十分鐘做校驗實機上能省出好幾個晚上的調(diào)試時間。