window_screen_pyqt.py 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. import datetime
  2. from PyQt5.QtWidgets import QWidget, QApplication, QMainWindow, QLabel
  3. from PyQt5.QtGui import QPixmap, QPainter, QResizeEvent, QCloseEvent, QPaintEvent, QFont
  4. from PyQt5.QtCore import QSize, QTimer, QRect, Qt
  5. import async_communication as CM
  6. import message_pb2 as message
  7. import google.protobuf.text_format as tf
  8. import projector_control as PJC
  9. import logging
  10. logging.basicConfig(filename='log.txt',
  11. format='%(asctime)s - %(name)s - %(levelname)s - %(message)s-%(funcName)s',
  12. level=logging.ERROR)
  13. MeasureStatu = {"ok": 0, "无数据": 1, "噪声": 2, "超界": 3, "故障": 4}
  14. ArrowType = {0: "正确图片", 0x01: "向后调整", 0x02: "向前调整", 0x04: "向右调整", 0x08: "向左调整"
  15. , 0x10: "左前调整", 0x06: "右前调整", 0x09: "右后调整", 0x05: "左后调整"}
  16. class PicLabel(QLabel):
  17. def __init__(self, parent):
  18. super(PicLabel, self).__init__(parent=parent)
  19. self.image = None
  20. self.show = False
  21. self.setStyleSheet("border-width:1px;border-style:solid;border-color:rgb(150,150,150)")
  22. self.timer = QTimer()
  23. self.timer.timeout.connect(self.OnTimer)
  24. self.last_moving_statu = None
  25. def FlashImg(self, pixmap):
  26. self.image = pixmap
  27. if self.timer.isActive() == False:
  28. self.timer.start(500)
  29. def ShowImg(self, pixmap):
  30. self.timer.stop()
  31. self.show = True
  32. self.image = pixmap
  33. self.repaint()
  34. def OnTimer(self):
  35. self.show = not self.show
  36. self.repaint()
  37. def paintEvent(self, a0: QPaintEvent) -> None:
  38. if self.show == True:
  39. if not self.image == None:
  40. w, h = self.size().width(), self.size().height()
  41. iw, ih = self.image.width(), self.image.height()
  42. painter = QPainter(self)
  43. painter.drawPixmap(QRect(0, 0, w, h), self.image, QRect(0, 0, iw, ih))
  44. class Frame(QMainWindow):
  45. def __init__(self, import_id, images, prj_parameter, second_screen=False):
  46. super(Frame, self).__init__()
  47. self.flag = None
  48. self.last_back_io = None
  49. self.images = images
  50. self.images = {}
  51. self.import_id = import_id
  52. self.dispatch_statu = CM.TimeStatu(timeout=0.1)
  53. self.measure_statu = CM.TimeStatu(timeout=0.1)
  54. self.terminal_statu = CM.TimeStatu(timeout=0.1)
  55. for key, file in images.items():
  56. self.images[key] = pix = QPixmap(file)
  57. self.InitUI()
  58. # self.last_door_statu=None
  59. self.last_moving_statu = None
  60. # self.last_show = None
  61. # self.last_back_io = "正常"
  62. # self.flag = None
  63. if second_screen == True:
  64. desktop = QApplication.desktop()
  65. screen_count = desktop.screenCount()
  66. displays = [desktop.availableGeometry(i) for i in range(desktop.screenCount())]
  67. second_offx = 0
  68. second_offy = 0
  69. if len(displays) == 2:
  70. second_offx = displays[1].width()
  71. second_offy = displays[1].height()
  72. self.setGeometry(second_offx, second_offy, 200, 500)
  73. if prj_parameter is not None:
  74. prj_ip = prj_parameter['ip']
  75. prj_port = prj_parameter['port']
  76. prj_type = prj_parameter['type']
  77. self.pjc_ = PJC.ProjectorControl(prj_ip, prj_port, prj_type)
  78. self.pjc_.start()
  79. else:
  80. self.pjc_ = None
  81. self.timer = QTimer()
  82. self.timer.timeout.connect(self.Switch)
  83. self.timer.start(200)
  84. def InitUI(self):
  85. self.measure_info_txt = QLabel(self)
  86. self.car_number_txt = QLabel(self)
  87. self.car_number_txt.setStyleSheet("border-width:1px;border-style:solid;border-color:rgb(150,150,150)")
  88. self.car_number_txt.setAlignment(Qt.AlignCenter)
  89. self.measure_info_txt.setStyleSheet("color:blue")
  90. self.panel_txt = PicLabel(self)
  91. self.panel_arrow = PicLabel(self)
  92. def receive_dispatch(self, statu):
  93. # print('--------------------------------------')
  94. # print(datetime.datetime.now())
  95. # print('----------------------------------------')
  96. self.dispatch_statu = statu
  97. def receive_measureInfo(self, statu):
  98. self.measure_statu = statu
  99. def receive_terminal(self, statu):
  100. self.terminal_statu = statu
  101. def closeEvent(self, a0: QCloseEvent) -> None:
  102. if self.pjc_ is not None:
  103. self.pjc_.lightOff()
  104. self.pjc_.exit()
  105. self.pjc_.join()
  106. def resizeEvent(self, a0: QResizeEvent) -> None:
  107. w, h = a0.size().width(), a0.size().height()
  108. w, h = self.size().width(), self.size().height()
  109. top_w, top_h = w, int(h * 0.15)
  110. car_number_w, car_number_h = w, int(h * 0.10)
  111. txt_w, txt_h = w, int(h * 0.20)
  112. arrow_w, arrow_h = w, int(h * 0.55)
  113. font = QFont()
  114. font.setBold(True)
  115. font.setPixelSize(int(w / 40))
  116. self.measure_info_txt.setFont(font)
  117. self.measure_info_txt.setGeometry(0, 0, top_w, top_h)
  118. font.setPixelSize(int(w / 20))
  119. self.car_number_txt.setFont(font)
  120. self.car_number_txt.setGeometry(0, top_h, car_number_w, car_number_h)
  121. self.panel_txt.setGeometry(0, top_h + car_number_h, txt_w, txt_h)
  122. self.panel_arrow.setGeometry(0, top_h + car_number_h + txt_h, arrow_w, arrow_h)
  123. def Switch(self):
  124. try:
  125. if self.terminal_statu.timeout() is False:
  126. terminal_statu = message.terminal_node_statu()
  127. tf.Parse(self.terminal_statu.statu, terminal_statu)
  128. print(terminal_statu.car_number)
  129. self.car_number_txt.setText(terminal_statu.car_number)
  130. self.car_number_txt.setStyleSheet(
  131. "border-width:1px;border-style:solid;border-color:rgb(150,150,150);color:green")
  132. else:
  133. self.car_number_txt.setText("车牌号为空!")
  134. self.car_number_txt.setStyleSheet(
  135. "border-width:1px;border-style:solid;border-color:rgb(150,150,150);color:red")
  136. # 先判断连接状态
  137. if self.dispatch_statu.timeout():
  138. self.panel_txt.ShowImg(self.images['传感器超时'])
  139. self.panel_arrow.FlashImg(self.images['传感器超时'])
  140. return
  141. if self.measure_statu.timeout():
  142. self.panel_txt.ShowImg(self.images['测绘超时'])
  143. self.panel_arrow.FlashImg(self.images['测绘超时'])
  144. return
  145. # 有车才显示
  146. dispatch_statu = message.dispatch_node_statu()
  147. tf.Parse(self.dispatch_statu.statu, dispatch_statu)
  148. measure_info = message.measure_info()
  149. tf.Parse(self.measure_statu.statu, measure_info)
  150. # 测量状态
  151. lidar_statu = measure_info.ground_status # 测量状态(正常,无数据、噪声、超界)
  152. # 传感器状态
  153. dispatch_plc_passway_status = dispatch_statu.dispatch_plc_passway_status_vector[self.import_id - 1]
  154. sensor_1 = dispatch_plc_passway_status.sensor_1
  155. sensor_2 = dispatch_plc_passway_status.sensor_2
  156. if lidar_statu == MeasureStatu['故障']:
  157. self.panel_txt.ShowImg(self.images['测绘超时'])
  158. self.panel_arrow.FlashImg(self.images['测绘超时'])
  159. return
  160. # 获取传感器数据
  161. print('---------------------------------')
  162. print('PLC数据:')
  163. print(dispatch_plc_passway_status)
  164. print('----------------------------------')
  165. print('====================================')
  166. print('雷达数据:')
  167. print(measure_info)
  168. print('====================================')
  169. # 关门清除上一帧数据
  170. if dispatch_plc_passway_status.outside_door_status == 2:
  171. self.last_moving_statu = None
  172. # 判断超界信息
  173. if (sensor_1 >> 3) & 0x01 == 0:
  174. if not self.last_back_io == "超界":
  175. self.last_back_io = "超界"
  176. self.flag = False
  177. else:
  178. if not self.last_back_io == "正常":
  179. self.last_back_io = "正常"
  180. self.flag = True
  181. if (sensor_2 >> 2) & 0x01 == 0:
  182. self.panel_txt.ShowImg(self.images["空闲"])
  183. self.panel_arrow.ShowImg(self.images["空闲"])
  184. return
  185. if dispatch_plc_passway_status.car_height == 4:
  186. self.panel_txt.ShowImg(self.images["超高车辆"])
  187. self.panel_arrow.ShowImg(self.images["超高车辆"])
  188. return
  189. # 以下是有车的处理
  190. # 1,显示测量数据(实时和静态)
  191. realtime_info_txt = ''
  192. static_info_txt = ''
  193. realtime_info_txt = "(实时) 中心(%.3f,%.3f) 角度:%.2f° 宽:%.3f 轴距:%.3f 前轮角:%.2f°" % \
  194. (measure_info.cx, measure_info.cy, measure_info.theta, measure_info.width,
  195. measure_info.wheelbase, measure_info.front_theta)
  196. if not self.last_moving_statu == None:
  197. static_info_txt = "(静止) 中心(%.3f,%.3f) 角度:%.2f° 宽:%.3f 轴距:%.3f 前轮角:%.2f°" % \
  198. (self.last_moving_statu.cx, self.last_moving_statu.cy,
  199. self.last_moving_statu.theta, self.last_moving_statu.width,
  200. self.last_moving_statu.wheelbase, self.last_moving_statu.front_theta)
  201. self.measure_info_txt.setText(realtime_info_txt + "\n" + static_info_txt)
  202. # 2,获取车辆运动状态(静止or动态)
  203. border_statu = measure_info.border_statu
  204. is_moving = ((border_statu >> 11) & 0x01) == 1
  205. # 当前运动
  206. if is_moving:
  207. self.last_moving_statu = None
  208. else:
  209. # 当前静止
  210. if lidar_statu == MeasureStatu["ok"]:
  211. self.last_moving_statu = measure_info
  212. elif lidar_statu == MeasureStatu["超界"]:
  213. if not self.last_moving_statu == None:
  214. # 上一刻静止且数据正确,当前静止,不可能出现超界,将超界清除
  215. new_border = border_statu
  216. new_border = (new_border & (~(0x01 << 0)))
  217. new_border = (new_border & (~(0x01 << 1)))
  218. new_border = (new_border & (~(0x01 << 2)))
  219. new_border = (new_border & (~(0x01 << 3)))
  220. new_border = (new_border & (~(0x01 << 6)))
  221. new_border = (new_border & (~(0x01 << 7)))
  222. new_border = (new_border & (~(0x01 << 8)))
  223. new_border = (new_border & (~(0x01 << 9)))
  224. border_statu = new_border
  225. elif lidar_statu == MeasureStatu["无数据"]:
  226. # 当前静止无车,清除上一时刻数据
  227. self.last_moving_statu = None
  228. elif lidar_statu == MeasureStatu["噪声"]:
  229. if not self.last_moving_statu == None:
  230. # 上一时刻静止且正确,当前噪声,不显示当前数据,显示上一正确数据
  231. measure_info.CopyFrom(self.last_moving_statu)
  232. # 先判断光电
  233. if (sensor_1 >> 3) & 0x01 == 0:
  234. self.panel_txt.ShowImg(self.images["请调整"])
  235. self.panel_arrow.FlashImg(self.images["向前调整"])
  236. self.last_show = "调整"
  237. return
  238. elif (sensor_1 >> 4) & 0x01 == 0:
  239. self.panel_txt.ShowImg(self.images["请调整"])
  240. self.panel_arrow.FlashImg(self.images["向后调整"])
  241. self.last_show = "调整"
  242. return
  243. elif (sensor_1 >> 5) & 0x01 == 0:
  244. self.panel_txt.ShowImg(self.images["请调整"])
  245. self.panel_arrow.FlashImg(self.images["向右调整"])
  246. self.last_show = "调整"
  247. return
  248. elif (sensor_1 >> 6) & 0x01 == 0:
  249. self.panel_txt.ShowImg(self.images["请调整"])
  250. self.panel_arrow.FlashImg(self.images["向左调整"])
  251. self.last_show = "调整"
  252. return
  253. # 光电正常
  254. if lidar_statu == MeasureStatu["无数据"]:
  255. self.panel_txt.ShowImg(self.images["空闲"])
  256. self.panel_arrow.ShowImg(self.images["空闲"])
  257. self.last_show = "空闲"
  258. return
  259. elif lidar_statu == MeasureStatu["噪声"]:
  260. if self.last_moving_statu is None and self.flag is True:
  261. self.panel_txt.ShowImg(self.images['请调整'])
  262. self.panel_arrow.ShowImg(self.images["请调整"])
  263. self.last_show = "请调整"
  264. return
  265. if self.last_show == "超时":
  266. self.panel_txt.ShowImg(self.images["空闲"])
  267. self.panel_arrow.ShowImg(self.images["空闲"])
  268. self.last_show = "空闲"
  269. return
  270. elif lidar_statu == MeasureStatu["ok"]:
  271. self.panel_txt.ShowImg(self.images['正确文字'])
  272. self.panel_arrow.ShowImg(self.images['正确图片'])
  273. return
  274. # 查看是否超界
  275. elif lidar_statu == MeasureStatu["超界"]:
  276. if (border_statu >> 7) & 0x01 == 1:
  277. self.panel_txt.ShowImg(self.images['轴距超差'])
  278. self.panel_arrow.ShowImg(self.images['轴距超差'])
  279. return
  280. if (border_statu >> 6) & 0x01 == 1:
  281. self.panel_txt.ShowImg(self.images['超宽车辆'])
  282. self.panel_arrow.ShowImg(self.images['超宽车辆'])
  283. return
  284. if (border_statu >> 9) & 0x01 == 1:
  285. self.panel_txt.ShowImg(self.images['请调整'])
  286. self.panel_arrow.FlashImg(self.images['向左旋转'])
  287. return
  288. if (border_statu >> 8) & 0x01 == 1:
  289. self.panel_txt.ShowImg(self.images['请调整'])
  290. self.panel_arrow.FlashImg(self.images['向右旋转'])
  291. return
  292. if (border_statu >> 10) & 0x01 == 1:
  293. self.panel_txt.ShowImg(self.images['请调整'])
  294. self.panel_arrow.FlashImg(self.images['回正方向盘'])
  295. return
  296. if (border_statu >> 1) & 0x01 == 1:
  297. self.panel_txt.ShowImg(self.images['请调整'])
  298. self.panel_arrow.FlashImg(self.images["向前调整"])
  299. return
  300. if (border_statu >> 2) & 0x01 == 1:
  301. self.panel_txt.ShowImg(self.images['请调整'])
  302. self.panel_arrow.FlashImg(self.images["向右调整"])
  303. return
  304. if (border_statu >> 3) & 0x01 == 1:
  305. self.panel_txt.ShowImg(self.images['请调整'])
  306. self.panel_arrow.FlashImg(self.images["向左调整"])
  307. return
  308. border = border_statu & 0x0f
  309. if (border in ArrowType.keys()) is False:
  310. self.panel_txt.ShowImg(self.images['检查杂物'])
  311. self.panel_arrow.FlashImg(self.images['检查杂物'])
  312. self.last_show = "检查杂物"
  313. else:
  314. if ArrowType[border] == "正确图片":
  315. self.panel_arrow.ShowImg(self.images[ArrowType[border]])
  316. self.panel_txt.ShowImg(self.images['正确文字'])
  317. self.last_show = "正确"
  318. else:
  319. self.panel_arrow.FlashImg(self.images[ArrowType[border]])
  320. self.panel_txt.ShowImg(self.images['请调整'])
  321. self.last_show = "请调整"
  322. except Exception as e:
  323. print(str(e.args))
  324. logging.error(str(e.args))