Merge remote-tracking branch 'origin/master'

# Conflicts:
#	Util/util_pic.py
This commit is contained in:
cdeyw
2024-12-17 19:50:19 +08:00
13 changed files with 341 additions and 283 deletions

View File

@ -37,7 +37,7 @@ class RobotClient(TCPClient):
self.max_angle_interval = 0
def add_sendQuene(self,command): #后面 命令分等级,紧急命令直接执行
self.command_quene.put(command)
log.log_message(logging.INFO, f'{Constant.str_sys_command}{command}')
return
def send_Command(self):

View File

@ -34,18 +34,19 @@ class Catch:
if Constant.Debug or self.robotClient.check_outputQ(self.robotClient.con_ios[1]) and not self.robotClient.check_outputQ(self.robotClient.con_ios[0]):
self.catch_status = CatchStatus.COk
if self.catch_status == CatchStatus.CShake:
if not self.shake_continue.Q(True, 2000):
shakeQ = self.shakePulse.Q(True, 100, 100)
self.robotClient.sendIOControl(self.robotClient.con_ios[2], shakeQ)
if not self.shake_continue.Q(True, 1500):
shakeQ = self.shakePulse.Q(True, 50, 50)
self.robotClient.sendIOControl(self.robotClient.con_ios[2], 1 if shakeQ else 0)
print("正在震动" if shakeQ else "震动结束")
else:
self.shake_continue.SetReset()
self.catch_status = CatchStatus.COk
if Constant.Debug or self.robotClient.check_outputQ(self.robotClient.con_ios[2]):
self.robotClient.sendIOControl(self.robotClient.con_ios[2], False)
print("震动结束")
#if Constant.Debug or self.robotClient.check_outputQ(self.robotClient.con_ios[2]):
self.robotClient.sendIOControl(self.robotClient.con_ios[2], 0)
print("震动结束")
if self.catch_status == CatchStatus.COk:
self.robotClient.sendIOControl(self.robotClient.con_ios[1], 0)
pass

40
CU/Detect.py Normal file
View File

@ -0,0 +1,40 @@
from enum import Enum
import Constant
from Model.Position import Real_Position
from Trace.handeye_calibration import getPosition
from Util.util_time import CClockPulse, CTon
class DetectStatus(Enum):
DNone = 0
DDetect = 1
DOk = 2
class Detect:
def __init__(self,detection):
self.detection = detection
self.detect_status = DetectStatus.DNone
self.detect_position = None
def run(self):
if self.detect_status == DetectStatus.DNone:
return
if self.detect_status == DetectStatus.DDetect:
_, img, xyz, uvw, points = self.detection.get_position(Point_isVision=False, Box_isPoint=True,
First_Depth=True, Iter_Max_Pixel=30,
save_img_point=0, Height_reduce=30, width_reduce=30)
self.detection_image = img.copy()
if xyz == None or uvw == None or points == None:
self.detect_position = None
self.detect_status = DetectStatus.DOk
return
target_position, noraml_base = getPosition(*xyz, *uvw, None, points)
position = Real_Position().init_position(*target_position[:3], *noraml_base[:3])
position.Z = position.Z + 200
self.detect_position = position
self.detect_status = DetectStatus.DOk
if self.detect_status == DetectStatus.DOk:
return

View File

@ -1,4 +1,6 @@
import copy
import logging
import threading
import time
import cv2
@ -8,6 +10,7 @@ from PySide6.QtCore import Signal, QObject
import Constant
import Expection
from CU.Catch import Catch, CatchStatus
from CU.Detect import Detect, DetectStatus
from Model.FeedModel import PositionModel
from Model.Position import Real_Position, Detection_Position
from enum import Enum, IntEnum
@ -61,7 +64,7 @@ class FeedPosition:
class FeedLine:
def __init__(self, id, name, feed_positions:list):
self.feed_positions = feed_positions
self.feed_positions = copy.deepcopy(feed_positions)
self.feeding2end_pos_index = 0
self.origin2start_pos_index = 0
self.start2take_pos_index = 0
@ -180,10 +183,13 @@ class Feeding(QObject):
self.reset_status = ResetStatus.RNone
self.reversed_positions = []
self.current_position = None
self.index=1
self.pos_index = -1
self.pos_near_index = -1
self.catch = Catch(self.robotClient)
self.detect = Detect(self.detection)
self.detect_thread_img = threading.Thread(target=self.detect.run)
self.detect_thread_img.start()
pass
def init_detection_image(self):
@ -206,6 +212,12 @@ class Feeding(QObject):
# 0,
# 0);
# img_path = f'Image/{self.index}.png'
# img = cv2.imread(img_path)
# self.index += 1
# self.index = self.index % 4
# self.detection_image = img
if self.feedConfig == None:
self.feedStatus = FeedStatus.FNone
@ -241,6 +253,7 @@ class Feeding(QObject):
log.log_message(logging.INFO, Constant.str_feed_start)
if not self.robotClient.origin_position.compare(real_position) and not self.is_reverse:
# QMessageBox.information(None, "提示", Constant.str_feed_start_error) # Fuck 引起异常
log.log_message(logging.ERROR, Constant.str_feed_start_error)
self.need_origin_signal.emit(Constant.str_feed_start_error)
self.feedStatus = FeedStatus.FNone
return
@ -250,12 +263,11 @@ class Feeding(QObject):
return
self.feedConfig.feedLine.get_position_list()
self.detect.detect_status = DetectStatus.DNone
# = self.detection.get_position(Point_isVision=False, Box_isPoint=True, First_Depth=True, Iter_Max_Pixel=30,
# # save_img_point=0, Height_reduce=30, width_reduce=30)
self.feedConfig.feedLine.set_take_position(self.get_take_position())
# TODO 获取目标位置
#
self.feed_Mid_Status = FeedMidStatus.FMid_Start
@ -283,7 +295,18 @@ class Feeding(QObject):
if self.robotClient.type_detection == DetectType.EyeOutHand:
self.feed_Mid_Status = FeedMidStatus.FMid_Feed
self.next_position()
if self.detect.detect_status == DetectStatus.DNone:
self.detect.detect_status = DetectStatus.DDetect
elif self.detect.detect_status == DetectStatus.DOk:
if self.detect.detect_position != None:
log.log_message(logging.INFO, Constant.str_feed_takePhoto_success)
self.feedConfig.feedLine.set_take_position(self.detect.detect_position)
self.detection_image = self.detect.detection_image
self.next_position()
self.detect.detect_status = DetectStatus.DNone
else:
log.log_message(logging.ERROR, Constant.str_feed_takePhoto_fail)
self.take_no_photo_sigal.emit()
return
detect_pos_list = []
if not Constant.Debug:
@ -362,8 +385,7 @@ class Feeding(QObject):
# self.sendIOControl(self.robotClient.con_ios[1], 1)
# self.sendIOControl(self.robotClient.con_ios[2], 1)
log.log_message(logging.INFO, "到达抓料点位")
if self.catch.catch_status == CatchStatus.CNone :
self.catch.catch_status = CatchStatus.CTake
return
@ -379,9 +401,10 @@ class Feeding(QObject):
else:
log.log_message(logging.ERROR, Constant.str_feed_takePhoto_fail)
# self.take_no_photo = True
self.take_no_photo_sigal.emit()
# 继续获取图像
# TODO
# self.feedConfig.feedLine.set_take_position(self.get_take_position())
@ -430,7 +453,9 @@ class Feeding(QObject):
self.catch.catch_status = CatchStatus.CNone
time.sleep(self.robotClient.time_delay_put)
# self.detection.get_position(Point_isVision=False, Box_isPoint=True, First_Depth=True, Iter_Max_Pixel=30, save_img_point=0, Height_reduce=30, width_reduce=30)
self.feedConfig.feedLine.set_take_position(self.get_take_position())
# self.feedConfig.feedLine.set_take_position(self.get_take_position())
if self.detect.detect_status == DetectStatus.DNone:
self.detect.detect_status = DetectStatus.DDetect
self.feedConfig.num = self.feedConfig.num - 1
log.log_message(logging.INFO, f'{Constant.str_feed_feed_num}{self.feedConfig.num}')
self.next_position()
@ -486,7 +511,6 @@ class Feeding(QObject):
return
pos_model = self.reversed_positions[self.reverse_index]
if pos_model.status == FeedStatus.FTake.value: # 跳过取袋节点
print('跳过抓袋点位')
pos_model = self.reversed_positions[self.reverse_index + 1]
self.reverse_index = self.reverse_index+1
@ -554,10 +578,10 @@ class Feeding(QObject):
while self.run_reverse and self.reverse_index!=len(reversed_positions):
if self.reverse_index!=0 and not real_position.compare(current_position.get_position()):
continue
print(f'复位第{self.reverse_index}') #todo 缺少比对
#todo 缺少比对
pos_model = reversed_positions[self.reverse_index]
if pos_model.status == FeedStatus.FTake.value: # 跳过取袋节点
print('跳过抓袋点位')
pos_model = reversed_positions[self.reverse_index + 1]
# TODO take节点判断
@ -601,6 +625,7 @@ class Feeding(QObject):
position_instruction.m3 = real_position.U
position_instruction.m4 = real_position.V
position_instruction.m5 = real_position.W
position_instruction.smooth = 4
position_instruction.action = move_type.value
if position_instruction.action == 17:
@ -621,29 +646,28 @@ class Feeding(QObject):
f'U:{position_instruction.m3}-' \
f'V:{position_instruction.m4}-' \
f'W:{position_instruction.m5}'
print(log_str)
try:
log.log_message(logging.INFO, log_str)
except:
print("error")
return
self.robotClient.add_sendQuene(request_command)
pass
def get_take_position(self):
if Constant.Debug:
return self.robotClient.status_model.getRealPosition()
_, img, xyz, uvw, points = self.detection.get_position(Point_isVision=False, Box_isPoint=True, First_Depth=True, Iter_Max_Pixel=30,save_img_point=0, Height_reduce=30, width_reduce=30)
self.detection_image = img
if xyz ==None or uvw==None or points==None:
return None
target_position,noraml_base = getPosition(*xyz,*uvw,None,points)
position = Real_Position().init_position(*target_position[:3],*noraml_base[:3])
position.Z = position.Z+40
return position
# def get_take_position(self):
# if Constant.Debug:
# return self.robotClient.status_model.getRealPosition()
# _, img, xyz, uvw, points = self.detection.get_position(Point_isVision=False, Box_isPoint=True, First_Depth=True, Iter_Max_Pixel=30,save_img_point=0, Height_reduce=30, width_reduce=30)
# self.detection_image = img.copy()
# if xyz ==None or uvw==None or points==None:
# return None
# target_position,noraml_base = getPosition(*xyz,*uvw,None,points)
#
# position = Real_Position().init_position(*target_position[:3],*noraml_base[:3])
# position.Z = position.Z+200
# return position
def next_start(self,reverse=False):
print(f'原点到初始位置的第{self.feedConfig.feedLine.origin2start_pos_index}')
start_pos = self.feedConfig.feedLine.get_next_start_position(reverse)
self.feedStatus = FeedStatus(start_pos.status) if self.feedStatus != FeedStatus.FNone else FeedStatus.FNone
if start_pos.lineType == LineType.CureMid.value:
@ -655,13 +679,13 @@ class Feeding(QObject):
self.feedStatus = None
log.log_message(logging.ERROR, Constant.str_feed_angle_error)
else:
self.sendTargPosition(real_position=start_pos.get_position(),speed=self.robotClient.debug_speed,move_type=MoveType.WORLD)
self.sendTargPosition(real_position=start_pos.get_position(),speed=self.robotClient.debug_speed,move_type=MoveType.AXIS)
else:
self.sendTargPosition(real_position=start_pos.get_position(),speed=self.robotClient.debug_speed)
pass
def next_take(self,reverse=False):
print(f'初始位置到拍照点的第{self.feedConfig.feedLine.start2take_pos_index}')
take_pos = self.feedConfig.feedLine.get_next_take_position(reverse)
self.feedStatus = FeedStatus(take_pos.status) if self.feedStatus != FeedStatus.FNone else FeedStatus.FNone
if take_pos.lineType == LineType.CureMid.value:
@ -673,7 +697,6 @@ class Feeding(QObject):
pass
def next_Feed(self,reverse=False):
print(f'拍照到抛料回来的第{self.feedConfig.feedLine.feeding2end_pos_index}')
feed_pos = self.feedConfig.feedLine.get_next_feed_position(reverse)
self.feedStatus = FeedStatus(feed_pos.status) if self.feedStatus != FeedStatus.FNone else FeedStatus.FNone
if feed_pos.lineType == LineType.CureMid.value:

View File

@ -2,150 +2,163 @@
id = 1
name = 反应釜1
[Position2]
x = 421.397
y = 2095.76
z = 1403.803
u = 2.787
v = 17.14
w = -95.084
id = 2
order = 0
lineid = 1
status = 3
linetype = 2
[FeedLine2]
id = 2
name = 未定义
name = 反应釜2
[Position3]
x = 1.0
y = 2.0
z = 0.0
u = 0.0
v = 0.0
w = 0.0
x = 1882.882568
y = 786.492737
z = 1203.552246
u = 11.403661
v = -0.985981
w = -125.710434
id = 3
order = 0
lineid = 2
status = 3
linetype = 0
[Position5]
x = 7.0
y = 50.0
z = 1.0
u = 12.0
v = 0.0
w = 1.0
id = 5
[Position4]
x = 1868.06311
y = 872.854065
z = 1265.651855
u = 12.479004
v = 1.611398
w = -127.729263
id = 4
order = 2
lineid = 1
status = 4
linetype = 0
[Position4]
x = 7.0
y = 50.0
z = 1.0
u = 12.0
v = 0.0
w = 1.0
id = 4
order = 3
lineid = 1
status = 2
linetype = 0
[Position1]
x = 7.0
y = 50.0
z = 1.0
u = 12.0
v = 0.0
w = 1.0
x = 348.84654634488436
y = 1836.958560527403
z = 223.84778176988266
u = 2.3775411141593388
v = -0.7172354339862681
w = 95.0492701673298
id = 1
order = 4
lineid = 1
status = 5
linetype = 0
[Position6]
x = 7.0
y = 50.0
z = 1.0
u = 12.0
v = 0.0
w = 1.0
id = 6
order = 1
[Position7]
x = 2218.886475
y = 483.322144
z = 1371.784302
u = 8.190439
v = 7.692511
w = -143.628922
id = 7
order = 0
lineid = 1
status = 2
status = 3
linetype = 0
[Position7]
x = 7.0
y = 50.0
z = 1.0
u = 12.0
v = 0.0
w = 1.0
id = 7
[Position8]
x = 807.391785
y = 2337.584473
z = 1852.736816
u = -0.412497
v = 9.080836
w = -110.687553
id = 8
order = 5
lineid = 1
status = 6
linetype = 0
[Position8]
x = 7.0
y = 50.0
z = 1.0
u = 12.0
v = 0.0
w = 1.0
id = 8
[Position9]
x = 1759.061523
y = 1738.14978
z = 1852.472412
u = 0.723375
v = 9.708878
w = -126.572548
id = 9
order = 6
lineid = 1
status = 7
linetype = 0
[Position9]
x = 7.0
y = 50.0
z = 1.0
u = 12.0
v = 0.0
w = 1.0
id = 9
[Position10]
x = 1759.061523
y = 1738.14978
z = 1852.472412
u = 0.723375
v = 9.708878
w = -126.572548
id = 10
order = 7
lineid = 1
status = 8
linetype = 0
[Position10]
x = 7.0
y = 50.0
z = 1.0
u = 12.0
v = 0.0
w = 1.0
id = 10
order = 8
lineid = 1
status = 9
linetype = 0
[Position11]
x = 7.0
y = 50.0
z = 1.0
u = 12.0
v = 0.0
w = 1.0
x = 1960.667847
y = 837.290405
z = 1688.202637
u = -0.347183
v = 0.356827
w = -147.846161
id = 11
order = 9
order = 8
lineid = 1
status = 3
linetype = 0
[Position12]
x = 1643.540039
y = -24.557989
z = 995.504272
u = 0.167181
v = 2.42627
w = 177.088989
id = 12
order = 9
lineid = 1
status = 9
linetype = 0
[Position2]
x = 762.708984
y = 1915.674561
z = 1265.639648
u = 12.478849
v = 1.611004
w = -84.483177
id = 2
order = 3
lineid = 1
status = 3
linetype = 0
[Position5]
x = 1868.06311
y = 872.854065
z = 1265.651855
u = 12.479004
v = 1.611398
w = -127.729263
id = 5
order = 1
lineid = 1
status = 2
linetype = 0
[Position6]
x = 1425.824829
y = 952.627869
z = 1364.459839
u = -5.591513
v = -38.629269
w = -114.406639
id = 6
order = 1
lineid = 2
status = 2
linetype = 0

View File

@ -3,7 +3,7 @@ import os
Debug = True
IO_EmergencyPoint = 3
bag_height = 10 # 一袋的高度
position_accuracy = 0.05
position_accuracy = 0.1
manual_adjust_accuracy = 1
# speed = 10
# shake_speed = 20
@ -61,6 +61,7 @@ str_feed_start_error = '请先复位到原点'
str_feed_return_original_position_fail = '机械臂未按照实际路线点移动,未能寻找到适配路径点位'
str_feed_reset_no_line_error = '未定义的线段'
str_feed_angle_error = '角度差距过大,停止运行'
str_feed_reset_start = '开始复位'
str_sys_start = '进入系统'
str_sys_exit = '退出系统'
str_sys_switch_tool = '切换到工具坐标'
@ -78,6 +79,7 @@ str_sys_log_IO_error = 'IO更新失败'
str_sys_log_alarm_error = '发生报警:'
str_sys_log_move_error = '请填写全部坐标'
str_sys_set_position_error = '未选中行'
str_sys_command = '发送命令'
str_tcp_robot_connect_fail = '连接失败'
str_tcp_robot_connect_success = '连接成功'
str_tcp_robot_data_error = '数据解析错误'

View File

@ -1,3 +1,5 @@
import math
from Constant import position_accuracy
class Position:
def __init__(self):
@ -7,17 +9,30 @@ class Position:
self.U = 0.0
self.V = 0.0
self.W = 0.0
def compare(self,position):
if self.X-position.X<position_accuracy and \
self.Y-position.Y<position_accuracy and \
self.Z - position.Z < position_accuracy and \
self.U - position.U < position_accuracy and \
self.V - position.V < position_accuracy and \
self.W - position.W < position_accuracy:
distance = math.sqrt((self.X-position.X)**2+
(self.Y-position.Y)**2+
(self.Z - position.Z)**2+
(self.U - position.U)**2+
(self.V - position.V)**2+
(self.W - position.W) ** 2)
if distance<=position_accuracy:
return True
else:
return False
pass
# def compare(self,position):
# if self.X-position.X<position_accuracy and \
# self.Y-position.Y<position_accuracy and \
# self.Z - position.Z < position_accuracy and \
# self.U - position.U < position_accuracy and \
# self.V - position.V < position_accuracy and \
# self.W - position.W < position_accuracy:
# return True
# else:
# return False
# pass
def is_error_angel_move(self,position,interval):
if self.X - position.X >= interval or \

View File

@ -189,8 +189,7 @@ class CMDInstructRequest:
if len(self.instructions) != 0:
model_str = model_str+',"instructions":'+"[{"+self.instructions[0].toString()+"}]"+"}"
else:
model_str = model_str+',"instructions":'+"[{""}]"+"}" #model_str+"}"
print(model_str)
model_str = model_str+',"instructions":'+"[]"+"}" #model_str+"}"
return model_str
class CMDInstructReply:

View File

@ -47,14 +47,14 @@ photo_v5 = 0.0
photo_w5 = 1.0
linecount = 2
remain_linename = 1
remain_count = 0
io_take_addr = 3
io_zip_addr = 2
io_shake_addr = 10
remain_count = 574
io_take_addr = 8
io_zip_addr = 11
io_shake_addr = 12
takedelay = 0.2
putdelay = 0.1
shakedelay = 1.0
max_angle_interval=20
max_angle_interval = 20
[Speed]
debug_speed = 50

View File

@ -1,13 +1,25 @@
import logging
import cv2
from PIL.ImageQt import QImage, QPixmap
from Util.util_log import log
def cv2_to_qpixmap(cv_img):
"""将OpenCV图像转换为QPixmap"""
height, width, channel = cv_img.shape
bytes_per_line = 3 * width
q_img = QImage(cv_img.data, width, height, bytes_per_line, QImage.Format_RGB888)
return QPixmap.fromImage(q_img)
# img = cv_img.copy()
# cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB)
try:
img = cv_img.copy()
height, width, channel = img.shape
bytes_per_line = 3 * width
q_img = QImage(img.data, width, height, bytes_per_line, QImage.Format_RGB888)
return QPixmap.fromImage(q_img)
except Exception as e:
print(e)
log.log_message(logging.ERROR,e)
return None
# def cv2_to_qpixmap(cv_img):
# """将OpenCV图像转换为QPixmap"""

3
app.py
View File

@ -910,7 +910,6 @@ class MainWindow(QMainWindow, Ui_MainWindow):
else:
pause_command.cmdData.append("0")
request_command = pause_command.toString()
print(request_command)
self.robotClient.add_sendQuene(request_command)
def send_clear_alarm_command(self, pause: bool):
@ -918,7 +917,6 @@ class MainWindow(QMainWindow, Ui_MainWindow):
pause_command.cmdData.append("clearAlarmContinue")
pause_command.cmdData.append("1")
request_command = pause_command.toString()
print(request_command)
log_str = f'暂停:{pause}'
self.robotClient.add_sendQuene(request_command)
@ -927,7 +925,6 @@ class MainWindow(QMainWindow, Ui_MainWindow):
switch_command.cmdData.append("switchTool")
switch_command.cmdData.append("2")
request_command = switch_command.toString()
print(request_command)
self.robotClient.add_sendQuene(request_command)

67
main.py
View File

@ -1,6 +1,7 @@
import configparser
import json
import logging
import os
import queue
import sys
import threading
@ -8,6 +9,7 @@ from multiprocessing import Process
import traceback
import PySide6
import cv2
from PyQt5.uic.properties import QtWidgets
from PySide6 import QtCore
from PySide6.QtCore import QThread, Signal, Slot, QObject, QEvent, QTimer
@ -46,6 +48,7 @@ from view.ResetView import StopDialog
class MainWindow(QMainWindow, Ui_MainWindow):
updateUI_seting = Signal()
def __init__(self):
super(MainWindow, self).__init__()
self.setupUi(self)
@ -396,8 +399,6 @@ class MainWindow(QMainWindow, Ui_MainWindow):
continue
position_model = PositionModel(i)
break
if position_model.id == 999:
print("d")
if self.tableWidget_line_positions.currentRow()==-1:
row_i = self.tableWidget_line_positions.rowCount()
else:
@ -589,6 +590,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.main_threading = None
self.detection_person = None # DetectionPerson()
self.cton_take_no_photo = CRisOrFall()
self.index = 1
self.configReader.read(Constant.set_ini)
ip = self.configReader.get('Robot_Feed', 'IPAddress')
@ -642,6 +644,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.last_time = time.time()
self.remain_lineName = self.configReader.get('Robot_Feed', 'remain_lineName')
self.remain_Count = int(self.configReader.get('Robot_Feed', 'remain_Count'))
self.updateUI_seting.connect(self.update_seting_frame)
try:
self.robotClient.CreatConnect()
except:
@ -812,12 +815,13 @@ class MainWindow(QMainWindow, Ui_MainWindow):
def start_Runing(self):
self.main_threading = Thread(target=self.run)
self.robot_connect_threading = Thread(target=self.robotClient.run)
self.main_UI_threading = Thread(target=self.updateUI)
self.detect_person_thread = Thread(target=self.run_detect_persion)
self.main_threading.start()
self.robot_connect_threading.start()
self.main_UI_threading = Thread(target=self.updateUI)
self.main_UI_threading.start()
self.detect_person_thread = Thread(target=self.run_detect_persion)
self.detect_person_thread.start()
pass
def check_continue(self):
@ -1035,9 +1039,9 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.robotClient.time_delay_shake = time_delay_shake
self.configReader = configparser.ConfigParser()
self.configReader.read(Constant.set_ini)
self.configReader.set('Robot_Feed', 'solenoid_valve1_addr', str(take_addr))
self.configReader.set('Robot_Feed', 'solenoid_valve2_addr', str(press_addr))
self.configReader.set('Robot_Feed', 'solenoid_valve3_addr', str(shake_addr))
self.configReader.set('Robot_Feed', 'io_take_addr', str(take_addr))
self.configReader.set('Robot_Feed', 'io_zip_addr', str(press_addr))
self.configReader.set('Robot_Feed', 'io_shake_addr', str(shake_addr))
self.configReader.set('Robot_Feed', 'takeDelay', str(time_delay_take))
self.configReader.set('Robot_Feed', 'putDelay', str(time_delay_put))
self.configReader.set('Robot_Feed', 'shakeDelay', str(time_delay_shake))
@ -1177,8 +1181,6 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.send_start_tool_command()
def send_reset_button_click(self):
# TODO 清楚痕迹
# TODO 开启自动
# 触发自动运行
if self.robotClient.status_model.curMode != 7:
self.send_switch_tool_command()
@ -1189,6 +1191,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
line_head = self.comboBox_lineIndex.currentData()
self.send_clear_auto_command()
log.log_message(logging.INFO, Constant.str_feed_reset_start)
#safe_position = self.feedLine_dict[line_head].safe_position
# self.send_position_command(safe_position.X, safe_position.Y, safe_position.Z, safe_position.U, safe_position.V, safe_position.W,move_type=MoveType.WORLD)
if self.remain_lineName != '':
@ -1205,8 +1208,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
log.log_message(logging.ERROR, Constant.str_feed_reset_no_line_error)
return
self.feeding.reset_status = ResetStatus.RStart
dialog_reset = StopDialog()
dialog_reset.stop_thread_signal.connect(self.stop_reset_thread)
# dialog_reset = StopDialog()
# dialog_reset.stop_thread_signal.connect(self.stop_reset_thread)
else:
log.log_message(logging.ERROR, Constant.str_feed_reset_no_line_error)
return
@ -1364,13 +1367,14 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.label_date.setText(datetime.now().strftime("%Y-%m-%d"))
self.label_time.setText(datetime.now().strftime("%H:%M:%S"))
self.updateUI_Position()
self.updateUI_label_detection()
self.updateUI_label_status()
self.updateUI_frame_sign(self.feeding.feedStatus)
self.updateUI_IOPanel()
self.updateUI_seting.emit()
def update_seting_frame(self):
self.updateUI_Position()
self.updateUI_label_detection()
self.updateUI_label_status()
self.updateUI_frame_sign(self.feeding.feedStatus)
self.updateUI_IOPanel()
def updateRobotSeting(self):
self.lineEdit_origin_x.setText(str(self.robotClient.origin_position.X))
@ -1380,6 +1384,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.lineEdit_origin_v.setText(str(self.robotClient.origin_position.V))
self.lineEdit_origin_w.setText(str(self.robotClient.origin_position.W))
@Slot()
def show_no_photo_message_box(self):
self.feeding.pause = True
self.send_pause_command(pause=1)
@ -1409,6 +1414,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
pass
def updateUI_label_detection(self):
backgroud_img = Util.util_pic.cv2_to_qpixmap(self.feeding.detection_image)
if backgroud_img == None:
return
backgroud_img = backgroud_img.scaled(self.label_showDetection.size().width(),self.label_showDetection.size().height(), Qt.AspectRatioMode.IgnoreAspectRatio,Qt.TransformationMode.SmoothTransformation)
self.label_showDetection.setPixmap(backgroud_img)
@ -1560,7 +1567,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
clear_command = CMDInstructRequest()
request_command = clear_command.toString()
log.log_message(logging.INFO, Constant.str_sys_clearAlarm)
self.command_quene.put(request_command)
self.robotClient.add_sendQuene(request_command)
# self.command_quene.put(request_command)
def send_position_command(self, x1, x2, x3, x4, x5, x6, move_type: MoveType = MoveType.WORLD):
@ -1594,12 +1602,11 @@ class MainWindow(QMainWindow, Ui_MainWindow):
else:
pause_command.cmdData.append("0")
request_command = pause_command.toString()
print(request_command)
self.robotClient.add_sendQuene(request_command)
def send_emergency_alarm_command(self):
self.feeding.feedStatus = FeedStatus.FNone
self.feeding.feedConfig.num = 0
stop_command = CMDRequest()
stop_command.cmdData.append("actionStop")
stop_command.cmdData.append("1")
@ -1607,18 +1614,17 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.send_clear_auto_command()
self.robotClient.add_sendQuene(request_command)
self.feeding.send_emergency_sound()
self.feeding.feedConfig.num = 0
log.log_message(logging.INFO, Constant.str_sys_emergencyStop)
#TODO
def send_clear_alarm_command(self, pause: bool):
self.send_start_tool_command()
self.send_clear_auto_command()
pause_command = CMDRequest()
pause_command.cmdData.append("StopButton")
pause_command.cmdData.append("1")
request_command = pause_command.toString()
print(request_command)
log_str = f'暂停:{pause}'
self.robotClient.add_sendQuene(request_command)
def send_switch_tool_command(self):
@ -1626,8 +1632,6 @@ class MainWindow(QMainWindow, Ui_MainWindow):
switch_command.cmdData.append("switchTool")
switch_command.cmdData.append("2")
request_command = switch_command.toString()
print(request_command)
self.robotClient.add_sendQuene(request_command)
def send_start_tool_command(self):
@ -1635,8 +1639,6 @@ class MainWindow(QMainWindow, Ui_MainWindow):
switch_command.cmdData.append("startButton")
switch_command.cmdData.append("1")
request_command = switch_command.toString()
print(request_command)
self.robotClient.add_sendQuene(request_command)
def show_messagebox_of_person(self):
@ -1841,6 +1843,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.configReader.write(open(Constant.set_ini, 'w', encoding='utf-8'))
log.log_message(logging.INFO, f'设置原点:{x},{y},{z}')
except:
log.log_message(logging.ERROR, f'设置原点失败')
self.show_infomessage_box("设置原点失败")
@ -1966,14 +1969,16 @@ def handle_exception(exc_type, exc_value, exc_tb):
log.log_message(logging.INFO, "用户主动退出程序")
return
log.log_message(logging.ERROR, exc_value)
print("未处理的异常:", exc_type, exc_value)
traceback.print_exception(exc_type, exc_value, exc_tb)
if __name__ == "__main__":
app = MyApplication(sys.argv)
window = MainWindow()
window.show()
sys.excepthook = handle_exception # 你的 PySide 应用程序代码 pass
sys.exit(app.exec())
sys.excepthook = handle_exception
try :
sys.exit(app.exec())
except Exception as e:
log.log_message(logging.ERROR, e)

135
test.py
View File

@ -1,100 +1,51 @@
from PySide6.QtWidgets import QApplication, QPushButton, QMainWindow, QMessageBox
from PySide6.QtCore import QPropertyAnimation, QPoint, QParallelAnimationGroup, QEasingCurve, Property
from PySide6.QtGui import QColor, QPainter, QBrush
from PySide6.QtCore import Qt
from PySide6.QtCore import QThread, Signal, Slot
from PySide6.QtWidgets import QApplication, QDialog, QLabel, QVBoxLayout, QPushButton
import sys
import time
import Constant
# 定义子线程类
class WorkerThread(QThread):
# 创建信号,子线程处理完成后通知主线程弹窗
show_dialog_signal = Signal(str)
def run(self):
# 模拟子线程的工作
time.sleep(3) # 假设任务执行需要 3 秒钟
self.show_dialog_signal.emit("任务完成,弹出对话框") # 发出信号,通知主线程弹窗
print("子线程")
class RippleButton(QPushButton):
def __init__(self, text, parent=None):
super().__init__(text, parent)
self._ripple_radius = 0
self._ripple_opacity = 1.0
self.ripple_position = QPoint()
self.animation_group = QParallelAnimationGroup(self) # 设置父对象
self.setStyleSheet("background-color: #3498db; color: white; border-radius: 5px; padding: 10px;")
self.setAttribute(Qt.WA_StaticContents)
def paintEvent(self, event):
super().paintEvent(event)
if self._ripple_radius > 0:
painter = QPainter(self)
painter.setRenderHint(QPainter.Antialiasing)
color = QColor(255, 255, 255)
color.setAlphaF(self._ripple_opacity)
painter.setBrush(QBrush(color))
painter.setPen(Qt.NoPen)
painter.drawEllipse(self.ripple_position, self._ripple_radius, self._ripple_radius)
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
self.ripple_position = event.pos()
self.startRippleEffect()
super().mousePressEvent(event)
def startRippleEffect(self):
# 取消之前的动画
self.animation_group.stop()
self.animation_group.clear()
# 创建半径动画
radius_animation = QPropertyAnimation(self, b"rippleRadius")
radius_animation.setDuration(600)
radius_animation.setStartValue(0)
# 计算最大半径,确保覆盖按钮
max_radius = max(self.width(), self.height()) * 1.5
radius_animation.setEndValue(max_radius)
radius_animation.setEasingCurve(QEasingCurve.OutQuad)
# 创建透明度动画
opacity_animation = QPropertyAnimation(self, b"rippleOpacity")
opacity_animation.setDuration(600)
opacity_animation.setStartValue(0.5) # 初始透明度可以调整
opacity_animation.setEndValue(0.0)
opacity_animation.setEasingCurve(QEasingCurve.OutQuad)
# 将动画添加到动画组
self.animation_group.addAnimation(radius_animation)
self.animation_group.addAnimation(opacity_animation)
self.animation_group.start()
# 使用 @Property 装饰器正确定义属性
def getRippleRadius(self):
return self._ripple_radius
def setRippleRadius(self, radius):
self._ripple_radius = radius
self.update()
rippleRadius = Property(float, getRippleRadius, setRippleRadius)
def getRippleOpacity(self):
return self._ripple_opacity
def setRippleOpacity(self, opacity):
self._ripple_opacity = opacity
self.update()
rippleOpacity = Property(float, getRippleOpacity, setRippleOpacity)
class MainWindow(QMainWindow):
# 定义主窗口类
class MainWindow(QDialog):
def __init__(self):
super().__init__()
self.setWindowTitle("水滴扩散按钮示例")
self.setFixedSize(400, 300)
self.setWindowTitle("主窗口")
self.setGeometry(100, 100, 300, 200)
self.button = RippleButton("点击我", self)
self.button.setGeometry(150, 130, 100, 40)
self.button.clicked.connect(self.on_button_click)
def on_button_click(self):
print("按钮被点击了!")
QMessageBox.information(None, "提示", Constant.str_feed_photo_error_msgbox)
print("sadf")
self.button = QPushButton("开始任务", self)
self.button.clicked.connect(self.start_task)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())
layout = QVBoxLayout(self)
layout.addWidget(self.button)
@Slot(str)
def show_dialog(self, message):
# 接收到信号后显示弹窗
dialog = QDialog(self)
dialog.setWindowTitle("子线程通知")
label = QLabel(message, dialog)
dialog_layout = QVBoxLayout(dialog)
dialog_layout.addWidget(label)
dialog.exec()
def start_task(self):
# 创建并启动子线程
self.thread = WorkerThread()
self.thread.show_dialog_signal.connect(self.show_dialog) # 连接信号到主线程的槽函数
self.thread.start()
# 创建应用程序
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())