我正在尝试使用python创建makeblock mblock实现,但我在github上找到了此api,但它使用的是python 2.7,而我使用的是python 3.8,所以我尝试配置代码,使其可以在python 3.8上运行,但我运行了变成一个错误 初始化程序 机器人
<lib.mBot.mSerial object at 0x02CE9898>
start with serial
<lib.mBot.mHID object at 0x02E2B310>
self.device = mHID()
'mHID' object has no attribute 'dict'
Exception in thread Thread-2:
self.start()
Traceback (most recent call last):
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 154, in __onRead
start with HID
--------------------
n = self.device.inWaiting()
<lib.mBot.mBot object at 0x002FF640>
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 96, in inWaiting
--------------------
Error in sys.excepthook:
buf = self.dict.device.read(64)
Traceback (most recent call last):
AttributeError: 'mHID' object has no attribute 'dict'
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 134, in excepthook
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\abdsak11\AppData\Local\Programs\Python\Python38-32\lib\threading.py", line 932, in _bootstrap_inner
self.close()
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 142, in close
self.device.close()
self.run()
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 106, in close
File "C:\Users\abdsak11\AppData\Local\Programs\Python\Python38-32\lib\threading.py", line 870, in run
self.dict.device.close()
AttributeError: 'mHID' object has no attribute 'dict'
Original exception was:
Traceback (most recent call last):
File "c:/Users/abdsak11/OneDrive - Lärande/Dokument/GitHub/python-for-mbot/test.py", line 15, in <module>
self._target(*self._args, **self._kwargs)
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 163, in __onRead
bot.doMove(50,50)
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 179, in doMove
self.close()
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 142, in close
self.__writePackage(bytearray([0xff,0x55,0x7,0x0,0x2,0x5]+self.short2bytes(-leftSpeed)+self.short2bytes(rightSpeed)))
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 278, in short2bytes
self.device.close()
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 106, in close
return [ord(val[0]),ord(val[1])]
TypeError: ord() expected string of length 1, but int found
self.dict.device.close()
AttributeError: 'mHID' object has no attribute 'dict'
'mHID' object has no attribute 'dict'
Exception in thread Thread-1:
Traceback (most recent call last):
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 154, in __onRead
n = self.device.inWaiting()
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 96, in inWaiting
buf = self.dict.device.read(64)
AttributeError: 'mHID' object has no attribute 'dict'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\abdsak11\AppData\Local\Programs\Python\Python38-32\lib\threading.py", line 932, in _bootstrap_inner
self.run()
File "C:\Users\abdsak11\AppData\Local\Programs\Python\Python38-32\lib\threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 163, in __onRead
self.close()
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 142, in close
self.device.close()
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 106, in close
self.dict.device.close()
AttributeError: 'mHID' object has no attribute 'dict'
所以我想做的是通过USB COM3串行控制代码并将其上传到我的mbot,这就是我得到的错误,我尝试了一切,但均无法正常工作,而且我似乎无法找出错误的原因
mbot.py
这是我发现的主要api
import serial
import sys,time
import signal
from time import ctime,sleep
import glob,struct
from multiprocessing import Process,Manager,Array
import threading
import hid
class mSerial():
ser = None
def __init__(self):
print (self)
def start(self, port):
self.ser = serial.Serial(port,115200)
def device(self):
return self.ser
def serialPorts(self):
if sys.platform.startswith('win'):
ports = ['COM%s' % (i + 1) for i in range(256)]
elif sys.platform.startswith('linux') or sys.platform.startswith('cygwin'):
ports = glob.glob('/dev/tty[A-Za-z]*')
elif sys.platform.startswith('darwin'):
ports = glob.glob('/dev/tty.*')
else:
raise EnvironmentError('Unsupported platform')
result = []
for port in ports:
s = serial.Serial()
s.port = port
s.close()
result.append(port)
return result
def writePackage(self,package):
self.ser.write(package)
sleep(0.01)
def read(self):
return self.ser.read()
def isOpen(self):
return self.ser.isOpen()
def inWaiting(self):
return self.ser.inWaiting()
def close(self):
self.ser.close()
class mHID():
def __init__(self):
print (self)
def start(self):
print ("starting start \n\n")
self.manager = Manager()
print("manager pass \n\n")
self.dict = self.manager.dict()
print("dict pass \n\n")
self.dict.device = hid.device()
print("dict device pass \n\n")
self.dict.device.open(0x0416, 0xffff)
print("dict device open pass \n\n")
self.dict.device.hid_set_nonblocking(self.device,1)
print ("start")
self.buffer = []
self.bufferIndex = 0
def enumerate(self):
print ("enumerate")
for dev in self.dict.device.enumerate():
print ('------------------------------------------------------------')
print (dev.description())
def writePackage(self,package):
buf = []
buf += [0, len(package)]
for i in range(len(package)):
buf += [package[i]]
n = self.dict.device.write(buf)
sleep(0.01)
def read(self):
c = self.buffer[0]
self.buffer = self.buffer[1:]
return chr(c)
def isOpen(self):
return True
def inWaiting(self):
buf = self.dict.device.read(64)
l = 0
if len(buf)>0:
l = buf[0]
if l>0:
for i in range(0,l):
self.buffer += [buf[i+1]]
return len(self.buffer)
def close(self):
self.dict.device.close()
class mBot():
def __init__(self):
print ("init mBot")
signal.signal(signal.SIGINT, self.exit)
self.manager = Manager()
self.__selectors = self.manager.dict()
self.buffer = []
self.bufferIndex = 0
self.isParseStart = False
self.exiting = False
self.isParseStartIndex = 0
def startWithSerial(self, port):
self.device = mSerial()
self.device.start(port)
self.start()
def startWithHID(self):
self.device = mHID()
print ("self.device = mHID()\n \n")
self.device.start()
print ("self.device.start()\n \n")
self.start()
print ("self.start()\n \n")
def excepthook(self, exctype, value, traceback):
self.close()
def start(self):
sys.excepthook = self.excepthook
th = threading.Thread(target=self.__onRead,args=(self.onParse,))
th.start()
def close(self):
self.device.close()
def exit(self, signal, frame):
self.exiting = True
sys.exit(0)
def __onRead(self,callback):
while 1:
if(self.exiting==True):
break
try:
if self.device.isOpen()==True:
n = self.device.inWaiting()
for i in range(n):
r = ord(self.device.read())
callback(r)
sleep(0.01)
else:
sleep(0.5)
except Exception as ex:
print (str(ex))
self.close()
sleep(1)
def __writePackage(self,pack):
self.device.writePackage(pack)
def doRGBLed(self,port,slot,index,red,green,blue):
self.__writePackage(bytearray([0xff,0x55,0x9,0x0,0x2,0x8,port,slot,index,red,green,blue]))
def doRGBLedOnBoard(self,index,red,green,blue):
self.doRGBLed(0x7,0x2,index,red,green,blue)
def doMotor(self,port,speed):
self.__writePackage(bytearray([0xff,0x55,0x6,0x0,0x2,0xa,port]+self.short2bytes(speed)))
def doMove(self,leftSpeed,rightSpeed):
self.__writePackage(bytearray([0xff,0x55,0x7,0x0,0x2,0x5]+self.short2bytes(-leftSpeed)+self.short2bytes(rightSpeed)))
def doServo(self,port,slot,angle):
self.__writePackage(bytearray([0xff,0x55,0x6,0x0,0x2,0xb,port,slot,angle]))
def doBuzzer(self,buzzer,time=0):
self.__writePackage(bytearray([0xff,0x55,0x7,0x0,0x2,0x22]+self.short2bytes(buzzer)+self.short2bytes(time)))
def doSevSegDisplay(self,port,display):
self.__writePackage(bytearray([0xff,0x55,0x8,0x0,0x2,0x9,port]+self.float2bytes(display)))
def doIROnBoard(self,message):
self.__writePackage(bytearray([0xff,0x55,len(message)+3,0x0,0x2,0xd,message]))
def requestLightOnBoard(self,extID,callback):
self.requestLight(extID,8,callback)
def requestLight(self,extID,port,callback):
self.__doCallback(extID,callback)
self.__writePackage(bytearray([0xff,0x55,0x4,extID,0x1,0x3,port]))
def requestButtonOnBoard(self,extID,callback):
self.__doCallback(extID,callback)
self.__writePackage(bytearray([0xff,0x55,0x4,extID,0x1,0x1f,0x7]))
def requestIROnBoard(self,extID,callback):
self.__doCallback(extID,callback)
self.__writePackage(bytearray([0xff,0x55,0x3,extID,0x1,0xd]))
def requestUltrasonicSensor(self,extID,port,callback):
self.__doCallback(extID,callback)
self.__writePackage(bytearray([0xff,0x55,0x4,extID,0x1,0x1,port]))
def requestLineFollower(self,extID,port,callback):
self.__doCallback(extID,callback)
self.__writePackage(bytearray([0xff,0x55,0x4,extID,0x1,0x11,port]))
def onParse(self, byte):
position = 0
value = 0
self.buffer+=[byte]
bufferLength = len(self.buffer)
if bufferLength >= 2:
if (self.buffer[bufferLength-1]==0x55 and self.buffer[bufferLength-2]==0xff):
self.isParseStart = True
self.isParseStartIndex = bufferLength-2
if (self.buffer[bufferLength-1]==0xa and self.buffer[bufferLength-2]==0xd and self.isParseStart==True):
self.isParseStart = False
position = self.isParseStartIndex+2
extID = self.buffer[position]
position+=1
type = self.buffer[position]
position+=1
# 1 byte 2 float 3 short 4 len+string 5 double
if type == 1:
value = self.buffer[position]
if type == 2:
value = self.readFloat(position)
if(value<-255 or value>1023):
value = 0
if type == 3:
value = self.readShort(position)
if type == 4:
value = self.readString(position)
if type == 5:
value = self.readDouble(position)
if(type<=5):
self.responseValue(extID,value)
self.buffer = []
def readFloat(self, position):
v = [self.buffer[position], self.buffer[position+1],self.buffer[position+2],self.buffer[position+3]]
return struct.unpack('<f', struct.pack('4B', *v))[0]
def readShort(self, position):
v = [self.buffer[position], self.buffer[position+1]]
return struct.unpack('<h', struct.pack('2B', *v))[0]
def readString(self, position):
l = self.buffer[position]
position+=1
s = ""
for i in Range(l):
s += self.buffer[position+i].charAt(0)
return s
def readDouble(self, position):
v = [self.buffer[position], self.buffer[position+1],self.buffer[position+2],self.buffer[position+3]]
return struct.unpack('<f', struct.pack('4B', *v))[0]
def responseValue(self, extID, value):
self.__selectors["callback_"+str(extID)](value)
def __doCallback(self, extID, callback):
self.__selectors["callback_"+str(extID)] = callback
def float2bytes(self,fval):
val = struct.pack("f",fval)
return [ord(val[0]),ord(val[1]),ord(val[2]),ord(val[3])]
def short2bytes(self,sval):
val = struct.pack("h",sval)
return [ord(val[0]),ord(val[1])]
test.py
这是我正在使用的测试文件
from lib.mBot import *
if __name__ == "__main__":
bot = mBot()
print ("bot \n\n")
bot.startWithSerial("COM3")
print ("start with serial\n\n")
bot.startWithHID()
print ("start with HID \n\n")
print(f'--------------------\n')
print (bot)
print(f'--------------------\n')
bot.doMove(50,50)
答案 0 :(得分:0)
我相信您的麻烦就在这里
class mHID():
def __init__(self):
print (self)
def start(self):
# ...
self.dict = self.manager.dict()
# ...
def close(self):
self.dict.device.close()
即使计划以后再更改它们,也应始终在__init__()
中定义实例属性,至少以初始值None
定义。
此外,每当遇到必须在A
之前调用“ B
”的情况时,应编写代码以正确处理在没有B
的情况下调用A
的情况。 。在这种情况下,如果从未调用过close()
,start()
应该怎么做?为简单起见,我只是不执行任何操作,但您可以考虑引发异常。
class mHID():
def __init__(self):
print (self)
self.dct = None
def start(self):
# ...
self.dct = self.manager.dict()
# ...
def close(self):
if self.dct:
self.dct.device.close()
您会发现我也将self.dict
重命名为self.dct
。尽管由于self.
命名空间,从技术上来说,前一个名称可能是允许的,但dict
实际上是一个内置类。在各种情况下,您都可以处理阴影。至少,总是不得不提醒自己“这不是内置的dict
,而是一个实例变量,这让人感到困惑。
(可能的原因:您是否不想从初始化程序调用{{1}}的特定原因?)
警告:这不是“复制并粘贴答案”的简单情况。我在这里说明了一些设计原则,您应该将它们纳入其余的代码中。