樹(shù)莓派綜合項(xiàng)目2:智能小車(chē)(五)紅外避障

一、介紹

??閱讀本篇文章前建議先參考前期文章:
??樹(shù)莓派基礎(chǔ)實(shí)驗(yàn)34:L298N模塊驅(qū)動(dòng)直流電機(jī)實(shí)驗(yàn),學(xué)習(xí)了單個(gè)電機(jī)的簡(jiǎn)單驅(qū)動(dòng)。
??樹(shù)莓派綜合項(xiàng)目2:智能小車(chē)(一)四輪驅(qū)動(dòng),實(shí)現(xiàn)了代碼輸入對(duì)四個(gè)電機(jī)的簡(jiǎn)單控制。
??樹(shù)莓派綜合項(xiàng)目2:智能小車(chē)(二)tkinter圖形界面控制,實(shí)現(xiàn)了本地圖形界面控制小車(chē)的前進(jìn)后退、轉(zhuǎn)向和原地轉(zhuǎn)圈。
??樹(shù)莓派綜合項(xiàng)目2:智能小車(chē)(三)無(wú)線(xiàn)電遙控,實(shí)現(xiàn)了無(wú)線(xiàn)電遙控設(shè)備控制小車(chē)的前進(jìn)后退、轉(zhuǎn)向和原地轉(zhuǎn)圈。
??樹(shù)莓派綜合項(xiàng)目2:智能小車(chē)(四)超聲波避障,實(shí)現(xiàn)了超聲波傳感器實(shí)時(shí)感知小車(chē)前方障礙物的距離,當(dāng)距離近于某個(gè)閾值時(shí),小車(chē)自動(dòng)減速,再低于某個(gè)閾值時(shí)自動(dòng)剎車(chē),然后倒車(chē)至安全距離。

??本實(shí)驗(yàn)中將使用HJ-IR2紅外光電傳感器,探測(cè)到物體即輸出脈沖,輸入到樹(shù)莓派中處理,再對(duì)電機(jī)驅(qū)動(dòng)模塊進(jìn)行控制,實(shí)現(xiàn)壁障的功能,這樣的避障小車(chē)又稱(chēng)為簡(jiǎn)單的避障機(jī)器人。

??其它基礎(chǔ)內(nèi)容可以參考文集:樹(shù)莓派基礎(chǔ)實(shí)驗(yàn)

二、組件

★Raspberry Pi 3 B+全套*1

★睿思凱Frsky XM+ 迷你接收機(jī)*1

★電平反向器模塊*1

★睿思凱Frsky Taranis X9D PLUS SE2019遙控器*1

★L(fēng)298N擴(kuò)展板模塊*1

★智能小車(chē)底板模塊*1

★減速電機(jī)和車(chē)輪*4

★HC-SR04超聲波模塊*1

★HJ-IR2紅外光電傳感器*2

★跳線(xiàn)若干

三、實(shí)驗(yàn)原理

HJ-IR2紅外光電傳感器

??本實(shí)驗(yàn)原理和超聲波避障相似,紅外傳感器就是一個(gè)紅外對(duì)射開(kāi)關(guān),通電狀態(tài)下,紅外發(fā)射頭發(fā)射紅外信號(hào),經(jīng)過(guò)目標(biāo)反射后接收頭接收此信號(hào),并輸出一個(gè)低電平信號(hào),樹(shù)莓派采集這個(gè)低電平信號(hào)后采取相應(yīng)措施避障。

傳感器參數(shù)

探測(cè)距離調(diào)節(jié)

??若沒(méi)有被任何一個(gè)探頭檢測(cè)到障礙物,小車(chē)直行;左邊探頭檢測(cè)到障礙物時(shí)小車(chē)向右轉(zhuǎn),右邊探頭檢測(cè)到障礙物時(shí)小車(chē)向左轉(zhuǎn)。

??關(guān)于紅外傳感器的基礎(chǔ)知識(shí)請(qǐng)參見(jiàn)樹(shù)莓派基礎(chǔ)實(shí)驗(yàn)28:紅外避障傳感器實(shí)驗(yàn)。

四、實(shí)驗(yàn)步驟

??第1步: 連接電路。這里對(duì)紅外避障外的連線(xiàn)方法不在累述,請(qǐng)參考樹(shù)莓派綜合項(xiàng)目2:智能小車(chē)(四)超聲波避障。

樹(shù)莓派(name) 樹(shù)莓派(BOARD) 紅外探測(cè)模塊
GPIO.21 29 左側(cè)紅外輸出
GPIO.22 31 右側(cè)紅外輸出
5V 5V 兩個(gè)模塊的VCC
GND GND 兩個(gè)模塊的GND
加裝紅外避障模塊的小車(chē)

??第2步: motor_4w.py,moving_control.py,sbus_receiver_pi.py,ultrasonic.py文件的編碼這里不再累述,參考樹(shù)莓派綜合項(xiàng)目2:智能小車(chē)(四)超聲波避障。

??第3步:編寫(xiě)紅外探測(cè)模塊,文件名為infrared.py,與樹(shù)莓派基礎(chǔ)實(shí)驗(yàn)28:紅外避障傳感器實(shí)驗(yàn)中的Python程序基本相同,只是設(shè)置了類(lèi),重構(gòu)了程序。
infrared.py:

#!/usr/bin/env python3
#-*- coding: utf-8 -*-
#本模塊只含Infrared()一個(gè)類(lèi),用于紅外避障模塊測(cè)出是否有障礙物
#有障礙物時(shí)返回值0,無(wú)障礙物時(shí)返回值1

import RPi.GPIO as GPIO
import time
class Infrared():
    
    InfraredPinLeft = 29  #左側(cè)模塊的輸出連接樹(shù)莓派29號(hào)針腳
    InfraredPinRight = 31

    def setup(self):
        GPIO.setmode(GPIO.BOARD)
        GPIO.setup(Infrared.InfraredPinLeft, GPIO.IN, pull_up_down=GPIO.PUD_UP)
        GPIO.setup(Infrared.InfraredPinRight, GPIO.IN, pull_up_down=GPIO.PUD_UP)

    def infra_detect(self):
        infra_left_value = 1
        infra_right_value = 1
        if (0 == GPIO.input(Infrared.InfraredPinLeft)):  #當(dāng)檢測(cè)到障礙物時(shí),輸出低電平信號(hào)
            infra_left_value = 0
        if (0 == GPIO.input(Infrared.InfraredPinRight)):  #當(dāng)檢測(cè)到障礙物時(shí),輸出低電平信號(hào)
            infra_right_value = 0
        return infra_left_value,infra_right_value
 
    def destroy(self):
        GPIO.cleanup()

if __name__ == "__main__":
    
    try:
        infrared = Infrared()
        infrared.setup()
        while True:
            infra_left_value,infra_right_value = infrared.infra_detect()
            print('infra_left_value=%d infra_right_value=%d'%(infra_left_value,infra_right_value) )
            time.sleep(0.1)
    except KeyboardInterrupt:
        infrared.destroy()

??第4步: 編寫(xiě)樹(shù)莓派智能小車(chē)的主程序,文件名為smartcar.py,將這5個(gè)Python文件放入一個(gè)文件夾后,只運(yùn)行本文件就可以了。
??主程序中加入了infra_control()紅外避障函數(shù),實(shí)現(xiàn)了沒(méi)有障礙物時(shí)小車(chē)直行;左邊探頭檢測(cè)到障礙物時(shí)小車(chē)向右轉(zhuǎn),右邊探頭檢測(cè)到障礙物時(shí)小車(chē)向左轉(zhuǎn)。
smartcar.py:

#!/usr/bin/env python
#-*- coding: utf-8 -*-
#本模塊為樹(shù)莓派小車(chē)的主程序,
from motor_4w import Motor_4w
from sbus_receiver_pi import SBUSReceiver
from moving_control import MovingControl
from ultrasonic import Ultrasonic
from infrared import Infrared
import time

acc_value_sbus_enable = 1 #使能是否執(zhí)行SBUS油門(mén)信號(hào),為0時(shí)使遙控器油門(mén)信號(hào)無(wú)效

sbus_receiver = SBUSReceiver('/dev/ttyAMA0') #初始化SBUS信號(hào)接收實(shí)例
smp_car = Motor_4w() #初始化電機(jī)控制實(shí)例
smp_car.setGPIO()  #初始化引腳

ENA_pwm = smp_car.pwm(smp_car.ENA) #初始化使能信號(hào)PWM,A為左邊車(chē)輪
ENB_pwm = smp_car.pwm(smp_car.ENB) #初始化使能信號(hào)PWM,B為右邊車(chē)輪
    
smartcar = MovingControl(smp_car,ENA_pwm,ENB_pwm)  #初始化車(chē)輛運(yùn)動(dòng)控制實(shí)例

ultr = Ultrasonic() #初始化超聲波實(shí)例
ultr.setup()        #初始化超聲波引腳

infrared = Infrared()  #初始化紅外避障實(shí)例
infrared.setup()       #初始化紅外避障引腳

def ultra_control():
    '''超聲波傳感器控制'''
    global acc_value_sbus_enable
    dis = ultr.distance()
    print('distance= %.1f cm\n' %dis)
    if dis < 50:
    #當(dāng)障礙距離小于50cm時(shí),不執(zhí)行SBUS油門(mén)信號(hào)
        if smartcar.acc_value > 40:
        #當(dāng)障礙距離小于50cm,且油門(mén)大于40時(shí),油門(mén)設(shè)定為40,為防沖撞減速
            smartcar.acc_value = 40 
            smartcar.accelerator() #調(diào)節(jié)油門(mén)
    if dis < 10:
    #如果測(cè)距小于10cm時(shí),先停車(chē)再倒車(chē)0.3秒
        smartcar.brake()
        smartcar.reverse()
        time.sleep(0.3)
        
def infra_control():
    '''紅外避障傳感器控制'''
    infra_left_value = 1       #值默認(rèn)為1時(shí),表示無(wú)障礙物
    infra_right_value = 1
    infra_left_value,infra_right_value = infrared.infra_detect()
    if infra_left_value == 0:  #值為0時(shí),表示左側(cè)檢測(cè)到障礙物
        #smartcar.acc_value=80
        smartcar.accelerator(1,0)  #控制小車(chē)向右偏轉(zhuǎn)
        time.sleep(0.5)            #向右偏轉(zhuǎn)行進(jìn)0.5秒
    if infra_right_value == 0:
        #smartcar.acc_value=80
        smartcar.accelerator(0,1)
        time.sleep(0.5)
    print('infra_left_value=%d infra_right_value=%d'%(infra_left_value,infra_right_value) )

def sbus_control():
    '''無(wú)線(xiàn)電控制'''
    sbus_receiver.update() #獲取一個(gè)完整的幀數(shù)據(jù)
    global acc_value_sbus_enable
            
    aileron_value = sbus_receiver.get_rx_channel(0) #1通道為副翼通道,這里控制車(chē)原地轉(zhuǎn)向
    elevator_value = sbus_receiver.get_rx_channel(1)#2通道為升降舵通道,這里控制車(chē)前進(jìn)后退
    rudder_value = sbus_receiver.get_rx_channel(3)#4通道為方向舵通道,這里控制車(chē)左右偏移行進(jìn)
    
    if acc_value_sbus_enable == 1:
    #使能SBUS信號(hào)的油門(mén)控制    
        acc_value_sbus = 172  #3通道,即油門(mén)的值,最低時(shí)為172        
        if sbus_receiver.get_rx_channel(2):
            acc_value_sbus = sbus_receiver.get_rx_channel(2) #3通道為油門(mén)通道,這里控制車(chē)速度
        #將172~1811的油門(mén)通道值轉(zhuǎn)換為0~100的占空比信號(hào),
        smartcar.acc_value = int(100*(acc_value_sbus-172)/(1811-172))
        print('original.acc_value=',smartcar.acc_value) #檢測(cè)SBUS信號(hào)的油門(mén)值
        
    ultra_control()  #超聲波避障
    infra_control()  #紅外避障
       
    print('disposed.acc_value=',smartcar.acc_value)  #檢測(cè)超聲波函數(shù)處理后的油門(mén)值
      
    if 970 < rudder_value < 1100: #沒(méi)有左右偏移時(shí),中間值為992,但遙控器微調(diào)時(shí)會(huì)有上下浮動(dòng)
        pass                    #沒(méi)有左右偏移時(shí)
    elif rudder_value >=1100:      #向右偏移行進(jìn)時(shí)
        rate_right = (1811.0 - rudder_value)/(1811-1100) 
        #最大值一般為1811,這里使用浮點(diǎn)類(lèi)型,所以一定要使用1811.0
        smartcar.accelerator(1,rate_right)
    elif rudder_value <=970:       #向左偏移行進(jìn)時(shí)
        rate_left = (rudder_value - 172.0)/(970-172)  
        #最小值為172,這里使用浮點(diǎn)類(lèi)型,所以一定要使用172.0
        smartcar.accelerator(rate_left,1)
    print('elevator_value=%d,aileron_value=%d,rudder_value=%d'%(elevator_value,aileron_value,rudder_value))#測(cè)試數(shù)據(jù)用
            
    if aileron_value >= 1100:  #原地左轉(zhuǎn)彎
        smartcar.leftTurn()
        smartcar.accelerator()
    elif aileron_value <= 970: #原地右轉(zhuǎn)彎
        smartcar.rightTurn()
        smartcar.accelerator()
    else : 
        smartcar.brake()       #停車(chē)
                
    if elevator_value >=1100:  #前進(jìn)
        smartcar.forward()
        
    elif elevator_value <=970: #后退
        smartcar.reverse()
        #循環(huán)最后,這里不能再用停車(chē)了    

try:    
    
    while True:
        time.sleep(0.01)
        sbus_control()

except KeyboardInterrupt:  
    smp_car.destroy(ENA_pwm,ENB_pwm)
finally:
    smp_car.destroy(ENA_pwm,ENB_pwm)

這個(gè)項(xiàng)目的代碼90%是我原創(chuàng)瞎寫(xiě)的,有需要參考的同學(xué)可以下載:
樹(shù)莓派智能小車(chē)項(xiàng)目python源代碼下載

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容