2021年电赛
一 任务
设计并制作智能送药小车,模拟完成在医院药房与病房间药品的送取作业。院区结构示意如图 1 所示。院区走廊两侧的墙体由黑实线表示。走廊地面上画有居中的红实线,并放置标识病房号的黑色数字可移动纸张。药房和近端病房(1、 2 号)如图 1 所示位置固定不变,中部病房和远端病房号(3-8 号)测试时随机设定。
工作过程:参赛者手动将小车摆放在药房处(车头投影在门口区域内,面向病房),手持数字标号纸张由小车识别病房号,将约 200g 药品一次性装载到送药小车上;小车检测到药品装载完成后自动开始运送;小车根据走廊上的标识信息自动识别、寻径将药品送到指定病房(车头投影在门口区域内),点亮红色指示灯,等待卸载药品;病房处人工卸载药品后,小车自动熄灭红色指示灯,开始返回;小车自动返回到药房(车头投影在门口区域内,面向药房)后,点亮绿色指示灯。
二 要求
1.基本要求
(1)单个小车运送药品到指定的近端病房并返回到药房。要求运送和返回时间均小于 20s,超时扣分。
(2)单个小车运送药品到指定的中部病房并返回到药房。要求运送和返回时间均小于 20s,超时扣分。
(3)单个小车运送药品到指定的远端病房并返回到药房。要求运送和返回时间均小于 20s,超时扣分。
*
2.发挥部分
(1)两个小车协同运送药品到同一指定的中部病房。小车 1 识别病房号装载药品后开始运送,到达病房后等待卸载药品;然后,小车 2 识别病房号装载药品后启动运送,到达自选暂停点后暂停,点亮黄色指示灯,等待小车 1 卸载;小车 1 卸载药品,开始返回,同时控制小车 2 熄灭黄色指示灯并继续运送。要求从小车 2 启动运送开始,到小车 1 返回到药房且小车 2 到达病房的总时间(不包括小车 2 黄灯亮时的暂停时间)越短越好,超过 60s 计 0 分。
(2)两个小车协同到不同的远端病房送、取药品,小车 1 送药,小车 2 取药。小车 1 识别病房号装载药品后开始运送,小车 2 于药房处识别病房号等待小车 1 的取药开始指令;小车 1 到达病房后卸载药品,开始返回,同时向小车 2发送启动取药指令;小车 2 收到取药指令后开始启动,到达病房后停止,亮红色指示灯。要求从小车 1 返回开始,到小车 1 返回到药房且小车 2 到达取药病房的总时间越短越好,超过 60s 计 0 分。
(3)其他。
三 说明
(1)院区可由铺设白色亚光喷绘布制作。走廊上的黑线和红线由喷绘或粘贴线宽约为 1.5cm~1.8cm 的黑色和红色电工胶带制作。药房和病房门口区域指其标线外沿所涵盖的区域,其标线为约 2cm 黑白相间虚线。图 1 中非黑色、非红色仅用于识图解释,在实测院区中不出现。
(2)标识病房的黑色数字可在纸张上打印,数值为 1-8,每个数字边框长宽为 8cm×6cm,将“数字字模.pdf”文件按实际大小打印即可;数字标号纸张可由无痕不干胶等粘贴在走廊上,其边框距离实线约 2cm;图 1 中标识远端病房的两个并排数字边框之间距离约 2cm。
(3)小车长×宽×高不大于 25cm×20cm×25cm,使用普通车轮(不能使用履带或麦克纳姆轮等特殊结构)。两小车均由电池供电,小车间可无线通信,外界无任何附加电路与控制装置。
(4)作品应能适应无阳光直射的自然光照明及顶置多灯照明环境,测试时不得有特殊照明条件要求。
(5)每项测试开始时,只允许按一次复位键,装载药品后即刻启动运送时间计时,卸载药品后即刻启动返回时间计时。计时开始后,不得人工干预。每个测试项目只测试一次。
(6)小车于药房处识别病房号的时间不超过 20s。发挥部分(1)中自选暂停点处的小车 2 与小车 1 的车头投影外沿中心点的红实线距离不小于 70cm。
(7)有任何一个指示灯处于点亮状态的小车必须处于停止状态。两小车协同运送过程中不允许在同一走廊上错车或超车。
(8)测试过程中,小车投影落在黑实线上或两小车碰撞将被扣分;小车投影连续落在黑实线上超过 30cm 或整车越过黑实线,或两小车连续接触时间超过5s,该测试项计 0 分。
(9)参赛者需自带 2 套数字标号纸张,无需封箱。
直接附上代码:
import sensor, image,time,utime#获取库
from fpioa_manager import fm
from board import board_info
import lcd
#from pyb import UART #开启串口
from Maix import GPIO
from machine import UART
yellow_threshold = (53, 86, 22, 51, -31, 14)#括号里面是颜色阈值(53, 83, 22, 53, -7, 18)
num = 0
#摄像头初始化
sensor.reset()
sensor.set_hmirror(True) #镜像
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.set_vflip(1) #后置拍摄模式
sensor.skip_frames(10) # Let new settings take affect.
#sensor.set_auto_gain(False) # 关闭自动自动增益。默认开启的,在颜色识别中,一定要关闭白平衡。
#sensor.set_auto_whitebal(False)
fm.register(10, fm.fpioa.UART1_TX, force=True)
fm.register(11, fm.fpioa.UART1_RX, force=True)
uart = UART(UART.UART1, 115200, 8, 1, 0, timeout=1000, read_buf_len=4096)
lcd.init(type=1,freq=15000000,color=lcd.BLACK)
#sensor.snapshot(1.8)#去鱼眼化
#LCD初始化
clock = time.clock() # Tracks FPS.
img = sensor.snapshot()
K=5000#the value should be measured K=length*Lm # 实际的大小=K2*直径的像素
K2=10.5/101#QQVGA模式下K2=10.5/139 #QVGA模式下K2=10.5/279
#blobs = img.find_blobs([yellow_threshold], x_stride=5, y_stride=5, invert=False, area_threshold=10, pixels_threshold=25, merge=False, margin=0, threshold_cb=None, merge_cb=None)#调用颜色阈值
while(True):
clock.tick() # Track elapsed milliseconds between snapshots().
img = sensor.snapshot() # Take a picture and return the image.
#lcd.display(img)#lcd屏幕显示
blobs = img.find_blobs([yellow_threshold],pixels_threshold = 400,area_threshold = 200,margin=5,merge = False)
if blobs:
#如果找到了目标颜色
max_temp = 0
max_obj = blobs[0]
for b in blobs: #循环效果不好,会有很多误识别,采用单个矩形采样方便返回坐标
##迭代找到的目标颜色区域
if max_temp<=b.area():
max_temp = b.area()
max_obj = b
if max_temp>=b.area():
pass
x = b[0]
y = b[1]
width = b[2]
height = b[3]
img.draw_rectangle([x,y,width,height]) # rect
#用矩形标记出目标颜色区域
img.draw_cross(b[5], b[6]) # cx, cy
#在目标颜色区域的中心画十字形标记
num=10*100000000+max_temp*1000+b[5]
#uart.write("{}".format(ret))
#uart.write("{}".format(num)+'\r\n')
#print(b[5])
#print(ret)
if len(blobs)==0:
uart.write('\n'+'0000000000'+'\r')
time.sleep(0.001)
#print(0)
else:
uart.write('\n'+"{}".format(num)+'\r')
time.sleep(0.001)
#print(num)
#print(clock.fps())