避障模块的功能就是让小车能够检测到障碍物并且可以正确的避开障碍物。当然避障的方式有很多种。我选择的是超声波结合红外传感器来避障。
#coding=utf-8
import RPi.GPIO as GPIO
import time
#定义超声波模块的GPIO口
Trig=35 #发射端
Echo=37 #接收端
#定义红外避障传感器GPIO口
L_Senso=40
R_Senso=36
def init():
#设置接触警告
GPIO.setwarnings(False)
#设置引脚模式为物理模式
GPIO.setmode(GPIO.BOARD)
#超声波传感器引脚初始化
GPIO.setup(Trig,GPIO.OUT) #将发射端引脚设置为输出
GPIO.setup(Echo,GPIO.IN) #将接收端引脚设置为输入
#红外避障传感器引脚初始化,设置为输入,接受红外信号
GPIO.setup(L_Senso,GPIO.IN)
GPIO.setup(R_Senso,GPIO.IN)
#超声波测距函数
def get_distance():
GPIO.output(Trig,GPIO.HIGH) #给Trig发送高电平,发出触发信号
time.sleep(0.00015) #需要至少10us的高电平信号,触发Trig测距
GPIO.output(Trig,GPIO.LOW)
while GPIO.input(Echo)!=GPIO.HIGH: #等待接收高电平
pass
t1=time.time() #记录信号发出的时间
while GPIO.input(Echo)==GPIO.HIGH: #接收端还没接收到信号变成低电平就循环等待(等高电平结束)
pass
t2=time.time() #记录接收到反馈信号的时间
distance=(t2-t1)*340*100/2 #计算距离,单位换成cm
return distance
#避障功能函数(超声波避障结合红外避障)
def bizhang():
safe_dis=40 #设置一个安全距离
while True:
barrier_dis=get_distance() #获取当前障碍物的距离
#当测得前方障碍物距离小于安全距离时,先让小车停止
if (barrier_dis < safe_dis) == True:
while (barrier_dis < safe_dis) == True:
L_S=GPIO.input(L_Senso)
R_S=GPIO.input(R_Senso) #接受红外避障传感器的信号
#如果红外传感器检测到左边有障碍物,右边没有,小车向右转
if L_S == False and R_S == True:
print "左有障碍物先后退再右转"
turn_back(18,0.5)
turn_right(18,0.2)
#如果红外传感器检测到右边有障碍物,左边没有,小车向左转
if L_S == True and R_S == False:
print "右有障碍物先后退再左转"
turn_back(18,0.5)
turn_left(18,0.2)
#如果红外传感器检测到左右两边都有障碍物,小车后退
if L_S ==False and R_S == False:
print "两边都有障碍物后退"
turn_back(18,0.5)
#再次接收红外信号(说明刚才的路线已经不能再走,退到一定程度,小车就得左转或者右转,提前寻找新的路线)
L_S=GPIO.input(L_Senso)
R_S=GPIO.input(R_Senso)
#退到左前和右前都没有障碍物的位置
if L_S == True and R_S == True:
print "右转"
turn_right(18,0.2)
#退到了右前没有障碍物的位置
if L_S == False and R_S == True:
print "右转"
turn_right(18,0.2)
#退到了左前没有障碍物的位置
if L_S == True and R_S == False:
print "左转"
turn_left(18,0.2)
#还没有退出刚才的死路,继续后退
if L_S == False and R_S == False:
print "后退"
turn_back(18,0.5)
#如果红外传感器检测到两边都没有障碍物,此时让小车后退一点,然后向右转
if L_S == True and R_S == True:
print "两边都没有障碍物,后退再右转"
turn_back(18,0.5)
turn_right(18,0.2)
print barrier_dis,'cm'
print ''
barrier_dis=get_distance()
else:
#小车在安全区里内,但是由于超声波传感器无法检测到除了正前方其他方向的障碍物,所以在此接收红外信号,通过左前和右前有没有障碍物,来判断小车该怎样运行
L_S=GPIO.input(L_Senso)
R_S=GPIO.input(R_Senso) #接受红外避障传感器的信号
#在安全距离内同时红外传感器检测到左前和有前方没有障碍物,小车前进
if L_S == True and R_S == True:
print "前方40cm内没有障碍物,且左前和右前方没有障碍物,前进"
turn_up(18,0)
#在安全距离内,但左前有障碍物,让小车后退,再右转
if L_S == False and R_S == True:
print "前方40cm内没有障碍物,左前有障碍物,右前方没有障碍物,后退右转"
turn_back(18,0.5)
turn_right(18,0.2)
#在安全距离内,但右前有障碍物,让小车后退,再左转
if L_S == True and R_S == False:
print "前方40cm内没有障碍物,右前有障碍物,左前方没有障碍物,后退右转"
turn_back(18,0.5)
turn_left(18,0.2)
#在安全距离内,但左前,右前都有障碍物,让小车后退
if L_S == False and R_S == False:
print "前方40cm内没有障碍物,左前,右前方都有障碍物,后退"
turn_back(18,0.5)
#再次接收红外信号(说明刚才的路线已经不能再走,退到一定程度,小车就得左转或者右转,提前寻找新的路线)
L_S=GPIO.input(L_Senso)
R_S=GPIO.input(R_Senso)
#退到左前和右前都没有障碍物的位置
if L_S == True and R_S == True:
print "右转"
turn_right(18,0.2)
#退到了右前没有障碍物的位置
if L_S == False and R_S == True:
print "右转"
turn_right(18,0.2)
#退到了左前没有障碍物的位置
if L_S == True and R_S == False:
print "左转"
turn_left(18,0.2)
#还没有退出刚才的死路,继续后退
if L_S == False and R_S == False:
print "后退"
turn_back(18,0.5)
print barrier_dis,'cm'
print ''