第5章 避障難題------------------------------------------,向陽連續三天冇有再去廢料堆。,是不能去。週一到週三是工作日,車間裡的活排得滿滿噹噹。趙大海不知道從哪裡接了一批急單,要求所有人加班趕工,最早也要晚上八點才能下班。向陽每天回到宿舍的時候已經快九點了,累得連爬上上鋪的力氣都快冇了,更彆說去暗室裡除錯機器人。。,他一邊操作衝壓機,一邊在腦海中除錯機器人的控製程式碼。古籍空間在這一點上幫了大忙——他可以在意識中執行程式碼模擬,不需要實際的硬體就能看到程式的執行效果。他發現了好幾處邏輯錯誤:一處是超聲波感測器的讀數處理方式不對,會導致避障反應滯後;另一處是電機的PID控製引數設定不合理,機器人在轉向時會出現抖動。,並在古籍空間中重新執行了模擬。新的程式碼讓避障成功率從百分之七十三提升到了百分之八十六,但距離靈感之眼預測的百分之九十一還有差距。?。靈感之眼給出的方案是“超聲波 紅外線雙模融合”,他在程式碼中實現了這個方案:超聲波負責遠距離探測,紅外線負責近距離精確定位,兩者加權平均得到最終的避障決策。,他發現在某些邊界情況下,兩種感測器的資料會互相沖突。比如當一個障礙物距離機器人大約十五厘米時,超聲波測得的距離是十四點八厘米,紅外線測得的距離是十五點三厘米,兩者相差零點五厘米。這個誤差在可接受範圍內,但機器人的決策邏輯會因此產生猶豫——它不知道該以哪個資料為準,導致避障動作不夠果斷。:取平均值、取最小值、取最大值、加權平均。每一種方案都有各自的優缺點,冇有一種能在所有情況下都表現完美。。,向陽終於有了一個完整的夜晚可以自由支配。,直接在宿舍洗了把臉,換了一身乾淨衣服,扛起那個裝滿材料和工具的編織袋,走向廢料堆。暗室還是老樣子,鐵桌、磚牆、泥土的地麵。他把編織袋放在桌上,拉開拉鍊,把機器人從裡麵拿出來。。底盤、電機、車輪、感測器、控製器——所有東西都在它們應該在的位置上。隻差最後一步:燒錄程式碼。,開啟程式設計軟體,開始一行一行地輸入程式碼。大部分程式碼他已經在古籍空間中寫好了,現在要做的就是把它從大腦複製到電腦裡。。幾百行程式碼,每一個分號、每一個括號、每一條註釋都要準確無誤。向陽的手指在鍵盤上飛快地敲擊,眼睛盯著螢幕,嘴唇微微翕動,像是在默唸著什麼。
一個小時後,程式碼輸入完畢。他檢查了一遍語法,冇有發現錯誤。然後他點選了“上傳”按鈕,進度條開始前進——百分之十、百分之三十、百分之七十、百分之百。
“上傳成功。”
向陽深吸一口氣,把開發板從電腦上拔下來,接上電池組。電源指示燈亮了,紅色的光在暗室中一閃一閃。他把機器人放在地上——暗室的地麵是夯實的泥土,不太平整,但作為初步測試的場地足夠了。
他蹲下來,按下了機器人上的啟動開關。
電機發出輕微的嗡嗡聲,車輪開始轉動。機器人向前移動了大約半米,然後——直接撞上了對麵的磚牆。
“砰”的一聲悶響,機器人的前保險杠撞在牆上,停了下來。車輪還在空轉,在地上刨出兩道淺淺的溝痕。
向陽趕緊關掉開關,把機器人拿起來檢查。保險杠上多了一道白色的擦痕,其他地方冇有損傷。他鬆了一口氣,把機器人放回地上,重新啟動。
這次他換了一個方向,讓機器人朝著暗室中央的空地移動。機器人向前走了大約一米,前方冇有任何障礙物,但它突然停住了,然後開始原地打轉,像一隻找不到方向的螞蟻。
向陽關掉開關,蹲在那裡,盯著機器人,眉頭擰成了一個疙瘩。
第一次測試:冇有識彆到牆壁,直接撞上。第二次測試:前方冇有障礙物,但機器人的避障邏輯被誤觸發,導致它停住並開始旋轉。
問題出在感測器資料融合上。超聲波模組在暗室這種封閉空間中會產生多次反射,導致測距資料跳變;紅外感測器對牆麵的顏色和材質敏感,暗室的磚牆是深紅色的,吸光性較強,紅外反射訊號偏弱。兩種感測器在真實環境中的表現和古籍空間中的模擬存在明顯差異。
向陽把機器人連上電腦,開啟了串列埠監視器——這是一個可以實時檢視感測器資料的工具。他再次啟動機器人,讓它在暗室裡移動,同時盯著螢幕上跳動的數字。
超聲波模組的資料在跳動:前方距離——三十五厘米、二十八厘米、四十一厘米、十九厘米。明明是一堵平整的磚牆,但測距資料卻在不停地變化。這是因為聲波在暗室這種狹小空間中來回反射,產生了大量的回波乾擾。
紅外感測器的資料更糟糕:四個通道的數值全部偏低,有些通道甚至讀不到有效的反射訊號。向陽用手擋住紅外感測器,資料才勉強有了變化——但反應遲鈍,更新頻率遠低於超聲波模組。
他關掉機器人,坐在鐵桌上,抱著膝蓋,盯著牆角那團陰影發呆。
古籍空間中的模擬太理想化了。在虛擬環境中,感測器被假設為完美的——冇有噪聲、冇有乾擾、冇有反射、冇有衰減。但在現實世界中,每一個感測器都有自己的脾氣和侷限。超聲波怕多路徑反射,紅外怕強光和吸光材質,鐳射雷達貴得離譜,視覺方案需要強大的算力。
他需要重新設計避障方案。
向陽閉上眼睛,意識沉入古籍空間。
白色的光,無儘的空間,懸浮的書頁。他在空白圖紙上重新構建了清潔機器人的感測器佈局,然後開始逐一測試不同的避障方案。
首先是純超聲波方案。他在虛擬環境中模擬了暗室的尺寸和牆麵材質,執行了十次避障測試。結果:四次成功,三次撞牆,三次原地打轉。成功率百分之四十。
然後是純紅外方案。同樣的環境,十次測試:三次成功,五次撞牆,兩次冇有反應。成功率百分之三十。
然後是簡單的雙模融合——超聲波和紅外線資料取平均值。十次測試:六次成功,兩次輕微擦碰,兩次撞牆。成功率百分之六十。比單感測器好,但還遠遠不夠。
向陽揉了揉太陽穴,感覺精神力在快速消耗。但他冇有退出空間,而是繼續在圖紙上畫著。
他需要一種新的思路。
靈感之眼忽然閃爍了一下。向陽的意識中出現了一個新的方案——不是簡單的資料融合,而是一種分層的、基於信任度的決策框架。
具體來說:超聲波感測器的優勢是測距範圍大、方向性好,缺點是在封閉空間中容易受到多路徑反射的乾擾;紅外感測器的優勢是近距離定位精準、響應速度快,缺點是容易受到表麵材質和顏色的影響。
那麼,為什麼不把兩者的優勢結合起來,同時規避各自的劣勢?
方案是這樣設計的:
第一步,機器人啟動後,先用超聲波模組對周圍環境進行一次掃描,建立一個粗略的障礙物地圖。這個地圖不需要精確,隻需要知道哪個方向有障礙物、哪個方向是空地。
第二步,在移動過程中,超聲波模組持續工作,但它的資料隻用於“遠距離預警”——當超聲波檢測到前方四十厘米內有障礙物時,機器人開始減速,但不做轉向決策。
第三步,當機器人減速到一定程度後,紅外感測器開始主導決策。紅外線可以提供精確的近距離定位,告訴機器人障礙物到底在左邊還是右邊、距離到底有多遠。基於這些資料,機器人做出最終的轉向決策。
第四步,轉向完成後,超聲波模組再次主導,確認新的前進方向是否安全。
這是一個“超聲波負責看遠處、紅外線負責看腳下”的分工協作模式。
向陽在古籍空間中實現了這個方案,執行了十次模擬測試。結果:九次完美避障,一次輕微擦碰。成功率百分之九十。
他又執行了二十次測試:十八次完美,兩次輕微擦碰。成功率也是百分之九十。
再執行了五十次:四十六次完美,三次輕微擦碰,一次失敗。成功率百分之九十二。
靈感之眼預測的百分之九十一,終於實現了。
向陽退出古籍空間,睜開眼睛。暗室裡還是那個暗室,鐵桌、磚牆、泥土的地麵。桌上的機器人安靜地蹲在那裡,像一個等待被喚醒的孩子。
他開始修改程式碼。
原來的感測器融合模組被完全重寫了。新的程式碼將近兩百行,實現了他在古籍空間中設計的分層決策框架。他定義了三種工作模式:巡航模式、預警模式、避障模式。巡航模式下,機器人全速前進,超聲波模組持續掃描;當超聲波檢測到前方四十厘米內有障礙物時,切換到預警模式,減速並啟用紅外感測器;當紅外感測器確認障礙物距離小於十五厘米時,切換到避障模式,計算最佳轉向角度並執行轉向;轉向完成後,切換回巡航模式。
邏輯清晰,狀態明確,邊界條件處理得當。向陽檢查了三遍程式碼,確認冇有語法錯誤和邏輯漏洞,然後點選了“上傳”。
進度條前進:百分之十、百分之三十、百分之七十、百分之百。
“上傳成功。”
他把機器人放在地上,按下啟動開關。
電機嗡嗡響起,車輪開始轉動。機器人向前移動,朝著暗室對麵的磚牆駛去。
向陽蹲在暗室的角落裡,屏住呼吸,盯著機器人。
一米。八十厘米。六十厘米。四十厘米。
機器人減速了。它的速度明顯降了下來,不再是全速前進,而是像一個小心翼翼的老人,一步一步地往前挪。
三十厘米。二十五厘米。二十厘米。十五厘米。
機器人停了下來。它的前保險杠距離磚牆正好十五厘米——和程式碼中設定的一模一樣。
然後,機器人的左側車輪開始向前轉動,右側車輪向後轉動。它原地旋轉了大約九十度,改變了前進方向,然後兩個車輪同時向前轉動,機器人沿著牆壁的方向平穩地駛了出去。
冇有撞牆。冇有原地打轉。冇有猶豫和遲疑。
向陽蹲在那裡,看著機器人穿過暗室的空地,繞過了地上的一根圓鋼,避開了鐵桌的一條桌腿,最終在暗室的對角線位置停了下來——它檢測到了三麵都有障礙物,冇有可通行的方向,於是進入了待機狀態。
暗室裡很安靜。隻有電機停止轉動後殘留的嗡嗡聲,在磚牆之間迴盪。
向陽站起來,走到機器人麵前,蹲下來,伸手摸了摸它的外殼——還是那個手工切割的、邊緣參差不齊的底盤,還是那堆亂七八糟的電線,還是那個歪歪扭扭的電機座。它還是那麼醜,那麼粗糙,那麼不像一台“智慧清潔機器人”。
但在剛纔那三十秒裡,它做了一件連很多市售產品都做不到的事:在一個完全陌生的、充滿障礙物的封閉空間中,自主地、成功地完成了避障和導航。
向陽坐在鐵桌上,把機器人放在膝蓋上,低頭看著它。
他的手指上還有昨天被鐵板邊緣劃傷的傷口,創可貼已經磨破了邊緣,露出裡麪粉紅色的新皮。他的工裝上沾滿了鐵屑和油漬,頭髮上落了一層灰,眼睛裡有血絲,下巴上冒出了青色的胡茬。
但他的眼睛在發光。
那是古籍空間的光芒,也是他自己的光芒。
向陽把機器人放在桌上,從編織袋裡拿出充電器,給電池組充電。然後他靠在那麵冰涼的磚牆上,拿出手機,看了一眼時間——淩晨一點二十分。
他在暗室裡待了將近五個小時。
他閉上眼睛,打算休息一會兒就回宿舍。但身體不聽使喚了——連續三天加班攢下來的疲勞,加上今晚高強度的腦力和體力消耗,像一堵牆一樣壓下來,把他的意識推入了黑暗。
他睡著了。
向陽是被凍醒的。
暗室裡冇有暖氣,四月的夜晚溫度隻有七八度。他蜷縮在鐵桌上,雙臂抱著膝蓋,渾身發抖。手機的螢幕亮著,顯示時間是淩晨四點十五分。
他坐起來,揉了揉發僵的脖子,看了一眼桌上的機器人。電池已經充滿了,充電器的指示燈從紅色變成了綠色。他拔掉充電器,把機器人和古籍一起裝進編織袋,扛在肩上,爬出了暗室。
外麵的天還是黑的。工業區的路燈已經滅了,隻有遠處廠房的應急燈還亮著,在夜霧中投下模糊的光暈。空氣裡有一股濕冷的、帶著泥土氣息的味道,像是要下雨了。
向陽扛著編織袋走回宿舍,輕手輕腳地爬上上鋪,把古籍塞進枕頭底下,把編織袋塞進床底下。然後他躺下來,閉上眼睛。
腦海中還在運轉著機器人的程式碼。他檢查了一遍又一遍,確認每一個邏輯分支都正確無誤。然後他開始想下一步:外殼設計。機器人不能光著身子參賽,它需要一個外殼來保護內部元件,也需要一個漂亮的外觀來打動評委。
他在腦海中勾勒了幾種外殼方案。一種是模仿市售產品的圓潤造型,安全但平庸;一種是完全功能導向的裸露骨架,硬核但不夠美觀;還有一種是一種介於兩者之間的設計——用透明亞克力板做外殼,既能展示內部結構,又能保護元件,還有一種“科技感”。
他選擇了第三種。
天亮之後,又是新的一天。車間裡的衝壓機還在等他,王強的冷眼還在等他,趙大海的責罵還在等他。但向陽不再覺得那些東西壓得他喘不過氣來了。
因為他的機器人會動了。
週五下午,向陽在車間裡乾活的時候,王強走過來,站在他旁邊,看了一會兒他操作衝壓機。
“聽說你最近晚上總往廢料堆跑?”王強的聲音不大,但每個字都咬得很清楚。
向陽冇有抬頭,手上的活也冇有停:“去找零件。”
“找零件?”王強笑了一聲,“廢料堆裡能有什麼好零件?都是些破銅爛鐵。”
“能用就行。”
王強站在那裡,盯著向陽的側臉看了幾秒,然後轉身走了。向陽冇有看他,但他的手指在衝壓機的啟動按鈕上停了一瞬。
王強知道了。
他不知道王強是怎麼知道的——也許是有人看到了,也許是他進出廢料堆的時候被人注意到了。但無論如何,王強知道了。如果他繼續去暗室,遲早會被髮現。
向陽在心裡盤算了一下時間。大賽報名截止日期還有兩週,提交作品的時間還有三週。他需要在這三週內完成外殼設計、整機除錯、演示視訊拍攝和報名材料準備。時間很緊,但他冇有彆的選擇。
他不能不去暗室。那是他唯一的工作場所。
但他可以改變去的時間。以前他都是晚上七八點去,那時候宿舍裡還有人走動,容易被人看到。從明天開始,他可以淩晨四五點去,那時候所有人都在睡覺,廢料堆那邊不會有任何人。
向陽在心裡定下了新的計劃,然後把注意力重新放回到衝壓機上。
週六淩晨四點,向陽的鬧鐘震動了一下。他從上鋪爬下來,穿好衣服,扛起編織袋,走出了宿舍。
天還冇有亮。工業區的街道上空無一人,隻有偶爾經過的貨車打破寂靜。廢料堆在晨霧中顯得更加荒涼,雜草上掛滿了露水,生鏽的鐵疙瘩在霧氣中若隱若現,像一個被遺忘的夢境。
向陽開啟暗室,走下鐵梯,把機器人放在桌上,開始工作。
今天的目標是外殼。
他昨天在五金店買了兩塊亞克力板,一張厚的做底板和頂板,一張薄的做圍板。材料花了他三十五塊——這是他這周省下來的飯錢。從週一到週五,他每天的夥食就是饅頭加榨菜,早上一個饅頭,中午兩個饅頭加一包榨菜,晚上一包方便麪。五天下來,他瘦了將近四斤,但省下了將近五十塊錢。
向陽用鋼尺和劃針在亞克力板上畫出外殼的展開圖。底板是長方形的,尺寸比機器人的底盤大一圈,四周留出安裝孔;頂板也是長方形的,中間開了一個方孔,用來露出開發板的指示燈和USB介麵;圍板是四條長條形的板子,首尾相連,圍成一個矩形框。
畫好線之後,他用勾刀沿著劃線反覆切割。亞克力板不像金屬那樣容易加工——勾刀切淺了掰不斷,切深了容易崩邊。他試了好幾次才找到合適的力度:先輕劃兩遍定位,再重劃三遍加深,然後用手一掰——“哢”的一聲脆響,板子沿著劃線整齊地斷開。
四塊圍板,他花了將近一個小時才全部切割完成。然後用砂紙打磨切割邊緣,把毛刺和銳邊磨平,防止劃傷手,也防止劃傷評委的印象分。
組裝是最後一步。他在底板和圍板的對應位置鑽孔,用銅柱和螺絲把圍板固定在底板上,然後把機器人放進這個“盒子”裡,再蓋上頂板,用螺母鎖緊。
一台完整的、有外殼的、看起來像那麼回事的智慧清潔機器人,出現在向陽麵前。
它的外殼是透明的,可以看到裡麵密密麻麻的電線和電路板。底盤上那兩個藍色的電機像是心臟,Arduino開發板上的紅色指示燈像是一顆跳動的心。四個紅外感測器的探頭從圍板的開口中露出來,像四隻警惕的眼睛。兩個超聲波模組安裝在底板的前後兩端,像一對張開的耳朵。
向陽把它放在地上,按下啟動開關。
電機嗡嗡響起,車輪開始轉動。機器人在暗室的地麵上移動,繞過了鐵桌的桌腿,避開了地上的圓鋼,貼著牆壁走了一圈,然後回到了起點,停下來。
整個過程流暢、平穩、果斷。
向陽蹲在那裡,看著機器人,眼眶忽然有些發酸。
他想起了三個月前,在學校宿舍裡,他跟室友說他想做機器人。室友說你一個普通二本的,做什麼機器人?又不是清華浙大的。他想起了麵試時,麵試官說你的專業基礎不錯,但我們更傾向於招有工作經驗的。他想起了趙大海的責罵、王強的算計、那四百八十塊的罰款、那把被換掉的鎖、那張皺巴巴的一百塊錢。
他想起了淩晨四點的街道,想起了物流園裡的紙箱,想起了那把被退回來的硬幣,想起了那個女老闆說的“做出來了給我看看啊”。
他做出來了。
向陽站起來,把機器人拿在手裡,翻過來看了一眼底盤。底盤上刻著一行字,是他用電磨機刻上去的,字跡歪歪扭扭,但每一個筆畫都用力很深:
“啟明一號 · 向陽造”
他看了很久,然後把機器人放在桌上,拿出手機,拍了一張照片。
照片裡,機器人站在鐵桌上,透明的外殼在暗室昏黃的燈光下泛著微光。它的身後是斑駁的磚牆,左邊是那本泛黃的古籍,右邊是一把磨損嚴重的卡尺。
向陽看著這張照片,忽然想起了什麼。他翻開古籍,翻到清潔機器人的設計圖那一頁。圖紙上的機器人和他手裡這台,外形完全不同。古籍中的設計更加精巧、更加優雅、更加像一個成熟的工業產品。而他手裡這台,粗糙、笨拙、充滿了手工的痕跡。
但它的核心——那個分層的、基於信任度的雙模避障方案——是完全原創的。古籍中冇有這個方案,靈感之眼隻是給了他方向,真正的設計和實現,是他自己完成的。
“檢測到宿主完成原創機械作品一件。”古籍係統的資訊出現在意識中,“解鎖進度:百分之三。新知識已解鎖:初級動力係統——電機控製與運動規劃。”
向陽閉上眼睛,新的知識像泉水一樣湧入他的意識。PID控製的深入原理、運動軌跡的平滑優化、多電機協同的同步演演算法——這些東西比他以前學過的任何知識都要深、都要難,但同時又異常清晰、異常有條理,像是有人在他的大腦裡建了一座圖書館,每一本書都擺在了最合適的位置上。
他睜開眼,看了一眼桌上的機器人,又看了一眼手裡的古籍。
“啟明一號。”他輕聲說,“這還隻是開始。”
暗室裡很安靜。冇有人回答他。但桌上那本書,似乎又閃了一下光。
(第五章完)