DeviceControl.py 64 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583
  1. import asyncio
  2. import datetime
  3. import serial.tools.list_ports
  4. import time, json
  5. from .SerialIns import SerialIns
  6. from utils.SingletonType import SingletonType
  7. from .BaseClass import BaseClass
  8. from sockets import ConnectionManager
  9. from collections import defaultdict
  10. import threading
  11. import settings
  12. from .ProgramItem import ProgramItem
  13. from .capture.module_digicam import DigiCam
  14. from databases import insert_photo_records
  15. from .McuDeviationSet import McuDeviationSet
  16. from .OtherSet import OtherSet
  17. from .DebugUart import DebugUart
  18. import copy
  19. # mcu命令
  20. class DeviceControl(BaseClass, metaclass=SingletonType):
  21. lock = threading.Lock()
  22. def __init__(self, websocket_manager: ConnectionManager):
  23. super().__init__(websocket_manager)
  24. self.msg_type = "mcu"
  25. self.mcu_deviation_set = McuDeviationSet(self)
  26. self.mcu_other_set = OtherSet(self)
  27. self.debug_uart = DebugUart(self)
  28. self.m_t = 1
  29. # 0未开始 1进行中 2已结束 99异常
  30. self.action_state = 2
  31. self._mcu_move_state = 0
  32. self.state_camera_motor = 3
  33. self.state_camera_steering = 3
  34. self.state_turntable_steering = 3
  35. self.state_overturn_steering = 3
  36. self.state_move_turntable_steering = 3
  37. self.last_from_mcu_move_respond_data = None
  38. self.camera_motor_speed = 0
  39. self.camera_motor_value = 0
  40. self.init_state = False
  41. self.port_name = ""
  42. self.mcu_exit = False
  43. self.t_n = 0
  44. self.serial_ins = None
  45. self.connected_ports_dict = {} # 已连接的ports
  46. self.p_list = []
  47. self.temp_ports_dict = {}
  48. self.is_running = False
  49. self.is_runn_action = False
  50. self.is_stop_action = False
  51. self.connect_state = False
  52. self.device_name_dict = {
  53. "camera_steering": 0,
  54. "camera_high_motor": 1,
  55. "turntable_steering": 2,
  56. "overturn_steering": 3,
  57. "laser_position": 4,
  58. "buzzer": 5,
  59. "split": 6,
  60. "turntable_position_motor": 7,
  61. "mp3_player": 8,
  62. "mcu": 99,
  63. }
  64. # 最近的mcu基础信息,用于获取数据状态检查
  65. self.last_mcu_info_data = {
  66. "num": 0,
  67. "time": time.time(),
  68. "data": None,
  69. }
  70. # 最近的mcu的其他配置
  71. self.last_mcu_other_info_data = {
  72. "num": 0,
  73. "time": time.time(),
  74. "data": {},
  75. }
  76. self.command = {
  77. "to_device_move": 1, # 设备运动
  78. "to_init_device": 2, # 初始化设备
  79. "to_deal_other_device": 3, # 处理其他设备
  80. "get_all_info": 29, # 获取所有信息
  81. "set_deviation": 40, # 设置偏移量
  82. "get_deviation": 41, # 读取偏移量
  83. "signal_forwarding": 91, # 信号转发处理
  84. "signal_forwarding_return": 92, # 信号转发返回
  85. "get_other_info": 44, # 获取其他信息
  86. "open_rgb_led": 43, ## RGB灯的处理与通讯
  87. "set_other_info": 45, # 设置其他信息
  88. "query_remote_control_battery": 47, # 查询遥控器电量
  89. "set_turntable_mode": 48, # 设置转盘通讯方式 1、串口、2、无线、3 混合
  90. "stop_mcu": 93, # 停止运行mcu
  91. }
  92. # self.window = window
  93. self.last_push_time = defaultdict(float)
  94. self.is_running = False
  95. self.is_wait_connect = False # 等待链接
  96. self.send_data_queue = [] # 发送队列
  97. # self.lock = Lock()
  98. # 是否是刚进行完初始化;首次初始化,需要运动到指定第一个指定位置
  99. self.is_just_init_time = False
  100. # self.init()
  101. # ===========注册命令函数============
  102. self.deal_code_func_dict = {
  103. 29: self.get_from_mcu_base_info, # 获取基本情况
  104. 32: self.get_from_mcu_button, # 获取按键信息
  105. 42: self.get_from_mcu_deviation_info, # 获取偏移量信息
  106. 44: self.get_from_mcu_other_info, # 获取其他配置参数
  107. 90: self.get_from_mcu_connect_info, # 获取链接电脑信号
  108. 92: self.get_from_mcu_move_respond_data, # 获取MCU响应
  109. 100: self.print_mcu_error_data, # 打印下位机的错误内容
  110. }
  111. async def sendCommand(self,command):
  112. await asyncio.sleep(0.01)
  113. loop = asyncio.get_event_loop()
  114. loop.create_task(self.debug_uart.set(command), name="sendCommand2")
  115. async def getMcuOtherInfo(self):
  116. await asyncio.sleep(0.01)
  117. self.get_other_info()
  118. async def setMcuOtherInfo(self,data):
  119. await asyncio.sleep(0.01)
  120. for k, v in data.items():
  121. print("k:{},v:{}".format(k, v))
  122. data[k] = self.setOtherMaxMinValue(k, v)
  123. self.set_to_mcu_other_info(data)
  124. self.msg_type = "set_other_mcu_info"
  125. self.sendSocketMessage(
  126. code=0,
  127. msg="设置mcu其他配置信息完成",
  128. device_status=2,
  129. )
  130. self.msg_type = "mcu"
  131. def setOtherMaxMinValue(self,item, value):
  132. value = int(value)
  133. parameter_limits = {
  134. "is_auto_send_base_info": (0, 10000),
  135. "is_move_retry": (0, 10000),
  136. "is_data_response": (0, 10000),
  137. "low_speed": (0, 10000), # 假设低速范围是0到1000
  138. "is_test": (0, 10000),
  139. "to_init_mode": (0, 10000),
  140. "turntable_move_to_init_mode": (0, 10000), # 假设转盘通讯方式范围是0到3
  141. "led_count": (0, 10000), # 假设LED数量范围是0到10
  142. "turntable_steering_angle_ratio": (0, 10000), # 假设角度比例范围是0到100
  143. "is_manual_check": (0, 10000),
  144. "camera_steering_angle_ratio": (0, 100000), # 假设角度比例范围是0到100
  145. "is_auto_motor_to_disable": (0, 10000),
  146. "diff_dir": (0, 10000),
  147. "is_auto_send_pos_info": (0, 10000),
  148. "is_dog": (0, 10000),
  149. "has_been_set_motor_config": (0, 10000),
  150. }
  151. # 获取参数的最小值和最大值
  152. min_value, max_value = parameter_limits.get(item, (0, 10000))
  153. value = max(min_value, min(max_value, value))
  154. return value
  155. async def initDevice(self,is_force=False):
  156. if not self.is_running:
  157. self.sendSocketMessage(
  158. code=1, msg="mcu设备未连接,请先连接设备", device_status=0
  159. )
  160. return False
  161. if self.init_state ==True:
  162. print("已经初始化过,请勿重复初始化")
  163. self.sendSocketMessage(msg="设备初始化完成", device_status=2)
  164. return False
  165. self.serial_ins.clearn_flush()
  166. self.to_init_device_origin_point(device_name="mcu",is_force=is_force)
  167. print("MCU 开始循环~")
  168. while 1:
  169. await asyncio.sleep(0.01)
  170. if not self.serial_ins or not self.connect_state:
  171. break
  172. try:
  173. # print("mcu send_cmd")
  174. self.send_cmd()
  175. # time.sleep(0.01)
  176. self.get_basic_info_mcu()
  177. # self.close_other_window()
  178. except BaseException as e:
  179. print("121231298908", e)
  180. break
  181. self.is_running = False
  182. self.connect_state = False
  183. print("MCU 循环退出~")
  184. # self.sign_data.emit(
  185. # {"_type": "show_info", "plugins_mode": "mcu", "data": "MCU 连接失败"}
  186. # )
  187. message = {"_type": "show_info", "plugins_mode": "mcu", "data": "MCU 连接失败"}
  188. self.sendSocketMessage(code=1, msg="MCU 连接失败", data=message,device_status=-1)
  189. self.close_connect()
  190. def stop_mcu(self):
  191. buf = [self.command["stop_mcu"]]
  192. buf.extend(self.encapsulation_data(data=1, len_data=1))
  193. self.add_send_data_queue(buf)
  194. # 设置转盘通讯方式 1、串口、2、无线、3 混合
  195. def to_set_turntable_mode(self, mode=1):
  196. buf = [self.command["set_turntable_mode"]]
  197. buf.extend(self.encapsulation_data(data=mode, len_data=1))
  198. self.add_send_data_queue(buf)
  199. def query_remote_control_battery(self):
  200. """查询遥控器电量"""
  201. buf = [self.command["query_remote_control_battery"]]
  202. buf.extend(self.encapsulation_data(data=1, len_data=1))
  203. buf.extend(self.encapsulation_data(data=1, len_data=1))
  204. buf.extend(self.encapsulation_data(data=1, len_data=1))
  205. self.add_send_data_queue(buf)
  206. def encapsulation_data(self, data, len_data, data_magnification=1):
  207. # data_magnification 数据放大倍数,或缩小倍数,默认为1
  208. data = int(data * data_magnification)
  209. if len_data == 1:
  210. return [0xFF & data]
  211. elif len_data == 2:
  212. return [0xFF & data >> 8, 0xFF & data]
  213. elif len_data == 4:
  214. return [0xFF & data >> 24, 0xFF & data >> 16, 0xFF & data >> 8, 0xFF & data]
  215. def open_rgb_led(
  216. self,
  217. color_name,
  218. led_command=1,
  219. brightness=80,
  220. enable=True,
  221. mode="loop",
  222. times=2,
  223. interval=0.1,
  224. ):
  225. color_name_value = {
  226. "红色": (156, 6, 3),
  227. "黄色": (255, 206, 25),
  228. "绿色": (0, 128, 0),
  229. "蓝色": (0, 25, 255),
  230. "白色": (255, 250, 227),
  231. }
  232. if color_name in color_name_value:
  233. buf = [self.command["open_rgb_led"]]
  234. buf.append(1 if enable else 0)
  235. buf.append(led_command)
  236. buf.extend(color_name_value[color_name])
  237. buf.extend(
  238. [
  239. brightness,
  240. 1 if mode == "loop" else 2,
  241. times,
  242. int(interval * 10),
  243. ]
  244. )
  245. self.add_send_data_queue(buf)
  246. async def getDeviationInfo(self):
  247. await asyncio.sleep(0.01)
  248. try:
  249. # 发送获取偏移量
  250. data = [self.command["get_deviation"], 1]
  251. self.add_send_data_queue(data)
  252. # if self.serial_ins:
  253. # self.serial_ins.write_cmd(data)
  254. print("发送获取偏移量")
  255. except Exception as e:
  256. print(e)
  257. print("getDeviationInfo", "暂未获取到self.command")
  258. def set_deviation(self, device_name, _type=0, deviation=0):
  259. # turntable----0 angle_ratio 1 turntable_steering_deviation
  260. # overturn ----0 middle 1 high
  261. if device_name == "camera_high_motor":
  262. deviation = deviation / 10 # deviation 原单位为mm
  263. if device_name == "turntable_position_motor":
  264. deviation = deviation / 10 # deviation 原单位为mm
  265. if device_name == "camera_steering":
  266. pass
  267. if device_name == "turntable_steering":
  268. pass
  269. if device_name == "overturn_steering":
  270. pass
  271. device_id = self.device_name_dict[device_name]
  272. _dir = 1 if deviation >= 0 else 0
  273. deviation = int(abs(deviation * 10))
  274. data = [
  275. self.command["set_deviation"],
  276. device_id,
  277. _type,
  278. _dir,
  279. 0xFF & deviation >> 8,
  280. 0xFF & deviation,
  281. ]
  282. self.add_send_data_queue(data)
  283. # self.controlDevice(device_name, deviation)
  284. async def set_deviation_cmd(self,value,action_name,type):
  285. await asyncio.sleep(0.01)
  286. name_sets = [
  287. "相机电机", # min 0 max 400,步长1
  288. "相机舵机", # min -40 max 40,步长0.1
  289. "转盘舵机", # min -720 max 720,步长1
  290. "转盘前后电机", # min 0 max 950,步长1
  291. "翻板舵机中位", # min 0 max 180,步长0.5
  292. "翻板舵机高位", # min 0 max 180,步长0.5
  293. "翻板舵机上升速度", # min 1 max 10,步长1
  294. "翻板舵机下降速度", # min 1 max 10,步长1
  295. ]
  296. if action_name not in name_sets:
  297. self.msg_type = f"{type}_deviation"
  298. self.sendSocketMessage(msg="设置参数有误,请检查", device_status=0,code=1)
  299. self.msg_type = "mcu"
  300. return
  301. # 发送获取偏移量
  302. if type == "move":
  303. self.mcu_deviation_set.change_value(value, action_name)
  304. elif type == "set":
  305. self.mcu_deviation_set.set_deviation(action_name)
  306. self.msg_type = f"{type}_deviation"
  307. self.sendSocketMessage(msg=f"{action_name} 设置成功", device_status=2,code=0)
  308. self.msg_type = "mcu"
  309. def get_other_info(self):
  310. # 发送获取偏移量
  311. data = [self.command["get_other_info"], 1]
  312. self.add_send_data_queue(data)
  313. print("发送获取其他信息")
  314. def add_send_data_queue(self, data):
  315. self.lock.acquire()
  316. if self.serial_ins:
  317. print("send_data_queue append :{}".format(data))
  318. self.send_data_queue.append(data)
  319. self.lock.release()
  320. def send_all_cmd(self):
  321. while True:
  322. if self.send_data_queue:
  323. self.sendSocketMessage(msg="正在发送命令", device_status=1)
  324. data = self.send_data_queue.pop(0)
  325. self.serial_ins.write_cmd(data)
  326. self.sendSocketMessage(msg="命令发送完成", device_status=2)
  327. else:
  328. break
  329. def send_cmd(self):
  330. self.lock.acquire()
  331. if self.send_data_queue:
  332. self.sendSocketMessage(msg="正在发送命令", device_status=1)
  333. data = self.send_data_queue.pop(0)
  334. self.serial_ins.write_cmd(data)
  335. self.sendSocketMessage(msg="命令发送完成", device_status=2)
  336. # else:
  337. # self.t_n += 1
  338. # # 加大发送获取基础数据的时间间隔
  339. # # 默认为0.01秒一个循环,每隔1.5秒发送数据
  340. # if self.t_n > 150:
  341. # self.t_n = 0
  342. # data = [self.command["get_all_info"], 1]
  343. # self.serial_ins.write_cmd(data)
  344. self.lock.release()
  345. def print_mcu_error_data(self, receive_data):
  346. # 扫码数据
  347. try:
  348. data = receive_data[1:].decode()
  349. if "设备初始化完成" in data:
  350. self.init_state = True
  351. self.sendSocketMessage(msg=data, device_status=2)
  352. print("115 print_mcu_error_data:", data)
  353. except BaseException as e:
  354. print("117 error {}".format(e))
  355. return
  356. def get_from_mcu_move_respond_data(self, receive_data):
  357. self.last_from_mcu_move_respond_data = receive_data
  358. def get_from_mcu_connect_info(self, receive_data):
  359. connect_flag = receive_data[1]
  360. device_id = receive_data[2]
  361. try:
  362. mcu_has_been_set = receive_data[6] # 设备是否有初始化 ,1 表示已初始化
  363. except:
  364. mcu_has_been_set = 99 # 未知状态
  365. # self.self_sign.emit({"type": "connect_sign", "data": connect_flag})
  366. message = {"type": "connect_sign", "data": connect_flag}
  367. self.sendSocketMessage(msg="接收链接信息", data=message)
  368. print("接收链接信息")
  369. return
  370. def to_init_device_origin_point(self, device_name, is_force=False):
  371. device_id = self.device_name_dict[device_name]
  372. cmd = 2
  373. data = [cmd, device_id, 0 if is_force is False else 1]
  374. self.open_rgb_led(color_name="红色")
  375. self.add_send_data_queue(data)
  376. if device_name == "mcu":
  377. # 重置初始化标记为 从未初始化
  378. self.is_just_init_time = False
  379. return True
  380. # 设置其他信息
  381. def set_to_mcu_other_info(self, data):
  382. is_auto_send_base_info = data["is_auto_send_base_info"]
  383. is_move_retry = data["is_move_retry"]
  384. is_data_response = data["is_data_response"]
  385. low_speed = data["low_speed"]
  386. is_test = data["is_test"]
  387. to_init_mode = data["to_init_mode"]
  388. turntable_move_to_init_mode = data["turntable_move_to_init_mode"]
  389. led_count = data["led_count"]
  390. turntable_steering_angle_ratio = data["turntable_steering_angle_ratio"]
  391. is_manual_check = data["is_manual_check"]
  392. camera_steering_angle_ratio = data["camera_steering_angle_ratio"]
  393. is_auto_motor_to_disable = data["is_auto_motor_to_disable"]
  394. diff_dir = data["diff_dir"]
  395. is_auto_send_pos_info = data["is_auto_send_pos_info"]
  396. is_dog = data["is_dog"]
  397. has_been_set_motor_config = data["has_been_set_motor_config"]
  398. buf = [self.command["set_other_info"]]
  399. buf.extend(self.encapsulation_data(data=is_auto_send_base_info, len_data=1))
  400. buf.extend(self.encapsulation_data(data=is_move_retry, len_data=1))
  401. buf.extend(self.encapsulation_data(data=is_data_response, len_data=1))
  402. buf.extend(self.encapsulation_data(data=low_speed, len_data=2))
  403. buf.extend(self.encapsulation_data(data=is_test, len_data=1))
  404. buf.extend(self.encapsulation_data(data=to_init_mode, len_data=1))
  405. buf.extend(
  406. self.encapsulation_data(data=turntable_move_to_init_mode, len_data=1)
  407. )
  408. buf.extend(self.encapsulation_data(data=led_count, len_data=2))
  409. buf.extend(
  410. self.encapsulation_data(data=turntable_steering_angle_ratio, len_data=2)
  411. )
  412. buf.extend(self.encapsulation_data(data=is_manual_check, len_data=1))
  413. buf.extend(
  414. self.encapsulation_data(data=camera_steering_angle_ratio, len_data=4)
  415. )
  416. buf.extend(self.encapsulation_data(data=is_auto_motor_to_disable, len_data=1))
  417. buf.extend(self.encapsulation_data(data=diff_dir, len_data=1))
  418. buf.extend(self.encapsulation_data(data=is_auto_send_pos_info, len_data=1))
  419. buf.extend(self.encapsulation_data(data=is_dog, len_data=1))
  420. buf.extend(self.encapsulation_data(data=has_been_set_motor_config, len_data=1))
  421. self.add_send_data_queue(buf)
  422. def cleanAllReceiveData(self):
  423. while True:
  424. receive_data = self.serial_ins.read_cmd(out_time=1)
  425. if not receive_data:
  426. break
  427. def get_basic_info_mcu(self):
  428. receive_data = self.serial_ins.read_cmd(out_time=1)
  429. if receive_data is False:
  430. print("------------------------------------------------4657564654")
  431. self.connect_state = False
  432. return False
  433. if not receive_data:
  434. return
  435. # print("receive_data", receive_data)
  436. # 数据 结构 command,按命令解析
  437. # command 0(9) 相机高度1-2 相机角度3-4 转盘角度5-6 灯光状态7 激光指示器状态8,运行状态9
  438. command = receive_data[0]
  439. # receive_data_temp = receive_data[2:]
  440. # receive_data_temp_text = " ".join([hex(x) for x in receive_data_temp])
  441. # print("command",command)
  442. # print("receive_data", receive_data_temp_text)
  443. if command in self.deal_code_func_dict:
  444. self.deal_code_func_dict[command](receive_data)
  445. def get_from_mcu_button(self, receive_data):
  446. button_name = receive_data[1]
  447. self.deal_mcu_button(button_name)
  448. def deal_mcu_button(self, button_name):
  449. # 防止重复点击
  450. s = time.time()
  451. if s - self.last_push_time[button_name] > 0.1:
  452. self.last_push_time[button_name] = s
  453. # print("button_name", button_name)
  454. else:
  455. self.last_push_time[button_name] = s
  456. return
  457. if button_name == 1:
  458. # 自动执行全部
  459. # self.sign_data.emit(
  460. # {"_type": "mcu_button", "plugins_mode": "mcu", "data": "todo_1"}
  461. # )
  462. message = {"_type": "mcu_button", "plugins_mode": "mcu", "data": "todo_1"}
  463. self.sendSocketMessage(code=0, msg="", data=message)
  464. if button_name == 2:
  465. # self.sign_data.emit(
  466. # {"_type": "mcu_button", "plugins_mode": "mcu", "data": "todo_2"}
  467. # )
  468. message = {"_type": "mcu_button", "plugins_mode": "mcu", "data": "todo_2"}
  469. self.sendSocketMessage(code=0, msg="", data=message)
  470. if button_name == 3:
  471. # self.sign_data.emit(
  472. # {"_type": "mcu_button", "plugins_mode": "mcu", "data": "todo_3"}
  473. # )
  474. message = {"_type": "mcu_button", "plugins_mode": "mcu", "data": "todo_3"}
  475. self.sendSocketMessage(code=0, msg="", data=message)
  476. # 获取偏移量信息
  477. def get_from_mcu_deviation_info(self, receive_data):
  478. if len(receive_data) == 18:
  479. camera_high_motor_deviation_dir = receive_data[1]
  480. camera_high_motor_deviation = receive_data[2] << 8 | receive_data[3]
  481. camera_high_motor_deviation = (
  482. camera_high_motor_deviation * -1
  483. if camera_high_motor_deviation_dir == 0
  484. else camera_high_motor_deviation
  485. )
  486. camera_steering_deviation_dir = receive_data[4]
  487. camera_steering_deviation = (receive_data[5] << 8 | receive_data[6]) * 0.1
  488. camera_steering_deviation = (
  489. camera_steering_deviation * -1
  490. if camera_steering_deviation_dir == 0
  491. else camera_steering_deviation
  492. )
  493. turntable_steering_deviation_dir = receive_data[7]
  494. turntable_steering_deviation = (
  495. receive_data[8] << 8 | receive_data[9]
  496. ) * 0.1
  497. turntable_steering_deviation = (
  498. turntable_steering_deviation * -1
  499. if turntable_steering_deviation_dir == 0
  500. else turntable_steering_deviation
  501. )
  502. overturn_steering_middle_dir = receive_data[10]
  503. overturn_steering_middle = (receive_data[11] << 8 | receive_data[12]) * 0.1
  504. overturn_steering_middle = (
  505. overturn_steering_middle * -1
  506. if overturn_steering_middle_dir == 0
  507. else overturn_steering_middle
  508. )
  509. overturn_steering_high_dir = receive_data[13]
  510. overturn_steering_high = (receive_data[14] << 8 | receive_data[15]) * 0.1
  511. overturn_steering_high = (
  512. overturn_steering_middle * -1
  513. if overturn_steering_high_dir == 0
  514. else overturn_steering_high
  515. )
  516. overturn_steering_up_speed = receive_data[16]
  517. overturn_steering_down_speed = receive_data[17]
  518. # self.sign_data.emit(
  519. # {
  520. # "_type": "get_deviation_data",
  521. # "plugins_mode": "mcu",
  522. # "data": {
  523. # "camera_high_motor_deviation": camera_high_motor_deviation,
  524. # "camera_steering_deviation": camera_steering_deviation,
  525. # "turntable_steering_deviation": turntable_steering_deviation,
  526. # "overturn_steering_middle": overturn_steering_middle,
  527. # "overturn_steering_high": overturn_steering_high,
  528. # "overturn_steering_up_speed": overturn_steering_up_speed,
  529. # "overturn_steering_down_speed": overturn_steering_down_speed,
  530. # },
  531. # }
  532. # )
  533. # message = {
  534. # "_type": "get_deviation_data",
  535. # "plugins_mode": "mcu",
  536. # "data": {
  537. # "camera_high_motor_deviation": camera_high_motor_deviation,
  538. # "camera_steering_deviation": camera_steering_deviation,
  539. # "turntable_steering_deviation": turntable_steering_deviation,
  540. # "overturn_steering_middle": overturn_steering_middle,
  541. # "overturn_steering_high": overturn_steering_high,
  542. # "overturn_steering_up_speed": overturn_steering_up_speed,
  543. # "overturn_steering_down_speed": overturn_steering_down_speed,
  544. # },
  545. # }
  546. get_deviation_data = {
  547. "camera_high_motor_deviation": camera_high_motor_deviation,
  548. "camera_steering_deviation": camera_steering_deviation,
  549. "turntable_steering_deviation": turntable_steering_deviation,
  550. "turntable_front_end_deviation": 300,
  551. "overturn_steering_middle": overturn_steering_middle,
  552. "overturn_steering_high": overturn_steering_high,
  553. "overturn_steering_up_speed": overturn_steering_up_speed,
  554. "overturn_steering_down_speed": overturn_steering_down_speed,
  555. }
  556. self.initDeviationInfo(get_deviation_data)
  557. self.msg_type = "get_deviation_data"
  558. self.sendSocketMessage(msg="接收偏移量信息", data=get_deviation_data)
  559. self.msg_type = "mcu"
  560. print("接收偏移量信息")
  561. return
  562. def initDeviationInfo(self, get_deviation_data):
  563. # 初始化偏移量信息
  564. camera_high_motor_deviation = get_deviation_data["camera_high_motor_deviation"]
  565. camera_steering_deviation = get_deviation_data["camera_steering_deviation"]
  566. turntable_steering_deviation = get_deviation_data["turntable_steering_deviation"]
  567. overturn_steering_middle=get_deviation_data["overturn_steering_middle"]
  568. overturn_steering_high = get_deviation_data["overturn_steering_high"]
  569. overturn_steering_up_speed = get_deviation_data["overturn_steering_up_speed"]
  570. overturn_steering_down_speed = get_deviation_data["overturn_steering_down_speed"]
  571. self.mcu_deviation_set.last_value["相机电机"] = camera_high_motor_deviation
  572. self.mcu_deviation_set.last_value["相机舵机"] = camera_steering_deviation
  573. self.mcu_deviation_set.last_value["转盘舵机"] = turntable_steering_deviation
  574. self.mcu_deviation_set.last_value["翻板舵机中位"] = overturn_steering_middle
  575. self.mcu_deviation_set.last_value["翻板舵机高位"] = overturn_steering_high
  576. self.mcu_deviation_set.last_value["翻板舵机上升速度"] = (
  577. overturn_steering_up_speed
  578. )
  579. self.mcu_deviation_set.last_value["翻板舵机下降速度"] = (
  580. overturn_steering_down_speed
  581. )
  582. # 获取其他信息
  583. def get_from_mcu_other_info(self, receive_data):
  584. # TODO 已完成设置
  585. is_auto_send_base_info = self.get_data_from_receive_data(
  586. receive_data=receive_data, start=1, len_data=1
  587. )
  588. is_move_retry = self.get_data_from_receive_data(
  589. receive_data=receive_data, start=2, len_data=1
  590. )
  591. is_data_response = self.get_data_from_receive_data(
  592. receive_data=receive_data, start=3, len_data=1
  593. )
  594. low_speed = self.get_data_from_receive_data(
  595. receive_data=receive_data, start=4, len_data=2
  596. )
  597. is_test = self.get_data_from_receive_data(
  598. receive_data=receive_data, start=6, len_data=1
  599. )
  600. to_init_mode = self.get_data_from_receive_data(
  601. receive_data=receive_data, start=7, len_data=1
  602. )
  603. turntable_move_to_init_mode = self.get_data_from_receive_data(
  604. receive_data=receive_data, start=8, len_data=1
  605. )
  606. led_count = self.get_data_from_receive_data(
  607. receive_data=receive_data, start=9, len_data=2
  608. )
  609. turntable_steering_angle_ratio = self.get_data_from_receive_data(
  610. receive_data=receive_data, start=11, len_data=2
  611. )
  612. is_manual_check = self.get_data_from_receive_data(
  613. receive_data=receive_data, start=13, len_data=1
  614. )
  615. camera_steering_angle_ratio = self.get_data_from_receive_data(
  616. receive_data=receive_data, start=14, len_data=4
  617. )
  618. is_auto_motor_to_disable = self.get_data_from_receive_data(
  619. receive_data=receive_data, start=18, len_data=1
  620. )
  621. diff_dir = self.get_data_from_receive_data(
  622. receive_data=receive_data, start=19, len_data=1
  623. )
  624. is_auto_send_pos_info = self.get_data_from_receive_data(
  625. receive_data=receive_data, start=20, len_data=1
  626. )
  627. is_dog = self.get_data_from_receive_data(
  628. receive_data=receive_data, start=21, len_data=1
  629. )
  630. has_been_set_motor_config = self.get_data_from_receive_data(
  631. receive_data=receive_data, start=22, len_data=1
  632. )
  633. self.last_mcu_other_info_data["data"] = {
  634. "is_auto_send_base_info": is_auto_send_base_info,
  635. "is_move_retry": is_move_retry,
  636. "is_data_response": is_data_response,
  637. "low_speed": low_speed,
  638. "is_test": is_test,
  639. "to_init_mode": to_init_mode,
  640. "turntable_move_to_init_mode": turntable_move_to_init_mode,
  641. "led_count": led_count,
  642. "turntable_steering_angle_ratio": turntable_steering_angle_ratio,
  643. "is_manual_check": is_manual_check,
  644. "camera_steering_angle_ratio": camera_steering_angle_ratio,
  645. "is_auto_motor_to_disable": is_auto_motor_to_disable,
  646. "diff_dir": diff_dir,
  647. "is_auto_send_pos_info": is_auto_send_pos_info,
  648. "is_dog": is_dog,
  649. "has_been_set_motor_config": has_been_set_motor_config,
  650. }
  651. self.last_mcu_other_info_data["time"] = time.time()
  652. self.last_mcu_other_info_data["num"] += 1
  653. for k, v in self.last_mcu_other_info_data["data"].items():
  654. print("k:{},v:{}".format(k, v))
  655. self.msg_type = "get_mcu_other_info"
  656. self.sendSocketMessage(
  657. code=0,
  658. msg="获取mcu其他配置信息",
  659. device_status=2,
  660. data=self.last_mcu_other_info_data["data"],
  661. )
  662. self.msg_type = "mcu"
  663. def get_data_from_receive_data(
  664. self, receive_data, start, len_data, data_magnification=1
  665. ):
  666. # data_magnification 数据放大倍数,或缩小倍数,默认为1
  667. try:
  668. if len_data == 1:
  669. data = receive_data[start]
  670. return data * data_magnification
  671. elif len_data == 2:
  672. data = receive_data[start] << 8 | receive_data[start + 1]
  673. return data * data_magnification
  674. elif len_data == 4:
  675. data = (
  676. receive_data[start] << 24
  677. | receive_data[start + 1] << 16
  678. | receive_data[start + 2] << 8
  679. | receive_data[start + 3]
  680. )
  681. return data * data_magnification
  682. return None
  683. except:
  684. return None
  685. def get_from_mcu_base_info(self, receive_data):
  686. # 数据缓存
  687. self.last_mcu_info_data["time"] = time.time()
  688. self.last_mcu_info_data["num"] += 1
  689. # print("last_mcu_info_data:{}".format(self.last_mcu_info_data["time"]))
  690. self.state_camera_motor = 3
  691. self.state_camera_steering = 3
  692. self.state_turntable_steering = 3
  693. self.state_overturn_steering = 3
  694. self.state_move_turntable_steering = 3
  695. if len(receive_data) == 7:
  696. self.m_t = 1
  697. laser_state = receive_data[1]
  698. self.state_camera_motor = receive_data[2]
  699. self.state_camera_steering = receive_data[3]
  700. self.state_turntable_steering = receive_data[4]
  701. self.state_overturn_steering = receive_data[5]
  702. flag = receive_data[6]
  703. message = {
  704. "_type": "show_mcu_info",
  705. "plugins_mode": "mcu",
  706. "data": "激光状态;{laser_state},相机高度状态:{state_camera_motor},相机角度状态:{state_camera_steering},转盘状态:{state_turntable_steering},翻板状态:{state_overturn_steering},flag:{flag}".format(
  707. laser_state=laser_state,
  708. state_camera_motor=self.state_camera_motor,
  709. state_camera_steering=self.state_camera_steering,
  710. state_turntable_steering=self.state_turntable_steering,
  711. state_overturn_steering=self.state_overturn_steering,
  712. flag=flag,
  713. ),
  714. "data_state": {
  715. "state_camera_motor": self.state_camera_motor,
  716. "state_camera_steering": self.state_camera_steering,
  717. "state_turntable_steering": self.state_turntable_steering,
  718. "state_overturn_steering": self.state_overturn_steering,
  719. },
  720. }
  721. self.sendSocketMessage(msg="获取mcu设备运行状态信息", data=message)
  722. # print("转盘:{},时间:{}".format(self.state_turntable_steering, time.time()))
  723. if len(receive_data) == 8:
  724. self.m_t = 2
  725. laser_state = receive_data[1]
  726. self.state_camera_motor = receive_data[2]
  727. self.state_camera_steering = receive_data[3]
  728. self.state_turntable_steering = receive_data[4]
  729. self.state_overturn_steering = receive_data[5]
  730. self.state_move_turntable_steering = receive_data[6]
  731. flag = receive_data[7]
  732. message = {
  733. "_type": "show_mcu_info",
  734. "plugins_mode": "mcu",
  735. "data": "激光状态;{laser_state},相机高度状态:{state_camera_motor},相机角度状态:{state_camera_steering},转盘状态:{state_turntable_steering},转盘前后移动状态:{state_move_turntable_steering},翻板状态:{state_overturn_steering},flag:{flag}".format(
  736. laser_state=laser_state,
  737. state_camera_motor=self.state_camera_motor,
  738. state_camera_steering=self.state_camera_steering,
  739. state_turntable_steering=self.state_turntable_steering,
  740. state_overturn_steering=self.state_overturn_steering,
  741. state_move_turntable_steering=self.state_move_turntable_steering,
  742. flag=flag,
  743. ),
  744. "data_state": {
  745. "state_camera_motor": self.state_camera_motor,
  746. "state_camera_steering": self.state_camera_steering,
  747. "state_turntable_steering": self.state_turntable_steering,
  748. "state_overturn_steering": self.state_overturn_steering,
  749. "state_move_turntable_steering": self.state_move_turntable_steering,
  750. },
  751. }
  752. # if self.state_camera_motor
  753. if all(value == 2 for value in [self.state_camera_motor, self.state_camera_steering, self.state_turntable_steering, self.state_overturn_steering]):
  754. self.init_state = True
  755. self.sendSocketMessage(msg="设备初始化完成", device_status=2)
  756. self.sendSocketMessage(msg="获取mcu设备运行状态信息", data=message)
  757. # 检查是否成功初始化
  758. if self.is_just_init_time is False:
  759. if self.mcu_move_state == 2:
  760. self.is_just_init_time = True
  761. print("is_just_init_time")
  762. message = {
  763. "_type": "is_just_init_time",
  764. "plugins_mode": "mcu",
  765. "data": "",
  766. }
  767. self.sendSocketMessage(msg="检查设备初始化", data=message)
  768. return
  769. # def init(self, sign_data):
  770. # if sign_data["type"] == "connect_sign":
  771. # if sign_data["data"] == 0:
  772. # self.is_running = False
  773. # else:
  774. # self.is_running = True
  775. def scan_serial_port(self) -> dict:
  776. # 获取所有可用串口列表
  777. ports_dict = {}
  778. ports = serial.tools.list_ports.comports()
  779. # 遍历所有端口并打印信息
  780. for port in ports:
  781. if "CH340" in port.description:
  782. ports_dict[port.name] = {
  783. "name": port.name,
  784. "device": port.device,
  785. "description": port.description,
  786. "hwid": port.hwid,
  787. "manufacturer": port.manufacturer,
  788. "product": port.product,
  789. "serial_number": port.serial_number,
  790. }
  791. if len(ports_dict) <= 0:
  792. return {}
  793. return ports_dict
  794. def remove_port(self, port_name):
  795. """移除串口"""
  796. print("remove", port_name)
  797. data = {
  798. "_type": "remove_port",
  799. "plugins_mode": "auto_select_com",
  800. "data": {"port_name": port_name},
  801. }
  802. self.sendSocketMessage(1, "串口被移除", data)
  803. def add_port_by_linkage(self, port_name):
  804. # port_value :串口基础信息
  805. # todo 根据prot_value 信息自动进行连接
  806. print("add", port_name)
  807. # 对没有连接的设备进行尝试连接
  808. message_data = {
  809. "_type": "show_info",
  810. "plugins_mode": "auto_select_com",
  811. "data": {"text": "开始识别接口:{}".format(port_name)},
  812. }
  813. self.sendSocketMessage(
  814. msg="开始识别接口:{}".format(port_name), data=message_data, device_status=1
  815. )
  816. time.sleep(1)
  817. """
  818. 步骤:
  819. 1、进行临时连接,并发送命令,成功后,自动连接对应设备
  820. """
  821. try:
  822. # 尝试使用115200波特率链接
  823. serial_handle = serial.Serial(port=port_name, baudrate=115200, timeout=0.5)
  824. except:
  825. message_data = {
  826. "_type": "show_info",
  827. "plugins_mode": "auto_select_com",
  828. "data": {"text": "串口:{} 被占用,或无法识别".format(port_name)},
  829. }
  830. self.sendSocketMessage(
  831. 1,
  832. msg="串口:{} 被占用,或无法识别".format(port_name).format(port_name),
  833. data=message_data,
  834. device_status=-1,
  835. )
  836. print("串口:{} 被占用".format(port_name))
  837. return
  838. time.sleep(2)
  839. print("开始发送命令")
  840. data = [90, 1]
  841. try:
  842. serial_handle.flushInput() # 尝试重置输入缓冲区
  843. except serial.SerialTimeoutException:
  844. print("超时错误:无法在规定时间内重置输入缓冲区。")
  845. self.sendSocketMessage(
  846. 1,
  847. msg="超时错误:无法在规定时间内重置输入缓冲区。",
  848. data=None,
  849. )
  850. serial_handle.close()
  851. return
  852. print("尝试写入数据")
  853. buf = bytearray(b"")
  854. buf.extend([0x55, 0x55, (0xFF & len(data))])
  855. buf.extend(data)
  856. buf.extend([0xFF & ~sum(data)])
  857. try:
  858. self.receive_data = b""
  859. serial_handle.write(buf)
  860. except serial.SerialTimeoutException:
  861. print("写入数据错误")
  862. serial_handle.close()
  863. return
  864. time.sleep(0.3)
  865. print("尝试接收命令")
  866. receive_data = self.read_cmd(serial_handle)
  867. device_id = 0
  868. if receive_data:
  869. print("receive_data", receive_data)
  870. if receive_data[0] == 90:
  871. connect_flag = receive_data[1]
  872. device_id = receive_data[2]
  873. print("关闭串口:{}".format(port_name))
  874. serial_handle.close()
  875. if device_id > 0:
  876. if device_id == 1:
  877. self.to_connect_com(port_name)
  878. message_data = {
  879. "_type": "show_info",
  880. "plugins_mode": "auto_select_com",
  881. "data": {"text": "MCU开始连接"},
  882. }
  883. self.sendSocketMessage(
  884. msg="MCU开始连接", data=message_data, device_status=1
  885. )
  886. self.connected_ports_dict[port_name] = "MCU"
  887. message_data = {
  888. "_type": "select_port_name",
  889. "plugins_mode": "auto_select_com",
  890. "data": {
  891. "device_name": "mcu" if device_id == 1 else "remote_control",
  892. "port_name": port_name,
  893. },
  894. }
  895. self.sendSocketMessage(
  896. msg="MCU连接成功", data=message_data, device_status=2
  897. )
  898. time.sleep(2)
  899. loop = asyncio.get_event_loop()
  900. loop.create_task(self.initDevice(), name="init_mcu")
  901. # async def getBaseInfo():
  902. # while True:
  903. # await asyncio.sleep(1)
  904. # # 异步循环获取设备信息
  905. # self.to_get_mcu_base_info()
  906. # asyncio.gather(getBaseInfo())
  907. else:
  908. print("串口无法识别")
  909. self.sendSocketMessage(
  910. code=1,
  911. msg="串口无法识别,请重新插拔拍照机USB", data=message_data, device_status=-1
  912. )
  913. # 走其他途径处理
  914. # 检查当前MCU链接是否正常
  915. # 正常跳过;记录为其他列表
  916. # 不正常进行尝试连接
  917. # 连接不上,记录为其他列表
  918. def clearMyInstance(self):
  919. SingletonType.clear_instance()
  920. def to_connect_com(self, port_name):
  921. # 关闭串口
  922. print("to_connect_com", port_name)
  923. self.close_connect()
  924. time.sleep(0.3)
  925. self.connect_state = False
  926. try:
  927. self.serial_ins = SerialIns(port_name=port_name, baud=115200, timeout=0.1)
  928. if not self.serial_ins.serial_handle:
  929. message_data = {
  930. "_type": "show_info",
  931. "plugins_mode": "mcu",
  932. "data": "MCU 打开串口失败",
  933. }
  934. self.sendSocketMessage(
  935. msg="MCU 打开串口失败", data=message_data, device_status=-1
  936. )
  937. self.serial_ins = None
  938. self.connect_state = False
  939. return False
  940. except:
  941. message_data = {
  942. "_type": "show_info",
  943. "plugins_mode": "mcu",
  944. "data": "MCU 打开串口失败",
  945. }
  946. self.sendSocketMessage(
  947. msg="MCU 打开串口失败", data=message_data, device_status=-1
  948. )
  949. self.serial_ins = None
  950. self.connect_state = False
  951. return False
  952. message_data = {
  953. "_type": "show_info",
  954. "plugins_mode": "mcu",
  955. "data": "MCU 开始连接",
  956. }
  957. self.sendSocketMessage(msg="MCU 开始连接", data=message_data, device_status=1)
  958. # =======================发送连接请求=================================
  959. cmd = 90
  960. data = [cmd, 1]
  961. print("405 发送 连接请求 -----------------------------------------")
  962. print(self.serial_ins)
  963. # self.serial_ins.clearn_flush()
  964. self.serial_ins.write_cmd(data)
  965. # 延迟接收数据
  966. time.sleep(0.3)
  967. receive_data = self.serial_ins.read_cmd(out_time=1)
  968. if receive_data:
  969. print(
  970. "409 receive_data--90:{}".format(self.change_hex_to_int(receive_data))
  971. )
  972. if receive_data:
  973. # receive_data[2]=1 表示为MCU设备编号
  974. if receive_data[0] == 90 and receive_data[2] == 1:
  975. connect_flag = receive_data[1]
  976. # 是否有初始化
  977. try:
  978. mcu_has_been_set = receive_data[
  979. 6
  980. ] # 设备是否有初始化 ,1 表示已初始化
  981. except:
  982. mcu_has_been_set = 99 # 未知状态
  983. print("MCU初始化信息{}".format(mcu_has_been_set))
  984. message_data = {
  985. "_type": "show_info",
  986. "plugins_mode": "mcu",
  987. "data": "MCU 已连接",
  988. }
  989. self.sendSocketMessage(
  990. msg="MCU 已连接", data=message_data, device_status=1
  991. )
  992. self.connect_state = True
  993. self.is_running = True
  994. print("MCU 已连接")
  995. self.port_name = port_name
  996. return
  997. print("MCU 连接失败")
  998. message_data = {
  999. "_type": "show_info",
  1000. "plugins_mode": "mcu",
  1001. "data": "MCU 连接失败",
  1002. }
  1003. self.sendSocketMessage(msg="MCU 连接失败", data=message_data, device_status=-1)
  1004. self.close_connect()
  1005. def close_connect(self):
  1006. self.port_name = ""
  1007. if self.serial_ins:
  1008. self.serial_ins.close_serial_port()
  1009. self.is_running = False
  1010. self.connect_state = False
  1011. self.connected_ports_dict = {} # 已连接的ports
  1012. self.p_list = []
  1013. self.temp_ports_dict = {}
  1014. self.init_state = False
  1015. print("关闭MCU")
  1016. @property
  1017. def mcu_move_state(self):
  1018. if self.m_t == 1:
  1019. if (
  1020. self.state_camera_motor == 2
  1021. and self.state_camera_steering == 2
  1022. and self.state_turntable_steering == 2
  1023. and self.state_overturn_steering == 2
  1024. ):
  1025. self._mcu_move_state = 2
  1026. else:
  1027. self._mcu_move_state = 1
  1028. else:
  1029. if (
  1030. self.state_camera_motor == 2
  1031. and self.state_camera_steering == 2
  1032. and self.state_turntable_steering == 2
  1033. and self.state_overturn_steering == 2
  1034. and self.state_move_turntable_steering == 2
  1035. ):
  1036. self._mcu_move_state = 2
  1037. else:
  1038. self._mcu_move_state = 1
  1039. # self._mcu_move_state = 2
  1040. return self._mcu_move_state
  1041. def to_deal_device(self, device_name, value=1, _type=0, times=1, delay=0):
  1042. """
  1043. value 激光0关 1开
  1044. mp3_player value 表示0表示关,1表示开,_type 表示歌曲切换到指定歌曲
  1045. delay:延迟处理,单位为0.1秒,即delay=100时,表示延迟10秒
  1046. """
  1047. device_id = self.device_name_dict[device_name]
  1048. if device_name == "buzzer":
  1049. value = int(value)
  1050. cmd = 3
  1051. data = [
  1052. cmd,
  1053. device_id,
  1054. value,
  1055. _type,
  1056. times,
  1057. delay,
  1058. ]
  1059. self.add_send_data_queue(data)
  1060. # if self.serial_ins:
  1061. # self.serial_ins.write_cmd(data)
  1062. return True
  1063. def to_device_move(
  1064. self,
  1065. device_name,
  1066. value=0,
  1067. max_speed=None,
  1068. up_speed=None,
  1069. down_speed=None,
  1070. _is_debug=0,
  1071. is_relative=0,
  1072. is_deviation=1,
  1073. ):
  1074. """
  1075. 此处输入单位为 毫米,以及度 需要先缩小,再放大
  1076. """
  1077. print("移动",time.time())
  1078. speed = settings.moveSpeed()
  1079. cmd = 1
  1080. device_id = self.device_name_dict[device_name]
  1081. print("正在执行",device_name)
  1082. match device_name:
  1083. case "camera_high_motor":
  1084. # value 单位毫米
  1085. # max_speed = 10000 if max_speed is None else max_speed
  1086. # up_speed = 800 if up_speed is None else up_speed
  1087. # down_speed = 700 if down_speed is None else down_speed
  1088. max_speed = (
  1089. speed[device_name]["max_speed"] if max_speed is None else max_speed
  1090. )
  1091. up_speed = (
  1092. speed[device_name]["up_speed"] if up_speed is None else up_speed
  1093. )
  1094. down_speed = (
  1095. speed[device_name]["down_speed"]
  1096. if down_speed is None
  1097. else down_speed
  1098. )
  1099. value = value / 10 # value 单位毫米
  1100. assert 0 <= value <= 40
  1101. assert 0 <= max_speed <= 10000
  1102. case "camera_steering":
  1103. # 角度为度 未放大 精确到0.1度
  1104. max_speed = 6000 if max_speed is None else max_speed
  1105. up_speed = 500 if up_speed is None else up_speed
  1106. down_speed = 500 if down_speed is None else down_speed
  1107. assert -360 <= value <= 360
  1108. case "turntable_steering":
  1109. # 角度为度 未放大 精确到0.1度
  1110. # max_speed = 6000 if max_speed is None else max_speed
  1111. # up_speed = 500 if up_speed is None else up_speed
  1112. # down_speed = 400 if down_speed is None else down_speed
  1113. max_speed = (
  1114. speed[device_name]["max_speed"] if max_speed is None else max_speed
  1115. )
  1116. up_speed = (
  1117. speed[device_name]["up_speed"] if up_speed is None else up_speed
  1118. )
  1119. down_speed = (
  1120. speed[device_name]["down_speed"]
  1121. if down_speed is None
  1122. else down_speed
  1123. )
  1124. assert -720 <= value <= 720
  1125. case "overturn_steering":
  1126. # 角度为度 未放大 精确到0.1度
  1127. max_speed = 2 if max_speed is None else max_speed
  1128. up_speed = 1 if up_speed is None else up_speed
  1129. down_speed = 1 if down_speed is None else down_speed
  1130. assert 0 <= value <= 360
  1131. case "turntable_position_motor":
  1132. # value 单位毫米
  1133. max_speed = 11000 if max_speed is None else max_speed
  1134. up_speed = 900 if up_speed is None else up_speed
  1135. down_speed = 900 if down_speed is None else down_speed
  1136. value = value / 10 # value 单位毫米
  1137. assert 0 <= value <= 900
  1138. assert 0 <= max_speed <= 15000
  1139. _dir = True if value >= 0 else False
  1140. value = int(abs(value * 10)) # 此处value赋值后,单位为mm以及0.1度
  1141. print("准备执行",device_name, value)
  1142. data = [
  1143. cmd,
  1144. device_id,
  1145. 1 if _dir else 0,
  1146. 0xFF & value >> 8,
  1147. 0xFF & value,
  1148. 0xFF & max_speed >> 8,
  1149. 0xFF & max_speed,
  1150. 0xFF & up_speed >> 8,
  1151. 0xFF & up_speed,
  1152. 0xFF & down_speed >> 8,
  1153. 0xFF & down_speed,
  1154. _is_debug,
  1155. is_deviation,
  1156. is_relative,
  1157. ]
  1158. self.add_send_data_queue(data)
  1159. def to_get_mcu_base_info(self):
  1160. if self.connect_state:
  1161. self.lock.acquire()
  1162. # print('==========================>1111')
  1163. # print("-------------------to_get_mcu_base_info--------------------------")
  1164. data = [self.command["get_all_info"], 1]
  1165. f = True
  1166. try:
  1167. self.serial_ins.write_cmd(data)
  1168. except:
  1169. f = False
  1170. pass
  1171. self.lock.release()
  1172. if not f:
  1173. self.connect_state = False
  1174. return False
  1175. else:
  1176. return True
  1177. def check_before_action(self):
  1178. if self.state != 2:
  1179. print("check_before_action 设备正在运行中~")
  1180. self.sendSocketMessage(
  1181. code=1, msg="设备正在运行中", device_status=1
  1182. )
  1183. return False
  1184. if self.mcu_move_state != 2:
  1185. if settings.IS_LIN_SHI_TEST:
  1186. return True
  1187. # self.show_info("mcu 非停止状态")
  1188. self.sendSocketMessage(code=1, msg="mcu 非停止状态", device_status=1)
  1189. return True
  1190. def controlDevice(self, device_name, value):
  1191. '''控制设备移动等'''
  1192. if not self.is_running:
  1193. self.sendSocketMessage(
  1194. code=1, msg="mcu设备未连接,请先连接设备", device_status=0
  1195. )
  1196. return False
  1197. if not self.init_state:
  1198. self.sendSocketMessage(
  1199. code=1, msg="mcu设备未初始化", device_status=4
  1200. )
  1201. return False
  1202. _is_debug = 1 if settings.IS_DEBUG == "true" else 0
  1203. is_deviation = 0 if settings.IS_DEBUG == "true" else 1
  1204. print("控制设备==>_is_debug", _is_debug)
  1205. match device_name:
  1206. case "camera_high_motor":
  1207. # 相机电机
  1208. print(device_name, value)
  1209. self.to_device_move(
  1210. device_name=device_name,
  1211. value=float(value),
  1212. # max_speed=1400,
  1213. # up_speed=400,
  1214. # down_speed=100,
  1215. # _is_debug=_is_debug,
  1216. # is_deviation=is_deviation,
  1217. )
  1218. case "camera_steering":
  1219. print(device_name, value)
  1220. # 相机舵机
  1221. self.to_device_move(
  1222. device_name=device_name,
  1223. value=float(value),
  1224. # _is_debug=_is_debug,
  1225. # is_deviation=0,
  1226. )
  1227. case "turntable_steering":
  1228. # 转盘舵机
  1229. self.to_device_move(
  1230. device_name=device_name,
  1231. value=float(value),
  1232. # _is_debug=_is_debug,
  1233. # is_deviation=0,
  1234. )
  1235. case "turntable_position_motor":
  1236. # 转盘舵机
  1237. self.to_device_move(
  1238. device_name=device_name,
  1239. value=float(value),
  1240. # max_speed=1400,
  1241. # up_speed=400,
  1242. # down_speed=100,
  1243. # _is_debug=_is_debug,
  1244. # is_deviation=is_deviation,
  1245. )
  1246. case "overturn_steering":
  1247. # 翻板舵机中位
  1248. self.to_deal_device(
  1249. device_name="overturn_steering",
  1250. )
  1251. case "laser_position":
  1252. self.to_deal_device(
  1253. device_name="laser_position", value=0 if int(value) <= 0 else 1
  1254. )
  1255. case "take_picture":
  1256. capture_one = DigiCam()
  1257. try:
  1258. # camera_is_connect = capture_one.checkCameraConnect()
  1259. # if camera_is_connect is not True:
  1260. # self.sendSocketMessage(1,"相机未连接,请检查",device_status=-1)
  1261. # return
  1262. capture_one.getCaptureFolderPath()
  1263. if value > 0:
  1264. capture_one.auto_focus()
  1265. capture_one.run_capture_action("Capture")
  1266. except:
  1267. self.sendSocketMessage(1,"digicam未初始化,请检查",device_status=-1)
  1268. case "to_deal_device":
  1269. self.to_deal_device(device_name, value=value, _type=0, times=1)
  1270. case _:
  1271. pass
  1272. # case "photograph":
  1273. # self.photograph(goods_art_no=None)
  1274. def checkDevice(self):
  1275. if not self.is_running:
  1276. self.sendSocketMessage(
  1277. code=1, msg="mcu设备未连接,请先连接设备", device_status=0
  1278. )
  1279. return False
  1280. if self.init_state is not True:
  1281. self.sendSocketMessage(code=1, msg="mcu设备未初始化", device_status=4)
  1282. return False
  1283. if self.action_state != 2:
  1284. self.sendSocketMessage(
  1285. code=1,
  1286. msg="当前有未完成的任务,请稍后再试",
  1287. device_status=0,
  1288. )
  1289. return False
  1290. async def run_mcu_config(self, config_list, goods_art_no, action_info):
  1291. if self.checkDevice() == False:
  1292. return
  1293. image_counts = 0
  1294. if config_list:
  1295. action_names = []
  1296. if len(config_list) > 1:
  1297. if config_list[-1]["take_picture"] is True:
  1298. new_init_config = copy.copy(config_list[0])
  1299. new_init_config["action_name"] = "移动到初始位"
  1300. new_init_config["number_focus"] = 0
  1301. new_init_config["take_picture"] = False
  1302. new_init_config["shoe_upturn"] = False
  1303. new_init_config["pre_delay"] = 0.0
  1304. new_init_config["after_delay"] = 0.0
  1305. new_init_config["led_switch"] = True
  1306. new_init_config["turntable_angle"] = 0.0
  1307. new_init_config["is_wait"] = False
  1308. new_init_config["is_need_confirm"] = False
  1309. config_list.append(new_init_config)
  1310. for idx, item in enumerate(config_list):
  1311. is_take_picture = item["take_picture"]
  1312. action_id = item["id"]
  1313. record_id = -1
  1314. if is_take_picture:
  1315. action_names.append(item["action_name"])
  1316. image_counts += 1
  1317. # 批量插入
  1318. image_deal_mode = 0 if action_info == "执行左脚程序" else 1
  1319. state,record_id = insert_photo_records(
  1320. image_deal_mode=image_deal_mode,
  1321. goods_art_no=goods_art_no,
  1322. image_index=idx,
  1323. action_id=action_id,
  1324. )
  1325. config_list[idx]["record_id"] = record_id
  1326. total_len = len(config_list)
  1327. self.action_state = 1
  1328. self.msg_type = "image_process"
  1329. self.sendSocketMessage(
  1330. code=0,
  1331. msg="MCU 命令已发送完成",
  1332. device_status=2,
  1333. data={
  1334. "goods_art_no": goods_art_no,
  1335. "image_counts": image_counts,
  1336. "action_names": action_names,
  1337. "current_time": datetime.datetime.now(settings.TIME_ZONE).strftime(
  1338. "%Y-%m-%d %H:%M:%S"
  1339. ),
  1340. },
  1341. )
  1342. self.controlDevice("laser_position", 0)
  1343. self.msg_type = "mcu"
  1344. self.is_runn_action = True
  1345. for index, action in enumerate(config_list):
  1346. await asyncio.sleep(0.1)
  1347. if self.is_stop_action == True:
  1348. self.is_stop_action = False
  1349. break
  1350. # action_is_take_picture = action["take_picture"]
  1351. record_id = action["record_id"]
  1352. image_index = -1
  1353. if record_id == -1:
  1354. image_index = -1
  1355. else:
  1356. image_index = index
  1357. program_item = ProgramItem(
  1358. websocket_manager=self.websocket_manager,
  1359. action_data=action,
  1360. mcu=self,
  1361. goods_art_no=goods_art_no,
  1362. image_index=image_index,
  1363. record_id=record_id,
  1364. )
  1365. print("self.action_state===>", self.action_state)
  1366. if self.action_state != 1:
  1367. # 异常终止
  1368. print("action异常终止")
  1369. break
  1370. self.msg_type = "photo_take"
  1371. if not program_item.run(total_len):
  1372. self.sendSocketMessage(
  1373. code=1,
  1374. msg="{} 执行失败~".format(program_item.action_name),
  1375. device_status=0,
  1376. )
  1377. self.to_deal_device(device_name="buzzer", times=3)
  1378. break
  1379. else:
  1380. # self.show_info("{}执行完成~".format(action.action_name))
  1381. self.sendSocketMessage(
  1382. code=0,
  1383. msg="{} 执行完成~".format(program_item.action_name),
  1384. data={"goods_art_no": goods_art_no},
  1385. device_status=2,
  1386. )
  1387. self.msg_type = "mcu"
  1388. # 在第三张图时检查是否有对应图片生成
  1389. # if index == 3:
  1390. # # if not self.image_process_data.check_photo_is_get():
  1391. # self.sendSocketMessage(
  1392. # code=1,
  1393. # msg="未获取到图片数据",
  1394. # device_status=0,
  1395. # )
  1396. # self.action_state = 2
  1397. # return
  1398. if index == total_len - 1:
  1399. # 最后一个初始化处理
  1400. pass
  1401. # self.action_state = 2
  1402. self.action_state = 2
  1403. self.is_runn_action = False
  1404. self.msg_type = "photo_take_finish"
  1405. self.sendSocketMessage(
  1406. code=0,
  1407. msg=f"货号:{goods_art_no},执行完成",
  1408. device_status=2,
  1409. )
  1410. self.msg_type = "mcu"
  1411. self.controlDevice("laser_position", 1)
  1412. async def run_mcu_config_single(self, config_info, goods_art_no,msg_type="run_mcu_single_finish",image_index=-1,record_id=-1):
  1413. '''独立拍照 仅作测试用'''
  1414. if self.checkDevice() == False:
  1415. return
  1416. if config_info:
  1417. self.action_state = 1
  1418. self.msg_type = "mcu"
  1419. await asyncio.sleep(0.1)
  1420. program_item = ProgramItem(
  1421. websocket_manager=self.websocket_manager,
  1422. action_data=config_info,
  1423. mcu=self,
  1424. goods_art_no=goods_art_no,
  1425. image_index=image_index,
  1426. record_id=record_id,
  1427. )
  1428. print("self.action_state===>", self.action_state)
  1429. if self.action_state != 1:
  1430. # 异常终止
  1431. print("action异常终止")
  1432. return
  1433. self.msg_type = "photo_take"
  1434. # if not program_item.run_only_mcu(1):
  1435. # self.sendSocketMessage(
  1436. # code=1,
  1437. # msg="{} 执行失败~".format(program_item.action_name),
  1438. # device_status=0,
  1439. # )
  1440. # self.to_deal_device(device_name="buzzer", times=3)
  1441. # return
  1442. # else:
  1443. program_item.run(3)
  1444. # self.show_info("{}执行完成~".format(action.action_name))
  1445. self.sendSocketMessage(
  1446. code=0,
  1447. msg="{} 执行完成~".format(program_item.action_name),
  1448. data={"goods_art_no": goods_art_no},
  1449. device_status=2,
  1450. )
  1451. self.msg_type = "mcu"
  1452. self.action_state = 2
  1453. self.msg_type = msg_type
  1454. self.sendSocketMessage(
  1455. code=0,
  1456. msg=f"执行完成",
  1457. device_status=2,
  1458. )
  1459. self.msg_type = "mcu"
  1460. async def checkMcuConnection(device_ctrl: DeviceControl):
  1461. if device_ctrl.is_running == True:
  1462. message = {
  1463. "_type": "select_port_name",
  1464. "plugins_mode": "auto_select_com",
  1465. "data": device_ctrl.temp_ports_dict,
  1466. }
  1467. device_ctrl.device_status = 2
  1468. device_ctrl.sendSocketMessage(code=0, msg="MCU连接成功", data=message)
  1469. return
  1470. """实时检测串口是否连接"""
  1471. while True:
  1472. await asyncio.sleep(0.5)
  1473. if device_ctrl.mcu_exit:
  1474. break
  1475. ports_dict = device_ctrl.scan_serial_port()
  1476. device_ctrl.temp_ports_dict = ports_dict
  1477. if not ports_dict:
  1478. # 全部清空 移除所有串口
  1479. if device_ctrl.p_list:
  1480. _p = device_ctrl.p_list.pop()
  1481. device_ctrl.remove_port(_p)
  1482. print("串口未连接,请检查")
  1483. device_ctrl.sendSocketMessage(code=1, msg="串口未连接,请检查",device_status=-1)
  1484. continue
  1485. if ports_dict:
  1486. for index, _i in enumerate(device_ctrl.p_list):
  1487. if _i not in ports_dict:
  1488. _p = device_ctrl.p_list.pop(index)
  1489. device_ctrl.remove_port(_p)
  1490. for _port_name, _port_value in ports_dict.items():
  1491. if _port_name not in device_ctrl.p_list:
  1492. try:
  1493. device_ctrl.p_list.append(_port_name)
  1494. device_ctrl.add_port_by_linkage(_port_name)
  1495. except BaseException as e:
  1496. print("串口不存在{} {}".format(_port_name, e))
  1497. print("MCU断开连接,已释放")