Mcu.py 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066
  1. from .BaseClass import BaseClass
  2. from utils.SingletonType import SingletonType
  3. import settings
  4. from .SerialIns import SerialIns
  5. import time
  6. from threading import Lock
  7. from collections import defaultdict
  8. # from threading import Thread
  9. class Mcu(BaseClass, metaclass=SingletonType):
  10. instance = None
  11. init_flag = None
  12. # sign_data = Signal(dict)
  13. # self_sign = Signal(dict)
  14. def __init__(self, window, port_name=None):
  15. super().__init__(BaseClass)
  16. if self.init_flag:
  17. return
  18. else:
  19. self.init_flag = True
  20. # 终端设备是否处于运动中 1运动中,2已停止 3未初始化
  21. self.msg_type = "mcu"
  22. self.m_t = 1
  23. self._mcu_move_state = 0
  24. self.state_camera_motor = 3
  25. self.state_camera_steering = 3
  26. self.state_turntable_steering = 3
  27. self.state_overturn_steering = 3
  28. self.state_move_turntable_steering = 3
  29. self.last_from_mcu_move_respond_data = None
  30. self.camera_motor_speed = 0
  31. self.camera_motor_value = 0
  32. self.init_state = False
  33. self.connect_state = False
  34. self.port_name = ""
  35. self.serial_ins = None
  36. self.connect_turn_state = False
  37. self.serial_turn_ins = None
  38. self.t_n = 0
  39. if port_name:
  40. self.serial_ins = SerialIns(port_name=port_name, baud=115200)
  41. if self.serial_ins.serial_handle:
  42. self.connect_state = True
  43. self.port_name = port_name
  44. self.device_name_dict = {
  45. "camera_steering": 0,
  46. "camera_high_motor": 1,
  47. "turntable_steering": 2,
  48. "overturn_steering": 3,
  49. "laser_position": 4,
  50. "buzzer": 5,
  51. "split": 6,
  52. "turntable_position_motor": 7,
  53. "mp3_player": 8,
  54. "mcu": 99,
  55. }
  56. # 最近的mcu基础信息,用于获取数据状态检查
  57. self.last_mcu_info_data = {
  58. "num": 0,
  59. "time": time.time(),
  60. "data": None,
  61. }
  62. # 最近的mcu的其他配置
  63. self.last_mcu_other_info_data = {
  64. "num": 0,
  65. "time": time.time(),
  66. "data": {},
  67. }
  68. self.command = {
  69. "to_device_move": 1, # 设备运动
  70. "to_init_device": 2, # 初始化设备
  71. "to_deal_other_device": 3, # 处理其他设备
  72. "get_all_info": 29, # 获取所有信息
  73. "set_deviation": 40, # 设置偏移量
  74. "get_deviation": 41, # 读取偏移量
  75. "signal_forwarding": 91, # 信号转发处理
  76. "signal_forwarding_return": 92, # 信号转发返回
  77. "get_other_info": 44, # 获取其他信息
  78. "open_rgb_led": 43, ## RGB灯的处理与通讯
  79. "set_other_info": 45, # 设置其他信息
  80. "query_remote_control_battery": 47, # 查询遥控器电量
  81. "set_turntable_mode": 48, # 设置转盘通讯方式 1、串口、2、无线、3 混合
  82. "stop_mcu": 93, # 停止运行mcu
  83. }
  84. self.window = window
  85. self.last_push_time = defaultdict(float)
  86. self.is_running = False
  87. self.is_wait_connect = False # 等待链接
  88. self.send_data_queue = [] # 发送队列
  89. self.lock = Lock()
  90. # 是否是刚进行完初始化;首次初始化,需要运动到指定第一个指定位置
  91. self.is_just_init_time = False
  92. self.init()
  93. # ===========注册命令函数============
  94. self.deal_code_func_dict = {
  95. 29: self.get_from_mcu_base_info, # 获取基本情况
  96. 32: self.get_from_mcu_button, # 获取按键信息
  97. 42: self.get_from_mcu_deviation_info, # 获取偏移量信息
  98. 44: self.get_from_mcu_other_info, # 获取其他配置参数
  99. 90: self.get_from_mcu_connect_info, # 获取链接电脑信号
  100. 92: self.get_from_mcu_move_respond_data, # 获取MCU响应
  101. 100: self.print_mcu_error_data, # 打印下位机的错误内容
  102. }
  103. # 打印下位机的错误内容
  104. def print_mcu_error_data(self, receive_data):
  105. # 扫码数据
  106. try:
  107. data = receive_data[1:].decode()
  108. if data == "设备初始化完成":
  109. self.init_state = False
  110. self.sendSocketMessage(msg=data,device_status=2)
  111. print("115 print_mcu_error_data:", data)
  112. except BaseException as e:
  113. print("117 error {}".format(e))
  114. return
  115. # 停止运行mcu
  116. def stop_mcu(self):
  117. buf = [self.command["stop_mcu"]]
  118. buf.extend(self.encapsulation_data(data=1, len_data=1))
  119. self.add_send_data_queue(buf)
  120. # 设置转盘通讯方式 1、串口、2、无线、3 混合
  121. def to_set_turntable_mode(self, mode=1):
  122. buf = [self.command["set_turntable_mode"]]
  123. buf.extend(self.encapsulation_data(data=mode, len_data=1))
  124. self.add_send_data_queue(buf)
  125. # 查询遥控器电量
  126. def query_remote_control_battery(self):
  127. buf = [self.command["query_remote_control_battery"]]
  128. buf.extend(self.encapsulation_data(data=1, len_data=1))
  129. buf.extend(self.encapsulation_data(data=1, len_data=1))
  130. buf.extend(self.encapsulation_data(data=1, len_data=1))
  131. self.add_send_data_queue(buf)
  132. # 获取MCU响应
  133. def get_from_mcu_move_respond_data(self, receive_data):
  134. self.last_from_mcu_move_respond_data = receive_data
  135. def change_hex_to_int(self, _bytearray):
  136. return " ".join([hex(x) for x in _bytearray])
  137. # 获取基本情况
  138. def get_from_mcu_base_info(self, receive_data):
  139. # 数据缓存
  140. self.last_mcu_info_data["time"] = time.time()
  141. self.last_mcu_info_data["num"] += 1
  142. # print("last_mcu_info_data:{}".format(self.last_mcu_info_data["time"]))
  143. self.state_camera_motor = 3
  144. self.state_camera_steering = 3
  145. self.state_turntable_steering = 3
  146. self.state_overturn_steering = 3
  147. self.state_move_turntable_steering = 3
  148. if len(receive_data) == 7:
  149. self.m_t = 1
  150. laser_state = receive_data[1]
  151. self.state_camera_motor = receive_data[2]
  152. self.state_camera_steering = receive_data[3]
  153. self.state_turntable_steering = receive_data[4]
  154. self.state_overturn_steering = receive_data[5]
  155. flag = receive_data[6]
  156. message = {
  157. "_type": "show_mcu_info",
  158. "plugins_mode": "mcu",
  159. "data": "激光状态;{laser_state},相机高度状态:{state_camera_motor},相机角度状态:{state_camera_steering},转盘状态:{state_turntable_steering},翻板状态:{state_overturn_steering},flag:{flag}".format(
  160. laser_state=laser_state,
  161. state_camera_motor=self.state_camera_motor,
  162. state_camera_steering=self.state_camera_steering,
  163. state_turntable_steering=self.state_turntable_steering,
  164. state_overturn_steering=self.state_overturn_steering,
  165. flag=flag,
  166. ),
  167. "data_state": {
  168. "state_camera_motor": self.state_camera_motor,
  169. "state_camera_steering": self.state_camera_steering,
  170. "state_turntable_steering": self.state_turntable_steering,
  171. "state_overturn_steering": self.state_overturn_steering,
  172. },
  173. }
  174. self.sendSocketMessage(msg="获取mcu设备运行状态信息", data=message)
  175. # print("转盘:{},时间:{}".format(self.state_turntable_steering, time.time()))
  176. if len(receive_data) == 8:
  177. self.m_t = 2
  178. laser_state = receive_data[1]
  179. self.state_camera_motor = receive_data[2]
  180. self.state_camera_steering = receive_data[3]
  181. self.state_turntable_steering = receive_data[4]
  182. self.state_overturn_steering = receive_data[5]
  183. self.state_move_turntable_steering = receive_data[6]
  184. flag = receive_data[7]
  185. message = {
  186. "_type": "show_mcu_info",
  187. "plugins_mode": "mcu",
  188. "data": "激光状态;{laser_state},相机高度状态:{state_camera_motor},相机角度状态:{state_camera_steering},转盘状态:{state_turntable_steering},转盘前后移动状态:{state_move_turntable_steering},翻板状态:{state_overturn_steering},flag:{flag}".format(
  189. laser_state=laser_state,
  190. state_camera_motor=self.state_camera_motor,
  191. state_camera_steering=self.state_camera_steering,
  192. state_turntable_steering=self.state_turntable_steering,
  193. state_overturn_steering=self.state_overturn_steering,
  194. state_move_turntable_steering=self.state_move_turntable_steering,
  195. flag=flag,
  196. ),
  197. "data_state": {
  198. "state_camera_motor": self.state_camera_motor,
  199. "state_camera_steering": self.state_camera_steering,
  200. "state_turntable_steering": self.state_turntable_steering,
  201. "state_overturn_steering": self.state_overturn_steering,
  202. "state_move_turntable_steering": self.state_move_turntable_steering,
  203. },
  204. }
  205. self.sendSocketMessage(msg="获取mcu设备运行状态信息", data=message)
  206. # 检查是否成功初始化
  207. if self.is_just_init_time is False:
  208. if self.mcu_move_state == 2:
  209. self.is_just_init_time = True
  210. print("is_just_init_time")
  211. message = {
  212. "_type": "is_just_init_time",
  213. "plugins_mode": "mcu",
  214. "data": "",
  215. }
  216. self.sendSocketMessage(msg="检查设备初始化", data=message)
  217. return
  218. # 获取其他信息
  219. def get_from_mcu_other_info(self, receive_data):
  220. is_auto_send_base_info = self.get_data_from_receive_data(
  221. receive_data=receive_data, start=1, len_data=1
  222. )
  223. is_move_retry = self.get_data_from_receive_data(
  224. receive_data=receive_data, start=2, len_data=1
  225. )
  226. is_data_response = self.get_data_from_receive_data(
  227. receive_data=receive_data, start=3, len_data=1
  228. )
  229. low_speed = self.get_data_from_receive_data(
  230. receive_data=receive_data, start=4, len_data=2
  231. )
  232. is_test = self.get_data_from_receive_data(
  233. receive_data=receive_data, start=6, len_data=1
  234. )
  235. to_init_mode = self.get_data_from_receive_data(
  236. receive_data=receive_data, start=7, len_data=1
  237. )
  238. turntable_move_to_init_mode = self.get_data_from_receive_data(
  239. receive_data=receive_data, start=8, len_data=1
  240. )
  241. led_count = self.get_data_from_receive_data(
  242. receive_data=receive_data, start=9, len_data=2
  243. )
  244. turntable_steering_angle_ratio = self.get_data_from_receive_data(
  245. receive_data=receive_data, start=11, len_data=2
  246. )
  247. is_manual_check = self.get_data_from_receive_data(
  248. receive_data=receive_data, start=13, len_data=1
  249. )
  250. camera_steering_angle_ratio = self.get_data_from_receive_data(
  251. receive_data=receive_data, start=14, len_data=4
  252. )
  253. is_auto_motor_to_disable = self.get_data_from_receive_data(
  254. receive_data=receive_data, start=18, len_data=1
  255. )
  256. diff_dir = self.get_data_from_receive_data(
  257. receive_data=receive_data, start=19, len_data=1
  258. )
  259. is_auto_send_pos_info = self.get_data_from_receive_data(
  260. receive_data=receive_data, start=20, len_data=1
  261. )
  262. is_dog = self.get_data_from_receive_data(
  263. receive_data=receive_data, start=21, len_data=1
  264. )
  265. has_been_set_motor_config = self.get_data_from_receive_data(
  266. receive_data=receive_data, start=22, len_data=1
  267. )
  268. self.last_mcu_other_info_data["data"] = {
  269. "is_auto_send_base_info": is_auto_send_base_info,
  270. "is_move_retry": is_move_retry,
  271. "is_data_response": is_data_response,
  272. "low_speed": low_speed,
  273. "is_test": is_test,
  274. "to_init_mode": to_init_mode,
  275. "turntable_move_to_init_mode": turntable_move_to_init_mode,
  276. "led_count": led_count,
  277. "turntable_steering_angle_ratio": turntable_steering_angle_ratio,
  278. "is_manual_check": is_manual_check,
  279. "camera_steering_angle_ratio": camera_steering_angle_ratio,
  280. "is_auto_motor_to_disable": is_auto_motor_to_disable,
  281. "diff_dir": diff_dir,
  282. "is_auto_send_pos_info": is_auto_send_pos_info,
  283. "is_dog": is_dog,
  284. "has_been_set_motor_config": has_been_set_motor_config,
  285. }
  286. self.last_mcu_other_info_data["time"] = time.time()
  287. self.last_mcu_other_info_data["num"] += 1
  288. for k, v in self.last_mcu_other_info_data["data"].items():
  289. print("k:{},v:{}".format(k, v))
  290. # 设置其他信息
  291. def set_to_mcu_other_info(self, data):
  292. is_auto_send_base_info = data["is_auto_send_base_info"]
  293. is_move_retry = data["is_move_retry"]
  294. is_data_response = data["is_data_response"]
  295. low_speed = data["low_speed"]
  296. is_test = data["is_test"]
  297. to_init_mode = data["to_init_mode"]
  298. turntable_move_to_init_mode = data["turntable_move_to_init_mode"]
  299. led_count = data["led_count"]
  300. turntable_steering_angle_ratio = data["turntable_steering_angle_ratio"]
  301. is_manual_check = data["is_manual_check"]
  302. camera_steering_angle_ratio = data["camera_steering_angle_ratio"]
  303. is_auto_motor_to_disable = data["is_auto_motor_to_disable"]
  304. diff_dir = data["diff_dir"]
  305. is_auto_send_pos_info = data["is_auto_send_pos_info"]
  306. is_dog = data["is_dog"]
  307. has_been_set_motor_config = data["has_been_set_motor_config"]
  308. buf = [self.command["set_other_info"]]
  309. buf.extend(self.encapsulation_data(data=is_auto_send_base_info, len_data=1))
  310. buf.extend(self.encapsulation_data(data=is_move_retry, len_data=1))
  311. buf.extend(self.encapsulation_data(data=is_data_response, len_data=1))
  312. buf.extend(self.encapsulation_data(data=low_speed, len_data=2))
  313. buf.extend(self.encapsulation_data(data=is_test, len_data=1))
  314. buf.extend(self.encapsulation_data(data=to_init_mode, len_data=1))
  315. buf.extend(
  316. self.encapsulation_data(data=turntable_move_to_init_mode, len_data=1)
  317. )
  318. buf.extend(self.encapsulation_data(data=led_count, len_data=2))
  319. buf.extend(
  320. self.encapsulation_data(data=turntable_steering_angle_ratio, len_data=2)
  321. )
  322. buf.extend(self.encapsulation_data(data=is_manual_check, len_data=1))
  323. buf.extend(
  324. self.encapsulation_data(data=camera_steering_angle_ratio, len_data=4)
  325. )
  326. buf.extend(self.encapsulation_data(data=is_auto_motor_to_disable, len_data=1))
  327. buf.extend(self.encapsulation_data(data=diff_dir, len_data=1))
  328. buf.extend(self.encapsulation_data(data=is_auto_send_pos_info, len_data=1))
  329. buf.extend(self.encapsulation_data(data=is_dog, len_data=1))
  330. buf.extend(self.encapsulation_data(data=has_been_set_motor_config, len_data=1))
  331. self.add_send_data_queue(buf)
  332. # 获取按键信息
  333. def get_from_mcu_button(self, receive_data):
  334. button_name = receive_data[1]
  335. self.deal_mcu_button(button_name)
  336. # 获取偏移量信息
  337. def get_from_mcu_deviation_info(self, receive_data):
  338. if len(receive_data) == 18:
  339. camera_high_motor_deviation_dir = receive_data[1]
  340. camera_high_motor_deviation = receive_data[2] << 8 | receive_data[3]
  341. camera_high_motor_deviation = (
  342. camera_high_motor_deviation * -1
  343. if camera_high_motor_deviation_dir == 0
  344. else camera_high_motor_deviation
  345. )
  346. camera_steering_deviation_dir = receive_data[4]
  347. camera_steering_deviation = (receive_data[5] << 8 | receive_data[6]) * 0.1
  348. camera_steering_deviation = (
  349. camera_steering_deviation * -1
  350. if camera_steering_deviation_dir == 0
  351. else camera_steering_deviation
  352. )
  353. turntable_steering_deviation_dir = receive_data[7]
  354. turntable_steering_deviation = (
  355. receive_data[8] << 8 | receive_data[9]
  356. ) * 0.1
  357. turntable_steering_deviation = (
  358. turntable_steering_deviation * -1
  359. if turntable_steering_deviation_dir == 0
  360. else turntable_steering_deviation
  361. )
  362. overturn_steering_middle_dir = receive_data[10]
  363. overturn_steering_middle = (receive_data[11] << 8 | receive_data[12]) * 0.1
  364. overturn_steering_middle = (
  365. overturn_steering_middle * -1
  366. if overturn_steering_middle_dir == 0
  367. else overturn_steering_middle
  368. )
  369. overturn_steering_high_dir = receive_data[13]
  370. overturn_steering_high = (receive_data[14] << 8 | receive_data[15]) * 0.1
  371. overturn_steering_high = (
  372. overturn_steering_middle * -1
  373. if overturn_steering_high_dir == 0
  374. else overturn_steering_high
  375. )
  376. overturn_steering_up_speed = receive_data[16]
  377. overturn_steering_down_speed = receive_data[17]
  378. # self.sign_data.emit(
  379. # {
  380. # "_type": "get_deviation_data",
  381. # "plugins_mode": "mcu",
  382. # "data": {
  383. # "camera_high_motor_deviation": camera_high_motor_deviation,
  384. # "camera_steering_deviation": camera_steering_deviation,
  385. # "turntable_steering_deviation": turntable_steering_deviation,
  386. # "overturn_steering_middle": overturn_steering_middle,
  387. # "overturn_steering_high": overturn_steering_high,
  388. # "overturn_steering_up_speed": overturn_steering_up_speed,
  389. # "overturn_steering_down_speed": overturn_steering_down_speed,
  390. # },
  391. # }
  392. # )
  393. message = {
  394. "_type": "get_deviation_data",
  395. "plugins_mode": "mcu",
  396. "data": {
  397. "camera_high_motor_deviation": camera_high_motor_deviation,
  398. "camera_steering_deviation": camera_steering_deviation,
  399. "turntable_steering_deviation": turntable_steering_deviation,
  400. "overturn_steering_middle": overturn_steering_middle,
  401. "overturn_steering_high": overturn_steering_high,
  402. "overturn_steering_up_speed": overturn_steering_up_speed,
  403. "overturn_steering_down_speed": overturn_steering_down_speed,
  404. },
  405. }
  406. self.sendSocketMessage(msg="接收偏移量信息", data=message)
  407. print("接收偏移量信息")
  408. return
  409. # 设备链接信息
  410. def get_from_mcu_connect_info(self, receive_data):
  411. connect_flag = receive_data[1]
  412. device_id = receive_data[2]
  413. try:
  414. mcu_has_been_set = receive_data[6] # 设备是否有初始化 ,1 表示已初始化
  415. except:
  416. mcu_has_been_set = 99 # 未知状态
  417. # self.self_sign.emit({"type": "connect_sign", "data": connect_flag})
  418. message = {"type": "connect_sign", "data": connect_flag}
  419. self.sendSocketMessage(msg="接收链接信息", data=message)
  420. print("接收链接信息")
  421. return
  422. def init(self):
  423. self.self_sign.connect(self.deal_self_sign_data)
  424. # LED 灯光处理
  425. def open_rgb_led(
  426. self,
  427. color_name,
  428. led_command=1,
  429. brightness=80,
  430. enable=True,
  431. mode="loop",
  432. times=2,
  433. interval=0.1,
  434. ):
  435. color_name_value = {
  436. "红色": (156, 6, 3),
  437. "黄色": (255, 206, 25),
  438. "绿色": (0, 128, 0),
  439. "蓝色": (0, 25, 255),
  440. "白色": (255, 250, 227),
  441. }
  442. if color_name in color_name_value:
  443. buf = [self.command["open_rgb_led"]]
  444. buf.append(1 if enable else 0)
  445. buf.append(led_command)
  446. buf.extend(color_name_value[color_name])
  447. buf.extend(
  448. [
  449. brightness,
  450. 1 if mode == "loop" else 2,
  451. times,
  452. int(interval * 10),
  453. ]
  454. )
  455. self.add_send_data_queue(buf)
  456. def deal_self_sign_data(self, sign_data):
  457. if sign_data["type"] == "connect_sign":
  458. if sign_data["data"] == 0:
  459. self.is_running = False
  460. else:
  461. self.is_running = True
  462. def to_connect_com(self, port_name, is_test=False):
  463. # 关闭串口
  464. print("to_connect_com", port_name)
  465. self.close_connect()
  466. time.sleep(0.3)
  467. self.connect_state = False
  468. try:
  469. self.serial_ins = SerialIns(port_name=port_name, baud=115200, timeout=0.1)
  470. if not self.serial_ins.serial_handle:
  471. # self.sign_data.emit(
  472. # {
  473. # "_type": "show_info",
  474. # "plugins_mode": "mcu",
  475. # "data": "MCU 打开串口失败",
  476. # }
  477. # )
  478. message = {
  479. "_type": "show_info",
  480. "plugins_mode": "mcu",
  481. "data": "MCU 打开串口失败",
  482. }
  483. self.sendSocketMessage(code=1,msg="接收链接信息", data=message)
  484. self.serial_ins = None
  485. self.connect_state = False
  486. return False
  487. except:
  488. # self.sign_data.emit(
  489. # {
  490. # "_type": "show_info",
  491. # "plugins_mode": "mcu",
  492. # "data": "MCU 打开串口失败",
  493. # }
  494. # )
  495. message = {
  496. "_type": "show_info",
  497. "plugins_mode": "mcu",
  498. "data": "MCU 打开串口失败",
  499. }
  500. self.sendSocketMessage(code=1,msg="MCU 打开串口失败", data=message)
  501. self.serial_ins = None
  502. self.connect_state = False
  503. return False
  504. # self.sign_data.emit(
  505. # {"_type": "show_info", "plugins_mode": "mcu", "data": "MCU 开始连接"}
  506. # )
  507. message = {"_type": "show_info", "plugins_mode": "mcu", "data": "MCU 开始连接"}
  508. self.sendSocketMessage(
  509. code=1, msg="MCU 开始连接", data=message, device_status=1
  510. )
  511. # =======================发送连接请求=================================
  512. cmd = 90
  513. data = [cmd, 1]
  514. print("405 发送 连接请求 -----------------------------------------")
  515. print(self.serial_ins)
  516. # self.serial_ins.clearn_flush()
  517. self.serial_ins.write_cmd(data)
  518. # 延迟接收数据
  519. time.sleep(0.3)
  520. receive_data = self.serial_ins.read_cmd(out_time=1)
  521. if receive_data:
  522. print(
  523. "409 receive_data--90:{}".format(self.change_hex_to_int(receive_data))
  524. )
  525. if receive_data:
  526. # receive_data[2]=1 表示为MCU设备编号
  527. if receive_data[0] == 90 and receive_data[2] == 1:
  528. connect_flag = receive_data[1]
  529. # 是否有初始化
  530. try:
  531. mcu_has_been_set = receive_data[
  532. 6
  533. ] # 设备是否有初始化 ,1 表示已初始化
  534. except:
  535. mcu_has_been_set = 99 # 未知状态
  536. print("MCU初始化信息{}".format(mcu_has_been_set))
  537. # self.sign_data.emit(
  538. # {"_type": "show_info", "plugins_mode": "mcu", "data": "MCU 已连接"}
  539. # )
  540. message = {
  541. "_type": "show_info",
  542. "plugins_mode": "mcu",
  543. "data": "MCU 已连接",
  544. }
  545. self.sendSocketMessage(code=1, msg="MCU 开始连接", data=message)
  546. self.connect_state = True
  547. if not self.is_running:
  548. print("MCU start")
  549. self.start()
  550. self.self_sign.emit({"type": "connect_sign", "data": connect_flag})
  551. print("MCU 已连接")
  552. self.port_name = port_name
  553. return
  554. print("MCU 连接失败")
  555. self.sign_data.emit(
  556. {"_type": "show_info", "plugins_mode": "mcu", "data": "MCU 连接失败"}
  557. )
  558. self.close_connect()
  559. def close_connect(self):
  560. self.port_name = ""
  561. if self.serial_ins:
  562. self.serial_ins.close_serial_port()
  563. self.connect_state = False
  564. self.init_state = False
  565. @property
  566. def mcu_move_state(self):
  567. if self.m_t == 1:
  568. if (
  569. self.state_camera_motor == 2
  570. and self.state_camera_steering == 2
  571. and self.state_turntable_steering == 2
  572. and self.state_overturn_steering == 2
  573. ):
  574. self._mcu_move_state = 2
  575. else:
  576. self._mcu_move_state = 1
  577. else:
  578. if (
  579. self.state_camera_motor == 2
  580. and self.state_camera_steering == 2
  581. and self.state_turntable_steering == 2
  582. and self.state_overturn_steering == 2
  583. and self.state_move_turntable_steering == 2
  584. ):
  585. self._mcu_move_state = 2
  586. else:
  587. self._mcu_move_state = 1
  588. # self._mcu_move_state = 2
  589. return self._mcu_move_state
  590. def get_basic_info_mcu(self):
  591. receive_data = self.serial_ins.read_cmd(out_time=1)
  592. if receive_data is False:
  593. print("------------------------------------------------4657564654")
  594. self.connect_state = False
  595. return False
  596. if not receive_data:
  597. return
  598. # print("receive_data")
  599. # 数据 结构 command,按命令解析
  600. # command 0(9) 相机高度1-2 相机角度3-4 转盘角度5-6 灯光状态7 激光指示器状态8,运行状态9
  601. command = receive_data[0]
  602. if command in self.deal_code_func_dict:
  603. self.deal_code_func_dict[command](receive_data)
  604. def run(self):
  605. self.is_running = True
  606. self.serial_ins.clearn_flush()
  607. self.to_init_device_origin_point(device_name="mcu")
  608. print("MCU 开始循环~")
  609. while 1:
  610. time.sleep(0.01)
  611. if not self.serial_ins or not self.connect_state:
  612. break
  613. try:
  614. # print("mcu send_cmd")
  615. self.send_cmd()
  616. # time.sleep(0.01)
  617. self.get_basic_info_mcu()
  618. except BaseException as e:
  619. print("121231298908", e)
  620. break
  621. self.is_running = False
  622. self.connect_state = False
  623. print("MCU 循环退出~")
  624. # self.sign_data.emit(
  625. # {"_type": "show_info", "plugins_mode": "mcu", "data": "MCU 连接失败"}
  626. # )
  627. message = {"_type": "show_info", "plugins_mode": "mcu", "data": "MCU 连接失败"}
  628. self.sendSocketMessage(code=1,msg="MCU 连接失败",data=message)
  629. self.close_connect()
  630. def __del__(self):
  631. self.close_connect()
  632. def send_cmd(self):
  633. self.lock.acquire()
  634. if self.send_data_queue:
  635. data = self.send_data_queue.pop(0)
  636. self.serial_ins.write_cmd(data)
  637. else:
  638. self.t_n += 1
  639. # 加大发送获取基础数据的时间间隔
  640. # 默认为0.01秒一个循环,每隔1.5秒发送数据
  641. if self.t_n > 150:
  642. self.t_n = 0
  643. data = [self.command["get_all_info"], 1]
  644. self.serial_ins.write_cmd(data)
  645. self.lock.release()
  646. def add_send_data_queue(self, data):
  647. self.lock.acquire()
  648. if self.serial_ins:
  649. # print("send_data_queue append :{}".format(data))
  650. self.send_data_queue.append(data)
  651. self.lock.release()
  652. def get_deviation(self):
  653. # 发送获取偏移量
  654. data = [self.command["get_deviation"], 1]
  655. self.add_send_data_queue(data)
  656. # if self.serial_ins:
  657. # self.serial_ins.write_cmd(data)
  658. print("发送获取偏移量")
  659. def get_other_info(self):
  660. # 发送获取偏移量
  661. data = [self.command["get_other_info"], 1]
  662. self.add_send_data_queue(data)
  663. print("发送获取其他信息")
  664. def set_deviation(self, device_name, _type=0, deviation=0):
  665. # turntable----0 angle_ratio 1 turntable_steering_deviation
  666. # overturn ----0 middle 1 high
  667. if device_name == "camera_high_motor":
  668. deviation = deviation / 10 # deviation 原单位为mm
  669. if device_name == "turntable_position_motor":
  670. deviation = deviation / 10 # deviation 原单位为mm
  671. if device_name == "camera_steering":
  672. pass
  673. if device_name == "turntable_steering":
  674. pass
  675. if device_name == "overturn_steering":
  676. pass
  677. device_id = self.device_name_dict[device_name]
  678. _dir = 1 if deviation >= 0 else 0
  679. deviation = int(abs(deviation * 10))
  680. data = [
  681. self.command["set_deviation"],
  682. device_id,
  683. _type,
  684. _dir,
  685. 0xFF & deviation >> 8,
  686. 0xFF & deviation,
  687. ]
  688. self.add_send_data_queue(data)
  689. def deal_mcu_button(self, button_name):
  690. # 防止重复点击
  691. s = time.time()
  692. if s - self.last_push_time[button_name] > 0.1:
  693. self.last_push_time[button_name] = s
  694. # print("button_name", button_name)
  695. else:
  696. self.last_push_time[button_name] = s
  697. return
  698. if button_name == 1:
  699. # 自动执行全部
  700. # self.sign_data.emit(
  701. # {"_type": "mcu_button", "plugins_mode": "mcu", "data": "todo_1"}
  702. # )
  703. message = {"_type": "mcu_button", "plugins_mode": "mcu", "data": "todo_1"}
  704. self.sendSocketMessage(code=0, msg="", data=message)
  705. if button_name == 2:
  706. # self.sign_data.emit(
  707. # {"_type": "mcu_button", "plugins_mode": "mcu", "data": "todo_2"}
  708. # )
  709. message = {"_type": "mcu_button", "plugins_mode": "mcu", "data": "todo_2"}
  710. self.sendSocketMessage(code=0, msg="", data=message)
  711. if button_name == 3:
  712. # self.sign_data.emit(
  713. # {"_type": "mcu_button", "plugins_mode": "mcu", "data": "todo_3"}
  714. # )
  715. message = {"_type": "mcu_button", "plugins_mode": "mcu", "data": "todo_3"}
  716. self.sendSocketMessage(code=0, msg="", data=message)
  717. def get_mcu_state(self):
  718. """
  719. 获取mcu 设备状态,当状态为停止时,其他程序才可正常执行
  720. :return:
  721. """
  722. return True
  723. def to_get_mcu_base_info(self):
  724. if self.connect_state:
  725. self.lock.acquire()
  726. # print('==========================>1111')
  727. # print("-------------------to_get_mcu_base_info--------------------------")
  728. data = [self.command["get_all_info"], 1]
  729. f = True
  730. try:
  731. self.serial_ins.write_cmd(data)
  732. except:
  733. f = False
  734. pass
  735. self.lock.release()
  736. if not f:
  737. self.connect_state = False
  738. return False
  739. else:
  740. return True
  741. def to_deal_device(self, device_name, value=1, _type=0, times=1, delay=0):
  742. """
  743. value 激光0关 1开
  744. mp3_player value 表示0表示关,1表示开,_type 表示歌曲切换到指定歌曲
  745. delay:延迟处理,单位为0.1秒,即delay=100时,表示延迟10秒
  746. """
  747. device_id = self.device_name_dict[device_name]
  748. if device_name == "buzzer":
  749. value = int(value)
  750. cmd = 3
  751. data = [
  752. cmd,
  753. device_id,
  754. value,
  755. _type,
  756. times,
  757. delay,
  758. ]
  759. self.add_send_data_queue(data)
  760. # if self.serial_ins:
  761. # self.serial_ins.write_cmd(data)
  762. return True
  763. # 让设备运动到原点 并设置MCU需要进行初始化
  764. def to_init_device_origin_point(self, device_name, is_force=False):
  765. device_id = self.device_name_dict[device_name]
  766. cmd = 2
  767. data = [cmd, device_id, 0 if is_force is False else 1]
  768. self.open_rgb_led(color_name="红色")
  769. self.add_send_data_queue(data)
  770. if device_name == "mcu":
  771. # 重置初始化标记为 从未初始化
  772. QTimer.singleShot(5000, self.just_init)
  773. return True
  774. def just_init(self, *args):
  775. # 重置初始化标记为 从未初始化
  776. self.is_just_init_time = False
  777. def to_device_move(
  778. self,
  779. device_name,
  780. value=0,
  781. max_speed=None,
  782. up_speed=None,
  783. down_speed=None,
  784. _is_debug=0,
  785. is_relative=0,
  786. is_deviation=1,
  787. ):
  788. """
  789. 此处输入单位为 毫米,以及度 需要先缩小,再放大
  790. """
  791. speed = settings.moveSpeed()
  792. cmd = 1
  793. device_id = self.device_name_dict[device_name]
  794. if device_name == "camera_high_motor":
  795. # value 单位毫米
  796. # max_speed = 10000 if max_speed is None else max_speed
  797. # up_speed = 800 if up_speed is None else up_speed
  798. # down_speed = 700 if down_speed is None else down_speed
  799. max_speed = (
  800. speed[device_name]["max_speed"] if max_speed is None else max_speed
  801. )
  802. up_speed = speed[device_name]["up_speed"] if up_speed is None else up_speed
  803. down_speed = (
  804. speed[device_name]["down_speed"] if down_speed is None else down_speed
  805. )
  806. value = value / 10 # value 单位毫米
  807. assert 0 <= value <= 40
  808. assert 0 <= max_speed <= 10000
  809. if device_name == "camera_steering":
  810. # 角度为度 未放大 精确到0.1度
  811. max_speed = 6000 if max_speed is None else max_speed
  812. up_speed = 500 if up_speed is None else up_speed
  813. down_speed = 500 if down_speed is None else down_speed
  814. assert -360 <= value <= 360
  815. if device_name == "turntable_steering":
  816. # 角度为度 未放大 精确到0.1度
  817. # max_speed = 6000 if max_speed is None else max_speed
  818. # up_speed = 500 if up_speed is None else up_speed
  819. # down_speed = 400 if down_speed is None else down_speed
  820. max_speed = (
  821. speed[device_name]["max_speed"] if max_speed is None else max_speed
  822. )
  823. up_speed = speed[device_name]["up_speed"] if up_speed is None else up_speed
  824. down_speed = (
  825. speed[device_name]["down_speed"] if down_speed is None else down_speed
  826. )
  827. assert -720 <= value <= 720
  828. if device_name == "overturn_steering":
  829. # 角度为度 未放大 精确到0.1度
  830. max_speed = 2 if max_speed is None else max_speed
  831. up_speed = 1 if up_speed is None else up_speed
  832. down_speed = 1 if down_speed is None else down_speed
  833. assert 0 <= value <= 360
  834. if device_name == "turntable_position_motor":
  835. # value 单位毫米
  836. max_speed = 11000 if max_speed is None else max_speed
  837. up_speed = 900 if up_speed is None else up_speed
  838. down_speed = 900 if down_speed is None else down_speed
  839. value = value / 10 # value 单位毫米
  840. assert 0 <= value <= 900
  841. assert 0 <= max_speed <= 15000
  842. _dir = True if value >= 0 else False
  843. value = int(abs(value * 10)) # 此处value赋值后,单位为mm以及0.1度
  844. data = [
  845. cmd,
  846. device_id,
  847. 1 if _dir else 0,
  848. 0xFF & value >> 8,
  849. 0xFF & value,
  850. 0xFF & max_speed >> 8,
  851. 0xFF & max_speed,
  852. 0xFF & up_speed >> 8,
  853. 0xFF & up_speed,
  854. 0xFF & down_speed >> 8,
  855. 0xFF & down_speed,
  856. _is_debug,
  857. is_deviation,
  858. is_relative,
  859. ]
  860. self.add_send_data_queue(data)
  861. # if self.serial_ins:
  862. # self.serial_ins.write_cmd(data)
  863. # 通用串口数据解析器
  864. def get_data_from_receive_data(
  865. self, receive_data, start, len_data, data_magnification=1
  866. ):
  867. # data_magnification 数据放大倍数,或缩小倍数,默认为1
  868. try:
  869. if len_data == 1:
  870. data = receive_data[start]
  871. return data * data_magnification
  872. elif len_data == 2:
  873. data = receive_data[start] << 8 | receive_data[start + 1]
  874. return data * data_magnification
  875. elif len_data == 4:
  876. data = (
  877. receive_data[start] << 24
  878. | receive_data[start + 1] << 16
  879. | receive_data[start + 2] << 8
  880. | receive_data[start + 3]
  881. )
  882. return data * data_magnification
  883. return None
  884. except:
  885. return None
  886. def encapsulation_data(self, data, len_data, data_magnification=1):
  887. # data_magnification 数据放大倍数,或缩小倍数,默认为1
  888. data = int(data * data_magnification)
  889. if len_data == 1:
  890. return [0xFF & data]
  891. elif len_data == 2:
  892. return [0xFF & data >> 8, 0xFF & data]
  893. elif len_data == 4:
  894. return [0xFF & data >> 24, 0xFF & data >> 16, 0xFF & data >> 8, 0xFF & data]
  895. def __new__(cls, *args, **kwargs):
  896. """如果当前没有实例时,调用父类__new__方法,生成示例,有则返回保存的内存地址。"""
  897. if not cls.instance:
  898. cls.instance = super().__new__(cls)
  899. return cls.instance
  900. class McuDebug(object):
  901. def __init__(self, windows, is_debug=True, is_deviation=False):
  902. self.windows = windows
  903. self.is_debug = 1 if is_debug else 0
  904. self.is_deviation = 1 if is_deviation else 0
  905. def camera_high_motor(self, value):
  906. # 相机电机
  907. self.windows.mcu.to_device_move(
  908. device_name="camera_high_motor",
  909. value=value,
  910. max_speed=1400,
  911. up_speed=400,
  912. down_speed=100,
  913. _is_debug=self.is_debug,
  914. is_deviation=self.is_deviation,
  915. )
  916. def camera_steering(self, value):
  917. # 相机舵机
  918. self.windows.mcu.to_device_move(
  919. device_name="camera_steering",
  920. value=value,
  921. _is_debug=self.is_debug,
  922. is_deviation=self.is_deviation,
  923. )
  924. def turntable_steering(self, value):
  925. # 转盘舵机
  926. self.windows.mcu.to_device_move(
  927. device_name="turntable_steering",
  928. value=value,
  929. _is_debug=self.is_debug,
  930. is_deviation=self.is_deviation,
  931. )
  932. def turntable_position_motor(self, value):
  933. # 转盘舵机
  934. self.windows.mcu.to_device_move(
  935. device_name="turntable_position_motor",
  936. value=value,
  937. max_speed=1400,
  938. up_speed=400,
  939. down_speed=100,
  940. _is_debug=self.is_debug,
  941. is_deviation=self.is_deviation,
  942. )
  943. def overturn_steering(self, value):
  944. # 翻板舵机中位
  945. self.windows.mcu.to_device_move(
  946. device_name="overturn_steering",
  947. value=value,
  948. _is_debug=self.is_debug,
  949. is_deviation=self.is_deviation,
  950. )
  951. def to_deal_device(self, device_name, value=1, _type=0, times=1):
  952. self.windows.mcu.to_deal_device(
  953. device_name, value=value, _type=_type, times=times
  954. )
  955. def photograph(self, goods_art_no=None):
  956. self.windows.photograph(goods_art_no=goods_art_no)
  957. def __move_equipment(self, data):
  958. func_class = {
  959. "相机电机": self.camera_high_motor,
  960. "相机舵机": self.camera_steering,
  961. "转盘舵机": self.turntable_steering,
  962. "转盘前后电机": self.turntable_position_motor,
  963. }
  964. for key, value in data.items():
  965. if key in func_class:
  966. func_class[key](value=value)
  967. time.sleep(0.1)
  968. def move_equipment(self, data: dict):
  969. Thread(target=self.__move_equipment, args=(data,)).start()