207 lines
5.5 KiB
Python
207 lines
5.5 KiB
Python
"""
|
|
AI COM
|
|
|
|
MicroPython library for the AI COM ( for MixGo AI)
|
|
=======================================================
|
|
|
|
#Preliminary composition 20220905
|
|
|
|
dahanzimin From the Mixly Team
|
|
"""
|
|
|
|
import time,gc
|
|
|
|
|
|
class INFO:
|
|
def __init__(self, info1,info2,rect):
|
|
self.info1=info1
|
|
self.info2=info2
|
|
self.rect=rect
|
|
self.x=None
|
|
self.y=None
|
|
self.w=None
|
|
self.h=None
|
|
self.xc=None
|
|
self.yc=None
|
|
if type(rect) in [tuple,list]:
|
|
self.x=rect[0]
|
|
self.y=rect[1]
|
|
self.w=rect[2]
|
|
self.h=rect[3]
|
|
self.xc=rect[0]+rect[2]//2
|
|
self.yc=rect[1]+rect[3]//2
|
|
self.type="info"
|
|
|
|
class AI:
|
|
def __init__(self, uart, quick=False):
|
|
self._uart=uart
|
|
self._uart.init(baudrate=115200, timeout=500)
|
|
self._info=[]
|
|
self._sdata=[]
|
|
self._removal=quick
|
|
if not self._chip_id():
|
|
raise AttributeError("Cannot find a MixGo AI")
|
|
|
|
def send(self,data):
|
|
eec=0
|
|
buffer=str(data).encode()
|
|
for i in range(len(buffer)):
|
|
eec^=int(buffer[i])
|
|
eec=0 if eec==10 else eec
|
|
self._uart.write(buffer+chr(eec)+b'\n')
|
|
|
|
def recv(self,timeout=500,warn=True):
|
|
t_star=time.ticks_ms()
|
|
while not self._uart.any():
|
|
if time.ticks_diff(time.ticks_ms(), t_star) >timeout:
|
|
if warn:
|
|
print("Warning: MixGo AI timeout not responding")
|
|
return False
|
|
buffer = self._uart.readline()
|
|
if buffer:
|
|
eec=0
|
|
if len(buffer)>=3:
|
|
for i in range(len(buffer)-2):
|
|
eec^=int(buffer[i])
|
|
if eec==buffer[-2] or buffer[-2]==0:
|
|
try:
|
|
return eval(buffer[:-2].decode())
|
|
except:
|
|
return None
|
|
def _chip_id(self):
|
|
for _ in range(10):
|
|
self.send(["ok",[[],'']])
|
|
if self.recv(1000,False):
|
|
return True
|
|
|
|
def request(self,func='', para=[], name=None, timeout=1000):
|
|
if self._sdata != para:
|
|
self._sdata=para if self._removal else None
|
|
self.send([func,[para,name]])
|
|
else:
|
|
self.send([func,[[],name]])
|
|
|
|
#print(func)
|
|
if func in ['ailr','ailt','play','record','asr']: #不需要警告提醒
|
|
data=self.recv(timeout,False)
|
|
else:
|
|
data=self.recv(timeout,True)
|
|
|
|
self._info=[]
|
|
if data:
|
|
#报错处理
|
|
if "err" in data[0] and type(data[1])==list:
|
|
if type(data[1][0]) == IndexError or "Missing parameter" == data[1][0]:
|
|
self.send(["ok",[[],name]]) #恢复出厂
|
|
self.send([func,[para,name]]) #在发送参数
|
|
else:
|
|
raise RuntimeError("Error from MixGo AI",data[1][0])
|
|
else:
|
|
_len=max(len(data[0]),len(data[1]))
|
|
for i in range(_len):
|
|
if type(data[0][i]) == list:
|
|
info1=data[0][i][0]
|
|
info2=data[0][i][1]
|
|
else:
|
|
info1=data[0][i]
|
|
info2=None
|
|
|
|
if data[1]:
|
|
rect=data[1][i]
|
|
else:
|
|
rect=None
|
|
self._info.append(INFO(info1,info2,rect))
|
|
return self._info
|
|
|
|
def info_len(self):
|
|
return len(self._info)
|
|
|
|
def info_number(self,number):
|
|
if self.info_len() > number:
|
|
return self._info[number]
|
|
|
|
def configure(self, tx_pin, rx_pin, restart=False):
|
|
info=self.request('start',para=[["uart",tx_pin,rx_pin],restart])
|
|
return info[0].info1 if info else False
|
|
|
|
def find_qrcode(self):
|
|
info=self.request('qr')
|
|
return (info[0].info1,info[0].rect) if info else (None,None)
|
|
|
|
def find_barcode(self):
|
|
info=self.request('bar')
|
|
return (info[0].info1,info[0].rect) if info else (None,None)
|
|
|
|
def find_apriltag(self):
|
|
info=self.request('tag')
|
|
return (info[0].info1,info[0].rect) if info else (None,None)
|
|
|
|
def find_qrcodes(self):
|
|
return self.request('qr')
|
|
|
|
def find_barcodes(self):
|
|
return self.request('bar')
|
|
|
|
def find_apriltags(self):
|
|
return self.request('tag')
|
|
|
|
def find_lines(self, threshold=2500, theta_margin=25, rho_margin=25):
|
|
return self.request('line', para=[threshold, theta_margin, rho_margin])
|
|
|
|
def find_circles(self, threshold=2500, r_min=2, r_max=100):
|
|
return self.request('circle', para=[threshold, r_min, r_max])
|
|
|
|
def find_rects(self, threshold=2500):
|
|
return self.request('rect', para=[threshold])
|
|
|
|
def find_colors(self, scale=2):
|
|
info=self.request('color', para=[scale])
|
|
if info:
|
|
return info[0].info1,info[0].info2
|
|
else:
|
|
return None,None
|
|
|
|
def color_track(self, lab=[0, 100, 0, 100, 0, 0], pixels_threshold=10, margin=1):
|
|
return self.request('ctrace', para=[lab, pixels_threshold, margin])
|
|
|
|
def ailocal_train(self, lsit_names, path="mixgo", number=5, disname='自模型训练'):
|
|
info= self.request('ailt', para=[lsit_names, path, number], name=disname)
|
|
return info[0].info1 if info else False
|
|
|
|
def ailocal_class(self, lsit_names, path="mixgo", disname='自模型识别'):
|
|
return self.request('ailr', para=[lsit_names, path], name=disname)
|
|
|
|
def yolo_recognize(self, anchor, path, disname='物品识别'):
|
|
return self.request('aild', para=[anchor, path], name=disname)
|
|
|
|
def led_rgb(self, rgb1=(0,0,0), rgb2=(0,0,0)):
|
|
info= self.request('rgb', para=[rgb1, rgb2])
|
|
return info[0].info1 if info else False
|
|
|
|
def audio_play(self, bck_pin=12, ws_pin=13, dat_pin=14, path="mixgo.wav", volume=80):
|
|
info= self.request('play', para=[[bck_pin, ws_pin, dat_pin], path, volume])
|
|
return info[0].info1 if info else False
|
|
|
|
def audio_record(self, sample_rate=16000, path="mixgo.wav", times=5):
|
|
info= self.request('record', para=[sample_rate, path, times])
|
|
return info[0].info1 if info else False
|
|
|
|
def asr_recognize(self, corpus,threshold=0.1):
|
|
clist=[]
|
|
for cor in corpus:
|
|
clist.append([cor,threshold])
|
|
info=self.request('asr', para=[dict(clist)])
|
|
if info:
|
|
return info[0].info1,info[0].info2
|
|
else:
|
|
return None,None
|
|
|
|
def find_licenseplate(self):
|
|
return self.request('alpr')
|
|
|
|
def find_20object(self):
|
|
return self.request('voc20')
|
|
|
|
def face_detect(self):
|
|
return self.request('face_d')
|