DeviceControl.py 89 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197
  1. import asyncio
  2. import datetime
  3. from cv2 import log
  4. import serial.tools.list_ports
  5. import time, json
  6. from .SerialIns import SerialIns
  7. from utils.SingletonType import SingletonType
  8. from utils.utils_func import dynamic_parameter_issuance_get
  9. from .BaseClass import BaseClass
  10. from sockets import ConnectionManager
  11. from collections import defaultdict
  12. import threading
  13. import settings
  14. from .ProgramItem import ProgramItem
  15. from .capture.module_digicam import DigiCam
  16. from databases import insert_photo_records
  17. from .McuDeviationSet import McuDeviationSet
  18. from .OtherSet import OtherSet
  19. from .DebugUart import DebugUart
  20. from .LineControl import LineControl
  21. import copy
  22. import logging
  23. from mcu.capture.smart_shooter_class import SmartShooter
  24. import logging
  25. from conifg_info import ConfigManager
  26. from mcu.anheng_scale import AnhengScale
  27. logger = logging.getLogger(__name__)
  28. # mcu命令
  29. class DeviceControl(BaseClass, metaclass=SingletonType):
  30. lock = threading.Lock()
  31. def __init__(
  32. self, websocket_manager: ConnectionManager, smart_shooter: SmartShooter = None
  33. ):
  34. super().__init__(
  35. websocket_manager=websocket_manager, smart_shooter=smart_shooter
  36. )
  37. self.camera_high_motor_deviation_offset = 0
  38. self.camera_height = 400
  39. self.config_manager = None
  40. self.msg_type = "mcu"
  41. self.anheng_scale = AnhengScale(baudrate=9600, websocket_manager=self.websocket_manager)
  42. self.command = {
  43. "to_device_move": 1, # 设备运动
  44. 'to_init_device': 2, # 初始化设备
  45. "to_deal_other_device": 3, # 处理其他设备
  46. 'get_all_info': 29, # 获取所有信息
  47. 'set_deviation': 40, # 设置偏移量
  48. 'get_deviation': 41, # 读取偏移量
  49. "signal_forwarding": 91, # 信号转发处理
  50. "signal_forwarding_return": 92, # 信号转发返回
  51. "get_other_info": 44, # 获取其他信息
  52. "open_rgb_led": 43, ## RGB灯的处理与通讯
  53. "set_other_info": 45, # 设置其他信息
  54. "query_remote_control_battery": 47, # 查询遥控器电量
  55. # "set_turntable_mode": 48, # 设置转盘通讯方式 1、串口、2、无线、3 混合
  56. "get_mcu_device_id": 49, # 查询MCU的设备号
  57. "mcu_power_off": 53, # 设备关机
  58. "stop_mcu": 93, # 停止运行mcu
  59. "get_steering_temperature": 108, # 查询舵机的当前的温度
  60. # "steering_forwarding": 113, # 舵机信号转发处理
  61. # "steering_forwarding_callback": 114, # 舵机信号转发返回
  62. "get_motor_value": 119, # 获取当前电机值;逻辑值
  63. "set_zero_debug": 120, # 简单的设备归零,用于调试
  64. "set_stepper_disable": 121, # 释放,或恢复使能
  65. "test_devices": 152, # 测试设备是否正常
  66. "deal_by_json": 154, # 使用json进行数据下发
  67. }
  68. self.serial_ins = None
  69. self.mcu_deviation_set = McuDeviationSet(self)
  70. self.mcu_other_set = OtherSet(self)
  71. self.debug_uart = DebugUart(self)
  72. self.line_control = LineControl(websocket_manager)
  73. self.m_t = 1
  74. # 0未开始 1进行中 2已结束 99异常
  75. self.action_state = 2
  76. self._mcu_move_state = 0
  77. self.state_camera_motor = 3
  78. self.state_camera_steering = 3
  79. self.state_turntable_steering = 3
  80. self.state_overturn_steering = 3
  81. self.seed = 0
  82. self.last_camera_height = 0
  83. # 是否实时获取mcu状态信息
  84. self.is_get_mcu_state = True
  85. self.state_move_turntable_steering = 3
  86. self.last_from_mcu_move_respond_data = None
  87. self.camera_motor_speed = 0
  88. self.camera_motor_value = 0
  89. self.init_state = False
  90. self.port_name = ""
  91. self.mcu_exit = False
  92. self.t_n = 0
  93. self.connected_ports_dict = {} # 已连接的ports
  94. self.p_list = []
  95. self.temp_ports_dict = {}
  96. self.is_running = False
  97. self.is_runn_action = False
  98. self.is_stop_action = False
  99. self.connect_state = False
  100. self.is_init_while = False
  101. self.device_name_dict = {
  102. "camera_steering": 0,
  103. "camera_high_motor": 1,
  104. "turntable_steering": 2,
  105. "overturn_steering": 3,
  106. "laser_position": 4,
  107. "buzzer": 5,
  108. "split": 6,
  109. "turntable_position_motor": 7,
  110. "mp3_player": 8,
  111. "mcu": 99,
  112. "camera_zoom_motor": 10,
  113. }
  114. self.last_move_time = time.time()
  115. self.device_name_dict_mapping = {
  116. 0: "相机角度",
  117. 1: "相机高度",
  118. 2: "转盘角度",
  119. 3: "翻板角度",
  120. 4: "激光灯位置",
  121. 5: "蜂鸣器",
  122. 6: "split",
  123. 7: "转盘位置",
  124. 8: "播放音频",
  125. 99: "mcu命令",
  126. 10: "相机焦段",
  127. }
  128. # 最近的mcu基础信息,用于获取数据状态检查
  129. self.last_mcu_info_data = {
  130. "num": 0,
  131. "time": time.time(),
  132. "data": None,
  133. }
  134. # 最近的mcu的其他配置
  135. self.last_mcu_other_info_data = {
  136. "num": 0,
  137. "time": time.time(),
  138. "data": {},
  139. }
  140. # self.window = window
  141. self.last_push_time = defaultdict(float)
  142. self.is_running = False
  143. self.is_wait_connect = False # 等待链接
  144. self.send_data_queue = [] # 发送队列
  145. # self.lock = Lock()
  146. # 是否是刚进行完初始化;首次初始化,需要运动到指定第一个指定位置
  147. self.is_just_init_time = False
  148. # self.init()
  149. # ===========注册命令函数============
  150. self.deal_code_func_dict = {
  151. 29: self.get_from_mcu_base_info, # 获取基本情况
  152. 32: self.get_from_mcu_button, # 获取按键信息
  153. 42: self.get_from_mcu_deviation_info, # 获取偏移量信息
  154. 44: self.get_from_mcu_other_info, # 获取其他配置参数
  155. 90: self.get_from_mcu_connect_info, # 获取链接电脑信号
  156. 92: self.get_from_mcu_move_respond_data, # 获取MCU响应
  157. 100: self.print_mcu_error_data, # 打印下位机的错误内容
  158. 255: self.print_mcu_noraml_data, # 打印回执
  159. 124: self.read_register_data_by_usb, # 读取某个寄存器数据
  160. 125: self.write_register_data_by_usb, # 写入某个寄存器数据
  161. 126: self.get_all_registers_list_by_usb, # 获取所有寄存器
  162. 150: self.dynamic_parameter_issuance, # 动态参数下发
  163. }
  164. def set_dynamic_config(self, config):
  165. """
  166. 设置动态参数配置
  167. """
  168. print("set_dynamic_config", config)
  169. if not self.init_state:
  170. self.sendSocketMessage(code=1, msg="mcu设备未初始化", device_status=4)
  171. return False
  172. return self.config_manager.set_dynamic_value(config)
  173. def get_dynamic_config(self):
  174. """
  175. 获取动态参数配置
  176. """
  177. if not self.init_state:
  178. self.sendSocketMessage(code=1, msg="mcu设备未初始化", device_status=4)
  179. return False
  180. # 构建返回结果,过滤掉值为空的项,不修改原字典
  181. result = {}
  182. for item in self.config_manager.CONFIG_METADATA:
  183. item_value = self.config_manager.get_dynamic_value(self.config_manager.CONFIG_METADATA[item])
  184. # time.sleep(0.01)
  185. entry = dict(self.config_manager.CONFIG_METADATA[item])
  186. if not item_value:
  187. entry['value'] = None
  188. else:
  189. entry['value'] = item_value
  190. result[item] = entry
  191. # print("CONFIG_METADATA", self.config_manager.CONFIG_METADATA)
  192. # print("result", result)
  193. return result
  194. def get_dynamic_config_signle(self, name):
  195. """
  196. 获取动态参数配置-单独
  197. """
  198. data = {"addr": name}
  199. print("参数值打印", data)
  200. item_value = self.config_manager.get_dynamic_value(data)
  201. if not item_value:
  202. return None
  203. return item_value
  204. def one_key_turnoff(self, device_name, flag):
  205. # 一键关机
  206. if device_name in self.device_name_dict:
  207. device_id = self.device_name_dict[device_name]
  208. buf = [self.command["mcu_power_off"],
  209. device_id,
  210. 1 if flag else 0,
  211. ]
  212. self.add_send_data_queue(buf)
  213. # 使用json进行数据下发
  214. def send_json_to(self, data):
  215. try:
  216. data = data.encode()
  217. send_data = [self.command["deal_by_json"]]
  218. send_data.extend(data)
  219. # self.serial_ins.write_cmd(send_data)
  220. except BaseException as e:
  221. print("212", e)
  222. return False
  223. print("280----buf:", self.change_hex_to_int(send_data))
  224. # =============================
  225. buf = bytearray(b'')
  226. buf.extend([0x55, 0x55, (0xff & len(send_data))])
  227. buf.extend(send_data)
  228. buf.extend([0xff & ~sum(send_data)])
  229. print("增加校验码后:", self.change_hex_to_int(buf))
  230. self.add_send_data_queue(send_data)
  231. return True
  232. # 发送命令到MCU
  233. def send_hex_cmd_to(self, data: str, need_del_cr=True):
  234. while 1:
  235. if " " in data:
  236. data = data.replace(" ", " ")
  237. else:
  238. break
  239. data = data.strip()
  240. data = [int(x, 16) for x in data.split()]
  241. if need_del_cr:
  242. send_data = []
  243. if len(data) > 3:
  244. data = data[3:-1]
  245. # send_data.extend([0x55, 0x55, (0xff & len(data))])
  246. send_data.extend(data)
  247. # send_data.extend([0xff & ~sum(data)])
  248. else:
  249. send_data = []
  250. send_data.extend(data)
  251. print("303----buf:", self.change_hex_to_int(send_data))
  252. # =============================
  253. buf = bytearray(b'')
  254. buf.extend([0x55, 0x55, (0xff & len(send_data))])
  255. buf.extend(send_data)
  256. buf.extend([0xff & ~sum(send_data)])
  257. print("增加校验码后:", self.change_hex_to_int(buf))
  258. self.add_send_data_queue(send_data)
  259. def one_key_down(self):
  260. cmd = [0x55, 0x55, 0x69, 0x96, 0x00, 0x03, 0x00, 0xC8, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01,
  261. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
  262. 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  263. 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  264. 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
  265. 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
  266. 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x02]
  267. # self.add_send_data_queue(cmd)
  268. buf = bytearray(b"")
  269. buf.extend(cmd)
  270. # 55 55 02 5a 01 a4
  271. if self.serial_ins.serial_handle is not None:
  272. print("one_key_down buf {}".format(self.serial_ins.change_hex_to_int(buf)))
  273. self.serial_ins.serial_handle.write(buf)
  274. def get_device_info(self):
  275. if not self.init_state:
  276. self.sendSocketMessage(code=1, msg="mcu设备未初始化", device_status=4)
  277. return False
  278. cmd = [124]
  279. cmd.extend([0xff & 106 >> 8, 0xff & 106])
  280. # print("get_device_info cmd",cmd)
  281. data = self.get_basic_info_mcu_without_async(data=cmd)
  282. # print("get_device_info====>",data)
  283. if not data:
  284. return False
  285. return_data = self.analysis_data(data[1:])
  286. camera_focal_data = self.config_manager.camera_focal_data()
  287. # print("return_data", return_data)
  288. # print("camera_high_motor_deviation_offset", self.camera_high_motor_deviation_offset)
  289. if return_data:
  290. camera_height = return_data.get('value', 35)
  291. self.camera_height = camera_height - self.camera_high_motor_deviation_offset
  292. else:
  293. self.camera_height = 400 - self.camera_high_motor_deviation_offset
  294. self.msg_type = 'get_device_info'
  295. self.sendSocketMessage(
  296. code=0,
  297. msg="获取其他设备信息",
  298. device_status=2,
  299. data={"camera_height": self.camera_height, "camera_focal_data": camera_focal_data}
  300. )
  301. self.msg_type = 'mcu'
  302. return self.camera_height
  303. # 获取异步数据
  304. def analysis_data(self, _data):
  305. _addr = _data[0] << 8 | _data[1]
  306. if _addr not in self.config_manager.CONFIG_METADATA_BY_ADDR:
  307. return False
  308. start = 2
  309. _value = _data[start] << 40 | _data[start + 1] << 32 | _data[start + 2] << 24 | _data[start + 3] << 16 | _data[
  310. start + 4] << 8 | _data[start + 5]
  311. start = start + 5
  312. _read_only = True if _data[start + 1] == 1 else False # 是否只读
  313. _dir = 1 if _data[start + 2] == 1 else -1
  314. _type = "int" if _data[start + 3] == 1 else "float"
  315. _precision = _data[start + 4]
  316. if _dir < 0:
  317. _value = _value * _dir
  318. if _type == "float":
  319. if _precision > 0:
  320. _round_x = _precision
  321. _precision = _precision * -1
  322. _value = _value * 10 ** _precision
  323. _value = round(_value, _round_x)
  324. else:
  325. _value = int(_value)
  326. return_data = {"addr": _addr,
  327. "key_name": self.config_manager.CONFIG_METADATA_BY_ADDR[_addr],
  328. "readonly": _read_only,
  329. "value": _value}
  330. return return_data
  331. # 跳过异步,直接查询某个数据信息
  332. def get_basic_info_mcu_without_async(self, data, fiddler_cmd=0):
  333. """
  334. fiddler_cmd :只接收指定的命令内容
  335. """
  336. try:
  337. # 清空接收数据
  338. self.serial_ins.clearn_flush()
  339. self.serial_ins.write_cmd(data)
  340. time.sleep(0.06)
  341. r_data = self.get_basic_info_mcu()
  342. print("264----------r_data:", r_data)
  343. except BaseException as e:
  344. print("302---e", e)
  345. r_data = []
  346. #
  347. # self.async_lock.release()
  348. return r_data
  349. def dynamic_parameter_issuance(self, receive_data):
  350. print("dynamic_parameter_issuance receive_data", receive_data)
  351. func_code, status_code, out_par_data_list = dynamic_parameter_issuance_get(
  352. receive_data
  353. )
  354. r_data = {
  355. "func_code": func_code,
  356. "status_code": status_code,
  357. "out_par_data_list": out_par_data_list,
  358. }
  359. print(r_data)
  360. return r_data
  361. # 读取某个寄存器数据
  362. def read_register_data_by_usb(self, receive_data):
  363. return receive_data
  364. # 写入某个寄存器数据
  365. def write_register_data_by_usb(self, receive_data):
  366. return receive_data
  367. # 获取所有寄存器
  368. def get_all_registers_list_by_usb(self, receive_data):
  369. byte_list = receive_data[1:]
  370. _r_data = []
  371. for i in range(0, len(byte_list), 2):
  372. if i + 1 < len(byte_list):
  373. first_byte = byte_list[i]
  374. second_byte = byte_list[i + 1]
  375. _addr = first_byte << 8 | second_byte
  376. _r_data.append(_addr)
  377. return _r_data
  378. async def sendCommand(self, command):
  379. await asyncio.sleep(0.01)
  380. loop = asyncio.get_event_loop()
  381. loop.create_task(self.debug_uart.set(command), name="sendCommand2")
  382. async def getMcuOtherInfo(self):
  383. await asyncio.sleep(0.01)
  384. self.get_other_info()
  385. async def setMcuOtherInfo(self, data):
  386. await asyncio.sleep(0.01)
  387. for k, v in data.items():
  388. print("k:{},v:{}".format(k, v))
  389. logger.info("k:{},v:{}".format(k, v))
  390. data[k] = self.setOtherMaxMinValue(k, v)
  391. self.set_to_mcu_other_info(data)
  392. self.msg_type = "set_other_mcu_info"
  393. self.sendSocketMessage(
  394. code=0,
  395. msg="设置mcu其他配置信息完成",
  396. device_status=2,
  397. )
  398. self.msg_type = "mcu"
  399. def setOtherMaxMinValue(self, item, value):
  400. value = int(value)
  401. parameter_limits = {
  402. "is_auto_send_base_info": (0, 10000),
  403. "is_move_retry": (0, 10000),
  404. "is_data_response": (0, 10000),
  405. "low_speed": (0, 10000), # 假设低速范围是0到1000
  406. "is_test": (0, 10000),
  407. "to_init_mode": (0, 10000),
  408. "turntable_move_to_init_mode": (0, 10000), # 假设转盘通讯方式范围是0到3
  409. "led_count": (0, 10000), # 假设LED数量范围是0到10
  410. "turntable_steering_angle_ratio": (0, 10000), # 假设角度比例范围是0到100
  411. "is_manual_check": (0, 10000),
  412. "camera_steering_angle_ratio": (0, 100000), # 假设角度比例范围是0到100
  413. "is_auto_motor_to_disable": (0, 10000),
  414. "diff_dir": (0, 10000),
  415. "is_auto_send_pos_info": (0, 10000),
  416. "is_dog": (0, 10000),
  417. "has_been_set_motor_config": (0, 10000),
  418. }
  419. # 获取参数的最小值和最大值
  420. min_value, max_value = parameter_limits.get(item, (0, 10000))
  421. value = max(min_value, min(max_value, value))
  422. return value
  423. async def initDevice(self, is_force=False):
  424. if not self.is_running:
  425. self.sendSocketMessage(
  426. code=1, msg="mcu设备未连接,请先连接设备", device_status=0
  427. )
  428. return False
  429. if self.init_state == True:
  430. print("已经初始化过,请勿重复初始化")
  431. logger.info("已经初始化过,请勿重复初始化")
  432. self.sendSocketMessage(msg="设备初始化完成", device_status=2)
  433. return False
  434. self.config_manager = ConfigManager(self)
  435. self.serial_ins.clearn_flush()
  436. self.to_init_device_origin_point(device_name="mcu", is_force=is_force)
  437. print("MCU 开始循环~")
  438. logger.info("MCU 开始循环~")
  439. while 1:
  440. await asyncio.sleep(0.05)
  441. if not self.serial_ins or not self.connect_state:
  442. break
  443. try:
  444. self.send_cmd()
  445. if not self.get_basic_info_mcu():
  446. pass
  447. except BaseException as e:
  448. print("121231298908", e)
  449. logger.info(f"121231298908{e}")
  450. break
  451. self.is_running = False
  452. self.connect_state = False
  453. print("MCU 循环退出~")
  454. logger.info("MCU 循环退出~")
  455. print("串口未连接,请检查")
  456. logger.info("串口未连接,请检查")
  457. self.sendSocketMessage(code=1, msg="MCU串口未连接,请检查", device_status=-1)
  458. message = {"_type": "show_info", "plugins_mode": "mcu", "data": "MCU 连接失败"}
  459. self.sendSocketMessage(
  460. code=1, msg="MCU 连接失败", data=message, device_status=-1
  461. )
  462. self.close_connect()
  463. async def initControlLine(self, serial_handle):
  464. """实例化有线控制设备"""
  465. self.line_control.connect_state = True
  466. self.line_control.serial_ins = serial_handle
  467. await self.line_control.run()
  468. def stop_mcu(self):
  469. buf = [self.command["stop_mcu"]]
  470. buf.extend(self.encapsulation_data(data=1, len_data=1))
  471. self.add_send_data_queue(buf)
  472. # 设置转盘通讯方式 1、串口、2、无线、3 混合
  473. def to_set_turntable_mode(self, mode=1):
  474. buf = [self.command["set_turntable_mode"]]
  475. buf.extend(self.encapsulation_data(data=mode, len_data=1))
  476. self.add_send_data_queue(buf)
  477. def query_remote_control_battery(self):
  478. """查询遥控器电量"""
  479. buf = [self.command["query_remote_control_battery"]]
  480. buf.extend(self.encapsulation_data(data=1, len_data=1))
  481. buf.extend(self.encapsulation_data(data=1, len_data=1))
  482. buf.extend(self.encapsulation_data(data=1, len_data=1))
  483. self.add_send_data_queue(buf)
  484. def encapsulation_data(self, data, len_data, data_magnification=1):
  485. # data_magnification 数据放大倍数,或缩小倍数,默认为1
  486. data = int(data * data_magnification)
  487. if len_data == 1:
  488. return [0xFF & data]
  489. elif len_data == 2:
  490. return [0xFF & data >> 8, 0xFF & data]
  491. elif len_data == 4:
  492. return [0xFF & data >> 24, 0xFF & data >> 16, 0xFF & data >> 8, 0xFF & data]
  493. def open_rgb_led(
  494. self,
  495. color_name,
  496. led_command=1,
  497. brightness=80,
  498. enable=True,
  499. mode="loop",
  500. times=2,
  501. interval=0.1,
  502. ):
  503. color_name_value = {
  504. "红色": (156, 6, 3),
  505. "黄色": (255, 206, 25),
  506. "绿色": (0, 128, 0),
  507. "蓝色": (0, 25, 255),
  508. "白色": (255, 250, 227),
  509. }
  510. if color_name in color_name_value:
  511. buf = [self.command["open_rgb_led"]]
  512. buf.append(1 if enable else 0)
  513. buf.append(led_command)
  514. buf.extend(color_name_value[color_name])
  515. buf.extend(
  516. [
  517. brightness,
  518. 1 if mode == "loop" else 2,
  519. times,
  520. int(interval * 10),
  521. ]
  522. )
  523. self.add_send_data_queue(buf)
  524. def getDeviationInfo(self):
  525. # await asyncio.sleep(0.01)
  526. try:
  527. # 发送获取偏移量
  528. data = [self.command["get_deviation"], 1]
  529. self.add_send_data_queue(data)
  530. # if self.serial_ins:
  531. # self.serial_ins.write_cmd(data)
  532. print("发送获取偏移量")
  533. logger.info("发送获取偏移量")
  534. except Exception as e:
  535. print(e)
  536. print("getDeviationInfo", "暂未获取到self.command")
  537. logger.info("getDeviationInfo暂未获取到self.command")
  538. def set_deviation(self, device_name, _type=0, deviation=0):
  539. # turntable----0 angle_ratio 1 turntable_steering_deviation
  540. # overturn ----0 middle 1 high
  541. if device_name == "camera_high_motor":
  542. deviation = deviation / 10 # deviation 原单位为mm
  543. if device_name == "turntable_position_motor":
  544. deviation = deviation / 10 # deviation 原单位为mm
  545. if device_name == "camera_steering":
  546. pass
  547. if device_name == "turntable_steering":
  548. pass
  549. if device_name == "overturn_steering":
  550. pass
  551. device_id = self.device_name_dict[device_name]
  552. _dir = 1 if deviation >= 0 else 0
  553. deviation = int(abs(deviation * 10))
  554. data = [
  555. self.command["set_deviation"],
  556. device_id,
  557. _type,
  558. _dir,
  559. 0xFF & deviation >> 8,
  560. 0xFF & deviation,
  561. ]
  562. self.add_send_data_queue(data)
  563. # self.controlDevice(device_name, deviation)
  564. async def set_deviation_cmd(self, value, action_name, type):
  565. await asyncio.sleep(0.01)
  566. name_sets = [
  567. "相机电机", # min 0 max 400,步长1
  568. "相机舵机", # min -40 max 40,步长0.1
  569. "转盘舵机", # min -720 max 720,步长1
  570. "转盘前后电机", # min 0 max 950,步长1
  571. "翻板舵机中位", # min 0 max 180,步长0.5
  572. "翻板舵机高位", # min 0 max 180,步长0.5
  573. "翻板舵机上升速度", # min 1 max 10,步长1
  574. "翻板舵机下降速度", # min 1 max 10,步长1
  575. "相机焦段", # min 1 max 10,步长1
  576. ]
  577. if action_name not in name_sets:
  578. self.msg_type = f"{type}_deviation"
  579. self.sendSocketMessage(msg="设置参数有误,请检查", device_status=0, code=1)
  580. self.msg_type = "mcu"
  581. return
  582. # 发送获取偏移量
  583. if type == "move":
  584. self.mcu_deviation_set.change_value(value, action_name)
  585. elif type == "set":
  586. self.mcu_deviation_set.set_deviation(action_name)
  587. self.msg_type = f"{type}_deviation"
  588. self.sendSocketMessage(msg=f"{action_name} 设置成功", device_status=2, code=0)
  589. self.msg_type = "mcu"
  590. def get_other_info(self):
  591. # 发送获取偏移量
  592. data = [self.command["get_other_info"], 1]
  593. self.add_send_data_queue(data)
  594. print("发送获取其他信息")
  595. logger.info("发送获取其他信息")
  596. def add_send_data_queue(self, data):
  597. self.lock.acquire()
  598. if self.serial_ins:
  599. print("send_data_queue append :{}".format(data))
  600. logger.info("send_data_queue append %s", data)
  601. self.send_data_queue.append(data)
  602. self.lock.release()
  603. async def send_all_cmd(self):
  604. # await asyncio.sleep(0.001)
  605. while True:
  606. await asyncio.sleep(0.1)
  607. if self.send_data_queue:
  608. # self.sendSocketMessage(msg="正在发送命令", device_status=1)
  609. data = self.send_data_queue.pop(0)
  610. # print("\033[1;32;40m 正在发送命令 \033[0m",data)
  611. self.serial_ins.write_cmd(data)
  612. # self.sendSocketMessage(msg="命令发送完成", device_status=2)
  613. else:
  614. break
  615. def send_cmd(self):
  616. self.lock.acquire()
  617. if self.send_data_queue:
  618. # self.sendSocketMessage(msg="正在发送命令", device_status=1)
  619. data = self.send_data_queue.pop(0)
  620. self.serial_ins.write_cmd(data)
  621. # self.sendSocketMessage(msg="命令发送完成", device_status=2)
  622. else:
  623. # self.t_n += 1
  624. # 加大发送获取基础数据的时间间隔
  625. # 默认为0.01秒一个循环,每隔1.5秒发送数据
  626. if self.t_n == 150:
  627. # self.t_n = 0
  628. self.send_get_all_info_to_mcu()
  629. self.lock.release()
  630. def send_get_all_info_to_mcu(self):
  631. if self.is_get_mcu_state is False:
  632. return
  633. if self.serial_ins is None:
  634. logger.info("串口未连接,跳过发送获取全部信息命令")
  635. return
  636. data = [self.command["get_all_info"], 1]
  637. try:
  638. self.serial_ins.write_cmd(data)
  639. except Exception as e:
  640. logger.info(f"发送获取全部信息命令失败:{e}")
  641. def print_mcu_error_data(self, receive_data):
  642. # 扫码数据
  643. try:
  644. data = receive_data[1:].decode()
  645. if "设备初始化完成" in data:
  646. self.init_state = True
  647. logger.info(f"设备初始化完成:%{data}")
  648. self.sendSocketMessage(msg=data, device_status=2)
  649. else:
  650. # print("设备异常数据打印:", data)
  651. logger.info(f"115 设备异常数据打印:%{data}")
  652. current_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
  653. msg_data = {
  654. "message": data,
  655. "current_time": current_time
  656. }
  657. self.msg_type = "print_mcu_error_data"
  658. self.sendSocketMessage(msg="设备信息打印", data=msg_data, device_status=2)
  659. self.msg_type = "mcu"
  660. except BaseException as e:
  661. print("117 error {}".format(e))
  662. logger.info(f"117 error %{e}")
  663. return
  664. def print_mcu_noraml_data(self, receive_data):
  665. # 扫码数据
  666. print("接收到255数据:", receive_data)
  667. try:
  668. command_mapping = {
  669. 1: "设备运动",
  670. 2: "初始化设备", # 初始化设备
  671. 3: "处理其他设备", # 处理其他设备
  672. 29: "获取所有信息", # 获取所有信息
  673. 40: "设置偏移量", # 设置偏移量
  674. 41: "读取偏移量", # 读取偏移量
  675. 91: "信号转发处理", # 信号转发处理
  676. 92: "信号转发返回", # 信号转发返回
  677. 44: "获取其他信息", # 获取其他信息
  678. 43: "RGB灯的处理与通讯", ## RGB灯的处理与通讯
  679. 45: "设置其他信息", # 设置其他信息
  680. 47: "查询遥控器电量", # 查询遥控器电量
  681. 48: "设置转盘通讯方式 1、串口、2、无线、3 混合", #
  682. 93: "停止运行mcu", # 停止运行mcu
  683. 90: "连接MCU", # 连接MCU
  684. }
  685. # command = int(receive_data[0])
  686. command = int(receive_data[1])
  687. command_text = command_mapping[command]
  688. # receive_data_temp = receive_data[2:]
  689. receive_data_temp_text = " ".join([hex(x) for x in receive_data])
  690. # print("255 command_text:", command_text)
  691. if command_text in ["设备运动", "处理其他设备"]:
  692. device_id = int(receive_data[2])
  693. device_value = int(receive_data[3])
  694. device_name_info = self.device_name_dict_mapping[device_id]
  695. message_info = {"设备名称": device_name_info, "运动值": device_value}
  696. print("【设备运动】消息回执:", message_info)
  697. logger.info(f"设备运动消息回执:{message_info}")
  698. print("接收设备消息回执:", command_text)
  699. logger.info(f"接收设备消息回执:{receive_data_temp_text}")
  700. except BaseException as e:
  701. print(f"255 error {e}")
  702. logger.info(f"255 error {e}")
  703. return
  704. def get_from_mcu_move_respond_data(self, receive_data):
  705. self.last_from_mcu_move_respond_data = receive_data
  706. def get_from_mcu_connect_info(self, receive_data):
  707. connect_flag = receive_data[1]
  708. device_id = receive_data[2]
  709. try:
  710. mcu_has_been_set = receive_data[6] # 设备是否有初始化 ,1 表示已初始化
  711. except:
  712. mcu_has_been_set = 99 # 未知状态
  713. # self.self_sign.emit({"type": "connect_sign", "data": connect_flag})
  714. message = {"type": "connect_sign", "data": connect_flag}
  715. self.sendSocketMessage(msg="接收连接信息", data=message)
  716. print("接收链接信息")
  717. logger.info("接收链接信息")
  718. return
  719. def to_init_device_origin_point(self, device_name, is_force=False):
  720. device_id = self.device_name_dict[device_name]
  721. cmd = 2
  722. data = [cmd, device_id, 0 if is_force is False else 1]
  723. self.open_rgb_led(color_name="红色")
  724. self.add_send_data_queue(data)
  725. if device_name == "mcu":
  726. # 重置初始化标记为 从未初始化
  727. self.is_just_init_time = False
  728. return
  729. def set_stepper_disable(self, device_name, flag):
  730. if device_name in self.device_name_dict:
  731. device_id = self.device_name_dict[device_name]
  732. buf = [self.command["set_stepper_disable"],
  733. device_id,
  734. 1 if flag else 0,
  735. ]
  736. self.add_send_data_queue(buf)
  737. def to_recheck_focal(self, device_name, is_force=False):
  738. # 重新校准对焦圈
  739. device_id = self.device_name_dict[device_name]
  740. cmd = 2
  741. data = [cmd, device_id, 1]
  742. self.add_send_data_queue(data)
  743. return True
  744. # 设置其他信息
  745. def set_to_mcu_other_info(self, data):
  746. is_auto_send_base_info = data["is_auto_send_base_info"]
  747. is_move_retry = data["is_move_retry"]
  748. is_data_response = data["is_data_response"]
  749. low_speed = data["low_speed"]
  750. is_test = data["is_test"]
  751. to_init_mode = data["to_init_mode"]
  752. turntable_move_to_init_mode = data["turntable_move_to_init_mode"]
  753. led_count = data["led_count"]
  754. turntable_steering_angle_ratio = data["turntable_steering_angle_ratio"]
  755. is_manual_check = data["is_manual_check"]
  756. camera_steering_angle_ratio = data["camera_steering_angle_ratio"]
  757. is_auto_motor_to_disable = data["is_auto_motor_to_disable"]
  758. diff_dir = data["diff_dir"]
  759. is_auto_send_pos_info = data["is_auto_send_pos_info"]
  760. is_dog = data["is_dog"]
  761. has_been_set_motor_config = data["has_been_set_motor_config"]
  762. buf = [self.command["set_other_info"]]
  763. buf.extend(self.encapsulation_data(data=is_auto_send_base_info, len_data=1))
  764. buf.extend(self.encapsulation_data(data=is_move_retry, len_data=1))
  765. buf.extend(self.encapsulation_data(data=is_data_response, len_data=1))
  766. buf.extend(self.encapsulation_data(data=low_speed, len_data=2))
  767. buf.extend(self.encapsulation_data(data=is_test, len_data=1))
  768. buf.extend(self.encapsulation_data(data=to_init_mode, len_data=1))
  769. buf.extend(
  770. self.encapsulation_data(data=turntable_move_to_init_mode, len_data=1)
  771. )
  772. buf.extend(self.encapsulation_data(data=led_count, len_data=2))
  773. buf.extend(
  774. self.encapsulation_data(data=turntable_steering_angle_ratio, len_data=2)
  775. )
  776. buf.extend(self.encapsulation_data(data=is_manual_check, len_data=1))
  777. buf.extend(
  778. self.encapsulation_data(data=camera_steering_angle_ratio, len_data=4)
  779. )
  780. buf.extend(self.encapsulation_data(data=is_auto_motor_to_disable, len_data=1))
  781. buf.extend(self.encapsulation_data(data=diff_dir, len_data=1))
  782. buf.extend(self.encapsulation_data(data=is_auto_send_pos_info, len_data=1))
  783. buf.extend(self.encapsulation_data(data=is_dog, len_data=1))
  784. buf.extend(self.encapsulation_data(data=has_been_set_motor_config, len_data=1))
  785. self.add_send_data_queue(buf)
  786. async def cleanAllReceiveData(self):
  787. while True:
  788. await asyncio.sleep(0.001)
  789. receive_data = self.serial_ins.read_cmd(out_time=1)
  790. if not receive_data:
  791. break
  792. def get_basic_info_mcu(self):
  793. receive_data = self.serial_ins.read_cmd(out_time=1)
  794. if receive_data is False:
  795. logger.info("get_basic_info_mcu,------------------------------------------------4657564654")
  796. self.connect_state = False
  797. return False
  798. if not receive_data:
  799. return False
  800. command = receive_data[0]
  801. logger.info(f"get_basic_info_mcu{command}")
  802. if command in self.deal_code_func_dict:
  803. _data = ' '.join([hex(x) for x in receive_data])
  804. return self.deal_code_func_dict[command](receive_data)
  805. return False
  806. def get_from_mcu_button(self, receive_data):
  807. button_name = receive_data[1]
  808. self.deal_mcu_button(button_name)
  809. def deal_mcu_button(self, button_name):
  810. # 防止重复点击
  811. s = time.time()
  812. if s - self.last_push_time[button_name] > 0.1:
  813. self.last_push_time[button_name] = s
  814. # print("button_name", button_name)
  815. else:
  816. self.last_push_time[button_name] = s
  817. return
  818. if button_name == 1:
  819. # 自动执行全部
  820. # self.sign_data.emit(
  821. # {"_type": "mcu_button", "plugins_mode": "mcu", "data": "todo_1"}
  822. # )
  823. message = {"_type": "mcu_button", "plugins_mode": "mcu", "data": "todo_1"}
  824. self.sendSocketMessage(code=0, msg="", data=message)
  825. if button_name == 2:
  826. # self.sign_data.emit(
  827. # {"_type": "mcu_button", "plugins_mode": "mcu", "data": "todo_2"}
  828. # )
  829. message = {"_type": "mcu_button", "plugins_mode": "mcu", "data": "todo_2"}
  830. self.sendSocketMessage(code=0, msg="", data=message)
  831. if button_name == 3:
  832. # self.sign_data.emit(
  833. # {"_type": "mcu_button", "plugins_mode": "mcu", "data": "todo_3"}
  834. # )
  835. message = {"_type": "mcu_button", "plugins_mode": "mcu", "data": "todo_3"}
  836. self.sendSocketMessage(code=0, msg="", data=message)
  837. # 获取偏移量信息
  838. def get_from_mcu_deviation_info(self, receive_data):
  839. if len(receive_data) == 18:
  840. camera_high_motor_deviation_dir = receive_data[1]
  841. camera_high_motor_deviation = receive_data[2] << 8 | receive_data[3]
  842. camera_high_motor_deviation = (
  843. camera_high_motor_deviation * -1
  844. if camera_high_motor_deviation_dir == 0
  845. else camera_high_motor_deviation
  846. )
  847. camera_steering_deviation_dir = receive_data[4]
  848. camera_steering_deviation = (receive_data[5] << 8 | receive_data[6]) * 0.1
  849. camera_steering_deviation = (
  850. camera_steering_deviation * -1
  851. if camera_steering_deviation_dir == 0
  852. else camera_steering_deviation
  853. )
  854. turntable_steering_deviation_dir = receive_data[7]
  855. turntable_steering_deviation = (
  856. receive_data[8] << 8 | receive_data[9]
  857. ) * 0.1
  858. turntable_steering_deviation = (
  859. turntable_steering_deviation * -1
  860. if turntable_steering_deviation_dir == 0
  861. else turntable_steering_deviation
  862. )
  863. overturn_steering_middle_dir = receive_data[10]
  864. overturn_steering_middle = (receive_data[11] << 8 | receive_data[12]) * 0.1
  865. overturn_steering_middle = (
  866. overturn_steering_middle * -1
  867. if overturn_steering_middle_dir == 0
  868. else overturn_steering_middle
  869. )
  870. overturn_steering_high_dir = receive_data[13]
  871. overturn_steering_high = (receive_data[14] << 8 | receive_data[15]) * 0.1
  872. overturn_steering_high = (
  873. overturn_steering_middle * -1
  874. if overturn_steering_high_dir == 0
  875. else overturn_steering_high
  876. )
  877. overturn_steering_up_speed = receive_data[16]
  878. overturn_steering_down_speed = receive_data[17]
  879. self.camera_high_motor_deviation_offset = camera_high_motor_deviation
  880. get_deviation_data = {
  881. "camera_high_motor_deviation": camera_high_motor_deviation,
  882. "camera_steering_deviation": camera_steering_deviation,
  883. "turntable_steering_deviation": turntable_steering_deviation,
  884. "turntable_front_end_deviation": 300,
  885. "overturn_steering_middle": overturn_steering_middle,
  886. "overturn_steering_high": overturn_steering_high,
  887. "overturn_steering_up_speed": overturn_steering_up_speed,
  888. "overturn_steering_down_speed": overturn_steering_down_speed,
  889. }
  890. self.initDeviationInfo(get_deviation_data)
  891. self.msg_type = "get_deviation_data"
  892. self.sendSocketMessage(msg="接收偏移量信息", data=get_deviation_data)
  893. self.msg_type = "mcu"
  894. print("接收偏移量信息", get_deviation_data)
  895. logger.info("接收偏移量信息")
  896. return
  897. def initDeviationInfo(self, get_deviation_data):
  898. # 初始化偏移量信息
  899. camera_high_motor_deviation = get_deviation_data["camera_high_motor_deviation"]
  900. camera_steering_deviation = get_deviation_data["camera_steering_deviation"]
  901. turntable_steering_deviation = get_deviation_data[
  902. "turntable_steering_deviation"
  903. ]
  904. overturn_steering_middle = get_deviation_data["overturn_steering_middle"]
  905. overturn_steering_high = get_deviation_data["overturn_steering_high"]
  906. overturn_steering_up_speed = get_deviation_data["overturn_steering_up_speed"]
  907. overturn_steering_down_speed = get_deviation_data[
  908. "overturn_steering_down_speed"
  909. ]
  910. self.mcu_deviation_set.last_value["相机电机"] = camera_high_motor_deviation
  911. self.mcu_deviation_set.last_value["相机舵机"] = camera_steering_deviation
  912. self.mcu_deviation_set.last_value["转盘舵机"] = turntable_steering_deviation
  913. self.mcu_deviation_set.last_value["翻板舵机中位"] = overturn_steering_middle
  914. self.mcu_deviation_set.last_value["翻板舵机高位"] = overturn_steering_high
  915. self.mcu_deviation_set.last_value["翻板舵机上升速度"] = (
  916. overturn_steering_up_speed
  917. )
  918. self.mcu_deviation_set.last_value["翻板舵机下降速度"] = (
  919. overturn_steering_down_speed
  920. )
  921. # 获取其他信息
  922. def get_from_mcu_other_info(self, receive_data):
  923. # TODO 已完成设置
  924. is_auto_send_base_info = self.get_data_from_receive_data(
  925. receive_data=receive_data, start=1, len_data=1
  926. )
  927. is_move_retry = self.get_data_from_receive_data(
  928. receive_data=receive_data, start=2, len_data=1
  929. )
  930. is_data_response = self.get_data_from_receive_data(
  931. receive_data=receive_data, start=3, len_data=1
  932. )
  933. low_speed = self.get_data_from_receive_data(
  934. receive_data=receive_data, start=4, len_data=2
  935. )
  936. is_test = self.get_data_from_receive_data(
  937. receive_data=receive_data, start=6, len_data=1
  938. )
  939. to_init_mode = self.get_data_from_receive_data(
  940. receive_data=receive_data, start=7, len_data=1
  941. )
  942. turntable_move_to_init_mode = self.get_data_from_receive_data(
  943. receive_data=receive_data, start=8, len_data=1
  944. )
  945. led_count = self.get_data_from_receive_data(
  946. receive_data=receive_data, start=9, len_data=2
  947. )
  948. turntable_steering_angle_ratio = self.get_data_from_receive_data(
  949. receive_data=receive_data, start=11, len_data=2
  950. )
  951. is_manual_check = self.get_data_from_receive_data(
  952. receive_data=receive_data, start=13, len_data=1
  953. )
  954. camera_steering_angle_ratio = self.get_data_from_receive_data(
  955. receive_data=receive_data, start=14, len_data=4
  956. )
  957. is_auto_motor_to_disable = self.get_data_from_receive_data(
  958. receive_data=receive_data, start=18, len_data=1
  959. )
  960. diff_dir = self.get_data_from_receive_data(
  961. receive_data=receive_data, start=19, len_data=1
  962. )
  963. is_auto_send_pos_info = self.get_data_from_receive_data(
  964. receive_data=receive_data, start=20, len_data=1
  965. )
  966. is_dog = self.get_data_from_receive_data(
  967. receive_data=receive_data, start=21, len_data=1
  968. )
  969. has_been_set_motor_config = self.get_data_from_receive_data(
  970. receive_data=receive_data, start=22, len_data=1
  971. )
  972. self.last_mcu_other_info_data["data"] = {
  973. "is_auto_send_base_info": is_auto_send_base_info,
  974. "is_move_retry": is_move_retry,
  975. "is_data_response": is_data_response,
  976. "low_speed": low_speed,
  977. "is_test": is_test,
  978. "to_init_mode": to_init_mode,
  979. "turntable_move_to_init_mode": turntable_move_to_init_mode,
  980. "led_count": led_count,
  981. "turntable_steering_angle_ratio": turntable_steering_angle_ratio,
  982. "is_manual_check": is_manual_check,
  983. "camera_steering_angle_ratio": camera_steering_angle_ratio,
  984. "is_auto_motor_to_disable": is_auto_motor_to_disable,
  985. "diff_dir": diff_dir,
  986. "is_auto_send_pos_info": is_auto_send_pos_info,
  987. "is_dog": is_dog,
  988. "has_been_set_motor_config": has_been_set_motor_config,
  989. }
  990. self.last_mcu_other_info_data["time"] = time.time()
  991. self.last_mcu_other_info_data["num"] += 1
  992. for k, v in self.last_mcu_other_info_data["data"].items():
  993. print("k:{},v:{}".format(k, v))
  994. logger.info("k:%s,v:%s", k, v)
  995. self.msg_type = "get_mcu_other_info"
  996. self.sendSocketMessage(
  997. code=0,
  998. msg="获取mcu其他配置信息",
  999. device_status=2,
  1000. data=self.last_mcu_other_info_data["data"],
  1001. )
  1002. self.msg_type = "mcu"
  1003. def get_data_from_receive_data(
  1004. self, receive_data, start, len_data, data_magnification=1
  1005. ):
  1006. # data_magnification 数据放大倍数,或缩小倍数,默认为1
  1007. try:
  1008. if len_data == 1:
  1009. data = receive_data[start]
  1010. return data * data_magnification
  1011. elif len_data == 2:
  1012. data = receive_data[start] << 8 | receive_data[start + 1]
  1013. return data * data_magnification
  1014. elif len_data == 4:
  1015. data = (
  1016. receive_data[start] << 24
  1017. | receive_data[start + 1] << 16
  1018. | receive_data[start + 2] << 8
  1019. | receive_data[start + 3]
  1020. )
  1021. return data * data_magnification
  1022. return None
  1023. except:
  1024. return None
  1025. def get_from_mcu_base_info(self, receive_data):
  1026. # 数据缓存
  1027. self.last_mcu_info_data["time"] = time.time()
  1028. self.last_mcu_info_data["num"] += 1
  1029. # print("last_mcu_info_data:{}".format(self.last_mcu_info_data["time"]))
  1030. self.state_camera_motor = 3
  1031. self.state_camera_steering = 3
  1032. self.state_turntable_steering = 3
  1033. self.state_overturn_steering = 3
  1034. self.state_move_turntable_steering = 3
  1035. if len(receive_data) == 7:
  1036. self.m_t = 1
  1037. laser_state = receive_data[1]
  1038. self.state_camera_motor = receive_data[2]
  1039. self.state_camera_steering = receive_data[3]
  1040. self.state_turntable_steering = receive_data[4]
  1041. self.state_overturn_steering = receive_data[5]
  1042. flag = receive_data[6]
  1043. message = {
  1044. "_type": "show_mcu_info",
  1045. "plugins_mode": "mcu",
  1046. "data": "激光状态;{laser_state},相机高度状态:{state_camera_motor},相机角度状态:{state_camera_steering},转盘状态:{state_turntable_steering},翻板状态:{state_overturn_steering},flag:{flag}".format(
  1047. laser_state=laser_state,
  1048. state_camera_motor=self.state_camera_motor,
  1049. state_camera_steering=self.state_camera_steering,
  1050. state_turntable_steering=self.state_turntable_steering,
  1051. state_overturn_steering=self.state_overturn_steering,
  1052. flag=flag,
  1053. ),
  1054. "data_state": {
  1055. "state_camera_motor": self.state_camera_motor,
  1056. "state_camera_steering": self.state_camera_steering,
  1057. "state_turntable_steering": self.state_turntable_steering,
  1058. "state_overturn_steering": self.state_overturn_steering,
  1059. },
  1060. }
  1061. self.msg_type = "get_mcu_info"
  1062. self.sendSocketMessage(msg="获取mcu设备运行状态信息", data=message)
  1063. self.msg_type = "mcu"
  1064. # print("转盘:{},时间:{}".format(self.state_turntable_steering, time.time()))
  1065. if len(receive_data) == 8:
  1066. self.m_t = 2
  1067. laser_state = receive_data[1]
  1068. self.state_camera_motor = receive_data[2]
  1069. self.state_camera_steering = receive_data[3]
  1070. self.state_turntable_steering = receive_data[4]
  1071. self.state_overturn_steering = receive_data[5]
  1072. self.state_move_turntable_steering = receive_data[6]
  1073. flag = receive_data[7]
  1074. message = {
  1075. "_type": "show_mcu_info",
  1076. "plugins_mode": "mcu",
  1077. "data": "激光状态;{laser_state},相机高度状态:{state_camera_motor},相机角度状态:{state_camera_steering},转盘状态:{state_turntable_steering},转盘前后移动状态:{state_move_turntable_steering},翻板状态:{state_overturn_steering},flag:{flag}".format(
  1078. laser_state=laser_state,
  1079. state_camera_motor=self.state_camera_motor,
  1080. state_camera_steering=self.state_camera_steering,
  1081. state_turntable_steering=self.state_turntable_steering,
  1082. state_overturn_steering=self.state_overturn_steering,
  1083. state_move_turntable_steering=self.state_move_turntable_steering,
  1084. flag=flag,
  1085. ),
  1086. "data_state": {
  1087. "state_camera_motor": self.state_camera_motor,
  1088. "state_camera_steering": self.state_camera_steering,
  1089. "state_turntable_steering": self.state_turntable_steering,
  1090. "state_overturn_steering": self.state_overturn_steering,
  1091. "state_move_turntable_steering": self.state_move_turntable_steering,
  1092. },
  1093. }
  1094. # if self.state_camera_motor
  1095. if all(
  1096. value == 2
  1097. for value in [
  1098. self.state_camera_motor,
  1099. self.state_camera_steering,
  1100. self.state_turntable_steering,
  1101. self.state_overturn_steering,
  1102. ]
  1103. ):
  1104. self.init_state = True
  1105. self.sendSocketMessage(msg="设备初始化完成", device_status=2)
  1106. self.msg_type = "get_mcu_info"
  1107. self.sendSocketMessage(msg="获取mcu设备运行状态信息", data=message)
  1108. self.msg_type = "mcu"
  1109. # 检查是否成功初始化
  1110. if self.is_just_init_time is False:
  1111. if self.mcu_move_state == 2:
  1112. self.is_just_init_time = True
  1113. print("is_just_init_time")
  1114. logger.info("设备初始化完成")
  1115. message = {
  1116. "_type": "is_just_init_time",
  1117. "plugins_mode": "mcu",
  1118. "data": "",
  1119. }
  1120. self.sendSocketMessage(msg="检查设备初始化", data=message)
  1121. return
  1122. def scan_serial_port(self) -> dict:
  1123. # 获取所有可用串口列表
  1124. ports_dict = {}
  1125. ports = serial.tools.list_ports.comports()
  1126. # 遍历所有端口并打印信息
  1127. for port in ports:
  1128. # logger.info("扫描到的串口信息:{}".format(port.description))
  1129. if "CH34" in port.description:
  1130. ports_dict[port.name] = {
  1131. "name": port.name,
  1132. "device": port.device,
  1133. "description": port.description,
  1134. "hwid": port.hwid,
  1135. "manufacturer": port.manufacturer,
  1136. "product": port.product,
  1137. "serial_number": port.serial_number,
  1138. }
  1139. elif "Prolific USB-to-Serial Comm Port" in port.description:
  1140. ports_dict[port.name] = {
  1141. "name": port.name,
  1142. "device": port.device,
  1143. "description": port.description,
  1144. "hwid": port.hwid,
  1145. "manufacturer": port.manufacturer,
  1146. "product": port.product,
  1147. "serial_number": port.serial_number,
  1148. }
  1149. if len(ports_dict) <= 0:
  1150. return {}
  1151. return ports_dict
  1152. def remove_port(self, port_name):
  1153. """移除串口"""
  1154. print("remove", port_name)
  1155. logger.info("串口被移除")
  1156. data = {
  1157. "_type": "remove_port",
  1158. "plugins_mode": "auto_select_com",
  1159. "data": {"port_name": port_name},
  1160. }
  1161. self.sendSocketMessage(1, "串口被移除", data)
  1162. def is_serial_available(self, port):
  1163. try:
  1164. ser = serial.Serial(port)
  1165. ser.close()
  1166. return True
  1167. except serial.serialException:
  1168. return False
  1169. async def add_port_by_linkage(self, port_name, _port_value):
  1170. # port_value :串口基础信息
  1171. # todo 根据prot_value 信息自动进行连接
  1172. print("add port_name", port_name)
  1173. print("add port_value", _port_value)
  1174. logger.info("add port_name %s", port_name)
  1175. print("self.port_name", self.port_name)
  1176. logger.info("self.port_name %s", self.port_name)
  1177. if self.port_name == port_name:
  1178. self.port_name = ""
  1179. # 对没有连接的设备进行尝试连接
  1180. # 如果存在串口被占用则进行断开
  1181. self.is_serial_available(port_name)
  1182. return False
  1183. message_data = {
  1184. "_type": "show_info",
  1185. "plugins_mode": "auto_select_com",
  1186. "data": {"text": "开始识别接口:{}".format(port_name)},
  1187. }
  1188. self.sendSocketMessage(
  1189. msg="开始识别接口:{}".format(port_name), data=message_data, device_status=1
  1190. )
  1191. await asyncio.sleep(1)
  1192. """
  1193. 步骤:
  1194. 1、进行临时连接,并发送命令,成功后,自动连接对应设备
  1195. """
  1196. try:
  1197. # 尝试使用115200波特率链接
  1198. serial_handle = serial.Serial(port=port_name, baudrate=115200, timeout=0.5)
  1199. except Exception as e:
  1200. message_data = {
  1201. "_type": "show_info",
  1202. "plugins_mode": "auto_select_com",
  1203. "data": {"text": "串口:{} 被占用,或无法识别".format(port_name)},
  1204. }
  1205. self.sendSocketMessage(
  1206. 1,
  1207. msg="串口:{} 被占用,或无法识别".format(port_name).format(port_name),
  1208. data=message_data,
  1209. device_status=-1,
  1210. )
  1211. print("串口:{} 被占用".format(port_name))
  1212. logger.info("串口:%s 被占用", port_name)
  1213. if self.serial_ins.serial_handle is not None:
  1214. self.serial_ins.serial_handle.close()
  1215. return False
  1216. await asyncio.sleep(2)
  1217. print("开始发送命令")
  1218. logger.info("开始发送命令")
  1219. data = [90, 1]
  1220. try:
  1221. serial_handle.flushInput() # 尝试重置输入缓冲区
  1222. except serial.SerialTimeoutException:
  1223. print("超时错误:无法在规定时间内重置输入缓冲区。")
  1224. logger.info("超时错误:无法在规定时间内重置输入缓冲区。")
  1225. self.sendSocketMessage(
  1226. 1,
  1227. msg="超时错误:无法在规定时间内重置输入缓冲区。",
  1228. data=None,
  1229. )
  1230. serial_handle.close()
  1231. return False
  1232. print("尝试写入数据")
  1233. logger.info("尝试写入数据")
  1234. buf = bytearray(b"")
  1235. buf.extend([0x55, 0x55, (0xFF & len(data))])
  1236. buf.extend(data)
  1237. buf.extend([0xFF & ~sum(data)])
  1238. try:
  1239. self.receive_data = b""
  1240. serial_handle.write(buf)
  1241. except serial.SerialTimeoutException:
  1242. print("写入数据错误")
  1243. logger.info("写入数据错误")
  1244. serial_handle.close()
  1245. return False
  1246. await asyncio.sleep(0.3)
  1247. receive_data = self.read_cmd(serial_handle)
  1248. # print("尝试接收命令", receive_data)
  1249. # logger.info("尝试接收命令,%s", receive_data)
  1250. device_id = 0
  1251. if receive_data:
  1252. print("receive_data", receive_data)
  1253. logger.info("receive_data %s", receive_data)
  1254. if receive_data[0] == 90:
  1255. connect_flag = receive_data[1]
  1256. device_id = receive_data[2]
  1257. else:
  1258. if "Prolific USB-to-Serial Comm Port" in _port_value.get('description'):
  1259. # 电子秤不会应答探测命令,收不到数据属正常现象,落到下方统一连接
  1260. pass
  1261. else:
  1262. logger.info("串口数据未监听到,继续等待...%s", port_name)
  1263. return False
  1264. print("关闭串口:{}".format(port_name))
  1265. logger.info("关闭串口:%s", port_name)
  1266. serial_handle.close()
  1267. loop = asyncio.get_event_loop()
  1268. print("device_id============>>>", device_id)
  1269. logger.info("device_id============>>>%s", device_id)
  1270. if device_id > 0:
  1271. if device_id == settings.MCU_CODE:
  1272. state, _ = self.to_connect_com(port_name)
  1273. if not state:
  1274. return False
  1275. message_data = {
  1276. "_type": "show_info",
  1277. "plugins_mode": "auto_select_com",
  1278. "data": {"text": "MCU开始连接"},
  1279. }
  1280. self.sendSocketMessage(
  1281. msg="MCU开始连接", data=message_data, device_status=1
  1282. )
  1283. self.connected_ports_dict[port_name] = "MCU"
  1284. message_data = {
  1285. "_type": "select_port_name",
  1286. "plugins_mode": "auto_select_com",
  1287. "data": {
  1288. "device_name": "mcu" if device_id == 1 else "remote_control",
  1289. "port_name": port_name,
  1290. },
  1291. }
  1292. return True
  1293. elif device_id == 2:
  1294. # 有线接收器
  1295. self.connected_ports_dict[port_name] = "Line_Control"
  1296. # print("device_id", device_id)
  1297. # logger.info("device_id %s", device_id)
  1298. state = await self.line_control.to_connect_com(port_name)
  1299. if not state:
  1300. return False
  1301. self.line_control.connect_state = True
  1302. return True
  1303. else:
  1304. if "Prolific USB-to-Serial Comm Port" in _port_value.get('description'):
  1305. # 探测用的临时串口已在上方 close(Windows同一COM口不能重复打开)
  1306. # probe_connect 内部以9600重新打开并校验安衡协议特征,
  1307. # 确认是电子秤才真正连接,避免误占其他 Prolific 设备的串口
  1308. anheng_scale_ok = self.anheng_scale.probe_connect(port_name, True)
  1309. if not anheng_scale_ok:
  1310. print("安衡电子秤 识别失败(串口打开失败或非电子秤),稍后重试")
  1311. return False
  1312. else:
  1313. print("安衡电子秤 识别成功,串口已打开")
  1314. # 循环推送电子秤数据消息(参考 LineControl 模式:create_task(run()))
  1315. self.anheng_scale.start_run()
  1316. return True
  1317. else:
  1318. print("串口无法识别")
  1319. logger.info("串口无法识别")
  1320. self.sendSocketMessage(
  1321. code=1,
  1322. msg="串口无法识别,请重新插拔拍照机USB",
  1323. data=message_data,
  1324. device_status=-1,
  1325. )
  1326. return False
  1327. # 走其他途径处理
  1328. def clearMyInstance(self):
  1329. SingletonType.clear_instance()
  1330. def to_connect_com(self, port_name):
  1331. # 关闭串口
  1332. print("to_connect_com", port_name)
  1333. logger.info("to_connect_com %s", port_name)
  1334. self.close_connect()
  1335. time.sleep(0.3)
  1336. self.connect_state = False
  1337. try:
  1338. self.serial_ins = SerialIns(port_name=port_name, baud=115200, timeout=0.1)
  1339. if not self.serial_ins.serial_handle:
  1340. message_data = {
  1341. "_type": "show_info",
  1342. "plugins_mode": "mcu",
  1343. "data": "MCU 打开串口失败",
  1344. }
  1345. self.sendSocketMessage(
  1346. msg="MCU 打开串口失败", data=message_data, device_status=-1
  1347. )
  1348. self.serial_ins = None
  1349. self.connect_state = False
  1350. return False, None
  1351. except:
  1352. message_data = {
  1353. "_type": "show_info",
  1354. "plugins_mode": "mcu",
  1355. "data": "MCU 打开串口失败",
  1356. }
  1357. self.sendSocketMessage(
  1358. msg="MCU 打开串口失败", data=message_data, device_status=-1
  1359. )
  1360. self.serial_ins = None
  1361. self.connect_state = False
  1362. return False, None
  1363. message_data = {
  1364. "_type": "show_info",
  1365. "plugins_mode": "mcu",
  1366. "data": "MCU 开始连接",
  1367. }
  1368. self.sendSocketMessage(msg="MCU 开始连接", data=message_data, device_status=1)
  1369. # =======================发送连接请求=================================
  1370. cmd = 90
  1371. data = [cmd, 1]
  1372. print("405 发送 连接请求 -----------------------------------------")
  1373. logger.info("405 发送 连接请求 -----------------------------------------")
  1374. print(self.serial_ins)
  1375. logger.info(self.serial_ins)
  1376. # self.serial_ins.clearn_flush()
  1377. self.serial_ins.write_cmd(data)
  1378. # 延迟接收数据
  1379. time.sleep(0.3)
  1380. receive_data = self.serial_ins.read_cmd(out_time=1)
  1381. if receive_data:
  1382. print(
  1383. "409 receive_data--90:{}".format(self.change_hex_to_int(receive_data))
  1384. )
  1385. logger.info(
  1386. "409 receive_data--90:%s", str(self.change_hex_to_int(receive_data))
  1387. )
  1388. else:
  1389. return False, None
  1390. if receive_data:
  1391. # receive_data[2]=1 表示为MCU设备编号
  1392. if receive_data[0] == 90 and receive_data[2] == settings.MCU_CODE:
  1393. connect_flag = receive_data[1]
  1394. # 是否有初始化
  1395. try:
  1396. mcu_has_been_set = receive_data[
  1397. 6
  1398. ] # 设备是否有初始化 ,1 表示已初始化
  1399. except:
  1400. mcu_has_been_set = 99 # 未知状态
  1401. print("MCU初始化信息{}".format(mcu_has_been_set))
  1402. logger.info("MCU初始化信息%s", str(mcu_has_been_set))
  1403. message_data = {
  1404. "_type": "show_info",
  1405. "plugins_mode": "mcu",
  1406. "data": "MCU 已连接",
  1407. }
  1408. self.sendSocketMessage(
  1409. msg="MCU 已连接", data=message_data, device_status=1
  1410. )
  1411. self.connect_state = True
  1412. self.is_running = True
  1413. print("MCU 已连接")
  1414. logger.info("MCU 已连接")
  1415. self.port_name = port_name
  1416. # time.sleep(2)
  1417. loop = asyncio.get_event_loop()
  1418. # # 异步处理
  1419. loop.create_task(self.initDevice(), name="initDevice")
  1420. return True, None
  1421. print("MCU 连接失败")
  1422. logger.info("MCU 连接失败")
  1423. # for port in self.p_list:
  1424. # logger.info(
  1425. # "MCU 连接失败处理list移除操作,self port name %s,p_list:%s",
  1426. # port_name,
  1427. # self.p_list,
  1428. # )
  1429. # if port == port_name:
  1430. # logger.info("MCU 连接失败处理list移除操作,移除 %s", port_name)
  1431. # self.p_list.remove(port)
  1432. # self.remove_port(port)
  1433. message_data = {
  1434. "_type": "show_info",
  1435. "plugins_mode": "mcu",
  1436. "data": "MCU 连接失败",
  1437. }
  1438. self.sendSocketMessage(msg="MCU 连接失败", data=message_data, device_status=-1)
  1439. self.close_connect()
  1440. return False, None
  1441. def close_connect(self):
  1442. self.port_name = ""
  1443. if self.serial_ins:
  1444. self.serial_ins.close_serial_port()
  1445. self.is_running = False
  1446. self.connect_state = False
  1447. self.connected_ports_dict = {} # 已连接的ports
  1448. # self.p_list = []
  1449. # self.temp_ports_dict = {}
  1450. self.init_state = False
  1451. print("关闭MCU")
  1452. logger.info("关闭MCU")
  1453. def close_lineConnect(self):
  1454. """'关闭有线遥控器连接"""
  1455. self.line_control.port_name = ""
  1456. self.line_control.close_connect()
  1457. print("关闭有线遥控器")
  1458. logger.info("关闭有线遥控器")
  1459. def close_anheng_scale(self):
  1460. self.anheng_scale.disconnect()
  1461. @property
  1462. def mcu_move_state(self):
  1463. if self.is_get_mcu_state is False:
  1464. self._mcu_move_state = 2
  1465. # self.action_state = 2
  1466. else:
  1467. if self.m_t == 1:
  1468. if (
  1469. self.state_camera_motor == 2
  1470. and self.state_camera_steering == 2
  1471. and self.state_turntable_steering == 2
  1472. and self.state_overturn_steering == 2
  1473. ):
  1474. self._mcu_move_state = 2
  1475. else:
  1476. self._mcu_move_state = 1
  1477. else:
  1478. if (
  1479. self.state_camera_motor == 2
  1480. and self.state_camera_steering == 2
  1481. and self.state_turntable_steering == 2
  1482. and self.state_overturn_steering == 2
  1483. and self.state_move_turntable_steering == 2
  1484. ):
  1485. self._mcu_move_state = 2
  1486. else:
  1487. self._mcu_move_state = 1
  1488. # self._mcu_move_state = 2
  1489. return self._mcu_move_state
  1490. def to_deal_device(self, device_name, value=1, _type=0, times=1, delay=0):
  1491. """
  1492. value 激光0关 1开
  1493. mp3_player value 表示0表示关,1表示开,_type 表示歌曲切换到指定歌曲
  1494. delay:延迟处理,单位为0.1秒,即delay=100时,表示延迟10秒
  1495. """
  1496. device_id = self.device_name_dict[device_name]
  1497. if device_name == "buzzer":
  1498. value = int(value)
  1499. cmd = 3
  1500. data = [
  1501. cmd,
  1502. device_id,
  1503. value,
  1504. _type,
  1505. times,
  1506. delay,
  1507. ]
  1508. self.add_send_data_queue(data)
  1509. # if self.serial_ins:
  1510. # self.serial_ins.write_cmd(data)
  1511. return True
  1512. def to_device_move(
  1513. self,
  1514. device_name,
  1515. value=0,
  1516. max_speed=None,
  1517. up_speed=None,
  1518. down_speed=None,
  1519. _is_debug=0,
  1520. is_relative=0,
  1521. is_deviation=1,
  1522. times=2, is_response=False
  1523. ):
  1524. """
  1525. 此处输入单位为 毫米,以及度 需要先缩小,再放大
  1526. """
  1527. self.seed += 1
  1528. if self.seed > 9000:
  1529. self.seed = 1
  1530. print("移动", time.time())
  1531. logger.info("移动,%s", time.time())
  1532. speed = settings.moveSpeed()
  1533. cmd = 1
  1534. device_id = self.device_name_dict[device_name]
  1535. # if device_id != 1:
  1536. # print("F非MCU设备,禁止处理")
  1537. # return
  1538. print("正在执行", device_name)
  1539. logger.info("正在执行 %s", device_name)
  1540. match device_name:
  1541. case "camera_high_motor":
  1542. # value 单位毫米
  1543. # max_speed = 10000 if max_speed is None else max_speed
  1544. # up_speed = 800 if up_speed is None else up_speed
  1545. # down_speed = 700 if down_speed is None else down_speed
  1546. max_speed = (
  1547. speed[device_name]["max_speed"] if max_speed is None else max_speed
  1548. )
  1549. up_speed = (
  1550. speed[device_name]["up_speed"] if up_speed is None else up_speed
  1551. )
  1552. down_speed = (
  1553. speed[device_name]["down_speed"]
  1554. if down_speed is None
  1555. else down_speed
  1556. )
  1557. value = value / 10 # value 单位毫米
  1558. max_camera_hight = self.camera_height / 10
  1559. # print("高度位置",max_camera_hight)
  1560. if value > max_camera_hight:
  1561. value = max_camera_hight
  1562. assert 0 <= value <= max_camera_hight
  1563. assert 0 <= max_speed <= 10000
  1564. case "camera_steering":
  1565. # 角度为度 未放大 精确到0.1度
  1566. max_speed = 6000 if max_speed is None else max_speed
  1567. up_speed = 500 if up_speed is None else up_speed
  1568. down_speed = 500 if down_speed is None else down_speed
  1569. assert -360 <= value <= 360
  1570. case "turntable_steering":
  1571. # 角度为度 未放大 精确到0.1度
  1572. # max_speed = 6000 if max_speed is None else max_speed
  1573. # up_speed = 500 if up_speed is None else up_speed
  1574. # down_speed = 400 if down_speed is None else down_speed
  1575. max_speed = (
  1576. speed[device_name]["max_speed"] if max_speed is None else max_speed
  1577. )
  1578. up_speed = (
  1579. speed[device_name]["up_speed"] if up_speed is None else up_speed
  1580. )
  1581. down_speed = (
  1582. speed[device_name]["down_speed"]
  1583. if down_speed is None
  1584. else down_speed
  1585. )
  1586. assert -720 <= value <= 720
  1587. case "overturn_steering":
  1588. # 角度为度 未放大 精确到0.1度
  1589. max_speed = 2 if max_speed is None else max_speed
  1590. up_speed = 1 if up_speed is None else up_speed
  1591. down_speed = 1 if down_speed is None else down_speed
  1592. assert 0 <= value <= 360
  1593. case "turntable_position_motor":
  1594. # value 单位毫米
  1595. max_speed = 11000 if max_speed is None else max_speed
  1596. up_speed = 900 if up_speed is None else up_speed
  1597. down_speed = 900 if down_speed is None else down_speed
  1598. value = value / 10 # value 单位毫米
  1599. assert 0 <= value <= 900
  1600. assert 0 <= max_speed <= 15000
  1601. case "camera_zoom_motor":
  1602. # 相机焦段设置
  1603. # 精确到0.1焦段
  1604. max_speed = 500 if max_speed is None else max_speed
  1605. up_speed = 100 if up_speed is None else up_speed
  1606. down_speed = 100 if down_speed is None else down_speed
  1607. assert 0 <= value <= 150
  1608. _dir = True if value >= 0 else False
  1609. value = int(abs(value * 10)) # 此处value赋值后,单位为mm以及0.1度
  1610. print("准备执行", device_name, value)
  1611. logger.info("准备执行,%s %s", device_name, value)
  1612. data = [
  1613. cmd,
  1614. device_id,
  1615. 1 if _dir else 0,
  1616. 0xFF & value >> 8,
  1617. 0xFF & value,
  1618. 0xFF & max_speed >> 8,
  1619. 0xFF & max_speed,
  1620. 0xFF & up_speed >> 8,
  1621. 0xFF & up_speed,
  1622. 0xFF & down_speed >> 8,
  1623. 0xFF & down_speed,
  1624. _is_debug,
  1625. is_deviation,
  1626. is_relative,
  1627. times, # 重试次数
  1628. 0xff & self.seed >> 8, # 随机种子
  1629. 0xff & self.seed, # 随机种子
  1630. 1 if is_response is True else 0, # 是否返回内容
  1631. ]
  1632. self.add_send_data_queue(data)
  1633. current_time = time.time()
  1634. self.last_move_time = current_time
  1635. def to_get_mcu_base_info(self):
  1636. if self.connect_state:
  1637. self.lock.acquire()
  1638. # print('==========================>1111')
  1639. print("-------------------to_get_mcu_base_info--------------------------")
  1640. data = [self.command["get_all_info"], 1]
  1641. f = True
  1642. try:
  1643. self.serial_ins.write_cmd(data)
  1644. except:
  1645. f = False
  1646. pass
  1647. self.lock.release()
  1648. if not f:
  1649. self.connect_state = False
  1650. return False
  1651. else:
  1652. return True
  1653. def check_before_action(self):
  1654. if self.state != 2:
  1655. print("check_before_action 设备正在运行中~")
  1656. logger.info("check_before_action 设备正在运行中~")
  1657. self.sendSocketMessage(code=1, msg="设备正在运行中", device_status=1)
  1658. return False
  1659. if self.mcu_move_state != 2:
  1660. if settings.IS_LIN_SHI_TEST:
  1661. return True
  1662. # self.show_info("mcu 非停止状态")
  1663. self.sendSocketMessage(code=1, msg="mcu 非停止状态", device_status=1)
  1664. return True
  1665. async def controlDevice(self, device_name, value):
  1666. """控制设备移动等"""
  1667. await asyncio.sleep(0.01)
  1668. if not self.is_running:
  1669. self.sendSocketMessage(
  1670. code=1, msg="mcu设备未连接,请先连接设备", device_status=0
  1671. )
  1672. return False
  1673. if not self.init_state:
  1674. self.sendSocketMessage(code=1, msg="mcu设备未初始化", device_status=4)
  1675. return False
  1676. _is_debug = 1 if settings.IS_DEBUG == "true" else 0
  1677. is_deviation = 0 if settings.IS_DEBUG == "true" else 1
  1678. print("控制设备==>_is_debug", _is_debug)
  1679. logger.info("控制设备==>_is_debug %s", _is_debug)
  1680. match device_name:
  1681. case "camera_high_motor":
  1682. # 相机电机
  1683. print(device_name, value)
  1684. self.to_device_move(
  1685. device_name=device_name,
  1686. value=float(value),
  1687. )
  1688. self.to_device_move(
  1689. device_name=device_name,
  1690. value=float(value),
  1691. )
  1692. case "camera_steering":
  1693. print(device_name, value)
  1694. # 相机舵机
  1695. self.to_device_move(
  1696. device_name=device_name,
  1697. value=float(value),
  1698. )
  1699. self.to_device_move(
  1700. device_name=device_name,
  1701. value=float(value),
  1702. )
  1703. case "turntable_steering":
  1704. # 转盘舵机
  1705. self.to_device_move(
  1706. device_name=device_name,
  1707. value=float(value),
  1708. )
  1709. self.to_device_move(
  1710. device_name=device_name,
  1711. value=float(value),
  1712. )
  1713. case "turntable_position_motor":
  1714. # 转盘舵机
  1715. self.to_device_move(
  1716. device_name=device_name,
  1717. value=float(value),
  1718. )
  1719. self.to_device_move(
  1720. device_name=device_name,
  1721. value=float(value),
  1722. )
  1723. case "overturn_steering":
  1724. # 翻板舵机中位
  1725. self.to_deal_device(
  1726. device_name="overturn_steering",
  1727. )
  1728. case "laser_position":
  1729. self.to_deal_device(
  1730. device_name="laser_position", value=0 if int(value) <= 0 else 1
  1731. )
  1732. case "take_picture":
  1733. # loop = asyncio.get_event_loop()
  1734. # if value>0:
  1735. # # 指定自动对焦
  1736. # loop.create_task(
  1737. # self.smart_shooter.CameraAutofocus(),
  1738. # name="CameraAutofocus",
  1739. # )
  1740. # 拍照
  1741. await self.smart_shooter.CameraShooter(msg_type="run_mcu")
  1742. case "to_deal_device":
  1743. self.to_deal_device(device_name, value=value, _type=0, times=1)
  1744. case "camera_zoom_motor":
  1745. self.to_device_move(device_name="camera_zoom_motor", value=int(value))
  1746. case "camera_focal_distance":
  1747. self.to_device_move(device_name="camera_zoom_motor", value=int(value))
  1748. case _:
  1749. pass
  1750. async def _do_camera_check(self):
  1751. """执行一次完整的状态查询检测,返回是否全部停止"""
  1752. self.send_get_all_info_to_mcu()
  1753. await asyncio.sleep(0.5)
  1754. return all(
  1755. value == 2
  1756. for value in [
  1757. self.state_camera_motor,
  1758. self.state_camera_steering,
  1759. self.state_turntable_steering,
  1760. self.state_overturn_steering,
  1761. ]
  1762. )
  1763. async def camera_check_mcu_move_is_stop(self, re_check=False):
  1764. _s = time.time()
  1765. check_times = 0
  1766. await self.cleanAllReceiveData()
  1767. while 1:
  1768. if self.action_state != 1:
  1769. return False
  1770. # 发送获取设备状态消息
  1771. if await self._do_camera_check():
  1772. # 首次检测通过,追加一次确认检测,防止读到旧状态误判
  1773. logger.info("拍照前运动检测首次通过,发起确认检测")
  1774. if await self._do_camera_check():
  1775. logger.info("拍照前运动检测状态[成功],确认通过,耗时%.1f秒", time.time() - _s)
  1776. await asyncio.sleep(0.5)
  1777. return True
  1778. else:
  1779. logger.warning("拍照前运动检测确认失败,继续等待")
  1780. check_times += 1
  1781. else:
  1782. check_times += 1
  1783. if check_times > 5:
  1784. logger.info("拍照前运动检测状态[失败],耗时%.1f秒", time.time() - _s)
  1785. return False
  1786. await asyncio.sleep(0.2)
  1787. def checkDevice(self):
  1788. print("检查设备是否运行中")
  1789. logger.info("检查设备是否运行中")
  1790. if not self.is_running:
  1791. self.sendSocketMessage(
  1792. code=1, msg="mcu设备未连接,请先连接设备", device_status=0
  1793. )
  1794. return False
  1795. if self.init_state is not True:
  1796. self.sendSocketMessage(code=1, msg="mcu设备未初始化", device_status=4)
  1797. return False
  1798. if self.action_state != 2:
  1799. self.sendSocketMessage(
  1800. code=1,
  1801. msg="当前有未完成的任务,请稍后再试",
  1802. device_status=0,
  1803. )
  1804. return False
  1805. async def run_mcu_config(
  1806. self, config_list, goods_art_no, action_info, smart_shooter, weight
  1807. ):
  1808. if self.checkDevice() == False:
  1809. return
  1810. image_counts = 0
  1811. if config_list:
  1812. action_names = []
  1813. record_ids = []
  1814. if len(config_list) > 1:
  1815. if config_list[-1]["take_picture"] is True:
  1816. new_init_config = copy.copy(config_list[0])
  1817. new_init_config["action_name"] = "移动到初始位"
  1818. new_init_config["number_focus"] = 0
  1819. new_init_config["take_picture"] = False
  1820. new_init_config["shoe_upturn"] = False
  1821. new_init_config["pre_delay"] = 0.0
  1822. new_init_config["after_delay"] = 0.0
  1823. # new_init_config["point_name"] = "A"
  1824. new_init_config["is_move_device"] = True
  1825. new_init_config["led_switch"] = True
  1826. new_init_config["turntable_angle"] = 0.0
  1827. new_init_config["is_wait"] = False
  1828. new_init_config["is_need_confirm"] = False
  1829. config_list.append(new_init_config)
  1830. for idx, item in enumerate(config_list):
  1831. is_take_picture = item["take_picture"]
  1832. action_id = item["id"]
  1833. record_id = -1
  1834. if is_take_picture:
  1835. image_counts += 1
  1836. # 批量插入
  1837. image_deal_mode = 0 if action_info == "执行左脚程序" else 1
  1838. state, record_id = await insert_photo_records(
  1839. image_deal_mode=image_deal_mode,
  1840. goods_art_no=goods_art_no,
  1841. image_index=idx,
  1842. action_id=action_id,
  1843. weight=str(weight)
  1844. )
  1845. config_list[idx]["record_id"] = record_id
  1846. total_len = len(config_list)
  1847. self.action_state = 1
  1848. self.msg_type = "image_process"
  1849. self.sendSocketMessage(
  1850. code=0,
  1851. msg="MCU 命令已发送完成",
  1852. device_status=2,
  1853. data={
  1854. "goods_art_no": goods_art_no,
  1855. "image_counts": image_counts,
  1856. "action_names": action_names,
  1857. "current_time": datetime.datetime.now(settings.TIME_ZONE).strftime(
  1858. "%Y-%m-%d %H:%M:%S"
  1859. ),
  1860. },
  1861. )
  1862. await self.controlDevice("laser_position", 0)
  1863. # await smart_shooter.EnableCameraPreview(
  1864. # enable_status=True, msg_type="smart_shooter_enable_preview"
  1865. # )
  1866. self.msg_type = "mcu"
  1867. self.is_runn_action = True
  1868. for index, action in enumerate(config_list):
  1869. # await asyncio.sleep(0.01)
  1870. if self.is_stop_action == True:
  1871. print("停止命令接收,立即终止")
  1872. logger.info("停止命令接收,立即终止")
  1873. break
  1874. # action_is_take_picture = action["take_picture"]
  1875. record_id = action["record_id"]
  1876. image_index = -1
  1877. if record_id == -1:
  1878. image_index = -1
  1879. else:
  1880. image_index = index
  1881. program_item = ProgramItem(
  1882. websocket_manager=self.websocket_manager,
  1883. action_data=action,
  1884. mcu=self,
  1885. goods_art_no=goods_art_no,
  1886. image_index=image_index,
  1887. smart_shooter=smart_shooter,
  1888. record_id=record_id,
  1889. is_get_mcu_state=True,
  1890. )
  1891. program_item.last_move_time = self.last_move_time
  1892. if self.action_state != 1:
  1893. # 异常终止
  1894. print("action异常终止")
  1895. logger.info("action异常终止")
  1896. break
  1897. self.msg_type = "photo_take"
  1898. if not await program_item.run(total_len):
  1899. self.sendSocketMessage(
  1900. code=1,
  1901. msg="{} 执行失败~".format(program_item.action_name),
  1902. data={"goods_art_no": goods_art_no, "id": action_id},
  1903. device_status=0,
  1904. )
  1905. self.to_deal_device(device_name="buzzer", times=3)
  1906. break
  1907. else:
  1908. if program_item.action_name == "移动到初始位":
  1909. self.msg_type = "mcu"
  1910. break
  1911. self.sendSocketMessage(
  1912. code=0,
  1913. msg="{} 执行完成~".format(program_item.action_name),
  1914. data={"goods_art_no": goods_art_no, "id": record_id},
  1915. device_status=2,
  1916. )
  1917. self.msg_type = "mcu"
  1918. if index == total_len - 1:
  1919. pass
  1920. if self.is_stop_action == True:
  1921. self.msg_type = "run_mcu_stop"
  1922. self.sendSocketMessage(
  1923. code=0,
  1924. msg=f"货号:{goods_art_no},执行终止",
  1925. device_status=2,
  1926. )
  1927. self.is_stop_action = False
  1928. self.action_state = 2
  1929. self.is_runn_action = False
  1930. self.msg_type = "photo_take_finish"
  1931. self.sendSocketMessage(
  1932. code=0,
  1933. msg=f"货号:{goods_art_no},执行完成",
  1934. device_status=2,
  1935. )
  1936. self.msg_type = "mcu"
  1937. await self.controlDevice("laser_position", 1)
  1938. self.action_state = 2
  1939. # await smart_shooter.EnableCameraPreview(
  1940. # enable_status=False, msg_type="smart_shooter_enable_preview"
  1941. # )
  1942. async def run_mcu_config_single(
  1943. self,
  1944. config_info,
  1945. goods_art_no,
  1946. msg_type="run_mcu_single_finish",
  1947. image_index=-1,
  1948. smart_shooter=None,
  1949. action_id=-1,
  1950. ):
  1951. """独立拍照 仅作测试用"""
  1952. await asyncio.sleep(0.01)
  1953. if self.checkDevice() == False:
  1954. return
  1955. print("检查完成", config_info)
  1956. logger.info("检查完成 %s", config_info)
  1957. if config_info:
  1958. self.action_state = 1
  1959. self.msg_type = "mcu"
  1960. program_item = ProgramItem(
  1961. websocket_manager=self.websocket_manager,
  1962. action_data=config_info,
  1963. mcu=self,
  1964. goods_art_no=goods_art_no,
  1965. image_index=image_index,
  1966. smart_shooter=smart_shooter,
  1967. record_id=action_id,
  1968. is_get_mcu_state=False,
  1969. )
  1970. program_item.last_move_time = self.last_move_time
  1971. if self.action_state != 1:
  1972. # 异常终止
  1973. print("action异常终止")
  1974. logger.info("action异常终止")
  1975. return
  1976. program_item.smart_shooter = smart_shooter
  1977. await program_item.run(3)
  1978. self.msg_type = "mcu"
  1979. logger.info(
  1980. "发送 run_mcu_signle消息,{} 执行完成~".format(program_item.action_name)
  1981. )
  1982. self.sendSocketMessage(
  1983. code=0,
  1984. msg="{} 执行完成~".format(program_item.action_name),
  1985. data={"goods_art_no": goods_art_no, "id": action_id},
  1986. device_status=2,
  1987. )
  1988. self.action_state = 2
  1989. self.msg_type = "run_mcu_single"
  1990. logger.info("发送 run_mcu_signle消息执行完成")
  1991. self.sendSocketMessage(
  1992. code=0,
  1993. msg=f"执行完成",
  1994. device_status=2,
  1995. )
  1996. self.msg_type = "mcu"
  1997. else:
  1998. self.sendSocketMessage(
  1999. code=1, msg="未查询到重拍记录得配置信息,请确认", device_status=0
  2000. )
  2001. self.action_state = 2
  2002. async def only_take_photo(self, goods_art_no, image_index, record_id):
  2003. await asyncio.sleep(0.1)
  2004. print("only_take_photo=====>", goods_art_no, image_index, record_id)
  2005. logger.info(
  2006. f"only_take_photo=====> {goods_art_no} {image_index} {record_id}"
  2007. )
  2008. if goods_art_no == "":
  2009. print("only_take_photo 数据查询异常")
  2010. logger.info("only_take_photo 数据查询异常")
  2011. return
  2012. # 关闭led
  2013. self.controlDevice("laser_position", 0)
  2014. program_item = ProgramItem(
  2015. websocket_manager=self.websocket_manager,
  2016. action_data={},
  2017. mcu=self,
  2018. goods_art_no=goods_art_no,
  2019. image_index=image_index,
  2020. record_id=record_id,
  2021. )
  2022. program_item.digicam_take_picture()
  2023. # 打开led
  2024. self.controlDevice("laser_position", 1)
  2025. async def checkMcuConnection(device_ctrl: DeviceControl):
  2026. if device_ctrl.is_running == True:
  2027. message = {
  2028. "_type": "select_port_name",
  2029. "plugins_mode": "auto_select_com",
  2030. "data": device_ctrl.temp_ports_dict,
  2031. }
  2032. device_ctrl.device_status = 2
  2033. device_ctrl.sendSocketMessage(code=0, msg="MCU连接成功", data=message)
  2034. return
  2035. if device_ctrl.is_init_while == True:
  2036. logger.info("mcu 初始化循环已创建,请勿重复创建")
  2037. device_ctrl.sendSocketMessage(
  2038. code=0, msg="mcu 初始化循环已创建,请勿重复创建", data={}
  2039. )
  2040. return
  2041. device_ctrl.is_init_while = True
  2042. """实时检测串口是否连接"""
  2043. while True:
  2044. await asyncio.sleep(1)
  2045. if device_ctrl.mcu_exit:
  2046. break
  2047. ports_dict = device_ctrl.scan_serial_port()
  2048. device_ctrl.temp_ports_dict = ports_dict
  2049. # print("device_ctrl.p_list", device_ctrl.p_list)
  2050. # logger.info("device_ctrl.p_list %s", device_ctrl.p_list)
  2051. if not ports_dict:
  2052. # 全部清空 移除所有串口
  2053. if device_ctrl.p_list:
  2054. _p = device_ctrl.p_list.pop()
  2055. device_ctrl.remove_port(_p)
  2056. continue
  2057. if ports_dict:
  2058. for index, _i in enumerate(device_ctrl.p_list):
  2059. if _i not in ports_dict:
  2060. _p = device_ctrl.p_list.pop(index)
  2061. device_ctrl.remove_port(_p)
  2062. for _port_name, _port_value in ports_dict.items():
  2063. if _port_name not in device_ctrl.p_list:
  2064. try:
  2065. flag = await device_ctrl.add_port_by_linkage(_port_name, _port_value)
  2066. if not flag:
  2067. continue
  2068. device_ctrl.p_list.append(_port_name)
  2069. except BaseException as e:
  2070. print("串口不存在{} {}".format(_port_name, e))
  2071. logger.info("串口不存在{} {}".format(_port_name, e))
  2072. device_ctrl.is_init_while = False
  2073. print("MCU断开连接,已释放")
  2074. logger.info("MCU断开连接,已释放")