牟曉東
超聲波傳感器能檢測(cè)與前方障礙物間的距離,如果將它固定于360 度旋轉(zhuǎn)的舵機(jī)上持續(xù)采樣,就能將采樣獲取的數(shù)據(jù)繪制成雷達(dá)圖進(jìn)行動(dòng)態(tài)展示。
樹莓派3B+ 和古德微擴(kuò)展板各一塊,HC-SR04 超聲波傳感器一個(gè),4 路8 線電滑環(huán)一個(gè),360 度舵機(jī)一個(gè),紅色、綠色LED 燈各一支;還需要電烙鐵和熱熔槍各一把。
用熱熔槍將滑環(huán)中央的轉(zhuǎn)子底端與舵機(jī)輸出轉(zhuǎn)子進(jìn)行固定,注意二者的中心點(diǎn)要盡量吻合,防止旋轉(zhuǎn)時(shí)偏心。再將滑環(huán)中央轉(zhuǎn)子的頂端與超聲波傳感器頂端固定好,也要中心對(duì)齊。接著,將滑環(huán)外圍的定子圈的四根線與古德微擴(kuò)展板的20 號(hào)和21 號(hào)(共四個(gè)引腳)進(jìn)行連接,紅線接電源正極VCC,黑線接地GND,橙紅色線接Trig 信號(hào)發(fā)射端,棕色線接Echo信號(hào)回聲端。滑環(huán)中央轉(zhuǎn)子4 根引線分別與超聲波傳感器的四個(gè)引腳進(jìn)行對(duì)應(yīng)連接(電烙鐵點(diǎn)錫);將舵機(jī)固定好之后,連接線插入擴(kuò)展板的18 號(hào)引腳,注意黑色、紅色和棕黃色三根線分別與GND、VCC和信號(hào)控制D 端連接;然后,將紅色和綠色LED 燈按照“長(zhǎng)腿正、短腿負(fù)”的規(guī)則分別插入擴(kuò)展板的5 號(hào)和6 號(hào)引腳;最后,給樹莓派插入數(shù)據(jù)線,通電啟動(dòng)操作系統(tǒng)(如圖1)。
(1)庫(kù)模塊的導(dǎo)入與變量初始化
首先, 導(dǎo)入GPIO Zero 、Matplot Lib等庫(kù)模塊: “from gpiozero import LED , Servo , Distance Sensor ”“ importnumpyasnp”“importmatplotlib”"impor tmatplotlib.pyplot as plt”和“importtime”; 然后進(jìn)行LED 燈、舵機(jī)和超聲波傳感器實(shí)例的初始化操作:“ Red _ LED= LED ( 5 ) ”“ Green_LED=LED(6)”“servo=Servo(18)”和“sensor=DistanceSensor(echo=21,trigger=20,max_distance=4)”, 并且通過(guò)語(yǔ)句“servo.mid()”控制360 度舵機(jī)以中速帶動(dòng)超聲波傳感器向一個(gè)方向開始旋轉(zhuǎn);再設(shè)置雷達(dá)圖繪制畫布的寬度和高度,大小分別為8 和6(單位為英寸):“plt.figure(figsize=(8,6))”;建立變量ax,賦值為“plt.subplot(111,projection='polar')”, 作用是設(shè)置畫圖樣式為“極坐標(biāo)”模式(Polar);建立變量theta, 賦值為“np.arange(0,2*np.pi,2*np.pi/30)”,通過(guò)調(diào)用Numpy 庫(kù)中的arange() 函數(shù)返回一個(gè)起點(diǎn)為0、終點(diǎn)為2Pi(360 度圓周)的等差數(shù)列,固定步長(zhǎng)為2Pi/30;語(yǔ)句“plt.ion()”的作用是將figure 繪圖設(shè)置為交互模式;建立變量data,賦值為空列表“[]”,作用是存放超聲波傳感器每旋轉(zhuǎn)360 度一周掃描后檢測(cè)生成的若干個(gè)與前方障礙物的間距值。
(2)“whileTrue:”循環(huán)體
如果超聲波傳感器檢測(cè)的障礙間距值在安全范圍內(nèi)(比如20cm),則控制綠色LED 燈常亮:“Green_LED.on()”;在每次旋轉(zhuǎn)360 度的過(guò)程中,需要獲取30 個(gè)值與之前產(chǎn)生的等差數(shù)列30 個(gè)刻度值對(duì)應(yīng):“for i in range(30):”; 建立變量distance,賦值為“round(sensor.distance,4)”, 獲取檢測(cè)到的障礙間距數(shù)據(jù)( 保留4位小數(shù)), 并且通過(guò)語(yǔ)句“print(i,distance)” 進(jìn)行輸出監(jiān)測(cè); 在“if distance<=0.2:” 分支結(jié)構(gòu)中, 如果條件成立則亮紅色LED 燈、關(guān)閉綠色LED 燈:“Red_LED.on()”“Green_LED.off()”, 持續(xù)時(shí)間為0.01 秒鐘:“time.sleep(0.01)”; 然后通過(guò)語(yǔ)句“data.append(distance)”, 將數(shù)據(jù)有序追加到data 列表中,再關(guān)閉紅色LED燈、打開綠色LED 燈:“Red_LED.off()”“Green_LED.on()”。

進(jìn)入下一次循環(huán)(range),30次循環(huán)結(jié)束之后, 開始繪制雷達(dá)圖: 語(yǔ)句“ax.plot(theta,data,'o--',color='g',label='data',linewidth=1)”對(duì)極坐標(biāo)進(jìn)行數(shù)據(jù)設(shè)置,包括30 個(gè)0 至360 度的等差刻度值、30 個(gè)超聲波檢測(cè)障礙間距值(data 列表)、線的模式(虛線)、顏色(Green 綠色)和線寬(linewidth)等; 語(yǔ)句“ax.fill(theta,data,facecolor='g',alpha=0.15)” 是對(duì)30個(gè)障礙間距值與極坐標(biāo)中心點(diǎn)圍成的封閉區(qū)域進(jìn)行設(shè)置,包括填充顏色和透明度等;語(yǔ)句“plt.pause(0.1)”的作用是控制交互式繪圖過(guò)程中數(shù)據(jù)更新的預(yù)留時(shí)間緩沖,預(yù)防出現(xiàn)圖形不能及時(shí)刷新顯示的問(wèn)題;語(yǔ)句“plt.cla()”的作用是清除當(dāng)前活動(dòng)軸的數(shù)據(jù)內(nèi)容(相當(dāng)于清空操作),語(yǔ)句“plt.show()”的作用是繪制顯示圖像,語(yǔ)句“data.clear()”的作用是清除data 列表中的當(dāng)前數(shù)據(jù),為下一次循環(huán)保存新數(shù)據(jù)“留空”。
將程序保存為Radar.py, 點(diǎn)擊“ 運(yùn)行” 按鈕進(jìn)行超聲波動(dòng)態(tài)雷達(dá)的測(cè)試。超聲波傳感器在舵機(jī)的帶動(dòng)下開始勻速旋轉(zhuǎn),程序界面中也不斷有“00.2698”“23 0.3555”等信息出現(xiàn),表示每次旋轉(zhuǎn)一周所監(jiān)測(cè)到的30 個(gè)障礙間距值;同時(shí),綠色LED 燈亮起,如果出現(xiàn)有近距離的障礙物(在20cm 范圍內(nèi)),則會(huì)亮起紅色LED 燈。超聲波傳感器每旋轉(zhuǎn)一周,就會(huì)出現(xiàn)一個(gè)雷達(dá)極坐標(biāo)圖,繪制有每個(gè)點(diǎn)所處的二維空間位置(角度值)和距離中心的半徑大小(障礙物間距值),同時(shí)在這些坐標(biāo)點(diǎn)所包圍生成的封閉區(qū)域內(nèi),雷達(dá)圖是以一定透明度的綠色來(lái)展示的。隨著超聲波傳感器的不停旋轉(zhuǎn),同時(shí)在其周圍變換出現(xiàn)各種障礙物,整個(gè)雷達(dá)圖也在不斷發(fā)生變化(如圖2)。
關(guān)注“壹零社”公眾號(hào)下載源代碼。