电子工程师技术服务社区
公告
登录
|
注册
首页
技术问答
厂商活动
正点原子
板卡试用
资源库
下载
文章
社区首页
文章
树莓派综合项目2:智能小车(五)红外避障
分 享
扫描二维码分享
树莓派综合项目2:智能小车(五)红外避障
树莓派
智能小车
红外避障
张国平
关注
发布时间: 2021-02-09
丨
阅读: 1339
## 一、介绍 阅读本篇文章前建议先参考前期文章: [树莓派基础实验34:L298N模块驱动直流电机实验](https://www.icxbk.com/article/detail?aid=1506),学习了单个电机的简单驱动。 [树莓派综合项目2:智能小车(一)四轮驱动](https://www.icxbk.com/article/detail?aid=1555),实现了代码输入对四个电机的简单控制。 [树莓派综合项目2:智能小车(二)tkinter图形界面控制](https://www.icxbk.com/article/detail?aid=1624),实现了本地图形界面控制小车的前进后退、转向和原地转圈。 [树莓派综合项目2:智能小车(三)无线电遥控](https://www.icxbk.com/article/preview?astatus=1&aid=1843),实现了无线电遥控设备控制小车的前进后退、转向和原地转圈。 [树莓派综合项目2:智能小车(四)超声波避障](https://www.icxbk.com/article/detail?aid=1919),实现了超声波传感器实时感知小车前方障碍物的距离,当距离近于某个阈值时,小车自动减速,再低于某个阈值时自动刹车,然后倒车至安全距离。 本实验中将使用HJ-IR2红外光电传感器,探测到物体即输出脉冲,输入到树莓派中处理,再对电机驱动模块进行控制,实现壁障的功能,这样的避障小车又称为简单的避障机器人。 其它基础内容可以参考文集:[树莓派基础实验](https://www.jianshu.com/nb/41246217)。 ## 二、组件 ★Raspberry Pi 3 B+全套*1 ★睿思凯Frsky XM+ 迷你接收机*1 ★电平反向器模块*1 ★睿思凯Frsky Taranis X9D PLUS SE2019遥控器*1 ★L298N扩展板模块*1 ★智能小车底板模块*1 ★减速电机和车轮*4 ★HC-SR04超声波模块*1 ★HJ-IR2红外光电传感器*2 ★跳线若干 ## 三、实验原理 HJ-IR2红外光电传感器: ![HJ-IR2红外光电传感器](https://cf03.ickimg.com/bbsimages/202102/3d98f7b44076457cfaad1d11b4984b3b.jpg) 本实验原理和超声波避障相似,红外传感器就是一个红外对射开关,通电状态下,红外发射头发射红外信号,经过目标反射后接收头接收此信号,并输出一个低电平信号,树莓派采集这个低电平信号后采取相应措施避障。 ![传感器参数](https://cf03.ickimg.com/bbsimages/202102/e14142458dd9bd48a72b91661ca0d070.jpg) ![探测距离调节](https://cf03.ickimg.com/bbsimages/202102/1acc2acc758be1beaa42337094c87ff0.jpg) 若没有被任何一个探头检测到障碍物,小车直行;左边探头检测到障碍物时小车向右转,右边探头检测到障碍物时小车向左转。 关于红外传感器的基础知识请参见[树莓派基础实验28:红外避障传感器实验](https://www.jianshu.com/p/e4521781ea8c)。 ## 四、实验步骤 **第1步:** 连接电路。这里对红外避障外的连线方法不在累述,请参考[树莓派综合项目2:智能小车(四)超声波避障](https://www.icxbk.com/article/detail?aid=1919)。 | 树莓派(name) | 树莓派(BOARD)|红外探测模块 | |:-:|:-:|:-:| |GPIO.21|29|左侧红外输出| |GPIO.22|31|右侧红外输出| |5V|5V|两个模块的VCC| |GND|GND|两个模块的GND| 加装红外避障模块的小车: ![加装红外避障模块的小车](https://cf03.ickimg.com/bbsimages/202102/b69739ea11fba5c81a27425f30ee109e.jpg) **第2步:** motor_4w.py,moving_control.py,sbus_receiver_pi.py,ultrasonic.py文件的编码这里不再累述,参考[树莓派综合项目2:智能小车(四)超声波避障](https://www.icxbk.com/article/detail?aid=1919)。 **第3步**:编写红外探测模块,文件名为infrared.py,与[树莓派基础实验28:红外避障传感器实验](https://www.jianshu.com/p/e4521781ea8c)中的Python程序基本相同,只是设置了类,重构了程序。 infrared.py: ```python #!/usr/bin/env python3 #-*- coding: utf-8 -*- #本模块只含Infrared()一个类,用于红外避障模块测出是否有障碍物 #有障碍物时返回值0,无障碍物时返回值1 import RPi.GPIO as GPIO import time class Infrared(): InfraredPinLeft = 29 #左侧模块的输出连接树莓派29号针脚 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)): #当检测到障碍物时,输出低电平信号 infra_left_value = 0 if (0 == GPIO.input(Infrared.InfraredPinRight)): #当检测到障碍物时,输出低电平信号 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.sl
eep(0.1) except KeyboardInterrupt: infrared.destroy() ``` **第4步:** 编写树莓派智能小车的主程序,文件名为smartcar.py,将这5个Python文件放入一个文件夹后,只运行本文件就可以了。 主程序中加入了infra_control()红外避障函数,实现了没有障碍物时小车直行;左边探头检测到障碍物时小车向右转,右边探头检测到障碍物时小车向左转。 smartcar.py: ```python #!/usr/bin/env python #-*- coding: utf-8 -*- #本模块为树莓派小车的主程序, 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 #使能是否执行SBUS油门信号,为0时使遥控器油门信号无效 sbus_receiver = SBUSReceiver('/dev/ttyAMA0') #初始化SBUS信号接收实例 smp_car = Motor_4w() #初始化电机控制实例 smp_car.setGPIO() #初始化引脚 ENA_pwm = smp_car.pwm(smp_car.ENA) #初始化使能信号PWM,A为左边车轮 ENB_pwm = smp_car.pwm(smp_car.ENB) #初始化使能信号PWM,B为右边车轮 smartcar = MovingControl(smp_car,ENA_pwm,ENB_pwm) #初始化车辆运动控制实例 ultr = Ultrasonic() #初始化超声波实例 ultr.setup() #初始化超声波引脚 infrared = Infrared() #初始化红外避障实例 infrared.setup() #初始化红外避障引脚 def ultra_control(): '''超声波传感器控制''' global acc_value_sbus_enable dis = ultr.distance() print('distance= %.1f cm\n' %dis) if dis < 50: #当障碍距离小于50cm时,不执行SBUS油门信号 if smartcar.acc_value > 40: #当障碍距离小于50cm,且油门大于40时,油门设定为40,为防冲撞减速 smartcar.acc_value = 40 smartcar.accelerator() #调节油门 if dis < 10: #如果测距小于10cm时,先停车再倒车0.3秒 smartcar.brake() smartcar.reverse() time.sl
eep(0.3) def infra_control(): '''红外避障传感器控制''' infra_left_value = 1 #值默认为1时,表示无障碍物 infra_right_value = 1 infra_left_value,infra_right_value = infrared.infra_detect() if infra_left_value == 0: #值为0时,表示左侧检测到障碍物 #smartcar.acc_value=80 smartcar.accelerator(1,0) #控制小车向右偏转 time.sl
eep(0.5) #向右偏转行进0.5秒 if infra_right_value == 0: #smartcar.acc_value=80 smartcar.accelerator(0,1) time.sl
eep(0.5) print('infra_left_value=%d infra_right_value=%d'%(infra_left_value,infra_right_value) ) def sbus_control(): '''无线电控制''' sbus_receiver.update() #获取一个完整的帧数据 global acc_value_sbus_enable aileron_value = sbus_receiver.get_rx_channel(0) #1通道为副翼通道,这里控制车原地转向 elevator_value = sbus_receiver.get_rx_channel(1)#2通道为升降舵通道,这里控制车前进后退 rudder_value = sbus_receiver.get_rx_channel(3)#4通道为方向舵通道,这里控制车左右偏移行进 if acc_value_sbus_enable == 1: #使能SBUS信号的油门控制 acc_value_sbus = 172 #3通道,即油门的值,最低时为172 if sbus_receiver.get_rx_channel(2): acc_value_sbus = sbus_receiver.get_rx_channel(2) #3通道为油门通道,这里控制车速度 #将172~1811的油门通道值转换为0~100的占空比信号, smartcar.acc_value = int(100*(acc_value_sbus-172)/(1811-172)) print('original.acc_value=',smartcar.acc_value) #检测SBUS信号的油门值 ultra_control() #超声波避障 infra_control() #红外避障 print('disposed.acc_value=',smartcar.acc_value) #检测超声波函数处理后的油门值 if 970 < rudder_value < 1100: #没有左右偏移时,中间值为992,但遥控器微调时会有上下浮动 pass #没有左右偏移时 elif rudder_value >=1100: #向右偏移行进时 rate_right = (1811.0 - rudder_value)/(1811-1100) #最大值一般为1811,这里使用浮点类型,所以一定要使用1811.0 smartcar.accelerator(1,rate_right) elif rudder_value <=970: #向左偏移行进时 rate_left = (rudder_value - 172.0)/(970-172) #最小值为172,这里使用浮点类型,所以一定要使用172.0 smartcar.accelerator(rate_left,1) print('elevator_value=%d,aileron_value=%d,rudder_value=%d'%(elevator_value,aileron_value,rudder_value))#测试数据用 if aileron_value >= 1100: #原地左转弯 smartcar.leftTurn() smartcar.accelerator() elif aileron_value <= 970: #原地右转弯 smartcar.rightTurn() smartcar.accelerator() else : smartcar.brake() #停车 if elevator_value >=1100: #前进 smartcar.forward() elif elevator_value <=970: #后退 smartcar.reverse() #循环最后,这里不能再用停车了 try: while True: time.sl
eep(0.01) sbus_control() except KeyboardInterrupt: smp_car.destroy(ENA_pwm,ENB_pwm) finally: smp_car.destroy(ENA_pwm,ENB_pwm) ``` ![](https://cf03.ickimg.com/bbsimages/202102/1961b542da77daae13a850e15247b2e1.jpg)
原创作品,未经权利人授权禁止转载。详情见
转载须知
。
举报文章
点赞
(
0
)
张国平
关注
评论
(0)
登录后可评论,请
登录
或
注册
相关文章推荐
MK-米客方德推出工业级存储卡
Beetle ESP32 C3 蓝牙数据收发
Beetle ESP32 C3 wifi联网获取实时天气信息
开箱测评Beetle ESP32-C3 (RISC-V芯片)模块
正点原子数控电源DP100测评
DP100试用评测-----开箱+初体验
Beetle ESP32 C3环境搭建
【花雕体验】16 使用Beetle ESP32 C3控制8X32位WS2812硬屏之二
X
你的打赏是对原创作者最大的认可
请选择打赏IC币的数量,一经提交无法退回 !
100IC币
500IC币
1000IC币
自定义
IC币
确定
X
提交成功 ! 谢谢您的支持
返回
我要举报该内容理由
×
广告及垃圾信息
抄袭或未经授权
其它举报理由
请输入您举报的理由(50字以内)
取消
提交