朱成彪 ,張陸翔 ,2,趙奉奎
(1.南京林業(yè)大學(xué),江蘇 南京 210037; 2.南京奧聯(lián)新能源有限公司,江蘇 南京 210037)
隨著國家大力支持研發(fā)和使用智能設(shè)備,AGV(Automated Guided Vehicle)小車憑借其智能化、自動(dòng)化和高柔韌性等優(yōu)點(diǎn),應(yīng)用范圍越來越廣。 除了物流行業(yè),AGV 小車還被廣泛地應(yīng)用在汽車、醫(yī)藥、化工等行業(yè)中。 AGV 小車的運(yùn)用,有利于優(yōu)化產(chǎn)業(yè)結(jié)構(gòu),提高生產(chǎn)效率和加快物流等產(chǎn)業(yè)的升級(jí)。
AGV 小車智能高效的運(yùn)作離不開可靠的引導(dǎo)方式, 目前主流的引導(dǎo)方式主要包括電磁引導(dǎo)[1]、慣性引導(dǎo)[2]、激光引導(dǎo)[3]和視覺引導(dǎo)。 Hyunhak Cho等人(2017)提出了利用磁編碼器的電磁引導(dǎo)AGV系統(tǒng)[4]。 李照和舒志兵(2017)提出利用模糊算法來調(diào)控AGV 兩個(gè)主動(dòng)輪速度從而優(yōu)化電磁引導(dǎo)AGV 系統(tǒng)[5]。 Ti-chun Wang(2020)提出了基于多傳感器的慣性引導(dǎo)AGV 系統(tǒng)[6]。張東等人(2019)提出利用模糊 PID 算法優(yōu)化慣性引導(dǎo) AGV 系統(tǒng)[7]。Kyunghoon Jung(2014)提出利用無跡卡爾曼濾波器和模糊推理系統(tǒng)進(jìn)行定位改進(jìn)的激光引導(dǎo)AGV 系統(tǒng)[8]。 王心越(2019)等人設(shè)計(jì)了用于汽車防撞預(yù)警的激光引導(dǎo) AGV 系統(tǒng)[9]。劉康婷(2021)等人研究了基于視覺引導(dǎo)的AGV 系統(tǒng)[10]。 與前三種引導(dǎo)方式相比,視覺引導(dǎo)具有設(shè)備成本低、識(shí)別能力強(qiáng)、不易積累誤差和高柔韌性等特點(diǎn)[11-12]。
本文從引導(dǎo)線檢測和轉(zhuǎn)向控制兩方面入手,設(shè)計(jì)了基于視覺引導(dǎo)的AGV 系統(tǒng), 并通過試驗(yàn)證明搭載該系統(tǒng)的小車可以完成自動(dòng)引導(dǎo)。
如圖1 所示是AGV 小車的結(jié)構(gòu)圖, 小車包括Jetson Nano 主板、散熱器、攝像頭、無線網(wǎng)卡、天線、碳纖維底盤、橡膠輪胎、電機(jī)、舵機(jī)和避震器等部分。圖2 是AGV 系統(tǒng)的基本框架,小車通過攝像頭獲取前方路徑的圖像信息, 將信息傳入U(xiǎn)buntu 操作系統(tǒng)中,在Ubuntu 操作系統(tǒng)內(nèi)利用Python 語言對(duì)圖像信息進(jìn)行處理和分析。 Ubuntu 操作系統(tǒng)運(yùn)行在Nvidia Jetson Nano 主板中, 程序?qū)⒏鶕?jù)圖像信息處理結(jié)果將AGV 轉(zhuǎn)向和驅(qū)動(dòng)命令通過IIC 發(fā)送給驅(qū)動(dòng)板, 驅(qū)動(dòng)板則對(duì)舵機(jī)和電機(jī)進(jìn)行驅(qū)動(dòng),實(shí)現(xiàn)AGV 小車的循跡行駛。
圖1 AGV 小車結(jié)構(gòu)圖Figure 1 AGV Car structure diagram
圖2 AGV 系統(tǒng)的基本框架Figure2 Basic framework of AGV system
引導(dǎo)線檢測是本系統(tǒng)設(shè)計(jì)的基礎(chǔ),檢測流程如圖3 所示。 首先通過 Canny 算法,對(duì)攝像頭獲取的圖像信息進(jìn)行邊緣檢測, 檢測出圖像中的邊緣信息;再利用ROI 函數(shù)進(jìn)行剔除操作,將車道外的邊緣信息剔除,只保留需要的區(qū)域,通過霍夫變換將該區(qū)域內(nèi)的邊緣信息進(jìn)行整合分類,利用離群值過濾去除分類里誤差較大的邊緣信息;最后通過最小二乘擬合將處理好的邊緣信息進(jìn)行擬合,并使用畫線函數(shù)將擬合得到的線段在圖像上繪制出來以便后續(xù)操作。
圖3 邊緣檢測流程圖Figure 3 Flow chart of edge detection
進(jìn)行引導(dǎo)線檢測的第一步就是通過邊緣檢測將圖片的邊緣信息提取出來,之后再判斷這些邊緣是否屬于引導(dǎo)線, 所以說邊緣檢測是很重要的環(huán)節(jié)。 機(jī)器視覺上進(jìn)行邊緣檢測,一個(gè)通用的算法為Canny 算法。Canny 算法的基本步驟依次為:利用高斯模糊去除噪聲、計(jì)算梯度的方向和大小、對(duì)梯度幅值進(jìn)行非極大值抑制、選擇閾值、檢測和連接邊緣等[13-14]。 Canny 算法中梯度方向 θ 和大小 M 的計(jì)算公式如式1 所示。
Canny 算法是通過求取圖像上每一個(gè)像素點(diǎn)周圍像素變化的梯度來確定這個(gè)點(diǎn)是不是邊緣[15]。圖4 是Canny 邊緣檢測示例圖,圖中橫向?yàn)樘荻确较?,沿著梯度方向有三個(gè)點(diǎn):C,A 和B,可以很明顯看到A 點(diǎn)是處在邊緣上的點(diǎn),B 點(diǎn)和C 點(diǎn)沒有處在邊緣上。沿著梯度方向?qū)@三個(gè)點(diǎn)周邊的像素值求梯度,會(huì)發(fā)現(xiàn)C 點(diǎn)左右像素值大致相等,沿著橫向方向的梯度接近于0,B 點(diǎn)同理。 而對(duì)于A 點(diǎn),其左右像素值相差較大,對(duì)其左右兩邊的像素值求梯度,A 點(diǎn)處的梯度值會(huì)非常大。因此,可以通過求某點(diǎn)周圍像素值的梯度來反映其是否是邊緣點(diǎn),如果該點(diǎn)左右兩邊梯度值較大,則該點(diǎn)便極大概率為一個(gè)邊緣點(diǎn)。
圖4 Canny 邊緣檢測示例圖Figure 4 Flow chart of edge detection
在實(shí)際的引導(dǎo)線檢測過程中,往往還會(huì)受到許多其他因素影響,例如光照、攝像頭像素等。受到這些因素的影響,會(huì)導(dǎo)致檢測出現(xiàn)錯(cuò)誤,此時(shí)就需要利用Canny 算法對(duì)梯度設(shè)上閾值和下閾值,如圖5所示。
圖5 上下閾值示例圖Figure 5 Example diagram of upper and lower thresholds
對(duì)于一些梯度超過上閾值的點(diǎn), 如圖中的A點(diǎn),則認(rèn)為A 點(diǎn)是個(gè)邊緣點(diǎn)。 然后對(duì)于那些梯度小于下閾值的點(diǎn),如圖中D 點(diǎn),則認(rèn)為D 點(diǎn)不是一個(gè)邊緣點(diǎn)。然而還有一些點(diǎn)的梯度正好介于上閾值和下閾值之間,如圖中B 點(diǎn)和C 點(diǎn),這兩點(diǎn)有可能是邊緣點(diǎn),也有可能不是邊緣點(diǎn),無法對(duì)B 點(diǎn)和C 點(diǎn)進(jìn)行準(zhǔn)確判斷。 對(duì)此,Canny 算法中應(yīng)用了關(guān)聯(lián)討論:將梯度高于上閾值的點(diǎn)稱為強(qiáng)邊緣點(diǎn),如強(qiáng)邊緣A 點(diǎn); 將梯度在上閾值和下閾值之間的點(diǎn)稱為弱邊緣點(diǎn),如弱邊緣B 點(diǎn)和弱邊緣C 點(diǎn)。 任何一個(gè)弱邊緣點(diǎn),如果它與強(qiáng)邊緣點(diǎn)相連,如圖中弱邊緣B 點(diǎn)與強(qiáng)邊緣A 點(diǎn)相連, 此時(shí)就認(rèn)為B 點(diǎn)是真正的邊緣點(diǎn);如果弱邊緣不與強(qiáng)邊緣相連,如圖中C點(diǎn),則認(rèn)為C 點(diǎn)不是一個(gè)邊緣點(diǎn)。 通過這種方式,即可實(shí)現(xiàn)弱邊緣的檢測處理。 本論文調(diào)用OpenCV函數(shù)庫中的cv2.Canny 函數(shù)對(duì)圖像進(jìn)行Canny 算法檢測。Canny 邊緣檢測結(jié)果如圖6 所示,圖6a)為原始圖片,圖6b)為Canny 邊緣檢測的結(jié)果。 由圖可知,利用Canny 邊緣檢測可以準(zhǔn)確提取出圖像中的邊緣信息。
圖6 Canny 邊緣檢測結(jié)果圖Figure 6 Canny edge detection result graph
通過前文的Canny 邊緣檢測算法,成功提取圖像中的邊緣信息,這些邊緣信息里,既包括小車運(yùn)行車道的邊緣信息,也包括其他車道部分的邊緣信息。 圖像中其他車道部分的邊緣信息,對(duì)于檢測引導(dǎo)線來說是沒有意義的,會(huì)造成干擾,所以需要把這些無關(guān)的信息剔除。因?yàn)楸疚臋z測數(shù)據(jù)集的特殊性,小車運(yùn)行車道的圖像信息一直分布在圖像中一個(gè)類似梯形的區(qū)域內(nèi),如圖7 所示。
圖7 感興趣區(qū)域示例圖Figure 7 Example map of the region of interest
此時(shí)需要使用 ROI(Region of Interest)函數(shù),把圖像中這個(gè)梯形區(qū)域以外的那些邊緣信息剔除掉,只保留梯形區(qū)域里的信息,這樣就實(shí)現(xiàn)了對(duì)這些無關(guān)信息的過濾剔除。本論文通過調(diào)用OpenCV 函數(shù)庫中的 cv2.fillPoly 函數(shù), 并結(jié)合圖 7 中 1 號(hào)點(diǎn)、2號(hào)點(diǎn)、3 號(hào)點(diǎn)和4 號(hào)點(diǎn)的像素坐標(biāo)進(jìn)行感興趣區(qū)域提取。 感興趣區(qū)域提取結(jié)果如圖8 所示。
圖8 感興趣區(qū)域提取結(jié)果Figure 8 Region of interest
通過前文感興趣區(qū)域的提取獲取了圖中兩條引導(dǎo)線所在的梯形區(qū)域。下一步將利用這個(gè)梯形區(qū)域,從中提取出屬于引導(dǎo)線的線段,從而得到這兩條引導(dǎo)線的具體位置, 此時(shí)就需要用到霍夫變換?;舴蜃儞Q的基本原理是利用點(diǎn)和線的對(duì)偶性,即在原始二維圖像坐標(biāo)系下的一個(gè)點(diǎn)對(duì)應(yīng)了參數(shù)坐標(biāo)系中的一條直線;同樣,參數(shù)坐標(biāo)系的一條直線對(duì)應(yīng)了原始二維坐標(biāo)系下的一個(gè)點(diǎn),原始坐標(biāo)系下直線上所有的點(diǎn),它們的斜率和截距是相同的,所以它們在參數(shù)坐標(biāo)系下對(duì)應(yīng)于同一個(gè)點(diǎn)。這樣在將原始坐標(biāo)系下的各個(gè)點(diǎn)投影到參數(shù)坐標(biāo)系下之后,看參數(shù)坐標(biāo)系下有沒有聚集點(diǎn),類似的聚集點(diǎn)就對(duì)應(yīng)了原始坐標(biāo)系下的直線[15-16]。
因?yàn)橐龑?dǎo)線分為左引導(dǎo)線和右引線,兩條引導(dǎo)線存在差異,所以在進(jìn)行霍夫變換前需要先定義一個(gè)按照斜率分類的函數(shù),將檢測出來的線段按照斜率分成兩類,即一類是左引導(dǎo)線,另一類是右引導(dǎo)線。 本文通過調(diào)用OpenCV 函數(shù)庫中 cv2.Hough LinesP 函數(shù)進(jìn)行霍夫變換?;舴蜃儞Q檢測結(jié)果為左引導(dǎo)線分類里有77 條線段,右引導(dǎo)線分類里有74條線段。利用霍夫變換成功將感興趣區(qū)域中的線段進(jìn)行整合分類。
利用霍夫變換成功將所有感興趣區(qū)域內(nèi)的線段按照斜率分成了左引導(dǎo)線和右引導(dǎo)線兩類,但是其中可能會(huì)有一些誤差線段。霍夫變換一共識(shí)別出151 條線段,這些線段并不全屬于左引導(dǎo)線或右引導(dǎo)線,其中可能包含無用的線段,例如噪點(diǎn)的連線也會(huì)被識(shí)別成一條線段。 這些點(diǎn)需要過濾掉。 通過對(duì)Canny 邊緣檢測結(jié)果圖的觀察可以發(fā)現(xiàn)引導(dǎo)線共同的一個(gè)特征,就是屬于引導(dǎo)線的線段的斜率應(yīng)該是大致相同的。 對(duì)此,可以求梯形內(nèi)所有的線段集合,取斜率,找那些斜率與平均斜率相差特別大的線段,即為不屬于需要檢測的引導(dǎo)線。 在此就需要使用離群值過濾函數(shù)。
本論文通過使用函數(shù)reject_abnormal_lines(lines,threshold=0.2),函數(shù)中 threshold 參數(shù)的閾值設(shè)置為0.2, 即如果某條線段的斜率與平均斜率相差超過0.2 就會(huì)被檢測出來。 利用剔除函數(shù)將被檢測出來的線段進(jìn)行剔除, 通過不斷循環(huán)此函數(shù),直到所有線段的斜率與平均斜率相差都小于或等于0.2,就完成了離群值過濾,利用保留下來的線段完成后續(xù)檢測。離群值過濾檢測結(jié)果為左引導(dǎo)線分類里保留69 條線段, 右引導(dǎo)線分類里保留52 條線段。通過使用離群值過濾可以成功將斜率誤差較大的線段去除,與霍夫變換檢測結(jié)果相比,共去除了30 條線段。
通過離群值過濾去除了分類里的誤差線段,保留了符合檢測要求的線段,此時(shí)需要使用最小二乘擬合將左引導(dǎo)線和右引導(dǎo)線分類里的線段各擬合成一條線段[16]。本論文通過調(diào)用函數(shù)np.polyfit 進(jìn)行最小二乘擬合,并利用畫線函數(shù)將擬合得到的線段在原圖上繪制出來以便后續(xù)操作,繪制結(jié)果如圖9所示。
圖9 引導(dǎo)線檢測結(jié)果Figure 9 Leading line detection results
利用檢測出的引導(dǎo)線信息可實(shí)現(xiàn)小車在車道內(nèi)的直線運(yùn)行,但對(duì)于一個(gè)AGV 系統(tǒng),還需要考慮小車的自動(dòng)轉(zhuǎn)向問題。 對(duì)此,需要在上文的引導(dǎo)線檢測基礎(chǔ)上,再添加檢測一條輔助線,來幫助實(shí)現(xiàn)AGV 智能小車的轉(zhuǎn)向控制。 本論文中選擇通過檢測AGV 小車行駛路徑上一段連續(xù)路徑的中心線,并將檢測得到的線段作為輔助線, 圖10 為轉(zhuǎn)向輔助線檢測結(jié)果。 當(dāng)路徑發(fā)生轉(zhuǎn)向時(shí),中心線也會(huì)發(fā)生偏移,檢測出來的輔助線也會(huì)發(fā)生偏移,而輔助線偏移的方向就是AGV 智能小車行駛路徑前方路段的變化方向。
圖10 轉(zhuǎn)向輔助線檢測圖Figure 10 Inspection diagram of steering assist line
通過對(duì)路徑中心線的檢測,得到了用于辨別方向變化的輔助線, 但是AGV 智能小車的轉(zhuǎn)向控制還需要得到偏移角度,對(duì)此需要求出轉(zhuǎn)向輔助線的斜率。 在普通的二維坐標(biāo)系中,想要得到一條線的斜率,只需要這條線上的兩點(diǎn)就可以完成,在圖像的像素坐標(biāo)系中也是類似。 利用坐標(biāo)檢測函數(shù),對(duì)轉(zhuǎn)向輔助線兩個(gè)頂點(diǎn)進(jìn)行檢測, 得到這條線段兩個(gè)頂點(diǎn)的像素坐標(biāo) P1(X1,Y1)和 P2(X2,Y2),利用這兩個(gè)頂點(diǎn)坐標(biāo)就可以求出這條輔助線的斜率K??紤]到AGV 智能小車實(shí)際行駛的路徑情況,有一部分的路線是直線,此時(shí)沒有轉(zhuǎn)向的需求,因此需要在求取斜率時(shí)檢測兩個(gè)頂點(diǎn)坐標(biāo)的第一個(gè)值是否相同。
本論文通過使用IF 判斷函數(shù), 用以判斷兩頂點(diǎn)像素坐標(biāo)的第一個(gè)數(shù)值的差是否為0, 即判斷(X2-X1)是否為 0。 如果為 0 則代表 AGV 智能小車運(yùn)行前方路徑?jīng)]有發(fā)生轉(zhuǎn)向,后續(xù)轉(zhuǎn)向控制就不需要執(zhí)行;如果不為0,則代表AGV 智能小車運(yùn)行前方路徑發(fā)生轉(zhuǎn)向,需要執(zhí)行后續(xù)轉(zhuǎn)向控制。 本文使用函數(shù) K=(y2-y1)/(x2-x1)求取斜率,利用該方法成功得到轉(zhuǎn)向輔助線的斜率K。
利用兩個(gè)頂點(diǎn)像素坐標(biāo)成功求得轉(zhuǎn)向輔助線斜率K 之后, 此時(shí)就需要使用反三角函數(shù)中的反正切函函數(shù),如圖11 所示,利用公式S=arctanK 得到輔助線與像素坐標(biāo)中X 軸的夾角S,然后再利用D=90°-S 就可以得到AGV 智能小車行駛前方路徑相對(duì)于小車當(dāng)前行駛方向的偏轉(zhuǎn)角度。
圖11 偏移角度示例圖Figure 11 Example diagram of offset angle
通過利用輔助線得到AGV 智能小車的偏移角度,AGV 智能小車就可以利用這個(gè)數(shù)據(jù)進(jìn)行方向修正以實(shí)現(xiàn)轉(zhuǎn)向。 但在方向修正之前,還需要進(jìn)一步處理, 因?yàn)锳GV 智能小車本身行駛時(shí)可能會(huì)有一個(gè)初始轉(zhuǎn)向系數(shù)。 這里用A 表示這個(gè)轉(zhuǎn)向系數(shù),A0表示初始轉(zhuǎn)向系數(shù), 正常情況下轉(zhuǎn)向系數(shù)A 的取值區(qū)間為(-1,1),其中-1 和 1 表示小車完全向左轉(zhuǎn)和完全向右轉(zhuǎn)。 如果直接用這個(gè)初始值A(chǔ)0加上前文得到的偏移角度D,會(huì)因?yàn)閮蓚€(gè)數(shù)據(jù)類型不同而產(chǎn)生錯(cuò)誤,無法實(shí)現(xiàn)方向修正。因此,需要使用AGV 智能小車自帶的PID 控制將前文得到的偏移角度轉(zhuǎn)化為實(shí)際的轉(zhuǎn)向系數(shù)A1, 將轉(zhuǎn)向系數(shù)A1輸入AGV 智能小車舵機(jī)驅(qū)動(dòng)控制系統(tǒng)中替換初始值A(chǔ)0,讓舵機(jī)調(diào)整小車行駛方向,從而完成轉(zhuǎn)向控制。PID 比例微分積分控制, 其公式如式2 所示。 PID控制器的參數(shù)選擇必須考慮動(dòng)態(tài)和靜態(tài)性能指標(biāo)的要求。 通過試驗(yàn)得到優(yōu)化的Kp、Ki和Kd三個(gè)參數(shù)值,從而完成轉(zhuǎn)向控制。
通過引導(dǎo)線檢測和轉(zhuǎn)向控制兩部分的設(shè)計(jì),便完成了基于機(jī)器視覺引導(dǎo)的AGV 系統(tǒng), 將系統(tǒng)傳入小車開始試驗(yàn)。AGV 小車運(yùn)作流程如圖12 所示。
圖12 AGV 小車運(yùn)作流程圖Figure 12 Operation flow chart of AGV trolley
擺好并啟動(dòng)小車后, 驅(qū)動(dòng)電機(jī)控制小車向前行駛,車載攝像頭會(huì)不斷獲取前方路徑圖像信息,然后將信息傳入Jetson Nano 主板中。 主板會(huì)根據(jù)代碼指令對(duì)圖像信息進(jìn)行分析處理, 得到小車當(dāng)前的行駛數(shù)據(jù)和小車運(yùn)行前方的路徑信息, 并通過這些數(shù)據(jù)判斷小車是否需要轉(zhuǎn)向。 如果需要轉(zhuǎn)向, 就會(huì)將利用輔助線計(jì)算得到的偏移角度發(fā)送給小車?yán)锏腜ID 控制,PID 控制利用偏移角度計(jì)算得到小車需要的轉(zhuǎn)向系數(shù), 將轉(zhuǎn)向系數(shù)傳給小車的舵機(jī)驅(qū)動(dòng),舵機(jī)驅(qū)動(dòng)控制舵機(jī)使小車完成轉(zhuǎn)向。如果不需要轉(zhuǎn)向就判斷小車是否需要停車, 如果需要停車就停止驅(qū)動(dòng)電機(jī),使小車結(jié)束運(yùn)行;如果不需要停車, 就再通過攝像頭獲取新的路徑信息進(jìn)行數(shù)據(jù)處理和后續(xù)的判斷操作。 通過不斷循環(huán)收集數(shù)據(jù)、處理信息和判斷執(zhí)行等操作,以此完成小車的自動(dòng)引導(dǎo)。
本文主要介紹了基于視覺引導(dǎo)的AGV 系統(tǒng)設(shè)計(jì),系統(tǒng)主要通過引導(dǎo)線檢測和轉(zhuǎn)向控制兩部分實(shí)現(xiàn)。系統(tǒng)試驗(yàn)中引導(dǎo)線檢測程序能夠準(zhǔn)確檢測并提取引導(dǎo)線,信息分析程序能夠?qū)μ崛〉降囊龑?dǎo)線信息進(jìn)行正確分析處理,并且控制程序能使小車自動(dòng)沿引導(dǎo)線行駛。 試驗(yàn)結(jié)果表明基于機(jī)器視覺的AGV 小車能夠?qū)崿F(xiàn)自動(dòng)引導(dǎo)功能。