
這半個月我身邊不止一個準備智能車競賽的團隊都在傳一段“走馬觀碑”車模運行視頻。視頻不長畫面也不復雜車模在場地里沿路徑跑了一段轉向有動作速度不算快唯一顯眼的是標題最后那行字未加入視覺。如果猜得沒錯很多人看到的第一反應是沒視覺那這個視頻有什么可看的其實對一個準備參加第21屆全國大學生智能汽車競賽、目標還是視覺相關組別的隊伍來說這個視頻恰恰是整個工程里最值得留著的一份記錄。我的判斷是還沒接入視覺不等于車模狀態“不完整”。相反它是從純控制階段進入多傳感器融合階段之前必須留下的一條基線。很多團隊起步時急著往車模上堆攝像頭、跑模型結果車輛本身的轉向特性和速度閉環都沒穩住最后出了問題也分不清是視覺模塊的問題還是底層控制的問題。先讓車模在沒有視覺的情況下跑出可復現、可評價、可檢查的結果再考慮視覺接入才是真正省時間的順序。1. 先確認一下這段視頻到底證明了什么“未加入視覺”的視頻最容易給觀眾一種錯覺車模能跑但還差一個功能模塊。這個理解不能說錯但它把問題看小了。一個沒有視覺模塊參與的運行視頻真正證明的并不是“少了一塊功能”而是“底層運動系統已經具備被后續功能依賴的基礎”。1.1 視頻里的“能跑”到底跑通了哪幾層從智能車工程鏈路看車模能穩定運行至少要求三層成立第一層是執行層。電機驅動、舵機轉向、編碼器反饋、電池供電和電機驅動模塊之間的電氣連接必須正確。很多新手覺得這層簡單實際上問題最多的是供電不穩定和信號線受干擾。視頻里車模如果直道不抖動、轉向不發生異響至少說明執行層沒有嚴重的電氣缺陷。第二層是控制層。車模運行需要速度閉環和方向控制。所謂閉環不是“給它一個PWM讓它走”而是根據實際速度和實際位置持續修正輸出。沒有視覺靠的是編碼器和慣性傳感器這層跑穩定了才說明控制器的基礎參數基本合理。第三層是邏輯層。車模的狀態機、啟停策略、計時策略、串口輸出和日志記錄這些代碼在視頻里是看不見的但它們直接決定了車模的行為是否符合預期。一段運行視頻能夠順利錄完本身就說明程序沒有在中途崩潰、超時或卡死。所以這段視頻證明了車模在三層鏈路里已經打通了一個最小閉環。別小看這個閉環后續任何視覺模塊都只是在這個閉環之上增加“外部感知”而不是替換掉它。1.2 為什么視覺不能反過來決定車模基礎性能很多團隊在準備視覺組時會下意識地認為視覺才是核心競爭力底層控制隨便調一調就行。這是一個非常容易踩的坑。視覺模塊的輸入是圖像輸出是目標位置、角度或者路徑偏差而最終執行這些指令的依然是電機和舵機。如果車模本身的轉向響應延遲、速度波動大那么視覺給出來的偏差再準車模依然跑不出穩定的軌跡。視覺系統可以告訴你“應該往左修正2厘米”但底層控制器如果響應有80毫秒延遲這個修正指令到達執行層時車模已經駛過了目標點。反過來一段無視覺的車模視頻如果能夠穩定重復等于提前把“執行”和“控制”兩個變量控制住了。后面接入視覺時一旦出現軌跡抖動就可以大概率懷疑是感知或者視覺處理環節的問題而不是整車到處都可能有毛病。實際操作里我建議把無視覺運行視頻作為視覺接入前的回歸測試基準。以后每改一次視覺代碼都必須拍一段同樣路徑、同樣速度下的運行視頻做對比。只要底層軌跡變形了先檢查視覺管線再檢查車輛機械和控制。2. 還沒接視覺之前控制系統應該先守住幾條邊界視頻看起來是車模在跑但真正需要關心的不是畫面本身而是畫面里那些容易被忽略的“邊界條件”。沒有視覺階段恰恰是檢查這些邊界最干凈的窗口期。2.1 速度閉環和轉向響應不能只看跑起來我見過不少團隊車模能跑就急著調視覺結果連速度反饋的穩定區間都沒標定過。車模在0.5米/秒和1.5米/秒兩種工況下PWM和編碼器之間的關系完全不同。如果沒有視覺之前就把速度環調到“給目標速度能穩定收斂”的程度后面一旦視覺需要急停或低速過彎車模就會開始振蕩。在無視覺階段至少要確認下邊幾項電機PWM上限和下限。油門給到多少會原地抖動給到多少會飽和。速度閉環在低、中、高三檔下的超調量。目標速度從1.2米/秒降到0.6米/秒時會不會沖出目標再折返。舵機中位和中位附近的死區。視覺給到角度偏差后舵機是否有最小響應延遲。電池電壓下降后的表現。滿電和低電時同樣的PWM是否還能維持同樣的速度。這些數據不一定都體現在視頻里但視頻是驗證這些數據是否可信的第一手資料。如果拍完視頻回放時聽出電機在高頻抖動那就說明電流或者PWM占空比大概率沒到穩定的工作點。2.2 底層參數先固化再談感知融合“底層參數固化”的意思是在沒有視覺階段就定好一套相對穩定的參數組合之后不能因為視覺識別不準就隨便改底層PID。原因很簡單底層參數是多個變量共同作用的結果視覺是另外一個變量。兩個變量同時抖動的時候你根本無法定位問題。我建議在無視覺階段把下面幾個參數記錄下來作為團隊的參數基線目標速度與PWM的映射表。正常電量下不同目標速度對應的穩定電流范圍。舵機從物理中位到最大左轉和最大右轉的響應時間。車模從啟動指令到穩定達到目標速度所需的時間。在固定路徑上跑完一圈的總耗時和分段耗時。這些參數記錄下來之后后續接入視覺時只要某個指標明顯偏離基線就可以快速判斷是視覺引入的問題還是底層硬件狀態發生了變化。3. 視覺不是裝上去就能用它需要先跟硬件解耦很多人以為視覺模塊就是一個攝像頭加一個識別模型接上線就能給車模輸出角度。真實情況是視覺模塊從一開始就要面對取圖幀率、分辨率、曝光時間、圖像傳輸延遲、識別模型計算耗時、輸出結果的外推和濾波等一整套問題。在沒有視覺的階段先把視覺模塊和車模控制“解耦”是讓后續工作不那么混亂的前置條件。3.1 先把視覺跑在“離線輸入”上一個便于落地的做法是視覺程序先不連車模只處理提前錄好的圖像或者視頻流。把攝像頭架在場地邊采集幾段真實光照和賽道條件下的圖像標注好目標元素然后讓視覺程序跑離線識別。這樣可以確定一個最關鍵的問題當前算法在真實畫面上到底能不能穩定識別出目標。很多團隊會把視覺識別代碼直接放到車模上聯調結果發現畫面模糊、反光嚴重、目標太小一套問題堆在一起。如果先離線跑就能先排除算力和實時性對結果的干擾只看模型和圖像處理本身是否成立。這一步做完后再把視覺輸出打印到串口或者日志里手動對比預測結果和實際目標位置的誤差。等離線精度達到可接受范圍再轉到車模上進行實時測試。這個順序能節省大量聯調時間。3.2 圖像幀率低、處理慢經常不是算力問題“視覺取圖幀率低”“網口設置”“識別慢”這些是智能車視覺團隊里的高頻問題。但實際排查時很大一部分原因是攝像頭配置、傳輸帶寬和等待邏輯不對。在無視覺階段車模主控和攝像頭之間的數據通路往往沒有建立這時候最好先把一條“虛擬視覺通路”跑通。也就是說即使攝像頭還沒參與實際控制也要在程序里預留一個圖像輸入接口用一個固定測試圖像每隔固定周期喂給感知模塊驗證每個環節的時間戳和輸出延遲。它不替代真實攝像頭但能提前確認數據流、計算耗時和輸出接口是否順暢。等到真實攝像頭接入時需要重點確認的就不是“算法好不好用”而是“每一幀圖像到底經過了哪些環節消耗了多少時間”。如果每一幀從采集到輸出平均值已經超過控制周期那再好的識別模型都難以穩定控制車模軌跡。4. 一塊“未加入視覺”的車模視頻應該怎么拍、怎么看車模運行視頻不是單純記錄過程它其實是工程判斷的重要素材。拍得好回放時能看出很多參數問題拍得隨意最后只能作為紀念不能用來調試。4.1 拍攝條件要固定才有對比價值視覺接入前后的對比視頻必須保證拍攝條件一致。我在實踐中一般會這么做固定場地地圖包括路徑形狀、標志物、邊界線。固定出發位置和解說方向標注拍攝時間。盡量使用固定機位從車模正上方或斜上方高機位拍攝。同一次對比測試里保持光照條件基本一致避免中午強光和傍晚陰影造成誤判。視頻里要有計時參考建議直接在場地里放一塊帶秒數的電子表方便逐幀回放。這些細節看似與視覺無關但視覺接入后如果要判斷“是識別不穩定還是控制不穩定”就必須有同樣的拍攝基準來對照。4.2 回放時重點看四個特征每次拍完視頻不要只看“有沒有沖出跑道”可以按下面幾個特征去觀察直道上的橫向擺動。如果車模在直道出現周期性蛇形運動往往是速度環和方向環的耦合沒有調好。入彎前的減速點。視覺介入前車模應該根據路徑判斷提前減速。如果它總是在彎心里突然打舵說明路徑規劃或轉向響應不夠平滑。出彎后的恢復時長。視覺車模如果沒有提前規劃好出彎路徑出彎后會在直道上走斜線而不是沿切線拉直。車輪是否出現間歇性打滑。這一點視頻里可能不明顯但聽聲音可以發現。如果電機在彎道中有斷續嘯叫一般說明轉向負載超過輪胎抓地力。這些觀察結果在接入視覺之后要反復對照因為視覺只是改變了“決策依據”沒有改變底層執行物理特性。一個小提醒回放視頻時不要用手機自帶的默認倍速直接看建議用0.5倍速逐幀拖動尤其觀察車輪和舵機的相對時機。很多問題只在低倍速下才看得出來。5. 從無視覺到有視覺我建議按四步走為了讓“未加入視覺”的狀態轉換成“視覺穩定接管”的狀態而不至于推倒重來我總結了一個相對穩妥的四步推進順序。5.1 第一步先把底層的固定參考標記做好接入視覺之前先在場地里規劃好參考點。比如賽道邊界、起點線、特殊元素位置這些參考不做成視覺依賴而是作為物理坐標基準。車模在沒有視覺時就可以根據這些基準點記錄自己的運動軌跡方便后續用視覺識別結果和物理基準對照。這一步的核心目的是讓視覺結果有一個“真值”可以去比較。沒有真值的視覺只看著像識別準了實際誤差分布完全未知。5.2 第二步離線驗證視覺識別鏈路把攝像頭接到電腦或工控機上跑一段固定路徑的圖像生成識別結果曲線再和真實路徑對比。重點檢查三件事識別準確率、識別延遲、異常幀出現頻率。這個階段不要追求極限速度先保證結果穩定可復現。如果這一步發現識別結果有時提前、有時滯后不要直接調模型先確認時間戳是否統一。視覺程序里常見的一個隱患是圖像獲取時間和控制指令時間不在同一個時間基準下導致車模以為看到的是當前畫面實際上讀到的是幾十毫秒前的舊幀。5.3 第三步視覺結果先用于提示不直接參與控制別急著讓視覺輸出直接驅動舵機和電機。建議先把視覺結果輸出為“提示信號”比如只在屏幕上畫一個目標框然后讓車模繼續按原有路徑運行。人站在旁邊觀察比較視覺提示和真實位置是否一致。這一步很容易被大家跳過但它能發現很多隱蔽問題視覺識別結果是否抖動、幀數是否連續、輸出值是否滿足控制輸入的范圍。這些問題如果不提前暴露等到視覺參與控制就會表現為車模忽左忽右但你在畫面里又看不出是識別誤差還是控制誤差。5.4 第四步用安全系數建立視覺參與控制的邊界開始讓視覺參與控制時先設一個安全范圍。比如視覺輸出值如果超出合理區間就切換到底層預設路徑或者強制降速。這個機制叫保護性接管是視覺車模進入穩定階段前的必要保險。我通常會在代碼里加一個條件判斷視覺連續N幀輸出異常時車模自動回到低速直行狀態同時記錄日志。因為視覺識別在真實環境中一定會遇到遮攔、反光、目標短暫消失等場景如果沒有保護機制任何一次丟幀都可能讓車模直接沖出場地。6. 在21屆準備階段哪些取舍最容易被忽略關于第21屆全國大學生智能汽車競賽的準備爭議最大的一點通常是“要不要一開始就上視覺”。我的看法是如果你是視覺相關組別的隊伍盡早接觸視覺管線是對的但不要以犧牲車輛基礎控制為代價。無視覺階段不是逃避視覺而是為了讓視覺有更健康的運行平臺。6.1 別把大量時間花在調模型上先搞定工程鏈路很多隊伍的視覺計劃只有模型訓練和推理這一步。但實際工程鏈路是圖像采集、圖像預處理、目標檢測、坐標系轉換、目標跟蹤、結果平滑、控制指令生成、執行反饋。這中間任何一環斷了視覺都跑不起來。在沒有視覺的階段重點要把這條鏈路的骨架提前預留出來。比如圖像采集接口、數據可視化界面、日志系統、異常處理機制這些和具體模型無關但它們會決定視覺接入的順利程度。先把這些工程骨架搭好后續慢慢替換模型和技術細節時整體風險會小很多。6.2 記錄“未加入視覺”的基線是為了以后能回退我見過太多隊伍陷入一種狀態今天改了視覺參數車模跑得還行明天改了一個模型結構車模開始沖出去再往后改了一版底層PID結果視覺反而失靈但誰也不知道是哪一步引入的問題。如果無視覺階段保留了清晰的基線視頻和參數記錄這種情況就能得到控制。每次只改一個變量改完跑一次無視覺對比測試再跑一次帶視覺的測試對比差異。嚴格按這個流程走看起來慢實際上才是最快的問題定位方法。6.3 視頻不只是給評委看的更是給團隊看的智能車競賽的作品展示視頻、運行視頻確實有外部展示的意義但視頻更大的價值在內部。它記錄的是團隊調試過程中每一次有效變化也是一份低成本的狀態快照。等到比賽前一周誰還能記得三周前電機的響應參數是什么樣把視頻和日志按日期整理好就能更快找到回歸。我建議每支隊伍在無視覺階段就養成三條記錄習慣每次調參后拍一段固定路徑的運行視頻。視頻文件名里帶上日期、版本、目標速度、是否帶視覺。把視頻和參數表、串口日志放在同一個目錄下統一命名。用不了多少存儲空間卻能讓整個調試過程變得可追溯、可復盤、可交接。回到最初那段“未加入視覺”的走馬觀碑視頻。它最打動我的地方不是車模跑得多快而是團隊愿意承認當前階段的狀態并且用視頻把狀態釘在時間軸上。這一步意味著他們已經理解了智能車工程的切入點先穩定再感知再決策再優化。視覺不是一段被插進代碼庫的魔術而是整個鏈條上的一環。先跑通無視覺的基線版本視覺接進來才不會變成一場碰運氣的聯調。希望你們在21屆的備戰路上也給自己留一條“未加入視覺”的基線它會比你想象的更有用。