使用环境:
win10,STM32F407串口输出,输出格式b’,’
import os
import sys
import pyqtgraph as pg
import numpy as np
import threading
import serial
import serial.tools.list_ports
import array
import time
import PyQt5
from PyQt5.QtWidgets import *
from PyQt5.QtCore import pyqtSlot, QBasicTimer,Qt, QTimer,Qt
from PyQt5.QtWidgets import QDialog,QSplashScreen
from PyQt5 import QtWidgets
from PyQT_Form import Ui_Form
import math
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
jishu1 = 0 # type: int
#接收不到数据,循环10次之后退出
exit_sum = 0
#使用matplotlib模块绘图,可以嵌入到tkinter,但是性能不好
dis = np.zeros(80) #左车道线距离
dis2 = dis
dis3 = np.zeros(80) #右车道线距离
dis4 = dis3
dis5 = np.zeros(80) #方向盘转角
dis6 = dis5
dis7 = np.zeros(80) #方位角
dis8 = dis7
dis9 = np.zeros(80) #发送扭矩大小
dis10 = dis9
#截图命名
name_sum = 0
#pyqtgraph模块绘图,不能嵌入到tkinter,但是性能较好
gg = 0
zxd = 0
data = []
shuju = []
shuju2 = []
shuju3 = []
shuju4 = []
shuju5 = []
historyLength = 0
historyLength2 = 0
def good():
print('good')
class WorkThread(QThread):
trigger = pyqtSignal()
def __int__(self):
super(WorkThread, self).__init__()
def run(self):
ff = MyPyQT_Form()
while 1:
ff.lka_all()
# ff.recv()
# # 循环完毕后发出信号
# self.trigger.emit()
class MyPyQT_Form(QtWidgets.QWidget,Ui_Form):
def __init__(self):
super(MyPyQT_Form,self).__init__()
self.setupUi(self)
self.app_pyqt()
self.restart()
# self.recv()
def plotData(self):
global gg
# global lka_cs_in, c0_l_in, c0_r_in, angle_main_in, azi_main_in, Tor_Value, deviation_reminder
global lka_cs_in, lka_sign_timer_in, lka_on_in, torque_in, angle_main_in, c0_l_in, c0_r_in, azi_main_in, deviation_reminder, \
touchline_sign, Tor_Value, c0_l_lctype, c0_r_rtype, c2_l, c3_l, c2_r, c3_r, degree_confidence_l, degree_confidence_r, zxd
global data,shuju,shuju2,shuju3,shuju4,shuju5
global idx # 内部作用域想改变外部域变量
global historyLength
global historyLength2
gg = gg + 0.01
# print('lka_cs_in', lka_cs_in)
try:
# tmp = math.sin(gg) #测试使用
# tmp2 = math.cos(gg)
# tmp3 = 10 * math.sin(gg)
# tmp4 = 0.1 * math.sin(gg)
tmp = float(c0_l_in)
tmp2 = float(c0_r_in)
tmp3 = float(angle_main_in)
tmp4 = float(azi_main_in)
except:
tmp = 0
tmp2 = 0
tmp3 = 0
tmp4 = 0
try:
tmp5 = float(Tor_Value)
except:
tmp5 = 0
try:
tmp6 = float(deviation_reminder)
except:
tmp6 = 0
if len(data) <= historyLength:
data.append(tmp)
shuju.append(tmp2)
shuju2.append(tmp3)
shuju3.append(tmp4)
shuju4.append(tmp5)
shuju5.append(tmp6)
else:
data[:-1] = data[1:] # 前移
data[-1] = tmp
shuju[:-1] = shuju[1:] # 前移
shuju[-1] = tmp2
shuju2[:-1] = shuju2[1:] # 前移
shuju2[-1] = tmp3
shuju3[:-1] = shuju3[1:] # 前移
shuju3[-1] = tmp4
shuju4[:-1] = shuju4[1:] # 前移
shuju4[-1] = tmp5
shuju5[:-1] = shuju5[1:] # 前移
shuju5[-1] = tmp6
self.curve1.setData(data)
self.curve2.setData(shuju)
self.curve3.setData(shuju2)
self.curve4.setData(shuju3)
self.curve5.setData(shuju4)
self.curve6.setData(shuju5)
idx += 1
try:
self.lineEdit.clear()
self.lineEdit.setText(str(float(lka_cs_in)))
self.lineEdit_2.clear()
self.lineEdit_2.setText(str(float(torque_in)))
self.lineEdit_3.clear()
self.lineEdit_3.setText(str(float(angle_main_in)))
self.lineEdit_4.clear()
self.lineEdit_4.setText(str(float(c0_l_in)))
self.lineEdit_5.clear()
self.lineEdit_5.setText(str(float(c0_r_in)))
self.lineEdit_6.clear()
self.lineEdit_6.setText(str(float(azi_main_in)))
self.lineEdit_7.clear()
self.lineEdit_7.setText(str(float(deviation_reminder)))
self.lineEdit_8.clear()
self.lineEdit_8.setText(str(float(lka_sign_timer_in)))
self.lineEdit_9.clear()
self.lineEdit_9.setText(str(float(Tor_Value)))
self.lineEdit_10.clear()
self.lineEdit_10.setText(str(float(touchline_sign)))
self.lineEdit_11.clear()
self.lineEdit_11.setText(str(float(lka_on_in)))
self.lineEdit_12.clear()
self.lineEdit_12.setText(str(float(degree_confidence_l)))
self.lineEdit_13.clear()
self.lineEdit_13.setText(str(float(degree_confidence_r)))
self.lineEdit_14.clear()
self.lineEdit_14.setText(str(float(c0_l_lctype)))
self.lineEdit_15.clear()
self.lineEdit_15.setText(str(float(c0_r_rtype)))
self.lineEdit_16.clear()
self.lineEdit_16.setText(str(float(c2_l)))
self.lineEdit_17.clear()
self.lineEdit_17.setText(str(float(c3_l)))
self.lineEdit_18.clear()
self.lineEdit_18.setText(str(float(c2_r)))
self.lineEdit_19.clear()
self.lineEdit_19.setText(str(float(c3_r)))
self.lineEdit_20.clear()
self.lineEdit_20.setText(str(float(zxd)))
if float(lka_cs_in) >= 30.0:
if float(degree_confidence_r) < 2 or float(degree_confidence_l) < 2:
self.textEdit.clear()
self.textEdit.setText('置信度较低\n不能识别车道线')
elif deviation_reminder == b'1.0' and jishu1 == 0:
self.textEdit.clear()
self.textEdit.setText('左偏离')
if touchline_sign == b'1':
self.textEdit.clear()
self.textEdit.setText('左偏离+压线\n正在退出纠正...')
elif deviation_reminder == b'-1.0' and jishu1 == 0:
self.textEdit.clear()
self.textEdit.setText('右偏离')
if touchline_sign == b'1':
self.textEdit.clear()
self.textEdit.setText('右偏离+压线\n正在退出纠正...')
elif touchline_sign == b'1':
self.textEdit.clear()
self.textEdit.setText('压线\n正在退出纠正...')
elif jishu1 == 1:
self.textEdit.clear()
self.textEdit.setText('数据错误')
elif float(zxd == 1):
self.textEdit.clear()
self.textEdit.setText('已开启转向灯\nLKA未激活')
else:
self.textEdit.clear()
else:
self.textEdit.clear()
self.textEdit.setText('车速<30Km/h\nLKA未激活')
except:
pass
def recv(self): # 从串口获取数据
# start1 = time.time()
global exit_sum, jishu1
try:
data3 = serial1.readline()
data_str = str(data3)
if data_str.count(',') != 19:
data3 = b'0,0,0,0.0,0.00,0.000,0.000,0.00,0.0,0,0.00,0,0,0.000,0.000,0.000,0.000,0,0,1\n'
jishu1 = 1
exit_sum = exit_sum + 1
elif data_str.count(',') == 19:
jishu1 = 0
exit_sum = 0
# end1 = time.time()
# print(end1 - start1)
except:
data3 = b'0,0,0,0.0,0.00,0.000,0.000,0.00,0.0,0,0.00,0,0,0.000,0.000,0.000,0.000,0,0,2\n'
# print('data3:',data3)
return data3
def app_pyqt(self):
global idx, historyLength
global data, shuju, shuju2, shuju3, shuju4, shuju5
win = pg.GraphicsLayoutWidget(self.frame)
self.verticalLayout.addWidget(win)
win.setWindowTitle(u'实时监测卡车参数')
data = array.array('d') # 可动态改变数组的大小,double型数组
shuju = array.array('d') # 可动态改变数组的大小,double型数组
shuju2 = array.array('d')
shuju3 = array.array('d')
shuju4 = array.array('d')
shuju5 = array.array('d')
historyLength = 200 # 横坐标长度
p = win.addPlot() # 把图p加入到窗口中
p.showGrid(x=True, y=True) # 把X和Y的表格打开
p.setRange(xRange=[0, historyLength], yRange=[-4.0, 4.0], padding=0)
p.setLabel(axis='left', text='左右车道线距离') # 靠左
p.setLabel(axis='bottom', text='time')
p.setTitle('车道线距离') # 表格的名字
self.curve1 = p.plot(pen='w') # 绘制一个图形
self.curve2 = p.plot(pen='g') # 绘制一个图形
angle_steer = win.addPlot(left='方向盘转角', bottom='time',title='方向盘转角')
angle_steer.showGrid(x=True, y=True) # 把X和Y的表格打开
angle_steer.setRange(xRange=[0, historyLength], yRange=[-180, 180], padding=0)
self.curve3 = angle_steer.plot(pen='w')
win.nextRow()
azi = win.addPlot(left='方位角', bottom='time', title='方位角')
azi.showGrid(x=True, y=True) # 把X和Y的表格打开
azi.setRange(xRange=[0, historyLength], yRange=[-0.2, 0.2], padding=0)
self.curve4 = azi.plot(pen='w')
T_send = win.addPlot(left='发送扭矩', bottom='time', title='发送扭矩')
T_send.showGrid(x=True, y=True) # 把X和Y的表格打开
T_send.setRange(xRange=[0, historyLength], yRange=[-2, 2], padding=0)
self.curve5 = T_send.plot(pen='r')
self.curve6 = T_send.plot(pen='g')
idx = 0
timer = QTimer(self)
timer.timeout.connect(self.plotData)
timer.start(20)
# 重启程序
def restart(self):
global data1, serial1, com_0, com_kou
try:
serial1.close()
except:
pass
port_list22 = list(serial.tools.list_ports.comports())
if len(port_list22) == 0:
pass
else:
com_0 = str(port_list22[0])
com_kou = com_0.split(' ')[0]
try:
serial1 = serial.Serial(com_kou, 115200, timeout=0.15) # com_kou
data1 = self.recv() # 将数据进行解析
self.lineEdit_21.clear()
self.lineEdit_21.setText('串口已打开 g1')
except:
data1 = b'000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000\n'
try:
if serial1.isOpen():
self.lineEdit_21.clear()
self.lineEdit_21.setText('串口已打开 g2')
else:
self.lineEdit_21.clear()
self.lineEdit_21.setText('串口未打开 error1')
except:
self.lineEdit_21.clear()
self.lineEdit_21.setText('检测不到串口 error1')
#主要数据处理
def lka_all(self):
global jishu1
global lka_cs_in, lka_sign_timer_in, lka_on_in, torque_in, angle_main_in, c0_l_in, c0_r_in, azi_main_in, deviation_reminder, \
touchline_sign, Tor_Value, c0_l_lctype, c0_r_rtype, c2_l, c3_l, c2_r, c3_r, degree_confidence_l, degree_confidence_r, zxd
global exit_sum
try:
data1 = self.recv() # 将数据进行解析
except:
data1 = b'0,0,0,0.0,0.00,0.000,0.000,0.00,0.0,0,0.00,0,0,0.000,0.000,0.000,0.000,0,0,3\n'
# print('data1:',data1)
if exit_sum > 9999: #接收不到数据,循环10次之后退出
os._exit(0)
if data1 != b'':
lka_cs_in = data1.split(str.encode(','))[0] # 车速信息
# self.lineEdit.clear()
# self.lineEdit.setText(str(float(lka_cs_in)))
lka_sign_timer_in = data1.split(str.encode(','))[1] # 程序执行到那一步的标志位.
# self.lineEdit_2.clear()
# self.lineEdit_2.setText(str(float(lka_sign_timer_in)))
lka_on_in = data1.split(str.encode(','))[2] # LKA的总开关是否开启
# self.lineEdit_3.clear()
# self.lineEdit_3.setText(str(float(lka_on_in)))
torque_in = data1.split(str.encode(','))[3] # 方向盘的扭矩,驾驶员驾驶的扭矩
# self.lineEdit_4.clear()
# self.lineEdit_4.setText(str(float(torque_in)))
angle_main_in = data1.split(str.encode(','))[4] # 方向盘的转角
# self.lineEdit_5.clear()
# self.lineEdit_5.setText(str(float(angle_main_in)))
c0_l_in = data1.split(str.encode(','))[5] # 距离左边线的距离
# self.lineEdit_6.clear()
# self.lineEdit_6.setText(str(float(c0_l_in)))
c0_r_in = data1.split(str.encode(','))[6] # 距离右边线的距离
# self.lineEdit_7.clear()
# self.lineEdit_7.setText(str(float(c0_r_in)))
azi_main_in = data1.split(str.encode(','))[7] # 车身的方位角
# self.lineEdit_8.clear()
# self.lineEdit_8.setText(str(float(azi_main_in)))
deviation_reminder = data1.split(str.encode(','))[8] # 是否满足偏离条件,左偏为1,右偏为-1
# self.lineEdit_9.clear()
# self.lineEdit_9.setText(str(float(deviation_reminder)))
touchline_sign = data1.split(str.encode(','))[9] # 是否压线
# self.lineEdit_10.clear()
# self.lineEdit_10.setText(str(float(touchline_sign)))
# print(touchline_sign)
Tor_Value = data1.split(str.encode(','))[10] # 发送的扭矩值
# self.lineEdit_11.clear()
# self.lineEdit_11.setText(str(float(Tor_Value)))
c0_l_lctype = data1.split(str.encode(','))[11] # 左车道线类型
# self.lineEdit_12.clear()
# self.lineEdit_12.setText(str(float(c0_l_lctype)))
c0_r_rtype = data1.split(str.encode(','))[12] # 右车道线类型
# self.lineEdit_13.clear()
# self.lineEdit_13.setText(str(float(c0_r_rtype)))
c2_l = data1.split(str.encode(','))[13] # zuo曲率
# self.lineEdit_14.clear()
# self.lineEdit_14.setText(str(float(c2_l)))
c3_l = data1.split(str.encode(','))[14] # 左曲率导数
# self.lineEdit_15.clear()
# self.lineEdit_15.setText(str(float(c3_l)))
c2_r = data1.split(str.encode(','))[15] # 右曲率
# self.lineEdit_16.clear()
# self.lineEdit_16.setText(str(float(c2_r)))
c3_r = data1.split(str.encode(','))[16] # 右曲率倒数
# self.lineEdit_17.clear()
# self.lineEdit_17.setText(str(float(c3_r)))
degree_confidence_l = data1.split(str.encode(','))[17] # 左置信度
# self.lineEdit_18.clear()
# self.lineEdit_18.setText(str(float(degree_confidence_l)))
degree_confidence_r = data1.split(str.encode(','))[18] # 右置信度
# self.lineEdit_19.clear()
# self.lineEdit_19.setText(str(float(degree_confidence_r)))
zxd = data1.split(str.encode(','))[19] # 右置信度
# self.lineEdit_20.clear()
# self.lineEdit_20.setText(str(float(zxd)))
# print('error error1111111111111111111111')
def closecom(self):
global serial1
try:
serial1.close()
self.lineEdit_21.clear()
self.lineEdit_21.setText(str('串口已关闭 g3'))
except:
self.lineEdit_21.clear()
self.lineEdit_21.setText(str('检测不到串口 error2'))
# 实现pushButton_click()函数,textEdit是我们放上去的文本框的id
def dynamicgraph(self):
timer = QTimer(self)
timer.timeout.connect(self.plotData)
timer.start(20)
def quitall(self):
self.closecom()
os._exit(0)
def pausescreenshot(self):
reply = QMessageBox.warning(self,
"警告",
"暂时没有该功能!",
QMessageBox.Yes)
# self.echo(reply)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
# splash = QSplashScreen(PyQt5.QtGui.QPixmap("kaiji.jpg"))
# splash.show()
# # 定义字体格式
# font = PyQt5.QtGui.QFont()
# font.setPointSize(20)
# font.setBold(True)
# font.setWeight(75)
# splash.setFont(font)
# splash.showMessage("正在加载。。。", Qt.AlignCenter, Qt.red, )
# time.sleep(0.5)
# splash.showMessage("启动。。。", Qt.AlignCenter, Qt.red)
# time.sleep(0.5)
# # 设置进程,启动加载页面时可以进行其他操作而不会卡死
# app.processEvents()
my_pyqt_form = MyPyQT_Form()
workThread = WorkThread()
workThread.start()
my_pyqt_form.show()
# # 结束启动页
# splash.finish(my_pyqt_form)
sys.exit(app.exec_())