2021年电赛F题智能送药小车(国二)开源分享

文章目录

题目任务

设计并制造了一种智能送药车,模拟医院药房和病房之间的送药过程。庭院的结构如图1所示。庭院走廊两侧的墙壁用黑色实线表示。走廊地板在中央涂上了一条红色实线,并在可拆卸的纸上放置了一个黑色数字来标识病房编号。药房位置和近端病房号(1号和2号)如图1所示固定,中心病房号和远端病房号(3-8号)在测试过程中随机设置。

[En]

An intelligent drug delivery car is designed and made to simulate the delivery of drugs between the hospital pharmacy and the ward. The structure of the courtyard is shown in figure 1. The walls on both sides of the courtyard corridor are represented by black solid lines. The corridor floor is painted with a solid red line in the center, and a black number identifying the ward number is placed on removable paper. The position of pharmacy and proximal ward number (No. 1 and No. 2) is fixed as shown in figure 1, and the central ward number and distal ward number (No. 3-8) are randomly set during the test.

工作过程:参赛者手动将小车摆放在药房处(车头投影在门口区域内,面向 病房),手持数字标号纸张由小车识别病房号,将约 200g 药品一次性装载到送药小车上;小车检测到药品装载完成后自动开始运送;小车根据走廊上的标识信 息自动识别、寻径将药品送到指定病房(车头投影在门口区域内),点亮红色指示灯,等待卸载药品;病房处人工卸载药品后,小车自动熄灭红色指示灯,开始返回;小车自动返回到药房(车头投影在门口区域内,面向药房)后,点亮绿色指示灯。

2021年电赛F题智能送药小车(国二)开源分享

; 前言(闲话)

由于疫情,比赛被推迟了,这让我们有更多的时间准备(鱼)。比赛持续了四天三夜,占用了一个周五上课时间(只是碰巧是实习,偷铁贼累了就得熬夜。)

[En]

The competition was postponed because of the epidemic, which gave us more time to prepare (fish). The competition lasted four days and three nights, occupying a Friday with classes (just happened to be an internship, and iron thieves had to stay up late when they were tired. )

因为太多了,摸不着鱼,我想救三条就好了。没想到,我冲进了国家的第二年,梦想成真,打破了学校十年的纪录。所以我们必须坚持竞争,以防纪录被打破。

[En]

Because it was too much to touch the fish, I thought it would be good to save three. Unexpectedly, I rushed into the second year of the country and made a dream come true, breaking the school’s ten-year record. So we have to stick to the competition, in case the record is broken.

我负责视觉,并将编写详细的实现方法,保姆级教程,包括神经网络培训。

[En]

I am responsible for vision and will write detailed implementation methods, nanny-level tutorials, including neural network training.

一、团队分工介绍

它由队长赵家辉(电控编程)、团队成员陈伟谦(视觉识别)和吴金英(机械设计)组成,其中包括两名前辈和一名初级学生。

[En]

It is composed of captain Zhao Jiahui (electronic control programming), team members Chen Weiqian (visual recognition) and Wu Jinying (mechanical design), including two seniors and one junior.

//两位光电专业、一位机械的hhh

二、题目分析、破题

1.要点分析

任务可简单分为3个:
(1)巡线移动。完成最基础的移动功能,是所有功能的基础。本作品采用 灰度传感器循迹步进电机的巡线移动方案。
(2)识别病房号数字。可采用openmv、k210、树莓派等视觉单片机识别。由于没有提前准备k210,且树莓派大小、功耗较大,因此 采用最常见的openmv。为保证性能足够,采用 openmv4plus
(3)双机通信。本作品采用 蓝牙双机通信,实现数据共享。
完成以上3个任务后,就是对小车代码逻辑的构思和想法。后面的就是多调试代码,修bug即可。

2.系统方案

  • 1、单片机选择 采用 ArduinoMEGA2560单片机作主控。由于其代码开源性,代码简易,适合新手使用。强大的库函数能极大减少开发时间。且对于该题目,运算速度足够,因此采用。
  • 2、运动系统 采用42步进电机。该款电机转动精确度高,扭力大,额定电流2A以下,且控制简单,不会因为不同驱动的电压而导致转动步数的偏差,无需使用闭环控制即能走出非常好的直线,不易走歪,短距离内可精准控制运动位移。驱动采用TB6600 H桥双极恒相流驱动。驱动及电机采用淘宝成品套件,设置驱动细分数为800。由于驱动体积较大,且42步进电机运行时电流较小,因此可以拆除该驱动模块的金属外壳(散热器),从而达到极大缩小体积和重量。2021年电赛F题智能送药小车(国二)开源分享 前轮采用牛眼轮进行支撑。牛眼轮的选择最好选摩擦力小的。本作品用的牛眼轮摩擦力较大,使得电机的速度不能提得太高,否则摩擦力会将车的运动姿态扰乱,走起来一抖一抖的。
  • 3、循迹系统 采用 八路灰度传感器(实际只用了4路)。调节好阈值,能精准分辨红白色。推荐使用下图的灰度传感器。用非常简单的数字逻辑检测循迹代码即能完成循迹功能。
    2021年电赛F题智能送药小车(国二)开源分享
  • 4、视觉系统 手持病房号采用 模板匹配识别,原因是手持病房号可动态调整远近、角度,模板匹配也能很快识别成功。 地面上的病房号数字采用OpenMV4 H7 Plus 神经网络方法识别。对比模板匹配,识别成功率极高,高达90%以上。由于性能受限,运行时图像仅有2~3帧,需要在病房号前停下零点几秒让其图像稳定下来识别数字。
  • 5、通信系统 采用 HM-10蓝牙模块进行双机通信。主蓝牙仅能接收从蓝牙的信息,不能传信息给从蓝牙。因此从蓝牙接1号车,主蓝牙接2号车。2号车只需要接收1号车指令即可完成所有任务。注意:需提前AT指令设置主从模式和自动连接蓝牙的操作。
  • 6、其他 采用了 oled屏幕显示本次读取病房号是否成功,及实时显示一些小车运行状态,方便调试。设置红绿黄指示灯、蜂鸣器提示等功能。 采用 双边自复位按钮作复位键。由于主控单片机和OpenMV工作电平不一致,复位引脚不能接入同一按键上,因此使用此按键可一键复位两个单片机。 药物检测采用简单的 红外避障模块检测高低电平即可。

; 三、电控部分

电控部分已在立创开源平台发布!比赛准备的全部工程都有!点这里!!
也可以访问:https://oshwhub.com/AngleLeon/gong-ke-sai-xin-hao-zheng-ge-ban_copy
电控代码也在里面。

1、主控拓展电路

2021年电赛F题智能送药小车(国二)开源分享
  • (1)单片机及其引脚外接 其中arduino的D2-D5作为IO口接入电机驱动模块,驱动两个步进电机(每个步进电机由DIR和PUL控制),D23-D37的其中一些引脚接灰度传感器的8个数字信号口。
  • (2)电源输入、输出 12V从圆孔DC5.5系列接口输入,一路直出给步进电机驱动和步进电机供电,领一路经过5V稳压模块给单片机等其他模块供电。引出8组5V电源接口,方便扩展。
  • (3)其他
    其他多余的接口没有特别定义,只是单纯引出,备用。

; 2、步进电机驱动信号整合板

两个步进电机需要两个驱动板,需要较多信号线和电源线,会导致接线较乱、易松。为了稳定性更好,制作了这块信号整合板,并使用了XH2.54红白排插线,连接不易松,且易拔插。

  • (1)原理图 分为12V电源输入输出,布线配合单片机扩展板的IO分布。
    2021年电赛F题智能送药小车(国二)开源分享
  • (2)PCB及仿真图 印丝层加入了对应的IO口数字号,标注了步进电机驱动细分数对应的拨码器状态。且该pcb孔位、大小完全适配拆了散热外壳后的步进电机驱动模块,能直接安装在驱动上,省空间。

2021年电赛F题智能送药小车(国二)开源分享

PCB设计分析

由于主要难度在电控编程上,因此对于PCB的布线难度较小,有一定基础即可,没有需要特别注意的地方。

四、视觉部分

很多人觉得很难看到,因为没有办法建立深度学习的训练环境。巧合的是,我主持的这个伟大的创新项目就是关于视觉神经网络的,理解它的人识别数字非常简单。然而,菜鸟很难将模型加载到嵌入式系统上。这里我只介绍一个极简主义方法,不需要了解神经网络的内涵,手持菜鸟入门教学。

[En]

Many people find it difficult to see because there is no way to build a training environment for deep learning. coincidentally, the great innovation project I presided over is just about visual neural networks, and it is very simple for people who understand it to identify numbers. however, it is difficult for rookies to load the model on the embedded system. Here I only introduce a minimalist method, do not need to understand the connotation of neural network, hand-held rookie introduction to teaching.

本人比赛使用的是 OpenMv4 Plus,这是 支持神经网络最低配的一款,当然 _K210、树莓派_等都可以吊打Openmv,但是由于比赛没有准备其他两款,只能选择普普通通的Openmv了。
先上结果:

2021年电赛F题智能送药小车(国二)开源分享
2021年电赛F题智能送药小车(国二)开源分享

; 神经网络的训练:

//大神请忽略此部分~~~
在线端训练网站:https://studio.edgeimpulse.com

2021年电赛F题智能送药小车(国二)开源分享
  • 1、使用Opemv采集数据 打开 工具-数据集编辑器-新数据集
    2021年电赛F题智能送药小车(国二)开源分享
    创建相应数字的文件夹
    2021年电赛F题智能送药小车(国二)开源分享
    通过helloworld.py例程来采集图像,需要把画质改为 QQVGA
    多加sensor.set_windowing(20,76,40,40) #框选位置,左右都需要
import sensor, image, time

sensor.reset()
sensor.set_pixformat(sensor.GRAYSCALE)
sensor.set_framesize(sensor.QQVGA)
sensor.set_windowing(20,76,40,40)
sensor.skip_frames(time = 2000)
clock = time.clock()

while(True):
    clock.tick()
    img = sensor.snapshot()
    print(clock.fps())

然后开始收集,把号码放在左右两边,两边都收集几十到100件左右。

[En]

Then begin to collect, put the numbers on the left and right sides, and collect about dozens to 100 pieces on both sides.

  • 2、在网站导入图像(Create impulse) 从openmv IDE通过API密匙上传采集到的数据集。
  • 3、调整图像(Image) 按默认设置就好了。
  • 4、迁移学习(Transfer learning) 参数也是按默认就行。
    2021年电赛F题智能送药小车(国二)开源分享
  • 5、保存模型(Versioning) 及时做好备份,这是云端的,防止多次采集训练后效果还没以前某一次好。
  • 6、导出模型

2021年电赛F题智能送药小车(国二)开源分享下载神经网络后解压导入Openmv,完成。

; 运行代码:

下面是Openmv端运行代码,代码含模板匹配,移步星瞳官网文档,写得比我好。
Openmv端程序框图:

2021年电赛F题智能送药小车(国二)开源分享

主程序:

import time, sensor, image,os,tf
from image import SEARCH_EX, SEARCH_DS
from pyb import UART

uart = UART(3, 9600)

sensor.reset()

sensor.set_framesize(sensor.QQVGA)

sensor.set_pixformat(sensor.GRAYSCALE)

net = "trained.tflite"
labels = [line.rstrip('\n') for line in open("labels.txt")]

template1 = ["/1.pgm"]
template2 = ["/2.pgm"]
template3 = ["/3.pgm","/3a.pgm","/3b.pgm"]
template4 = ["/4.pgm","/4a.pgm","/4b.pgm"]
template5 = ["/5.pgm","/5a.pgm","/5b.pgm"]
template6 = ["/6.pgm","/6a.pgm","/6b.pgm"]
template7 = ["/7.pgm","/7a.pgm","/7b.pgm"]
template8 = ["/8.pgm","/8a.pgm","/8b.pgm"]

A0=1
A9=1
B0=1
A1=0
A2=0
A3=0
A4=0
A5=0
A6=0
A7=0
A8=0
B0=1
C0=1
C1=0
C2=1
D0=1
D1=1

clock = time.clock()

while (True):
        clock.tick()
        img = sensor.snapshot()
        while(A0):
            clock.tick()
            img = sensor.snapshot()
            t1 = image.Image(template1[0])
            r1 = img.find_template(t1, 0.80, step=4, search=SEARCH_EX)
            if r1:
                img.draw_rectangle(r1)
                A1=1
                A0=0
            t2 = image.Image(template2[0])
            r2 = img.find_template(t2, 0.80, step=4, search=SEARCH_EX)
            if r2:
                img.draw_rectangle(r2)
                A2=1
                A0=0
            t3 = image.Image(template3[0])
            r3 = img.find_template(t3, 0.85, step=4, search=SEARCH_EX)
            if r3:
                img.draw_rectangle(r3)
                print('3')
                A3=1
                A0=0
            t4 = image.Image(template4[0])
            r4 = img.find_template(t4, 0.80, step=4, search=SEARCH_EX)
            if r4:
                img.draw_rectangle(r4)
                print('4')
                A4=1
                A0=0
            t5 = image.Image(template5[0])
            r5 = img.find_template(t5, 0.80, step=4, search=SEARCH_EX)
            if r5:
                img.draw_rectangle(r5)
                print('5')
                A5=1
                A0=0
            t6 = image.Image(template6[0])
            r6 = img.find_template(t6, 0.80, step=4, search=SEARCH_EX)
            if r6:
                img.draw_rectangle(r6)
                print('6')
                A6=1
                A0=0
            t7 = image.Image(template7[0])
            r7 = img.find_template(t7, 0.80, step=4, search=SEARCH_EX)
            if r7:
                img.draw_rectangle(r7)
                print('7')
                A7=1
                A0=0
            t8 = image.Image(template8[0])
            r8 = img.find_template(t8, 0.85, step=4, search=SEARCH_EX)
            if r8:
                img.draw_rectangle(r8)
                print('8')
                A8=1
                A0=0

        while(A9):
            if A1==1:
                uart.write('1')
                print('1')
                num=1
                A9=0
            if A2==1:
                uart.write('2')
                print('2')
                num=2
                A9=0
            if A3==1:
                uart.write('3')
                print('3')
                num=3
                A9=0
            if A4==1:
                uart.write('4')
                print('4')
                num=4
                A9=0
            if A5==1:
                uart.write('5')
                print('5')
                num=5
                A9=0
            if A6==1:
                uart.write('6')
                print('6')
                num=6
                A9=0
            if A7==1:
                uart.write('7')
                print('7')
                num=7
                A9=0
            if A8==1:
                uart.write('8')
                print('8')
                num=8
                A9=0

        while(True):
            while(B0):
                    if (uart.any()):
                        B = uart.read()
                        print(B)
                        if B==b'1':
                            print("1")
                            B0=0
                            C0=1
            while(C0):
                img = sensor.snapshot()
                roiL=(20,76,40,40)
                for obj in tf.classify(net, img, roiL,min_scale=1, scale_mul=0.8, x_overlap=0.5, y_overlap=0.5):
                    print("**********\nPredictions at [x=%d,y=%d,w=%d,h=%d]" % obj.rect())
                    img.draw_rectangle(obj.rect())
                    predictions_list = list(zip(labels, obj.output()))
                for i in range(len(predictions_list)):
                    print("%s = %f" % (predictions_list[i][0], predictions_list[i][1]))
                    num1=ord(predictions_list[i][0])-48
                    if predictions_list[i][1]>0.7 and num1==num:
                        uart.write('1')
                        print('11')
                        C1=1
                        C0=0
                roiR=(89,77,40,40)
                for obj in tf.classify(net, img, roiR,min_scale=1, scale_mul=0.8, x_overlap=0.5, y_overlap=0.5):
                    print("**********\nPredictions2 at [x=%d,y=%d,w=%d,h=%d]" % obj.rect())
                    img.draw_rectangle(obj.rect())
                    predictions_list2 = list(zip(labels, obj.output()))
                for p in range(len(predictions_list2)):
                    print("%s = %f" % (predictions_list2[p][0], predictions_list2[p][1]))
                    num2=ord(predictions_list2[p][0])-48
                    if predictions_list2[p][1]>0.7 and num2 == num:
                        uart.write('2')
                        print("22")
                        C1=1
                        C0=0
                if C1==0:
                    uart.write('0')
                    print("00")
            print(clock.fps(), "fps")

五、机械部分

  • 1、整车模型 如图为小车机械结构3D图。前轮采用两个牛眼轮进行辅助支撑,后轮为步进电机驱动的动力轮。长21cm、宽19.5cm、高24.5cm。
    2021年电赛F题智能送药小车(国二)开源分享
    图中1为牛眼轮,2为八路灰度传感器模块,3为小车底板,4为六角铜柱,5为单片机和PCB扩展板,6为摄像头支架固定底座,7为OpenMV摄像头,8为药品,9为药仓,10为红外对射模块,11为步进电机驱动板,12为普通轮子,13为步进电机,14为12V锂电池,15为支撑座。
  • 2、车底盘图

2021年电赛F题智能送药小车(国二)开源分享

如图为车底盘CAD图,使用激光切割亚克力制成。厚度4mm左右。

最终成品图:

2021年电赛F题智能送药小车(国二)开源分享

; 总结

1.选择自己最擅长的方案。不要去尝试其他不熟悉的方案,因为4天3页时间真的很紧急。打算做控制类一定要把通用代码准备好,如PID,视觉双机通信等。

2.作为队长要根据每个队员的优势长处设定任务,队长要担任起进度规划的重任,经常是”单核多线程”工作。每个队员都要有强烈的责任感,在选队员上是关键。例如我们队伍有一个机械,负责车组装和3d建模打印等操作,效率极高,半天时间就设计完,一天不到就组装出第一台车,为我们队伍节省了非常多宝贵的调试时间。

3.运气也是实力的一部分。本次比赛的题目非常符合我们队伍阵容,车控电控、神经网络、机械,完美适配我们三人的优势,也许这些都是命中注定。

4.颁奖典礼时听王越院士说到:建议电赛以后的题目越来越多的人工智能,现在机器学习、深度学习实在太火了,掌握深度学习这项技能十分重要,如果不懂视觉,这次的电赛可能就没办法打了。

附件

B站演示视频:https://www.bilibili.com/video/BV1Qb4y1i7Sn/

主控电路工程:https://oshwhub.com/AngleLeon/gong-ke-sai-xin-hao-zheng-ge-ban_copy#P5

主控代码:https://download.csdn.net/download/weixin_45902201/76727241

Openmv端代码:https://download.csdn.net/download/weixin_45902201/76727631

想白嫖代码请访问立创开源平台 ,不想麻烦可以直接下载

Original: https://blog.csdn.net/weixin_45902201/article/details/122557717
Author: 苏幕遮不遮
Title: 2021年电赛F题智能送药小车(国二)开源分享

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/10395/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

最近整理资源【免费获取】:   👉 程序员最新必读书单  | 👏 互联网各方向面试题下载 | ✌️计算机核心资源汇总