自动驾驶算法开发
01-红外循迹
02-红外循迹+超声波避障
03-红外循迹+超声波避障+交通标志识别(USB)
04-车道线检测(USB)
05-车道线检测+交通标志识别(USB)
06-命令
07-连接指南
08-竞赛文档
本文档使用 MrDoc 发布
-
+
首页
03-红外循迹+超声波避障+交通标志识别(USB)
## 红外循迹+超声波避障+交通标志识别 ### 一、交通指示牌 >我们常见的指示牌有很多种,比如禁令标志、警告标志、指示标志等。  (1)禁令标志: 禁止标志(红圈内有斜杠线):告诉驾驶员某项行为是禁止的,如禁止左转、禁止超车等。 停车标志(红圈内有字母P):指示停车区域或停车场。 (2)警告标志: 曲线道路标志:警告前方有弯曲的道路。 斑马线标志:提醒驾驶员注意行人横穿道路。 (3)指示标志: 方向标志:提供方向信息,如指示前往城市或出口。 路名标志:标识道路的名称和编号。 本项目使用yolov5算法对指示牌图像数据进行训练和学习,从而获得一个能够识别交通标志的模型。 ### 二、交通标志识别模型 >模型是AI的灵魂,它决定了AI能做什么。为了实现对交通标志的自动识别,我们需要训练一个交通标志识别模型。 #### 1.模型训练流程  #### 2.数据工程建立 >在浏览器输入 https://bot.aispore.cn/ 进入编程平台,右上角登录账号后,在左边栏选择数据集,建立数据工程。  点击查看数据工程  点击创建新工程  ##### (1)数据采集 >点击拍照  >点击拍照,输入小车ip地址,调用摄像头  >点击拍照,获取照片,点击确定后保存到数据工程中  ##### (2)数据标注 >点击新增标签  >输入标签名称  >选择标签,进行数据标注  ##### (3)导出数据 >在所有图片都标注完之后,点击生成数据集  >输入名称,导出数据集  >导出成功后去训练模型  #### 3.模型训练 >输入名称,勾选,点击创建  >点击参数调整  >修改训练参数后去训练  #### 4.模型编译,推理 >训练成功后点击去编译,输入参数,点击开始编译   ### 三、程序流程  ### 四、程序实现 from time import sleep # 导入sleep函数用于延时控制 from bot.utils import Voice # 导入语音提示模块 from tool import * # 导入工具函数库 import time # 导入时间模块 import os # 导入操作系统接口模块 import sys # 导入系统接口模块 import json # 导入JSON处理模块 import math # 导入数学模块 import numpy as np # 导入数值计算库 from bot.ugv import Motor # 导入电机控制模块 from sensor import Ultrasonic, Infrared # 导入超声波和红外传感器模块 from tpu_factory import TPUFactory # 导入TPU加速模块(用于交通标志识别) import cv2 as cv # 导入OpenCV用于图像处理 from cap import VideoCapture # 导入摄像头捕获模块 # 全局配置参数类(新增:交通标志识别相关配置) class Config: # YOLO目标检测参数 IOU_THRESH = 0.6 # 交并比阈值,用于非极大值抑制 CONF_THRESH = 0.9 # 置信度阈值,过滤低置信度检测结果 IMG_SIZE = [416, 416] # 模型输入图像尺寸 # 交通标识类别定义 CLASSES = ["decelerate", "turn", "whistle", "stop", "red", "yellow", "green"] # 交通标志处理类(新增:实现交通标志识别和处理逻辑) class TrafficSignProcessor: def __init__(self, classes): self.classes = classes # 交通标识类别列表 self.current_sign = -1 # 当前识别的交通标志ID(-1表示未识别) self.last_sign_time = 0 # 上次识别到标志的时间戳 self.sign_thresholds = { # 不同标志的处理时间阈值 "whistle": 0.5, # 鸣笛标识 "turn": 0.5, # 转弯标识 "stop": 0.5, # 停止标识 "light": 1.0 # 红绿灯标识 } def process_detection(self, detections): """处理YOLO模型的目标检测结果""" if not detections: # 无检测结果时直接返回 return for obj in detections: # 遍历每个检测到的目标 x, y, w, h, conf, cls_id = obj # 解析目标信息(坐标、宽高、置信度、类别ID) area = w * h # 计算目标面积 # 过滤无效检测(y坐标有效且面积合理) if not (0 < y < 480 and 1000 < area < 3000): continue self._update_sign_state(cls_id) # 更新交通标志状态 def _update_sign_state(self, sign_id): """根据新检测到的标识更新系统状态""" current_time = time.time() # 获取当前时间 sign_name = self.classes[sign_id] # 获取标识名称 # 新标志检测逻辑 if self.current_sign == -1: self._handle_new_sign(sign_id, sign_name) # 红绿灯特殊处理(状态变化时更新) elif sign_name in ["red", "yellow", "green"] and self.classes[self.current_sign] in ["red", "yellow"]: self.current_sign = sign_id # 更新最后检测时间 self.last_sign_time = current_time def _handle_new_sign(self, sign_id, sign_name): """处理新检测到的交通标志,触发语音提示""" self.current_sign = sign_id # 更新当前标识ID self.last_sign_time = time.time() # 更新最后检测时间 # 根据标志类型触发语音提示 if sign_name == "decelerate": voice_.send(1) # 减速提示 elif sign_name == "turn": voice_.send(2) # 转弯提示 def execute_sign_action(self, lane_follower=None): """执行交通标志对应的动作,返回动作状态和类型""" if self.current_sign == -1: # 未识别到标志时返回 return False, None sign_name = self.classes[self.current_sign] # 获取标志名称 elapsed = time.time() - self.last_sign_time # 计算距上次识别的时间 threshold = self.sign_thresholds.get(sign_name, 0) # 获取处理阈值 # 未达到处理阈值时返回 if elapsed < threshold: return False, None # 根据标志类型执行对应动作 if sign_name == "whistle": voice_.send(3) # 鸣笛提示 self.current_sign = -1 return False, None elif sign_name == "turn": self.current_sign = -1 return True, "turn" # 触发转弯动作 elif sign_name == "stop": self.current_sign = -1 return True, "stop" # 触发停车动作 elif sign_name == "decelerate": self.current_sign = -1 return True, "decelerate" # 触发减速动作 elif sign_name in ["red", "yellow", "green"]: if elapsed > self.sign_thresholds["light"]: self.current_sign = -1 return True, sign_name # 返回红绿灯状态 return False, None # 超声波距离测量函数(计算传感器到障碍物的距离) def Ultrasonic_get_distance(sonic): # 计算超声波往返时间对应的距离(时间×声速/2=单程距离) distance = sonic.output_time() * 340 / 2 * 100 # 时间单位为秒,声速340m/s,乘以100转换为厘米 if distance < 500: # 有效检测距离范围(<5米) DISTANCE = round(distance, 2) # 保留两位小数 else: print("distance is 0") # 超出检测范围时标记为0 DISTANCE = 0 return DISTANCE # 返回距离值(厘米) if __name__ == "__main__": # 超声波传感器引脚配置 TRIG = 449 # 触发信号引脚 ECHO = 474 # 回波信号引脚 # 基础行驶速度设置(PWM值) speed = 2500 # 红外循迹传感器引脚配置(从左到右) io1 = 444 # 左1传感器 io2 = 496 # 左2传感器 io3 = 443 # 右2传感器 io4 = 510 # 右1传感器 # 初始化语音提示模块 voice_ = Voice() # 初始化TPU加速的YOLOv5模型(新增:交通标志识别) try: tpu_yolo = TPUFactory(algorithm="yolov5") # 创建TPU工厂实例 except Exception as e: voice_.send(250) # 播放错误提示音 print(f"导入YOLO模型异常: {e}") sys.exit(1) if not tpu_yolo.link(): # 连接TPU设备 voice_.send(250) # 播放错误提示音 print("TPU连接失败") sys.exit(1) pwd = os.path.dirname(os.path.abspath(__file__)) # 获取当前脚本路径 model_path = os.path.join(os.path.join(pwd, "model"), "yolov5") # 构建模型路径 tpu_yolo.model_init(model_path, host=True) # 初始化YOLO模型 # 初始化超声波传感器 try: sonic = Ultrasonic(TRIG, ECHO) # 创建超声波传感器对象 except Exception as e: voice_.send(250) # 播放错误提示音 print(f"初始化超声波模块异常:{e}") sys.exit(1) # 初始化红外循迹传感器 try: infrared1 = Infrared(io1) # 左1传感器 infrared2 = Infrared(io2) # 左2传感器 infrared3 = Infrared(io3) # 右2传感器 infrared4 = Infrared(io4) # 右1传感器 except Exception as e: voice_.send(250) # 播放错误提示音 print(f"初始化红外传感器异常:{e}") sys.exit(1) # 初始化电机控制并设置初始速度 Control_Motor = Motor(0, 0, 0, 0) # 创建电机控制对象 Control_Motor.GS_run(speed, speed) # 左右轮以相同速度前进 # 状态标志初始化 flag_turn = 0 # 转弯计数器 status_run = 0 # 行驶状态标志(0=偏左,1=偏右) # 初始化摄像头(用于图像采集和交通标志识别) try: cap = VideoCapture() # 创建摄像头捕获对象 except Exception as e: voice_.send(248) # 播放摄像头异常提示音 print(f"初始化摄像头异常,error: {e}") time.sleep(5) exit(0) # 初始化交通标志处理器(新增) sign_processor = TrafficSignProcessor(Config.CLASSES) # 播放系统启动成功提示音 voice_.send(116) # 主控制循环 while True: try: # 超声波传感器数据采集 dis = Ultrasonic_get_distance(sonic) # 获取障碍物距离 print("dis:", dis) # 打印距离值(调试用) # 红外传感器数据采集 io1_status = infrared1.Read_Status() # 读取左1传感器状态 io2_status = infrared2.Read_Status() # 读取左2传感器状态 io3_status = infrared3.Read_Status() # 读取右2传感器状态 io4_status = infrared4.Read_Status() # 读取右1传感器状态 print("io:", io1_status, io2_status, io3_status, io4_status) # 打印传感器状态(调试用) # 障碍物检测逻辑(距离小于25cm时标记为需要避障) if int(dis) < 25: duobi = 1 else: duobi = 0 # 新增:交通标志检测流程 img = cap.read() # 读取摄像头图像 if img is not None: # 执行目标检测(使用TPU加速) detections = tpu_yolo.predict(img, Config.IMG_SIZE, Config.CONF_THRESH, Config.IOU_THRESH) sign_processor.process_detection(detections) # 处理检测结果 # 执行交通标志动作并获取动作状态 sign_action, sign_type = sign_processor.execute_sign_action() # 交通标志优先级控制(高于循迹,低于障碍物) if sign_action: if sign_type == "stop": Control_Motor.Stop() # 检测到停止标志时停车 print("检测到停止标志,停车") time.sleep(2) elif sign_type == "decelerate": # 检测到减速标志时降低速度 Control_Motor.GS_run(speed-1000, speed-1000) print("检测到减速标志,减速行驶") elif sign_type == "turn": # 检测到转弯标志时执行转弯(简化处理) Control_Motor.Rotate_Right() print("检测到转弯标志,执行转弯") elif sign_type in ["red", "yellow"]: # 检测到红灯或黄灯时停车 Control_Motor.Stop() print(f"检测到{sign_type}灯,停车") continue # 执行交通标志动作后跳过循迹逻辑 # 障碍物优先控制逻辑 if duobi == 0: # 红外循迹控制逻辑(与原逻辑一致) if io1_status == 0 and io4_status == 1: # 左传感器检测到黑线,向右调整 speed_L = speed - 1200 speed_R = speed + 1200 Control_Motor.GS_run(speed_L, speed_R) flag_turn = 0 status_run = 0 elif io4_status == 0 and io1_status == 1: # 右传感器检测到黑线,向左调整 speed_L = speed + 1200 speed_R = speed - 1200 Control_Motor.Advance() Control_Motor.GS_run(speed_L, speed_R) flag_turn = 0 status_run = 1 elif (io2_status == 0 and io3_status == 0) and (io1_status == 1 or io4_status == 1): # 中间传感器检测到黑线,直线行驶 speed_L = speed speed_R = speed Control_Motor.Advance() Control_Motor.GS_run(speed_L, speed_R) flag_turn = 0 elif (io2_status == 0 and io3_status == 1) and (io1_status == 1 or io4_status == 1): # 左中传感器检测到黑线,轻微右调整 speed_L = speed - 500 speed_R = speed + 500 Control_Motor.GS_run(speed_L, speed_R) Control_Motor.Advance() flag_turn = 0 status_run = 0 elif (io2_status == 1 and io3_status == 0) and (io1_status == 1 or io4_status == 1): # 右中传感器检测到黑线,轻微左调整 speed_L = speed + 500 speed_R = speed - 500 Control_Motor.GS_run(speed_L, speed_R) Control_Motor.Advance() flag_turn = 0 status_run = 1 elif io1_status == 1 and io2_status == 1 and io3_status == 1 and io4_status == 1: # 所有传感器未检测到黑线,执行转弯 if flag_turn > 25: speed_L = 1500 speed_R = 1500 Control_Motor.GS_run(speed_L, speed_R) if status_run == 0: Control_Motor.Rotate_Left() # 左转 else: Control_Motor.Rotate_Right() # 右转 flag_turn = flag_turn + 1 else: Control_Motor.Stop() # 异常情况停车 time.sleep(0.01) # 控制循环频率 elif duobi == 1: # 检测到障碍物时停车 Control_Motor.Stop() print("前面有障碍") time.sleep(2) # 停留2秒 # 退出控制(按'q'键退出) if has_digit_input() == 'q': break except KeyboardInterrupt: break # 捕获Ctrl+C中断 # 资源释放流程 Control_Motor.close() # 关闭电机控制 infrared1.close() # 关闭左1红外传感器 infrared2.close() # 关闭左2红外传感器 infrared3.close() # 关闭右2红外传感器 infrared4.close() # 关闭右1红外传感器 sonic.close() # 关闭超声波传感器 tpu_yolo.release() # 释放TPU资源(新增) cap.release() # 释放摄像头资源 voice_.close() # 关闭语音模块 print("END----------------------") # 打印程序结束提示 [【附件】model.zip](/media/attachment/2025/05/model.zip)
gdsoke
2025年6月26日 16:14
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
分享
链接
类型
密码
更新密码