window_screen_pyqt.py 13 KB

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