本人正在用python通过bleak蓝牙连接舵机设备进行控制,由于bleak的connect()
函数是async的,我在main函数里通过asyncio.run()
来调用,现在问题在于,同样的代码,如果我在main函数前面加入import mediapipe as mp
后,运行就会卡住,不会报错也不会输出连接成功的信息。
main.py
# main.py
from control_center import ControlCenter
if __name__ == "__main__":
controlCenter = ControlCenter()
asyncio.run(controlCenter.servo_controller.connect())
# controlCenter.servo_controller.connect()
print (controlCenter.servo_controller.client)
print (controlCenter.servo_controller.paired)
print (controlCenter.btmKp)
control_center.py
# control_center.py
import logging
from bt2 import ServoController
class ControlCenter:
def __init__(self):
self.count = 0
self.btmKp = 20
self.topKp = 20
self.offsetX = 0
self.offsetY = 0
self.offsetDeadBlock = 0.05
self.lastBtmDegree = 90
self.lastTopDegree = 90
# 常量
self.FRAME_HEAD = 0x55;
self.FRAME_LENGTH = 0x0b;
self.FRAME_TYPE = 0x03;
self.SERVO_NUM = 0x02;
# 变量
self.servoId1 = 0x01;
self.positionLow1 = 0xdc;
self.positionHigh1 = 0x05;
self.servoId2 = 0x02;
self.positionLow2 = 0xdc;
self.positionHigh2 = 0x05;
self.servo_controller = ServoController("48:87:2d:62:a5:ae")
# self.servo_controller.connect()
bt2.py
from bleak import BleakClient
class ServoController:
def __init__(self, address):
self.address = address
self.client = BleakClient(self.address)
self.paired = False
async def connect(self):
print("111")
await self.client.connect()
print("222")
self.paired = await self.client.pair(protection_level=2)
print(f"Connected: {self.client.is_connected}")
print(f"Paired: {self.paired}")
async def disconnect(self):
await self.client.disconnect()
print('Disconnected')
async def send_command(self, command):
if not self.client.is_connected or not self.paired:
raise Exception("Not connected or paired.")
await self.client.write_gatt_char(24, bytes(command))
以上代码可以运行,结果如下
但在main.py加入import mediapipe as mp
后,即使没有任何地方使用,也会一直卡住不会继续执行,也不会报错或退出程序。
mediapipe库和asyncio之间的兼容性问题吧
问题点:导入mediapipe库卡住
分析:初次运行mediapipe代码可能需要下载模型,且模型在github上,延迟导致卡住.
处理方案: 尝试单独使用mediapipe库,顺利完成mediapipe的demo,再看问题是否解决.
在main.py加入import mediapipe as mp后,即使没有任何地方使用,也会一直卡住不会继续执,这个现象比较明细的可能就是在导入这个包的,或者说加载这个包的时候卡住了。那就要检查下这个包是否安装正确,版本之类、兼容性的问题。其次,有可能在使用了这个包之后,连接出现了问题,我看你上面的代码在打印了111之后有个await self.client.connect()的操作,也有可能是一直在等待连接,又连接不上
可能多个包之间存在兼容性问题
这可能是因为bleak蓝牙连接的操作需要消耗大量的计算资源,而导致程序阻塞。
修改包的版本试试
基于new bing部分指引作答:
这可能是由于在asyncio.run()函数中使用了asyncio事件循环,并且在该事件循环中的某些任务被阻塞,导致整个程序卡住。可能的原因是mediapipe库的导入和asyncio.run()之间存在一些冲突或不兼容性。
有几种方法可以尝试解决这个问题:
异步导入:尝试使用importlib库进行异步导入mediapipe,以便不会阻塞主事件循环。可以将import mediapipe as mp替换为以下代码:
import importlib
import asyncio
async def import_mediapipe():
global mp
mp = importlib.import_module('mediapipe')
async def main():
await import_mediapipe()
controlCenter = ControlCenter()
await controlCenter.servo_controller.connect()
print(controlCenter.servo_controller.client)
print(controlCenter.servo_controller.paired)
print(controlCenter.btmKp)
asyncio.run(main())
然后尝试运行修改后的代码,看看是否仍然会卡住。
使用异步调用:将controlCenter.servo_controller.connect()修改为await controlCenter.servo_controller.connect(),并将main()函数定义为异步函数。修改后的代码如下:
import asyncio
from control_center import ControlCenter
async def main():
controlCenter = ControlCenter()
await controlCenter.servo_controller.connect()
print(controlCenter.servo_controller.client)
print(controlCenter.servo_controller.paired)
print(controlCenter.btmKp)
if __name__ == "__main__":
asyncio.run(main())
然后尝试运行修改后的代码,看看是否仍然会卡住。
调整代码结构:如果以上方法仍然无效,可以尝试重新组织代码结构,将mediapipe的导入放在asyncio.run()之前,或将mediapipe的导入放在单独的函数中,在需要使用它的地方再导入。这样可以避免mediapipe的导入对asyncio.run()的影响。
希望其中一种方法能够解决你的问题。
第一:卡住有可能是get请求的服务端响应超时,通常需要设置一个请求的超时时间:timeout。
第二:三次请求,只出现了两次结果,debug时正常:这也许是终端输出的问题,请求没有丢失,是协程跑的太快了,终端输出有时候不会全部打印,加个time.sleep(0.1)的话,应该可以看到所有请求都执行了的。(多进程时,也是这样的)
第三:bug报错的是“KeyError”,可以肯定的是,取值的时候没有对应key,报错中看不到具体的报错代码,无法推断!