常見的視覺循跡小車都具備有路徑識別、軌跡跟蹤、轉(zhuǎn)向避障、自主決策等基本功能,如果不采用紅外避障的方案,那么想要完全滿足以上這些功能,攝像頭、電機(jī)、傳感器這類關(guān)鍵部件缺一不可,由此一來小車成本也就難以控制了。
但如果,有這樣一款視覺循跡小車,它可以完全自己手搓,并用成本極低的雪糕棒來搭建車體架構(gòu),不僅保留了傳統(tǒng)循跡小車具備的所有功能,還額外適配上一塊小屏幕并配上UI界面用于升級人機(jī)交互方式。
更重要的是,它的器件成本被壓縮到200元左右,這樣的視覺循跡小車能讓你心動嗎~
核桃派視覺循跡小車簡介
核桃派H616視覺循跡小車的循跡功能和人機(jī)交互界面整體代碼由Python+Qt實(shí)現(xiàn),它通過攝像頭獲取周圍環(huán)境的圖像信息,并利用圖像處理算法識別出特定的標(biāo)記或路徑,然后根據(jù)標(biāo)記或路徑的形狀和方向信息,自動控制小車的行駛方向和速度,以實(shí)現(xiàn)沿著預(yù)定軌跡自動行駛的目的。
手搓一臺視覺循跡小車所需要用到的基礎(chǔ)硬件材料如下:
1、核桃派H616開發(fā)板+LCD屏幕≈178元;
2、四個(gè)電機(jī)+車輪≈16元;
3、電機(jī)驅(qū)動模塊≈4元;
4、攝像頭≈50元;
5、移動電源≈20元;
6、雪糕棒若干≈4元(也可以≈不要錢);
循跡功能實(shí)現(xiàn)
要讓小車實(shí)現(xiàn)循跡自運(yùn)動的操作,其實(shí)也可以說是一個(gè)在教小車如何精準(zhǔn)識別線路并做出判斷的過程,想要小車的攝像頭實(shí)現(xiàn)對路線的準(zhǔn)確判斷,就需要用到一個(gè)目前循跡小車最廣泛采用的技術(shù)手段——二值化。
二值化是圖像分割的一種方法,用于將圖像中的像素點(diǎn)矩陣的灰度值設(shè)置為0或255,也就是將整個(gè)圖像呈現(xiàn)出明顯的只有黑和白的視覺效果。
在二值化過程中,將大于某個(gè)臨界灰度值的像素灰度設(shè)為灰度極大值(通常是255),將小于這個(gè)值的像素灰度設(shè)為灰度極小值(通常是0),從而實(shí)現(xiàn)二值化。
# 根據(jù)不同模式,用不同的hsv上下限值
upper_hsv = (180,255,100)
lower_hsv = (0,0,0)
grayImage = cv2.inRange(hsvImage, np.array(lower_hsv), np.array( upper_hsv)) # 顏色二值化
二值化圖像后,整個(gè)畫面會被區(qū)分為黑白分明的兩種顏色,之后就需要進(jìn)行路線輪廓的描繪以及質(zhì)心的標(biāo)注,這個(gè)操作的目的是讓小車知道該往左拐還是往右拐,進(jìn)而控制兩邊車輪的速度。
- 獲取最大輪廓
# 獲取所有輪廓,畫出所有輪廓
contours, hierarchy = cv2.findContours(grayImage, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
areas = [cv2.contourArea(c) for c in contours]]
cv2.drawContours(rgbImage,contours, -1,(0,255,0),3)
- 計(jì)算質(zhì)心
# 計(jì)算面積最大輪廓的質(zhì)心
areas = [cv2.contourArea(c) for c in contours]
try:
M = cv2.moments(contours[areas.index(max(areas))])
except:
pass
M10=M.get("m10")
M01=M.get("m01")
M00=M.get("m00")
if M00 <= 0 :
continue
cX = int(M10 / M00)
cY = int(M01 / M00)
# 繪制質(zhì)心
cv2.circle(rgbImage, (cX, cY), 15, (255, 0, 255), -1)
在繪制輪廓與質(zhì)心后就需要進(jìn)行質(zhì)心坐標(biāo)的判斷,這里的原理很簡單,就是質(zhì)心偏左就往左轉(zhuǎn),質(zhì)心偏右就往右轉(zhuǎn),在判斷的同時(shí)通過電機(jī)來控制兩邊車輪的速度進(jìn)而控制小車的行駛方向。
根據(jù)質(zhì)心的位置計(jì)算車輪速度的控制參數(shù)postion,根據(jù)具體的計(jì)算公式可以得知,postion的取值范圍為-50到+50,其中0代表質(zhì)心在正中間,+越大質(zhì)心越往左,-越大質(zhì)心越往右,則進(jìn)行下面的速度計(jì)算和控制,否則將速度設(shè)置為0,再根據(jù)postion和delta_sum的值以及其他參數(shù)的調(diào)整,計(jì)算并控制左右車輪的速度。
# 車輪速度控制
if self.flag_start.status() == True :
# -50 ~ +50 :0為正中間,+越大則越往左,-越大則越往右,
postion = int(int(center_x - cX) / int(center_x / 50))
# postion += self.delta_sum
step = self.postion_last - postion
self.delta_sum += (postion - step)*0.01
if self.delta_sum > 100:
self.delta_sum = 100
elif self.delta_sum < -100:
self.delta_sum = -100
if abs(postion) < 5 :
self.delta_sum = 0
# print("self.delta_sum", self.delta_sum)
self.postion_last = postion
speed_l = 50 - postion - int(self.delta_sum)
speed_r = 50 + postion + int(self.delta_sum)
motor.L.speed(speed_l)
motor.R.speed(speed_r)
self._slider_l.setValue(speed_l)
self._slider_r.setValue(speed_r)
人機(jī)交互界面
核桃派H616開發(fā)板上預(yù)裝了PyQt,所以可以使用Qt自帶的設(shè)計(jì)器軟件來畫窗口,在設(shè)計(jì)好后通過命令一鍵轉(zhuǎn)化為Python代碼,再去核桃派的開發(fā)文檔復(fù)制一段顯示案例的代碼,就可以輕松在電腦上預(yù)覽到剛剛的窗口畫面。
為了在遠(yuǎn)程服務(wù)器上運(yùn)行圖形界面應(yīng)用程序,通過設(shè)置os.environ[“DISPLAY”] = ":0.0"允許Thonny遠(yuǎn)程運(yùn)行。
# 允許Thonny遠(yuǎn)程運(yùn)行
import os
os.environ["DISPLAY"] = ":0.0"
定義了一個(gè)名為event_press的函數(shù),用于處理QPushButton按鈕的released事件。當(dāng)按鈕被釋放時(shí),切換work.flag_start的狀態(tài),并根據(jù)狀態(tài)改變按鈕的文本。
def event_press():
if work.flag_start.status():
work.flag_start.disable()
ui.pushButton.setText("點(diǎn)擊開始")
else :
work.flag_start.enable()
ui.pushButton.setText("點(diǎn)擊結(jié)束")
為了處理三個(gè)不同按鈕的released事件,定義了change_to_mode三個(gè)函數(shù),這些函數(shù)用于將work.flag_mode的模式設(shè)置為不同的值。文章來源:http://www.zghlxwxcb.cn/news/detail-832118.html
def change_to_mode0():
work.flag_mode.set_mod( 0 )
def change_to_mode1():
work.flag_mode.set_mod( 1 )
def change_to_mode2():
work.flag_mode.set_mod( 2 )
ui.pushButton.released.connect(event_press)
ui.pushButton_auto.released.connect(change_to_mode0)
ui.pushButton_black.released.connect(change_to_mode1)
ui.pushButton_white.released.connect(change_to_mode2)
以上這些代碼片段是構(gòu)成一個(gè)由PyQt所創(chuàng)建GUI的關(guān)鍵部分。它通過創(chuàng)建一個(gè)窗口,并在窗口中顯示了一些UI元素,同時(shí)定義了一些事件處理函數(shù),這個(gè)應(yīng)用程序根據(jù)用戶的操作來控制某些功能,并使用定時(shí)器來讓解釋器每隔一段時(shí)間運(yùn)行一次,以保持界面響應(yīng)性能,最后進(jìn)入主循環(huán)等待事件的觸發(fā)和處理。文章來源地址http://www.zghlxwxcb.cn/news/detail-832118.html
到了這里,關(guān)于花費(fèi)200元,我用全志H616和雪糕棒手搓了一臺可UI交互的視覺循跡小車的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!