树莓派小车————避障篇

6 篇文章 30 订阅
1 篇文章 0 订阅

避障模块的功能就是让小车能够检测到障碍物并且可以正确的避开障碍物。当然避障的方式有很多种。我选择的是超声波结合红外传感器来避障。

  • 为什么要用超声波传感器结合红外传感器?
    因为硬件原因,没有舵机,原本超声波可以安装在舵机上,通过舵机转动,让超声波检测周围障碍物,我们可以设置舵机转动的角度,最大程度减少超声波检测的盲区。我在设计的时候提前没有想到要舵机,所以后来也来不及了。
    我的超声波传感器固定在了小车的正前方,只能检测到正前方的障碍物,左右两边的障碍物超声波无法检测,所以我只能在左前和右前两个位置安装了两个红外避障传感器来检测障碍物。
  • 避障方案还存在的不足?
    1.虽然用红外传感器检测了左右的障碍物,但是超声波依然存在盲区,高于和低于超声波检测位置的障碍物无法检测到。
    2.小车后方的障碍物没有检测的装置
    3.红外传感器在强光下无法正常工作
  • 如何完善避障方案?
    如果你想设计更加完善的避障方案,需要做如下工作:
    1.增加舵机
    2.小车后方增加超声波传感器或者红外传感器
    接下来讲解避障电路和原理
  • 电路连接:
    (1)超声波的电路连接:超声波共有4个引脚,VCC、GND、Trig、Echo。
    Trig是发送端,发出超声波,Echo是接收端,接收超声波。电路连接图如下:
    在这里插入图片描述
    如上图所示,VCC接了2号引脚(+5V),GND接了39号引脚(GND),Trig和Echo分别接了35和37号引脚(GPIO),还是一样,你自己在设计的时候可以选择正确的任何引脚。
    (2)红外避障传感器的电路连接:红外避障传感器共有三个引脚,VCC、GND、OUT。电路连接图如下:
    在这里插入图片描述
    如图中所示,两个传感器的VCC都接树莓派的4号引脚(+5V),GND都接树莓派的34号引脚(GND),OUT分别接了36号和40号引脚(GPIO口)。还是一样,你自己可以选择引脚来设计。
  • 避障原理:
    (1)超声波测距原理:
    超声波传感器包括发射端(Trig)和接收端(Echo),使用IO口Trig触发测距,给在至少10us的高电平信号下会模块会自动发射方波,发出信号的同时接收端会输出高电平,等到接收到反射回来的信号时,Echo就会跳转为低电平。通过超声波的工作原理可知:从Trig=1到Echo=0的时间,就是超声波从发射到返回的时间,因此:障碍物的距离=Echo高电平持续的时间*声速/2。
    (2)红外避障传感器:红外传感器检测到障碍物时状态为False,两个灯亮,没有检测到时为True,一个灯亮。
  • 设计方案图解:
    在这里插入图片描述
  • 代码:
#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 ''
  • 注:
    (1)你在测试运行时,需要添加基本运动的代码。
    (2)我的避障的处理代码只能作为参考,写的不是很简洁。可以参考部分原理,你自己需要设计符合你自己情况的避障代码。
  • 13
    点赞
  • 174
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
树莓派小车的红外遥控和超声波避障可以通过编写代码来实现。下面是一个简单的示例代码,可以通过红外遥控控制小车的前进、后退、左转和右转,并使用超声波传感器避开障碍物。 ```python import RPi.GPIO as GPIO import time # 设置红外遥控引脚 ir_pin = 18 # 设置超声波引脚 trig_pin = 16 echo_pin = 12 # 设置小车电机引脚 motor_left_pin1 = 7 motor_left_pin2 = 11 motor_right_pin1 = 13 motor_right_pin2 = 15 # 初始化GPIO GPIO.setmode(GPIO.BOARD) GPIO.setup(ir_pin, GPIO.IN) GPIO.setup(trig_pin, GPIO.OUT) GPIO.setup(echo_pin, GPIO.IN) GPIO.setup(motor_left_pin1, GPIO.OUT) GPIO.setup(motor_left_pin2, GPIO.OUT) GPIO.setup(motor_right_pin1, GPIO.OUT) GPIO.setup(motor_right_pin2, GPIO.OUT) # 定义小车运动函数 def move_forward(): GPIO.output(motor_left_pin1, GPIO.HIGH) GPIO.output(motor_left_pin2, GPIO.LOW) GPIO.output(motor_right_pin1, GPIO.HIGH) GPIO.output(motor_right_pin2, GPIO.LOW) def move_backward(): GPIO.output(motor_left_pin1, GPIO.LOW) GPIO.output(motor_left_pin2, GPIO.HIGH) GPIO.output(motor_right_pin1, GPIO.LOW) GPIO.output(motor_right_pin2, GPIO.HIGH) def move_left(): GPIO.output(motor_left_pin1, GPIO.LOW) GPIO.output(motor_left_pin2, GPIO.HIGH) GPIO.output(motor_right_pin1, GPIO.HIGH) GPIO.output(motor_right_pin2, GPIO.LOW) def move_right(): GPIO.output(motor_left_pin1, GPIO.HIGH) GPIO.output(motor_left_pin2, GPIO.LOW) GPIO.output(motor_right_pin1, GPIO.LOW) GPIO.output(motor_right_pin2, GPIO.HIGH) def stop(): GPIO.output(motor_left_pin1, GPIO.LOW) GPIO.output(motor_left_pin2, GPIO.LOW) GPIO.output(motor_right_pin1, GPIO.LOW) GPIO.output(motor_right_pin2, GPIO.LOW) # 定义超声波避障函数 def obstacle_avoidance(): GPIO.output(trig_pin, GPIO.HIGH) time.sleep(0.00001) GPIO.output(trig_pin, GPIO.LOW) while GPIO.input(echo_pin) == 0: pulse_start = time.time() while GPIO.input(echo_pin) == 1: pulse_end = time.time() pulse_duration = pulse_end - pulse_start distance = pulse_duration * 17150 distance = round(distance, 2) if distance < 20: stop() else: move_forward() # 定义红外遥控函数 def ir_control(): ir_value = GPIO.input(ir_pin) if ir_value == 0: move_forward() elif ir_value == 1: move_backward() elif ir_value == 2: move_left() elif ir_value == 3: move_right() else: stop() # 主循环 while True: ir_control() obstacle_avoidance() ``` 以上代码只是一个简单的示例,实际应用中需要根据具体情况进行修改和优化。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值