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 MeasureStatu={"ok":0,"无数据":1,"噪声":2,"超界":3} 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) 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,images,prj_parameter,second_screen=False): super(Frame, self).__init__() self.images=images self.images = {} self.icpu_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_icpu(self,statu): self.icpu_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): 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.icpu_statu.timeout(): self.panel_txt.ShowImg(self.images['传感器超时']) self.panel_arrow.FlashImg(self.images['传感器超时']) self.last_show="超时" return if self.measure_statu.timeout(): self.panel_txt.ShowImg(self.images['测绘超时']) self.panel_arrow.FlashImg(self.images['测绘超时']) self.last_show="超时" return #有车才显示 icpu_statu=message.in_mcpu_statu() tf.Parse(self.icpu_statu.statu,icpu_statu) measure_info=message.measure_info() tf.Parse(self.measure_statu.statu,measure_info) # if 门关,self.last_moving_statu 清除上一帧数据 # if self.last_moving_statu none 且后光电从被压到释放 且当前雷达数据为噪声 #提示 雷达呗干扰 if icpu_statu.door_statu == 3: self.last_moving_statu = None if icpu_statu.back_io == 2:#正常 if not self.last_back_io=="正常": self.last_back_io="正常" self.flag = True elif icpu_statu.back_io == 1: if not self.last_back_io=="超界": self.last_back_io="超界" self.flag = False # 外门状态控制投影仪 if self.pjc_ is not None: if icpu_statu.door_statu==3: #关门状态 if not self.last_door_statu=="closed": print("close") self.pjc_.lightOff() self.last_door_statu="closed" elif icpu_statu.door_statu==2 or icpu_statu.door_statu==4: if not self.last_door_statu=="opened": self.pjc_.lightOn() print("open") self.last_door_statu="opened" if icpu_statu.is_occupy != 2: self.panel_txt.ShowImg(self.images["空闲"]) self.panel_arrow.ShowImg(self.images["空闲"]) self.last_show = "空闲" 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 lidar_statu=measure_info.ground_status # 测量状态(正常,无数据、噪声、超界) 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 is_moving: if icpu_statu.back_io==1: 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['轴距超差']) self.last_show="轴距超差" return if (border_statu>>9)&0x01==1: self.panel_txt.ShowImg(self.images['请调整']) self.panel_arrow.FlashImg(self.images['向左旋转']) self.last_show="请调整" return if (border_statu>>8)&0x01==1: self.panel_txt.ShowImg(self.images['请调整']) self.panel_arrow.FlashImg(self.images['向右旋转']) self.last_show="请调整" return if (border_statu>>10)&0x01==1: self.panel_txt.ShowImg(self.images['请调整']) self.panel_arrow.FlashImg(self.images['回正方向盘']) self.last_show="请调整" return if (border_statu>>6)&0x01==1: self.panel_txt.ShowImg(self.images['超宽车辆']) self.panel_arrow.ShowImg(self.images['超宽车辆']) self.last_show="超宽" 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="请调整"