WiFi無線通訊改造實(shí)戰(zhàn):從選型到調(diào)度對(duì)接)
做倉(cāng)儲(chǔ)自動(dòng)化這些年AGV小車的通訊問題一直是現(xiàn)場(chǎng)開會(huì)的高頻話題。尤其是那些還在用拖鏈電纜或者滑觸線傳輸串口信號(hào)的AGV跑個(gè)幾千公里之后斷芯、接觸不良、干擾誤碼全來了。我最近接手了一個(gè)物流倉(cāng)儲(chǔ)項(xiàng)目需要對(duì)在役的一批磁導(dǎo)引AGV做通訊改造核心訴求就一句話把車載控制器上的串口信號(hào)搬到無線鏈路上做到實(shí)時(shí)、穩(wěn)定、可運(yùn)維。我最終選了串口轉(zhuǎn)WiFi模塊的方向這文章就把整個(gè)項(xiàng)目從選型、組網(wǎng)、配置、調(diào)優(yōu)到對(duì)接調(diào)度系統(tǒng)的完整過程拆開講重點(diǎn)記錄幾個(gè)容易踩的坑和現(xiàn)場(chǎng)驗(yàn)證過的參數(shù)給正在做類似AGV無線化改造的朋友一個(gè)可以直接參考的樣板。1. 改造背景AGV車載通訊為什么必須動(dòng)刀子1.1 有線串口在移動(dòng)設(shè)備上的三大痛點(diǎn)很多AGV出廠時(shí)用的還是RS232或RS485串口與上位機(jī)通訊通訊線纜的走向無非兩種跟隨AGV本體走拖鏈或者通過滑觸線、地溝連接。這兩種方式在靜態(tài)設(shè)備上沒問題但AGV是連續(xù)移動(dòng)的問題會(huì)隨時(shí)間成倍放大。第一個(gè)痛點(diǎn)是拖鏈電纜的疲勞斷芯。AGV一天跑八小時(shí)拖鏈每分鐘彎折幾十次導(dǎo)線的銅芯在反復(fù)彎折下會(huì)慢慢斷裂。這種故障非常隱蔽外層絕緣皮是完好的用萬用表量通斷也可能正常但到現(xiàn)場(chǎng)一跑就丟數(shù)據(jù)、報(bào)亂碼。我們統(tǒng)計(jì)過一批運(yùn)行兩年的AGV因?yàn)榫€纜問題導(dǎo)致的通訊故障占了全部故障的四成以上。第二個(gè)痛點(diǎn)是滑觸線的接觸可靠性?;|線受安裝精度、灰塵、氧化層的影響很大AGV轉(zhuǎn)彎、過接縫時(shí)碳刷和滑觸線之間會(huì)產(chǎn)生瞬間接觸電阻波動(dòng)直接表現(xiàn)在串口信號(hào)上就是偶發(fā)性的幀錯(cuò)誤、CRC校驗(yàn)失敗。這種故障最討厭不是一直壞而是“偶爾壞一下”定位非常困難。第三個(gè)痛點(diǎn)是運(yùn)維成本。AGV數(shù)量一多幾十輛車的線纜狀態(tài)巡檢、插頭緊固、備件更換都是實(shí)打?qū)嵉娜肆屯C(jī)成本。尤其是在庫房這種環(huán)境叉車、人員、貨架來回穿梭線纜外露本身就是安全隱患。所以這個(gè)項(xiàng)目改動(dòng)刀子不是拍腦袋而是被現(xiàn)場(chǎng)故障率逼出來的。改造目標(biāo)很明確去掉車載通訊的物理線纜依賴把串口數(shù)據(jù)無縫搬到無線鏈路上讓AGV和調(diào)度系統(tǒng)之間的數(shù)據(jù)交互不再受線纜狀態(tài)制約。1.2 為什么是串口轉(zhuǎn)WiFi而不是其他無線做無線通訊改造可選的方向其實(shí)不少藍(lán)牙、ZigBee、LoRa、4G/5G、WiFi我為什么最終選了串口轉(zhuǎn)WiFi模塊藍(lán)牙的問題在于連接數(shù)和對(duì)移動(dòng)漫游的支持不夠穩(wěn)定藍(lán)牙主從模式下多車并發(fā)管理很麻煩而且傳輸距離和穿透能力都偏弱。ZigBee和LoRa的優(yōu)點(diǎn)是功耗低、自組網(wǎng)能力強(qiáng)但它們的通信帶寬太小了ZigBee的典型吞吐率也就是幾十kbps到兩百多kbps傳一些精簡(jiǎn)的狀態(tài)幀勉強(qiáng)夠用一旦后續(xù)要升級(jí)傳輸更大塊的數(shù)據(jù)比如AGV的日志、傳感器波形、視覺輔助信息帶寬就成了瓶頸。LoRa更適合低速率、遠(yuǎn)距離、小數(shù)據(jù)量的物聯(lián)網(wǎng)場(chǎng)景放在倉(cāng)庫里給AGV用反而有種“大炮打蚊子”且?guī)挷粔虻拿芨小?G/5G呢作為公網(wǎng)方案會(huì)引入SIM卡管理、運(yùn)營(yíng)商信號(hào)覆蓋、流量資費(fèi)和斷網(wǎng)風(fēng)險(xiǎn)等一系列運(yùn)營(yíng)問題而且很多倉(cāng)儲(chǔ)場(chǎng)景在地下室或金屬貨架密集區(qū)域公網(wǎng)信號(hào)并不好。更重要的是AGV調(diào)度系統(tǒng)的通訊要求足夠確定性的內(nèi)網(wǎng)環(huán)境走公網(wǎng)鏈路多了很多不可控因素。串口轉(zhuǎn)WiFi模塊恰好落在平衡點(diǎn)上2.4GHz頻段的WiFi在倉(cāng)庫里有現(xiàn)成的AP覆蓋基礎(chǔ)帶寬充裕支持TCP/IP協(xié)議棧可以直接承載串口數(shù)據(jù)映射到Socket連接上模塊本身成本低單臺(tái)AGV加一個(gè)模塊幾十到一兩百塊錢的物料成本就能搞定而802.11協(xié)議本身對(duì)移動(dòng)漫游有標(biāo)準(zhǔn)機(jī)制配合好AP部署策略可以做到AGV跨AP區(qū)域時(shí)連接不中斷。另外還有一個(gè)重要的考慮是通用性。AGV車上的控制器五花八門PLC、單片機(jī)、嵌入式工控機(jī)但它們基本都保留了串口。串口轉(zhuǎn)WiFi模塊在原車控制器看來就是一個(gè)“透明的串口設(shè)備”不需要?jiǎng)涌刂破鞯某绦蜻壿嫼陀布涌谶@讓我們能在不停產(chǎn)、不大改線束的情況下完成改造風(fēng)險(xiǎn)是最低的。1.3 改造目標(biāo)與技術(shù)指標(biāo)在動(dòng)手之前我把需求量化了一下這個(gè)環(huán)節(jié)很重要沒有指標(biāo)就沒辦法判斷改造效果通訊實(shí)時(shí)性從AGV控制器串口發(fā)出數(shù)據(jù)到調(diào)度服務(wù)器收到數(shù)據(jù)端到端延遲不大于50ms常態(tài)最好在20ms以內(nèi)。通訊可靠性在AGV全路徑運(yùn)動(dòng)過程中包括跨AP漫游時(shí)TCP連接不中斷單日丟包率低于0.1%。協(xié)議兼容性原車串口協(xié)議不做任何改動(dòng)模塊工作在透明傳輸模式下相當(dāng)于一根“無線串口線”。并發(fā)規(guī)模至少支持現(xiàn)場(chǎng)30臺(tái)AGV同時(shí)在線調(diào)度指令下發(fā)延遲不因車輛數(shù)量增加而明顯惡化。這幾個(gè)指標(biāo)成了后面選型和調(diào)試的參照系也幫我在和現(xiàn)場(chǎng)工人、甲方溝通時(shí)有了明確的驗(yàn)收標(biāo)準(zhǔn)。2. 硬件選型與組網(wǎng)架構(gòu)設(shè)計(jì)2.1 串口轉(zhuǎn)WiFi模塊選型怎么看指標(biāo)市面上的串口轉(zhuǎn)WiFi模塊很多從幾十塊的ESP8266方案到幾百塊的工業(yè)級(jí)專用模塊都有。這種改造項(xiàng)目我建議選工業(yè)級(jí)模塊而不是自己用ESP8266搭原因后面會(huì)講。選型時(shí)我主要看五個(gè)關(guān)鍵項(xiàng)第一串口電平要匹配。AGV控制器有的是TTL電平串口有的是RS232有的是RS485。模塊必須選對(duì)應(yīng)電平版本的否則要額外加電平轉(zhuǎn)換電路。RS485還牽扯到方向控制很多模塊是內(nèi)置自動(dòng)換向的買的時(shí)候要確認(rèn)。第二工作溫度范圍。倉(cāng)庫雖然不像露天環(huán)境那么極端但夏天庫房頂部溫度經(jīng)常有四十多度AGV電控箱內(nèi)部溫度更高。商業(yè)級(jí)模塊標(biāo)稱0~70℃實(shí)際在密封電控箱里很容易到臨界值工業(yè)級(jí)一般標(biāo)-40~85℃留的余量大得多。第三供電電壓和功耗。車載電控通常是24V直流系統(tǒng)模塊一般要5V或3.3V供電需要加DC-DC降壓模塊。功耗方面要關(guān)注峰值電流WiFi發(fā)射瞬間的電流可以達(dá)到兩三百毫安供電電路必須留夠余量。第四天線接口形式。優(yōu)先選帶外置天線的型號(hào)用IPEX接口或者SMA接口這樣天線可以從電控箱里引出來貼在車體外側(cè)。內(nèi)置PCB天線的模塊裝在金屬電控箱里信號(hào)會(huì)被屏蔽得很慘。第五協(xié)議棧和功能完整性。至少需要支持TCP Server、TCP Client、UDP三種工作模式支持心跳包配置支持AT指令和網(wǎng)頁配置雙通道。高端一些的模塊還支持Modbus TCP網(wǎng)關(guān)模式如果現(xiàn)場(chǎng)有Modbus RTU設(shè)備這個(gè)功能會(huì)很有用。我在這批項(xiàng)目中選的是USR-WIFI232系列級(jí)別的模塊作為主力型號(hào)參考它的原因是資料全、Socket模式支持完善、透?jìng)鞣€(wěn)定性經(jīng)過大量工業(yè)場(chǎng)景驗(yàn)證。如果你的現(xiàn)場(chǎng)預(yù)算緊張用ESP8266做概念驗(yàn)證POC是可以的但批量上車我不建議無線驅(qū)動(dòng)的穩(wěn)定性和長(zhǎng)時(shí)間運(yùn)行的重連機(jī)制都跟不上。2.2 三種典型組網(wǎng)拓?fù)鋵?duì)比串口轉(zhuǎn)WiFi模塊的組網(wǎng)方式不是只有一種根據(jù)現(xiàn)場(chǎng)網(wǎng)絡(luò)條件我梳理了三種典型方案第一種STA模式接入現(xiàn)有倉(cāng)庫WiFi。這是最常用的方案。AGV車載模塊作為無線終端連接倉(cāng)庫里原有的AP通過交換機(jī)到達(dá)調(diào)度服務(wù)器。優(yōu)點(diǎn)是復(fù)用現(xiàn)有網(wǎng)絡(luò)不需要新增無線設(shè)施缺點(diǎn)是對(duì)原有WiFi網(wǎng)絡(luò)的覆蓋質(zhì)量、漫游策略要求高AP部署不佳的話AGV跑到信號(hào)盲區(qū)就抓瞎。第二種專用AP模式。針對(duì)沒有現(xiàn)成無線覆蓋或者不想和辦公網(wǎng)絡(luò)混用的現(xiàn)場(chǎng)在調(diào)度機(jī)房部署一個(gè)專用AP車載模塊的WiFi配置成STA模式直連這個(gè)AP。這個(gè)方案的好處是網(wǎng)絡(luò)干凈、干擾可控、安全性好AGV通訊和其他業(yè)務(wù)完全隔離。缺點(diǎn)是AP覆蓋范圍有限大庫房可能要多布幾個(gè)AP做漫游。第三種模塊AP模式直連服務(wù)器。有的小規(guī)模場(chǎng)景只有一兩臺(tái)AGV可以把模塊配成AP模式服務(wù)器側(cè)用無線網(wǎng)卡連接模塊的SSID實(shí)現(xiàn)點(diǎn)對(duì)點(diǎn)通訊。這個(gè)方案最簡(jiǎn)單但擴(kuò)展性極差A(yù)GV一增加就沒法玩了而且AP模式下模塊自身的IP管理比較別扭。我在這個(gè)項(xiàng)目里用的是“專用AP模式雙頻段覆蓋”的變體主AP放在庫房中部高位考慮到AGV主要走貨架通道又在庫房?jī)啥搜a(bǔ)了兩個(gè)從AP做漫游擴(kuò)展。這樣設(shè)計(jì)的好處是AGV調(diào)度網(wǎng)絡(luò)和辦公網(wǎng)絡(luò)徹底隔離不會(huì)出現(xiàn)辦公區(qū)有人看視頻導(dǎo)致AGV延遲突然飆升的尷尬情況。組網(wǎng)方案適用場(chǎng)景優(yōu)點(diǎn)缺點(diǎn)STA接入現(xiàn)有WiFi已有成熟無線覆蓋的庫房部署成本低復(fù)用基礎(chǔ)設(shè)施受原網(wǎng)絡(luò)干擾影響漫游策略難控專用AP模式無線覆蓋差或要求隔離的現(xiàn)場(chǎng)網(wǎng)絡(luò)干凈時(shí)延穩(wěn)定易排查需新增AP設(shè)備和布線模塊AP模式1~2臺(tái)AGV的小型驗(yàn)證實(shí)現(xiàn)最快無需AP并發(fā)能力差擴(kuò)展性不足2.3 天線安裝與現(xiàn)場(chǎng)覆蓋天線看起來是小細(xì)節(jié)實(shí)際上決定了大半的通訊質(zhì)量。AGV的電控箱大多是金屬材質(zhì)如果模塊的天線還留在箱體內(nèi)部WiFi信號(hào)會(huì)被金屬殼體屏蔽掉哪怕AP就在十米外信號(hào)也可能只有-80dBm以下。我的做法是在電控箱面板上開一個(gè)SMA孔把天線引出來固定在AGV車體頂部或側(cè)面的非金屬區(qū)域。注意天線要保持垂直朝向盡量遠(yuǎn)離變頻器、電機(jī)驅(qū)動(dòng)線和電池主線這些大電流線路的電磁干擾對(duì)2.4GHz信號(hào)影響非常明顯。現(xiàn)場(chǎng)AP的安裝位置也要花心思。很多倉(cāng)庫為了美觀把AP裝在鋼梁下方但鋼梁本身會(huì)遮擋信號(hào)而且AGV的行駛路徑主要是貼地的AP的覆蓋要重點(diǎn)保證車體天線高度那個(gè)平面的信號(hào)強(qiáng)度。我習(xí)慣在部署后用手機(jī)或筆記本沿著AGV運(yùn)行路徑實(shí)測(cè)一遍信號(hào)強(qiáng)度確保最差位置不低于-70dBm。這個(gè)標(biāo)準(zhǔn)定下來之后后面AGV在庫房里跑基本沒遇到過因?yàn)楦采w盲區(qū)導(dǎo)致的通訊中斷。3. 模塊配置與核心參數(shù)實(shí)操3.1 串口參數(shù)匹配改錯(cuò)一位全盤皆輸模塊拿回來第一件事不是連WiFi而是先看原車控制器的串口參數(shù)。AGV控制器的串口配置在項(xiàng)目資料里一般都能找到但最保險(xiǎn)的方式是直接連串口工具抓一下實(shí)際輸出。串口參數(shù)包括四個(gè)波特率、數(shù)據(jù)位、停止位、校驗(yàn)位。絕大多數(shù)設(shè)備用的是9600或115200波特率、8數(shù)據(jù)位、1停止位、無校驗(yàn)即“9600 8N1”。但千萬不要因?yàn)椤敖^大多數(shù)”就默認(rèn)了我們項(xiàng)目里有一臺(tái)AGV用的就是19200波特率和偶校驗(yàn)第一次上電時(shí)因?yàn)閰?shù)沒配對(duì)收到的全是亂碼耽誤了半天才排查出來。配置模塊時(shí)進(jìn)入網(wǎng)頁管理界面后把串口設(shè)置和控制器保持一致。這里有個(gè)容易被忽略的細(xì)節(jié)串口緩沖區(qū)的大小。模塊一般在串口側(cè)有一個(gè)接收緩沖區(qū)常見的是1024字節(jié)或2048字節(jié)。如果AGV控制器不是用逐字節(jié)查詢的方式而是一次性發(fā)送大塊數(shù)據(jù)幀緩沖區(qū)太小會(huì)導(dǎo)致數(shù)據(jù)被截?cái)?。我用的模塊支持設(shè)置“打包時(shí)間”和“打包長(zhǎng)度”意思是從收到第一個(gè)字節(jié)開始等待多少毫秒或者攢夠多少字節(jié)后再通過WiFi發(fā)出去。對(duì)實(shí)時(shí)性要求高的場(chǎng)景把打包時(shí)間設(shè)置在5ms左右比較合適既能保證小幀數(shù)據(jù)的及時(shí)性又能把連續(xù)字節(jié)合并成有效的網(wǎng)絡(luò)包。3.2 WiFi接入與地址規(guī)劃WiFi接入這塊要注意SSID不要用特殊字符密碼加密方式選擇WPA2-PSK AES不要用WEP或者開放網(wǎng)絡(luò)。AGV調(diào)度通訊的數(shù)據(jù)涉及位置、任務(wù)指令雖然沒有太高的保密要求但至少要防止無關(guān)設(shè)備接入搗亂。IP地址規(guī)劃上我給每臺(tái)AGV分配固定IP而不是依賴DHCP動(dòng)態(tài)獲取。之前吃過虧DHCP租約到期或者服務(wù)器重啟后地址池順序變化導(dǎo)致服務(wù)器端維護(hù)的連接映射表錯(cuò)亂明明連接還在但車和地址對(duì)不上號(hào)了。固定IP之后服務(wù)器可以直接通過IP識(shí)別每臺(tái)AGV排查問題也好定位。具體操作上我先在路由器/交換機(jī)上做DHCP靜態(tài)綁定把模塊的MAC地址和規(guī)劃好的IP綁定起來同時(shí)也把IP、網(wǎng)關(guān)、子網(wǎng)掩碼這幾個(gè)參數(shù)直接在模塊網(wǎng)頁里寫死成靜態(tài)雙保險(xiǎn)。實(shí)踐證明這一步對(duì)運(yùn)行穩(wěn)定性的提升立竿見影。3.3 工作模式選型TCP Client是首選串口轉(zhuǎn)WiFi模塊的工作模式我強(qiáng)烈建議AGV車載端全部用TCP Client模式。原因很直接在調(diào)度系統(tǒng)中服務(wù)器作為Server端IP地址是固定的所有AGV作為Client主動(dòng)向服務(wù)器發(fā)起連接并由服務(wù)器端維護(hù)連接表。這種架構(gòu)的好處有三個(gè)第一AGV的數(shù)量變動(dòng)不會(huì)影響服務(wù)器地址配置車多了就多建幾條連接車少了就少幾條完全動(dòng)態(tài)。第二TCP自帶的ACK和重傳機(jī)制能保證串口數(shù)據(jù)幀在網(wǎng)絡(luò)層不丟失。雖然會(huì)帶來一點(diǎn)延遲開銷但AGV控制指令這類數(shù)據(jù)可靠性遠(yuǎn)比那幾毫秒延遲重要。第三服務(wù)器端按Socket句柄區(qū)分不同的AGV天然解決了多車并發(fā)時(shí)的數(shù)據(jù)歸屬問題。配置TCP Client的關(guān)鍵點(diǎn)是服務(wù)器IP和端口。端口號(hào)要避開常用的服務(wù)端口避免沖突。我習(xí)慣給AGV調(diào)度單獨(dú)開一個(gè)端口比如9001這個(gè)端口在服務(wù)器防火墻里要放行否則AGV側(cè)顯示連接失敗容易讓人誤判成模塊問題。有些模塊在配置TCP Client時(shí)還可以設(shè)置“連接超時(shí)時(shí)間”和“重連間隔”。我建議把重連間隔設(shè)在3~5秒太短了網(wǎng)絡(luò)抖動(dòng)時(shí)會(huì)頻繁發(fā)起連接反而加重?zé)o線擁塞太長(zhǎng)了則AGV掉線后不能及時(shí)恢復(fù)。這個(gè)參數(shù)在后期調(diào)優(yōu)時(shí)很常用。3.4 透?jìng)髂J降膸讉€(gè)關(guān)鍵坑大部分AGV控制器走的是自定義串口協(xié)議不是標(biāo)準(zhǔn)Modbus所以模塊配置成“透明傳輸模式”就夠了。但透明傳輸并不是真的“透明”有幾個(gè)坑得提前埋好對(duì)策。第一個(gè)坑是網(wǎng)絡(luò)安全機(jī)制。模塊在透明傳輸模式下默認(rèn)是允許任意TCP客戶端連接的這在調(diào)試期方便但上線后容易出問題。建議在模塊里啟用“允許連接的遠(yuǎn)程IP列表”功能把調(diào)度服務(wù)器的IP加進(jìn)去其他IP一概不響應(yīng)。第二個(gè)坑是模塊上電后自動(dòng)重連的時(shí)機(jī)。AGV運(yùn)行中偶爾會(huì)因?yàn)楝F(xiàn)場(chǎng)斷電重啟模塊重啟后需要幾十秒時(shí)間去掃描WiFi并建立TCP連接這個(gè)空窗期里調(diào)度服務(wù)器會(huì)報(bào)“AGV通信超時(shí)”。解決方式是在服務(wù)器端做斷線緩存把AGV重啟期間的指令存起來等連接恢復(fù)后補(bǔ)發(fā)而不是直接判定為故障。第三個(gè)坑是網(wǎng)絡(luò)空閑時(shí)的假死。有些無線模塊在鏈路空閑一定時(shí)間后會(huì)自動(dòng)進(jìn)入省電模式導(dǎo)致數(shù)據(jù)來了不能立刻發(fā)送。工業(yè)AGV場(chǎng)景一定要在模塊配置里關(guān)閉省電模式或者設(shè)置成“始終喚醒”狀態(tài)。我遇到過一次AGV停在充電站待命調(diào)度下發(fā)任務(wù)指令結(jié)果車過了十幾秒才動(dòng)排查半天發(fā)現(xiàn)是模塊的休眠策略在作怪。還有一個(gè)容易被忽略但很重要的點(diǎn)如果原車走的是RS485總線且總線上掛了多個(gè)從站設(shè)備比如驅(qū)動(dòng)器、傳感器串口轉(zhuǎn)WiFi模塊只是把整個(gè)RS485總線上的數(shù)據(jù)打包到無線鏈路中。這時(shí)要特別注意總線上不要讓兩個(gè)主站同時(shí)發(fā)數(shù)據(jù)否則RS485的沖突仲裁機(jī)制會(huì)在無線化的過程中變復(fù)雜導(dǎo)致數(shù)據(jù)錯(cuò)亂。4. 實(shí)時(shí)性能調(diào)優(yōu)延遲、掉線與漫游4.1 端到端延遲實(shí)測(cè)方法沒有實(shí)測(cè)數(shù)據(jù)一切實(shí)時(shí)性都是紙上談兵。我在項(xiàng)目現(xiàn)場(chǎng)用的測(cè)試方法很簡(jiǎn)單分三步走。第一步測(cè)無線鏈路延遲。在調(diào)度服務(wù)器上對(duì)每臺(tái)AGV模塊的IP執(zhí)行ping命令看平均RTT和丟包率。在庫房里距離AP二十米左右的理想位置ping值一般在2~5ms隔一堵貨架墻會(huì)到5~15ms如果超過30ms就要考慮信號(hào)遮擋或者干擾了。第二步測(cè)串口到網(wǎng)絡(luò)的整體延遲。這個(gè)需要借助模塊的調(diào)試功能。我的做法是在AGV側(cè)用串口調(diào)試工具發(fā)送一串帶時(shí)間戳的測(cè)試幀同時(shí)在服務(wù)器側(cè)用網(wǎng)絡(luò)調(diào)試助手接收對(duì)比發(fā)送和接收的時(shí)間戳差。實(shí)測(cè)下來9600波特率下發(fā)送一個(gè)20字節(jié)的幀串口側(cè)的發(fā)送時(shí)間本身就要約20ms再加上WiFi傳輸?shù)膸缀撩攵说蕉搜舆t大概在25ms左右。如果把波特率提高到115200串口發(fā)送時(shí)間縮短到2ms左右端到端延遲可以壓到10ms以內(nèi)。測(cè)試項(xiàng)目測(cè)試方式實(shí)測(cè)結(jié)果無線鏈路RTT服務(wù)器ping模塊IP2~15ms串口到網(wǎng)絡(luò)整體延遲串口打時(shí)間戳幀網(wǎng)絡(luò)接收對(duì)比9600波特率約25ms115200約10msTCP連接重連耗時(shí)手動(dòng)斷開AP觀察恢復(fù)時(shí)間一般為3~8秒跨AP漫游斷流時(shí)間AGV跑通道中間跨AP點(diǎn)抓包約100~300ms第三步驗(yàn)證多車并發(fā)的延遲變化。把現(xiàn)場(chǎng)30臺(tái)AGV的模塊全部上線連服務(wù)器再重復(fù)第二步的測(cè)試確認(rèn)延遲沒有顯著上升。這一步是驗(yàn)收的硬指標(biāo)如果并發(fā)一上來延遲就翻倍說明無線鏈路規(guī)劃或服務(wù)器處理能力有問題得回頭排查。4.2 心跳包、掉線重連與看門狗機(jī)制無線鏈路的“實(shí)時(shí)”不等于鏈路永遠(yuǎn)不斷。模塊長(zhǎng)期運(yùn)行后WiFi連接可能因?yàn)镈HCP租約、AP重啟、無線干擾等原因悄然斷開問題在于TCP連接斷開了但車載控制器還不知道繼續(xù)往串口發(fā)數(shù)據(jù)數(shù)據(jù)就會(huì)在模塊的緩沖區(qū)里堆積造成“假在線”的現(xiàn)象。解決假在線的標(biāo)準(zhǔn)做法是開啟心跳機(jī)制分網(wǎng)絡(luò)層和應(yīng)用層兩道。網(wǎng)絡(luò)層的心跳是TCP KeepAlive很多模塊里可以設(shè)置KeepAlive間隔默認(rèn)可能關(guān)著要打開我一般設(shè)在30秒。應(yīng)用層的心跳是模塊向服務(wù)器定時(shí)發(fā)送自定義的心跳幀比如每10秒發(fā)送一串固定的字節(jié)例如0xAA 0x55 0x00 0x01。服務(wù)器端只要在超過設(shè)定時(shí)間比如30秒沒有收到某臺(tái)AGV的任何數(shù)據(jù)就判定該車離線觸發(fā)告警并停止下發(fā)指令。模塊側(cè)的掉線重連也要做硬性配置。我在模塊里設(shè)置的參數(shù)是檢測(cè)到WiFi斷開后立即重連TCP斷線后3秒重連重連失敗則不斷重試同時(shí)開啟硬件看門狗防止模塊內(nèi)部程序跑飛。這里說一個(gè)實(shí)操心得模塊的硬件看門狗觸發(fā)后會(huì)讓模塊重啟重啟再連上服務(wù)器一般需要30秒左右這期間AGV通訊是完全中斷的。所以不要依賴看門狗去解決頻繁掉線問題它只是最后一道保險(xiǎn)。真正要做的是把掉線的根因找出來大部分情況下都出在無線覆蓋和配置上。4.3 漫游、干擾與信道優(yōu)化AGV在倉(cāng)庫里跑會(huì)從一臺(tái)AP的信號(hào)范圍跑到另一臺(tái)AP的范圍這個(gè)切換過程叫漫游。家用WiFi的漫游體驗(yàn)差沒關(guān)系最多是視頻卡一下AGV的漫游可能會(huì)讓一個(gè)正在執(zhí)行中的任務(wù)被打斷所以漫游策略必須專門調(diào)。很多普通WiFi模塊不支持快速漫游802.11r在漫游時(shí)是“先斷開再連接”斷流時(shí)間在幾百毫秒到一秒不等。對(duì)于100ms周期的實(shí)時(shí)指令下發(fā)來說這個(gè)間隙確實(shí)會(huì)有影響。我們的應(yīng)對(duì)方案有三個(gè)層面一是把模塊的漫游觸發(fā)閾值調(diào)低一些讓模塊“戀家”一點(diǎn)避免在AP邊緣頻繁切換二是在AGV運(yùn)行路徑規(guī)劃中盡量避免讓AGV長(zhǎng)時(shí)間停留在兩臺(tái)AP的信號(hào)交界處或者在這個(gè)區(qū)域適當(dāng)降低AGV的運(yùn)行速度三是如果模塊支持“根據(jù)信號(hào)強(qiáng)度主動(dòng)切換”的功能就把切換閾值設(shè)置在-75dBm左右低于這個(gè)值再切高于這個(gè)值就老老實(shí)實(shí)待在原AP上。干擾問題在2.4GHz頻段尤其嚴(yán)重。倉(cāng)庫里的無線掃碼槍、工控機(jī)無線網(wǎng)卡、甚至是叉車上的藍(lán)牙設(shè)備都在搶這個(gè)頻段。我現(xiàn)場(chǎng)用無線頻譜分析儀掃了一遍發(fā)現(xiàn)好幾個(gè)AP的工作通道被附近的藍(lán)牙信標(biāo)和微波設(shè)備壓得厲害。解決方式很簡(jiǎn)單把相鄰AP的工作信道錯(cuò)開1、6、11三個(gè)非重疊信道盡量分開用同時(shí)把AP發(fā)射功率調(diào)到合適的檔位不要把信號(hào)開太滿造成相鄰AP相互干擾。如果倉(cāng)庫不大甚至可以直接改成5GHz頻段AGV模塊也選支持雙頻的型號(hào)5GHz干擾小、速率高穿墻能力弱一點(diǎn)但AGV都是走視距內(nèi)的通道問題不大。5. 與AGV調(diào)度系統(tǒng)的通訊對(duì)接5.1 通信幀結(jié)構(gòu)設(shè)計(jì)無線鏈路打通之后調(diào)度系統(tǒng)和AGV控制器之間的串口協(xié)議就得跑在這條鏈路上。原車協(xié)議是廠商定的我們盡量不動(dòng)但為了讓服務(wù)器端能穩(wěn)定解析我在原有協(xié)議外面包了一層通用幀結(jié)構(gòu)專門用來解決“數(shù)據(jù)從哪來、到哪去、是否完整”的問題。幀結(jié)構(gòu)設(shè)計(jì)如下幀頭用2個(gè)字節(jié)0xAA 0x55然后跟1個(gè)字節(jié)的長(zhǎng)度域表示負(fù)載長(zhǎng)度1個(gè)字節(jié)的幀類型域區(qū)分上行狀態(tài)、下行指令、心跳應(yīng)答然后是負(fù)載數(shù)據(jù)最后2個(gè)字節(jié)放CRC16校驗(yàn)。上行狀態(tài)幀示例AA 55 0A 01 22 00 00 01 2C 01 00 64 58 1E 幀頭 長(zhǎng)度 類型 負(fù)載數(shù)據(jù)(10字節(jié)) CRC16其中負(fù)載數(shù)據(jù)里包含AGV當(dāng)前坐標(biāo)X、坐標(biāo)Y、方向角、速度、電量以及故障碼。調(diào)度服務(wù)器收到這個(gè)幀后先做CRC校驗(yàn)再按幀類型分發(fā)到對(duì)應(yīng)的解析模塊。下行指令幀的結(jié)構(gòu)類似只是類型域不同負(fù)載是目標(biāo)點(diǎn)、速度、動(dòng)作命令這些。心跳幀則是固定內(nèi)容如AA 55 00 02 34 12不帶負(fù)載。幀結(jié)構(gòu)定下來之后還有一個(gè)重要決策AGV的狀態(tài)上報(bào)頻率。我們用100ms一個(gè)周期也就是每秒10幀每幀十來個(gè)字節(jié)數(shù)據(jù)量并不大但服務(wù)器端解析、存儲(chǔ)、畫面刷新的壓力會(huì)成一個(gè)臺(tái)階。這個(gè)頻率要根據(jù)調(diào)度系統(tǒng)的算力來定如果調(diào)度服務(wù)器性能一般把周期放寬到200ms也行AGV速度不高的話完全夠用。5.2 粘包和半包的處理串口數(shù)據(jù)走TCP傳輸最經(jīng)典的問題就是粘包和半包。TCP是面向字節(jié)流的它不保證一次recv收到的數(shù)據(jù)恰好對(duì)應(yīng)一幀串口數(shù)據(jù)。調(diào)度服務(wù)器同時(shí)管理幾十臺(tái)AGV的連接每路連接都在不停收數(shù)據(jù)如果不做拆包處理服務(wù)器端解析到的一定是亂套的字節(jié)流。我在服務(wù)器端的接收邏輯是用一個(gè)環(huán)形緩沖區(qū)把收到的字節(jié)先全部塞進(jìn)去然后循環(huán)掃描緩沖區(qū)按我們定的幀頭、長(zhǎng)度、CRC規(guī)則一幀一幀地拆出來。粘包的情況靠幀頭和長(zhǎng)度自然切分半包的情況則等下一批數(shù)據(jù)到達(dá)后再拼出來。給一段參考的Python解析框架def parse_stream(buffer): frames [] while True: if len(buffer) 4: break # 查找?guī)^ if buffer[0] ! 0xAA or buffer[1] ! 0x55: buffer.pop(0) continue # 解析長(zhǎng)度 payload_len buffer[2] total_len 4 payload_len 2 if len(buffer) total_len: break # 半包等待更多數(shù)據(jù) frame_body bytes(buffer[:total_len]) frames.append(frame_body) del buffer[:total_len] return frames這個(gè)框架在實(shí)際項(xiàng)目里運(yùn)行很穩(wěn)定。關(guān)鍵點(diǎn)在于使用緩沖區(qū)和循環(huán)解析而不是依賴單次recv事件就認(rèn)為收到完整幀這一點(diǎn)對(duì)任何自定義串口協(xié)議的無線化改造都適用。5.3 調(diào)度系統(tǒng)對(duì)接openTCS與自定義雙通道談到AGV調(diào)度系統(tǒng)圈子里聊得最多的一個(gè)是開源系統(tǒng)openTCS一個(gè)是各家自研的調(diào)度平臺(tái)。這個(gè)項(xiàng)目里我接觸過openTCS做技術(shù)驗(yàn)證也對(duì)接過自研調(diào)度平臺(tái)兩邊都說說。openTCS比較適合中小規(guī)模、以路徑規(guī)劃和任務(wù)分配為核心訴求的場(chǎng)景。它本身有一套相對(duì)完整的Kernel和Vehicle Driver框架你可以把你的AGV當(dāng)作一個(gè)“vehicle”接入通過通訊驅(qū)動(dòng)層往AGV發(fā)命令、收狀態(tài)。openTCS底層路徑規(guī)劃用到了A*相關(guān)的算法多臺(tái)AGV并行調(diào)度時(shí)指令下發(fā)頻次較高對(duì)通訊鏈路的實(shí)時(shí)性要求也更嚴(yán)格。把串口轉(zhuǎn)WiFi鏈路作為openTCS和AGV之間的傳輸通道需要在openTCS里配置一個(gè)自定義通信驅(qū)動(dòng)讓它向AGV模塊的TCP端口發(fā)送協(xié)議指令并解析AGV上報(bào)的狀態(tài)幀。自研調(diào)度平臺(tái)的對(duì)接方式就更靈活了通常是調(diào)度平臺(tái)提供一個(gè)TCP服務(wù)端AGV模塊的TCP Client連上來平臺(tái)側(cè)用獨(dú)立的通訊模塊統(tǒng)一管理連接和解析。我的經(jīng)驗(yàn)是無論用哪套系統(tǒng)都要在調(diào)度平臺(tái)和AGV控制器之間加一個(gè)“協(xié)議適配層”不要讓調(diào)度平臺(tái)直接拼串口協(xié)議字節(jié)。這樣即便以后換了控制器或者換了調(diào)度系統(tǒng)改的只是適配層的映射關(guān)系不至于推倒重來。5.4 多車并發(fā)帶寬與調(diào)度節(jié)奏多臺(tái)AGV同時(shí)在線很多人會(huì)擔(dān)心WiFi帶寬不夠用。我簡(jiǎn)單算過一筆賬每臺(tái)AGV以100ms周期上報(bào)一個(gè)15字節(jié)左右的幀每秒就是150字節(jié)30臺(tái)AGV每秒總共也就4.5KB左右的上行數(shù)據(jù)量下行指令更稀疏偶爾一條任務(wù)指令也就是幾十字節(jié)。這個(gè)數(shù)據(jù)量相對(duì)WiFi幾Mbps到幾十Mbps的實(shí)際吞吐率來說是九牛一毛。真正的瓶頸不在于帶寬而在于AP的并發(fā)連接數(shù)。普通企業(yè)級(jí)AP帶幾十個(gè)終端問題不大但如果是幾塊錢一個(gè)的民用路由器帶機(jī)量二三十臺(tái)就可能出現(xiàn)連接不穩(wěn)定、延遲飆升。所以如果現(xiàn)場(chǎng)AGV數(shù)量超過二十臺(tái)AP一定選企業(yè)級(jí)的并關(guān)注它的推薦帶機(jī)量參數(shù)。調(diào)度節(jié)奏上也要控制好指令風(fēng)暴。有的調(diào)度算法比如多車路徑規(guī)劃時(shí)會(huì)在某個(gè)節(jié)點(diǎn)同時(shí)向大量AGV下發(fā)指令所有數(shù)據(jù)包同時(shí)涌向AP的下行隊(duì)列WiFi的競(jìng)爭(zhēng)機(jī)制會(huì)讓某些包延遲明顯增大。我做過一個(gè)優(yōu)化給AP開啟WMMWi-Fi Multimedia模式把AGV調(diào)度業(yè)務(wù)的數(shù)據(jù)包標(biāo)記為高優(yōu)先級(jí)隊(duì)列和倉(cāng)庫里的掃碼槍、辦公數(shù)據(jù)區(qū)分開實(shí)測(cè)在指令高峰期延遲提高了30%以上的穩(wěn)定性。這個(gè)優(yōu)化零成本效果卻很明顯值得所有做AGV無線改造的人試一下。6. 現(xiàn)場(chǎng)問題實(shí)錄與排查經(jīng)驗(yàn)6.1 高頻故障速查表整個(gè)項(xiàng)目實(shí)施下來我把遇到過的和同行業(yè)朋友分享過的典型問題整理成了一張速查表現(xiàn)場(chǎng)出問題可以直接對(duì)著查。故障現(xiàn)象可能原因排查手段與解決串口數(shù)據(jù)亂碼波特率、校驗(yàn)位配置不匹配核對(duì)原車控制器串口參數(shù)在模塊網(wǎng)頁重新配置服務(wù)器收不到任何數(shù)據(jù)TCP連接未建立或模塊處于AT模式檢查模塊工作模式是否為透明傳輸檢查服務(wù)器IP端口放行模塊偶發(fā)掉線又自動(dòng)恢復(fù)DHCP租約到期或IP地址沖突改為靜態(tài)IPDNS靜態(tài)綁定小車一直在某區(qū)域丟包AP覆蓋盲區(qū)或金屬貨架遮擋沿路徑測(cè)試信號(hào)調(diào)整AP位置或增加補(bǔ)點(diǎn)延遲突然飆升到幾百毫秒同頻段干擾或某AP帶機(jī)量過載換信道、開WMM、QoS標(biāo)記錯(cuò)開非重疊信道重啟后長(zhǎng)時(shí)間連不上服務(wù)器模塊開機(jī)掃描SSID耗時(shí)長(zhǎng)關(guān)閉省電模式縮短TCP重連間隔必要時(shí)讓模塊記憶上次連接兩臺(tái)AGV的數(shù)據(jù)互相串服務(wù)器端按幀頭解析邏輯缺陷檢查粘包半包處理邏輯按Socket區(qū)分?jǐn)?shù)據(jù)源6.2 三個(gè)典型案例復(fù)盤案例一某臺(tái)AGV一過通道拐彎就掉線。排查了很久最后發(fā)現(xiàn)是AGV走到拐彎處時(shí)車身正好把天線遮擋在了金屬貨架和車體之間形成定向屏蔽。解決辦法不是在無線參數(shù)上動(dòng)刀而是把天線位置從車體側(cè)面改到了車頂中央信號(hào)立馬從-78dBm改善到-62dBm。這個(gè)案例讓我深刻體會(huì)到天線位置是無線通訊里最便宜的優(yōu)化項(xiàng)也是最容易被忽略的優(yōu)化項(xiàng)。案例二服務(wù)器端顯示多臺(tái)AGV狀態(tài)刷新延遲但ping模塊都是正常的。查到最后發(fā)現(xiàn)是服務(wù)器端程序用單線程在輪詢解析所有Socket連接某臺(tái)AGV的串口日志數(shù)據(jù)量一上來把整個(gè)處理線程阻塞了。優(yōu)化方式是把每臺(tái)AGV的連接解析放到獨(dú)立線程或者使用異步IO問題瞬間消失。這提醒我無線鏈路沒問題的時(shí)候要看鏈路兩端的處理程序有沒有瓶頸。案例三AGV停在充電樁區(qū)域時(shí)頻繁報(bào)“通信超時(shí)”。這個(gè)位置AP信號(hào)其實(shí)是滿格的但充電樁運(yùn)行時(shí)的電磁干擾非常嚴(yán)重頻譜儀上能看到明顯的底噪抬升。我把充電區(qū)域的AP調(diào)到5GHz頻段同時(shí)把模塊也換成雙頻型號(hào)問題解決。如果模塊不支持5GHz那么在充電樁區(qū)域加裝屏蔽措施或者把充電樁和AP的物理距離拉開至少五米也有改善。6.3 改造后的穩(wěn)定性數(shù)據(jù)與心得改造上線運(yùn)行三個(gè)月后我拉了一次數(shù)據(jù)AGV因通訊故障導(dǎo)致的停機(jī)次數(shù)從改造前平均每周兩三次降到了一個(gè)月不到一次拖鏈電纜和滑觸線相關(guān)的備件費(fèi)用基本清零。無線鏈路的平均端到端延遲穩(wěn)定在15ms左右最差情況跨AP漫游瞬間控制在300ms以內(nèi)滿足最初定下的指標(biāo)。我個(gè)人在實(shí)際操作中的體會(huì)有三點(diǎn)供大家參考。第一串口轉(zhuǎn)WiFi改造并不是什么高科技它的核心價(jià)值在于用最小改動(dòng)成本把移動(dòng)設(shè)備從物理線纜的束縛里解放出來但前提是無線基礎(chǔ)設(shè)施必須按工業(yè)標(biāo)準(zhǔn)來搭省掉AP部署和信道優(yōu)化的錢后面會(huì)用故障時(shí)間加倍還回來。第二模塊的選型寧可用工業(yè)級(jí)也別圖便宜用開發(fā)板長(zhǎng)時(shí)間運(yùn)行的穩(wěn)定性差異特別大這個(gè)錢不能省。第三調(diào)試時(shí)一定要把原車串口協(xié)議吃透一定要設(shè)計(jì)好服務(wù)器端的拆包邏輯這兩個(gè)環(huán)節(jié)做好了后面所有問題都好解決做不好無線鏈路再快也會(huì)在數(shù)據(jù)解析上栽跟頭。這批AGV后續(xù)計(jì)劃接入視覺導(dǎo)航和自動(dòng)充電功能串口轉(zhuǎn)WiFi這條鏈路從帶寬和時(shí)延上都是夠用的到時(shí)候只需要在幀協(xié)議里擴(kuò)展新的幀類型就行。通訊改造雖然只是整個(gè)AGV系統(tǒng)里不起眼的一環(huán)但它就像人的神經(jīng)系統(tǒng)平時(shí)感覺不到它的存在一旦出問題整個(gè)系統(tǒng)都會(huì)癱瘓。把這層基礎(chǔ)打好后續(xù)的智能化升級(jí)才能走得穩(wěn)。