import datetime from PyQt5.QtWidgets import QWidget, QApplication, QMainWindow, QLabel from PyQt5.QtGui import QPixmap, QPainter, QResizeEvent, QCloseEvent, QPaintEvent, QFont from PyQt5.QtCore import QSize, QTimer, QRect, Qt import async_communication as CM import message_pb2 as message import google.protobuf.text_format as tf import projector_control as PJC import logging logging.basicConfig(filename='log.txt', format='%(asctime)s - %(name)s - %(levelname)s - %(message)s-%(funcName)s', level=logging.ERROR) MeasureStatu = {"ok": 0, "无数据": 1, "噪声": 2, "超界": 3, "故障": 4} ArrowType = {0: "正确图片", 0x01: "向后调整", 0x02: "向前调整", 0x04: "向右调整", 0x08: "向左调整" , 0x10: "左前调整", 0x06: "右前调整", 0x09: "右后调整", 0x05: "左后调整"} class PicLabel(QLabel): def __init__(self, parent): super(PicLabel, self).__init__(parent=parent) self.image = None self.show = False self.setStyleSheet("border-width:1px;border-style:solid;border-color:rgb(150,150,150)") self.timer = QTimer() self.timer.timeout.connect(self.OnTimer) self.last_moving_statu = None def FlashImg(self, pixmap): self.image = pixmap if self.timer.isActive() == False: self.timer.start(500) def ShowImg(self, pixmap): self.timer.stop() self.show = True self.image = pixmap self.repaint() def OnTimer(self): self.show = not self.show self.repaint() def paintEvent(self, a0: QPaintEvent) -> None: if self.show == True: if not self.image == None: w, h = self.size().width(), self.size().height() iw, ih = self.image.width(), self.image.height() painter = QPainter(self) painter.drawPixmap(QRect(0, 0, w, h), self.image, QRect(0, 0, iw, ih)) class Frame(QMainWindow): def __init__(self, import_id, images, prj_parameter, second_screen=False): super(Frame, self).__init__() self.flag = None self.last_back_io = None self.images = images self.images = {} self.import_id = import_id self.dispatch_statu = CM.TimeStatu(timeout=0.1) self.measure_statu = CM.TimeStatu(timeout=0.1) self.terminal_statu = CM.TimeStatu(timeout=0.1) for key, file in images.items(): self.images[key] = pix = QPixmap(file) self.InitUI() # self.last_door_statu=None self.last_moving_statu = None # self.last_show = None # self.last_back_io = "正常" # self.flag = None if second_screen == True: desktop = QApplication.desktop() screen_count = desktop.screenCount() displays = [desktop.availableGeometry(i) for i in range(desktop.screenCount())] second_offx = 0 second_offy = 0 if len(displays) == 2: second_offx = displays[1].width() second_offy = displays[1].height() self.setGeometry(second_offx, second_offy, 200, 500) if prj_parameter is not None: prj_ip = prj_parameter['ip'] prj_port = prj_parameter['port'] prj_type = prj_parameter['type'] self.pjc_ = PJC.ProjectorControl(prj_ip, prj_port, prj_type) self.pjc_.start() else: self.pjc_ = None self.timer = QTimer() self.timer.timeout.connect(self.Switch) self.timer.start(200) def InitUI(self): self.measure_info_txt = QLabel(self) self.car_number_txt = QLabel(self) self.car_number_txt.setStyleSheet("border-width:1px;border-style:solid;border-color:rgb(150,150,150)") self.car_number_txt.setAlignment(Qt.AlignCenter) self.measure_info_txt.setStyleSheet("color:blue") self.panel_txt = PicLabel(self) self.panel_arrow = PicLabel(self) def receive_dispatch(self, statu): # print('--------------------------------------') # print(datetime.datetime.now()) # print('----------------------------------------') self.dispatch_statu = statu def receive_measureInfo(self, statu): self.measure_statu = statu def receive_terminal(self, statu): self.terminal_statu = statu def closeEvent(self, a0: QCloseEvent) -> None: if self.pjc_ is not None: self.pjc_.lightOff() self.pjc_.exit() self.pjc_.join() def resizeEvent(self, a0: QResizeEvent) -> None: w, h = a0.size().width(), a0.size().height() w, h = self.size().width(), self.size().height() top_w, top_h = w, int(h * 0.15) car_number_w, car_number_h = w, int(h * 0.10) txt_w, txt_h = w, int(h * 0.20) arrow_w, arrow_h = w, int(h * 0.55) font = QFont() font.setBold(True) font.setPixelSize(int(w / 40)) self.measure_info_txt.setFont(font) self.measure_info_txt.setGeometry(0, 0, top_w, top_h) font.setPixelSize(int(w / 20)) self.car_number_txt.setFont(font) self.car_number_txt.setGeometry(0, top_h, car_number_w, car_number_h) self.panel_txt.setGeometry(0, top_h + car_number_h, txt_w, txt_h) self.panel_arrow.setGeometry(0, top_h + car_number_h + txt_h, arrow_w, arrow_h) def Switch(self): try: if self.terminal_statu.timeout() is False: terminal_statu = message.terminal_node_statu() tf.Parse(self.terminal_statu.statu, terminal_statu) print(terminal_statu.car_number) self.car_number_txt.setText(terminal_statu.car_number) self.car_number_txt.setStyleSheet( "border-width:1px;border-style:solid;border-color:rgb(150,150,150);color:green") else: self.car_number_txt.setText("车牌号为空!") self.car_number_txt.setStyleSheet( "border-width:1px;border-style:solid;border-color:rgb(150,150,150);color:red") # 先判断连接状态 if self.dispatch_statu.timeout(): self.panel_txt.ShowImg(self.images['传感器超时']) self.panel_arrow.FlashImg(self.images['传感器超时']) return if self.measure_statu.timeout(): self.panel_txt.ShowImg(self.images['测绘超时']) self.panel_arrow.FlashImg(self.images['测绘超时']) return # 有车才显示 dispatch_statu = message.dispatch_node_statu() tf.Parse(self.dispatch_statu.statu, dispatch_statu) measure_info = message.measure_info() tf.Parse(self.measure_statu.statu, measure_info) # 测量状态 lidar_statu = measure_info.ground_status # 测量状态(正常,无数据、噪声、超界) # 传感器状态 dispatch_plc_passway_status = dispatch_statu.dispatch_plc_passway_status_vector[self.import_id - 1] sensor_1 = dispatch_plc_passway_status.sensor_1 sensor_2 = dispatch_plc_passway_status.sensor_2 if lidar_statu == MeasureStatu['故障']: self.panel_txt.ShowImg(self.images['测绘超时']) self.panel_arrow.FlashImg(self.images['测绘超时']) return # 获取传感器数据 print('---------------------------------') print('PLC数据:') print(dispatch_plc_passway_status) print('----------------------------------') print('====================================') print('雷达数据:') print(measure_info) print('====================================') # 关门清除上一帧数据 if dispatch_plc_passway_status.outside_door_status == 2: self.last_moving_statu = None # 判断超界信息 if (sensor_1 >> 3) & 0x01 == 0: if not self.last_back_io == "超界": self.last_back_io = "超界" self.flag = False else: if not self.last_back_io == "正常": self.last_back_io = "正常" self.flag = True if (sensor_2 >> 2) & 0x01 == 0: self.panel_txt.ShowImg(self.images["空闲"]) self.panel_arrow.ShowImg(self.images["空闲"]) return if dispatch_plc_passway_status.car_height == 4: self.panel_txt.ShowImg(self.images["超高车辆"]) self.panel_arrow.ShowImg(self.images["超高车辆"]) return # 以下是有车的处理 # 1,显示测量数据(实时和静态) realtime_info_txt = '' static_info_txt = '' realtime_info_txt = "(实时) 中心(%.3f,%.3f) 角度:%.2f° 宽:%.3f 轴距:%.3f 前轮角:%.2f°" % \ (measure_info.cx, measure_info.cy, measure_info.theta, measure_info.width, measure_info.wheelbase, measure_info.front_theta) if not self.last_moving_statu == None: static_info_txt = "(静止) 中心(%.3f,%.3f) 角度:%.2f° 宽:%.3f 轴距:%.3f 前轮角:%.2f°" % \ (self.last_moving_statu.cx, self.last_moving_statu.cy, self.last_moving_statu.theta, self.last_moving_statu.width, self.last_moving_statu.wheelbase, self.last_moving_statu.front_theta) self.measure_info_txt.setText(realtime_info_txt + "\n" + static_info_txt) # 2,获取车辆运动状态(静止or动态) border_statu = measure_info.border_statu is_moving = ((border_statu >> 11) & 0x01) == 1 # 当前运动 if is_moving: self.last_moving_statu = None else: # 当前静止 if lidar_statu == MeasureStatu["ok"]: self.last_moving_statu = measure_info elif lidar_statu == MeasureStatu["超界"]: if not self.last_moving_statu == None: # 上一刻静止且数据正确,当前静止,不可能出现超界,将超界清除 new_border = border_statu new_border = (new_border & (~(0x01 << 0))) new_border = (new_border & (~(0x01 << 1))) new_border = (new_border & (~(0x01 << 2))) new_border = (new_border & (~(0x01 << 3))) new_border = (new_border & (~(0x01 << 6))) new_border = (new_border & (~(0x01 << 7))) new_border = (new_border & (~(0x01 << 8))) new_border = (new_border & (~(0x01 << 9))) border_statu = new_border elif lidar_statu == MeasureStatu["无数据"]: # 当前静止无车,清除上一时刻数据 self.last_moving_statu = None elif lidar_statu == MeasureStatu["噪声"]: if not self.last_moving_statu == None: # 上一时刻静止且正确,当前噪声,不显示当前数据,显示上一正确数据 measure_info.CopyFrom(self.last_moving_statu) # 先判断光电 if (sensor_1 >> 3) & 0x01 == 0: self.panel_txt.ShowImg(self.images["请调整"]) self.panel_arrow.FlashImg(self.images["向前调整"]) self.last_show = "调整" return elif (sensor_1 >> 4) & 0x01 == 0: self.panel_txt.ShowImg(self.images["请调整"]) self.panel_arrow.FlashImg(self.images["向后调整"]) self.last_show = "调整" return elif (sensor_1 >> 5) & 0x01 == 0: self.panel_txt.ShowImg(self.images["请调整"]) self.panel_arrow.FlashImg(self.images["向右调整"]) self.last_show = "调整" return elif (sensor_1 >> 6) & 0x01 == 0: self.panel_txt.ShowImg(self.images["请调整"]) self.panel_arrow.FlashImg(self.images["向左调整"]) self.last_show = "调整" return # 光电正常 if lidar_statu == MeasureStatu["无数据"]: self.panel_txt.ShowImg(self.images["空闲"]) self.panel_arrow.ShowImg(self.images["空闲"]) self.last_show = "空闲" return elif lidar_statu == MeasureStatu["噪声"]: if self.last_moving_statu is None and self.flag is True: self.panel_txt.ShowImg(self.images['请调整']) self.panel_arrow.ShowImg(self.images["请调整"]) self.last_show = "请调整" return if self.last_show == "超时": self.panel_txt.ShowImg(self.images["空闲"]) self.panel_arrow.ShowImg(self.images["空闲"]) self.last_show = "空闲" return elif lidar_statu == MeasureStatu["ok"]: self.panel_txt.ShowImg(self.images['正确文字']) self.panel_arrow.ShowImg(self.images['正确图片']) return # 查看是否超界 elif lidar_statu == MeasureStatu["超界"]: if (border_statu >> 7) & 0x01 == 1: self.panel_txt.ShowImg(self.images['轴距超差']) self.panel_arrow.ShowImg(self.images['轴距超差']) return if (border_statu >> 6) & 0x01 == 1: self.panel_txt.ShowImg(self.images['超宽车辆']) self.panel_arrow.ShowImg(self.images['超宽车辆']) return if (border_statu >> 9) & 0x01 == 1: self.panel_txt.ShowImg(self.images['请调整']) self.panel_arrow.FlashImg(self.images['向左旋转']) return if (border_statu >> 8) & 0x01 == 1: self.panel_txt.ShowImg(self.images['请调整']) self.panel_arrow.FlashImg(self.images['向右旋转']) return if (border_statu >> 10) & 0x01 == 1: self.panel_txt.ShowImg(self.images['请调整']) self.panel_arrow.FlashImg(self.images['回正方向盘']) return if (border_statu >> 1) & 0x01 == 1: self.panel_txt.ShowImg(self.images['请调整']) self.panel_arrow.FlashImg(self.images["向前调整"]) return if (border_statu >> 2) & 0x01 == 1: self.panel_txt.ShowImg(self.images['请调整']) self.panel_arrow.FlashImg(self.images["向右调整"]) return if (border_statu >> 3) & 0x01 == 1: self.panel_txt.ShowImg(self.images['请调整']) self.panel_arrow.FlashImg(self.images["向左调整"]) return border = border_statu & 0x0f if (border in ArrowType.keys()) is False: self.panel_txt.ShowImg(self.images['检查杂物']) self.panel_arrow.FlashImg(self.images['检查杂物']) self.last_show = "检查杂物" else: if ArrowType[border] == "正确图片": self.panel_arrow.ShowImg(self.images[ArrowType[border]]) self.panel_txt.ShowImg(self.images['正确文字']) self.last_show = "正确" else: self.panel_arrow.FlashImg(self.images[ArrowType[border]]) self.panel_txt.ShowImg(self.images['请调整']) self.last_show = "请调整" except Exception as e: print(str(e.args)) logging.error(str(e.args))