[作品提交] 基于ESP32路标识别智能车

eew_V9qu8c   2022-10-15 16:49 楼主

作品名称

基于ESP32路标识别智能车

作者:王志远

一、作品简介

基于ESP32的路标识别智能车是ESP32为主控,控制麦克纳姆轮小车运动;OpenMV为从控,识别道路方向和道路交通标识,将道路方向和识别出的交通标识参数信息传输给ESP32,ESP32根据信息控制麦轮小车寻迹的同时,根据道路上的交通标识判定前进的方向,从而实现对小车的无人驾驶。

二、系统框图

QQ截图20221015163728.png

三、各部分功能说明

OpenMV从控:

STM32H OpenMV-H7是低功耗的Python3可编程机器视觉硬件,结合摄像头可以支持一系列广泛的图像处理功能和神经网络。OpenMV-H7使用跨平台 IDE 进行编程,该 IDE 允许查看摄像机的帧缓冲器、访问传感器控件、通过 USB 串行(或 WiFi/BLE(如果可用)将脚本上传到摄像机。OpenMV-H7 基板基于在 400MHz 下运行的STM32H743 MCU,具有 1MB SRAM、2MB 闪存、FPU、DSP 和硬件 JPEG 编码器。基板采用模块化传感器设计,将传感器与摄像机分离。模块化传感器设计使摄像机能够支持多个传感器,包括 OV7725、MT9V03x 全球快门传感器和 FLIR Lepton 1、2 和 3 热传感器。

STM32H743是OpenMV-H7是OpenMV-H7基板的MCU,其是一款32位的,Cortex-M7内核的芯片,该内核具有双精度浮点处理单元FPU,最高频率达到400MHz,并且内置1M RAM, 2M Flash。图2所示是STM32H743芯片的架构。OpenMV-H7芯片的实物图:

1.png

 

图 1 OpenMV-H7芯片

ESP32主控:

ESP32 集成了传统蓝牙、低功耗蓝牙和 Wi-Fi,具有广泛的用途:Wi-Fi 支持极大范围的通信连接,也支持通过路由器直接连接互联网;而蓝牙可以让用户连接手机或者广播 BLE Beacon 以便于信号检测。ESP32 芯片包含两个硬件定时器组。每组有两个通用硬件定时器。它们都是基于 16 位预分频器和 64 位。自动重载功能的向上/向下计数器的 64 位通用定时器。ESP32的实物图:

2.png

图 2 ESP32主控

OV7725摄像头:

OV7725摄像头是一款30W像素的摄像头模块,支持最大VGA分辨率输出,帧率最大可达60fps。能配置输出RAW RGB、RGB(GRB422、RGB565/RGB444)、YVA422这几种格式的视频流。通俗点讲:OV7725像素是30W,虽然像素低,但是帧率高,应用在颜色追踪等应用上效果不错。

LM298N电机驱动:

LM298N包含4通道逻辑驱动电路,内含两个H桥的高电压大电流双全桥式驱动器,可以驱动两个直流电机。端口A、B接到ESP代码配置的PWM通道上,用来输出PWM波,从而控制电机的运行速度。麦轮小车2个电机驱动的4个逻辑输入引脚接单片机引脚,从而控制小车轮子的正转和反转。电机驱动的实物图:

3.png

图 3 电机驱动实物图

麦轮小车:

麦克纳姆轮比普通的轮胎结构更加的复杂,它是由很多斜着安装的纺锤形滚棒组成,这种滚棒的倾斜度是,所以行驶操作的时候,左右力度很均匀,滚棒的中间位置也比其它两边的要高,这才有了麦克纳姆轮随意改变行驶方向的特性45°,不同方向不同大小的摩擦力能实现小车的水平移动,下面是对小车运动时的受力分析图:

5.png

图 4 麦轮小车受力分析图

电路原理:

由于各组件体积较大,不方便固定在小车上,连接线多且冗杂,时不时连接松动,这里本人决定购买ESP32模组,用PCB代替连接线,精简化小车主板,小车的电路分析图和实物图如下图所示:

 

6.png

寻迹原理:

OPenMV识别的交通标识包括红灯,绿灯,直行,掉头,停车,左转,右转和背景,在小车行驶过程中,OpenMV对图像进行二值化处理,对黑色的道路进行线性回归处理,判断前进的角度偏差和小车与道路的距离偏差,同时如果识别到交通标识,将识别的参数通过UART协议传输个ESP32,ESP32根据识别的结构控制小车运动,识别到红灯停止运动,绿灯前进,等等符合交通标识的结果进行运动,若没有交通标识,小车则按前进的方向进行寻迹。交通标识和道路如下图所示:

7.png

四、作品源码

ESP32主控端主程序:

  1. from machine import Pin, UART, Timer  
  2. from machine import Timer  
  3. import time  
  4. import bluetooth  
  5. from car import CAR  
  6. from neopixel import NeoPixel  
  7. RED=(25,0,0)  
  8. GREEN=(0,25,0)  
  9. LEFT=(0,25,25)  
  10. RIGHT= (25,0,25)  
  11. BLACK = (0,0,0)  
  12. global num  
  13. num = 8  
  14. pin = Pin(5, Pin.OUT)  
  15. np = NeoPixel(pin, 25)  
  16. buf = bytes(0)  
  17. BLE_MSG = ""  
  18. uart = UART(1, baudrate=115200, tx=17, rx=16)  
  19. if __name__ == "__main__":  
  20.     global speed  
  21.     speed = 200  
  22.     Car = CAR()  
  23.     Car.setspeed(speed)  
  24.     while True:  
  25.         if (uart.any()):  
  26.             buf = uart.readline()  
  27.             print('Echo Byte: {}'.format(buf))  
  28.             angle = buf.decode("utf-8")  
  29.             angle = angle.replace("\\n",'')  
  30.             x=angle.split(" ",1)  
  31.             distance = float(x[0])  
  32.             angle = float(x[1])  
  33.             Car.setspeed(300)  
  34.             Car.diserror(distance,angle)  
  35.             Car.angleerror(distance,angle)  

OpenMV从控端主程序:

  1. import sensor, image, time, math  
  2. from pyb import UART, LED  
  3. uart = UART(3, 115200)  
  4. sensor.set_hmirror(True)  
  5. GRAYSCALE_THRESHOLD = [(0, 25)]  
  6. ROIS = [(0, 100, 160, 20, 0.7),  
  7.         (0,  50, 160, 20, 0.3),  
  8.         (0,   0, 160, 20, 0.1) ]  
  9. weight_sum = 0  
  10. for r in ROIS: weight_sum += r[4]  
  11. sensor.reset()  
  12. sensor.set_pixformat(sensor.GRAYSCALE)  
  13. sensor.set_framesize(sensor.QQVGA)  
  14. sensor.skip_frames(time = 2000)  
  15. sensor.set_auto_gain(False)  
  16. sensor.set_auto_whitebal(False)  
  17. sensor.set_hmirror(True)  
  18. sensor.set_vflip(True)  
  19. clock = time.clock()  
  20. while(True):  
  21.     clock.tick()  
  22.     img = sensor.snapshot()  
  23.     centroid_sum = 0  
  24.     for r in ROIS:  
  25.         blobs = img.find_blobs(GRAYSCALE_THRESHOLD, roi=r[0:4], merge=True)  
  26.         if blobs:  
  27.             largest_blob = max(blobs, key=lambda b: b.pixels())  
  28.             img.draw_rectangle(largest_blob.rect())  
  29.             img.draw_cross(largest_blob.cx(),  
  30.                            largest_blob.cy())  
  31.             centroid_sum += largest_blob.cx() * r[4]  
  32.     center_pos = (centroid_sum / weight_sum)  
  33.     deflection_angle = 0  
  34.     deflection_angle = -math.atan((center_pos-80)/60)  
  35.     deflection_angle = math.degrees(deflection_angle)  
  36.     uart.write("%d\n" % deflection_angle)  
  37.     print("Turn Angle: %d\n" % deflection_angle)  
  38.     time.sleep_ms(100)  

五、作品功能演示视频

 

点击查看>> 演示视频

 

六、项目总结

心得体会:

通过参加此次得捷电子创新大赛,让我有机会系统的学习了神经网络的开发流程,对整个图像识别有了更加深刻的理解。在参加此次比赛之前,我虽然也曾经零零散散的参加过智能车、电赛、挑战杯之类的科技竞赛,但是我对嵌入式的理解却仅仅停留在表面的层级,认为单片机加操作系统就是嵌入式。但是在参了此次比赛后,我的认识就彻底改变了。

在作比赛的过程当中,前期通过大量的数据调研,也让我明白了智能算法真正部署落地的迫切性。很多时候,我们拥有着很多优秀的智能算法,但却因为算法的复杂性、对硬件平台算力苛刻的要求和硬件成本等一系列原因,使得这些可以造福于我们的方法迟迟没能得到很好的落地。这次我们选取的硬件平台是ESP32芯片和 OPenMV进行我们的作品制作,整个作品涉及嵌入式开发、图像识别、计算机网络通信等多个方面。虽然要学习的东西很多,但是我们仍然充分的利用课余的时间,争分夺秒一点一点的学习新知识。但是当我们一步步坚持下来后,其实发现也并没有想象中的那么困难。相反,通过这次比赛后我整个人的能力又得到了提升。让我对 AI 算法的原理、搭建、训练和部署落地有了全新的认识。我相信这些知识必定会对我日后的科研学习道路起到很大的帮助。

发帖分享:

套件分享:https://bbs.eeworld.com.cn/thread-1209483-1-1.html

七、神经网络模型训练

在神经网络部分,我们选取了 YOLOV2 检测网和 RESNET18 分类网满足需求,检测网数据集约 4000 张,分类网数据集约 3600 张。

11.png

  图 5数据集相关示意图  

练时长约 48 小时、 12 小时模型收敛,训练结束。检测网、分类网在Linux 端的验证集精度分别为 97%与 98%,满足理想状态。

22.png

图 6 训练结束时验证集精度

模型训练结束后,将最终完成的权重文件进行保存,在本地 Linux 系统内对训练完成的权重其进行测试。如图示,在测试过程当中,我们设置的输出阈值为70%。从测试结果可以看出,当同时出现多类路标时,能够准确分类绝大多数的路标,由于YOLOV2 具有更快的检测速率,能够在更短的时间内将采集到的路标全部识别出结果;当出现某一类路标时能够准确识别出路标的的种类,可以达到我们的预期目标,可以达到我们的预期目标,可以进行算法模型的量化处理。

33.png

图 7 不同路标的 PC 端预测结果

 

回复评论 (5)

恭喜恭喜,完成作业,希望得大奖!

点赞  2022-10-15 20:32
神经网络是你自己训练的吗?还是参考的现有模型?
点赞  2022-10-16 09:45

恭喜完成作品

点赞  2022-10-16 14:58
引用: Honghuzaitian 发表于 2022-10-16 09:45 神经网络是你自己训练的吗?还是参考的现有模型?

自己训练

点赞  2022-10-26 20:15

可以的啊,那很强,目前有发现什么识别bug吗?

点赞  2022-10-27 12:11
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复