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 self.max_angle_interval = 0
def add_sendQuene(self,command): #后面 命令分等级,紧急命令直接执行 def add_sendQuene(self,command): #后面 命令分等级,紧急命令直接执行
self.command_quene.put(command) self.command_quene.put(command)
log.log_message(logging.INFO, f'{Constant.str_sys_command}{command}')
return return
def send_Command(self): 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]): 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 self.catch_status = CatchStatus.COk
if self.catch_status == CatchStatus.CShake: if self.catch_status == CatchStatus.CShake:
if not self.shake_continue.Q(True, 2000): if not self.shake_continue.Q(True, 1500):
shakeQ = self.shakePulse.Q(True, 100, 100) shakeQ = self.shakePulse.Q(True, 50, 50)
self.robotClient.sendIOControl(self.robotClient.con_ios[2], shakeQ) self.robotClient.sendIOControl(self.robotClient.con_ios[2], 1 if shakeQ else 0)
print("正在震动" if shakeQ else "震动结束") print("正在震动" if shakeQ else "震动结束")
else: else:
self.shake_continue.SetReset() self.shake_continue.SetReset()
self.catch_status = CatchStatus.COk self.catch_status = CatchStatus.COk
if Constant.Debug or self.robotClient.check_outputQ(self.robotClient.con_ios[2]): #if Constant.Debug or self.robotClient.check_outputQ(self.robotClient.con_ios[2]):
self.robotClient.sendIOControl(self.robotClient.con_ios[2], False) self.robotClient.sendIOControl(self.robotClient.con_ios[2], 0)
print("震动结束") print("震动结束")
if self.catch_status == CatchStatus.COk: if self.catch_status == CatchStatus.COk:
self.robotClient.sendIOControl(self.robotClient.con_ios[1], 0)
pass 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 logging
import threading
import time import time
import cv2 import cv2
@ -8,6 +10,7 @@ from PySide6.QtCore import Signal, QObject
import Constant import Constant
import Expection import Expection
from CU.Catch import Catch, CatchStatus from CU.Catch import Catch, CatchStatus
from CU.Detect import Detect, DetectStatus
from Model.FeedModel import PositionModel from Model.FeedModel import PositionModel
from Model.Position import Real_Position, Detection_Position from Model.Position import Real_Position, Detection_Position
from enum import Enum, IntEnum from enum import Enum, IntEnum
@ -61,7 +64,7 @@ class FeedPosition:
class FeedLine: class FeedLine:
def __init__(self, id, name, feed_positions:list): 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.feeding2end_pos_index = 0
self.origin2start_pos_index = 0 self.origin2start_pos_index = 0
self.start2take_pos_index = 0 self.start2take_pos_index = 0
@ -180,10 +183,13 @@ class Feeding(QObject):
self.reset_status = ResetStatus.RNone self.reset_status = ResetStatus.RNone
self.reversed_positions = [] self.reversed_positions = []
self.current_position = None self.current_position = None
self.index=1
self.pos_index = -1 self.pos_index = -1
self.pos_near_index = -1 self.pos_near_index = -1
self.catch = Catch(self.robotClient) 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 pass
def init_detection_image(self): def init_detection_image(self):
@ -206,6 +212,12 @@ class Feeding(QObject):
# 0, # 0,
# 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: if self.feedConfig == None:
self.feedStatus = FeedStatus.FNone self.feedStatus = FeedStatus.FNone
@ -241,6 +253,7 @@ class Feeding(QObject):
log.log_message(logging.INFO, Constant.str_feed_start) log.log_message(logging.INFO, Constant.str_feed_start)
if not self.robotClient.origin_position.compare(real_position) and not self.is_reverse: if not self.robotClient.origin_position.compare(real_position) and not self.is_reverse:
# QMessageBox.information(None, "提示", Constant.str_feed_start_error) # Fuck 引起异常 # 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.need_origin_signal.emit(Constant.str_feed_start_error)
self.feedStatus = FeedStatus.FNone self.feedStatus = FeedStatus.FNone
return return
@ -250,12 +263,11 @@ class Feeding(QObject):
return return
self.feedConfig.feedLine.get_position_list() 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, # = 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) # # save_img_point=0, Height_reduce=30, width_reduce=30)
self.feedConfig.feedLine.set_take_position(self.get_take_position())
# TODO 获取目标位置 # TODO 获取目标位置
# #
self.feed_Mid_Status = FeedMidStatus.FMid_Start self.feed_Mid_Status = FeedMidStatus.FMid_Start
@ -283,7 +295,18 @@ class Feeding(QObject):
if self.robotClient.type_detection == DetectType.EyeOutHand: if self.robotClient.type_detection == DetectType.EyeOutHand:
self.feed_Mid_Status = FeedMidStatus.FMid_Feed 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 return
detect_pos_list = [] detect_pos_list = []
if not Constant.Debug: 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[1], 1)
# self.sendIOControl(self.robotClient.con_ios[2], 1) # self.sendIOControl(self.robotClient.con_ios[2], 1)
log.log_message(logging.INFO, "到达抓料点位")
if self.catch.catch_status == CatchStatus.CNone : if self.catch.catch_status == CatchStatus.CNone :
self.catch.catch_status = CatchStatus.CTake self.catch.catch_status = CatchStatus.CTake
return return
@ -379,9 +401,10 @@ class Feeding(QObject):
else: else:
log.log_message(logging.ERROR, Constant.str_feed_takePhoto_fail) log.log_message(logging.ERROR, Constant.str_feed_takePhoto_fail)
# self.take_no_photo = True # self.take_no_photo = True
self.take_no_photo_sigal.emit()
# 继续获取图像 # 继续获取图像
# TODO # TODO
# self.feedConfig.feedLine.set_take_position(self.get_take_position())
@ -430,7 +453,9 @@ class Feeding(QObject):
self.catch.catch_status = CatchStatus.CNone self.catch.catch_status = CatchStatus.CNone
time.sleep(self.robotClient.time_delay_put) 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.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 self.feedConfig.num = self.feedConfig.num - 1
log.log_message(logging.INFO, f'{Constant.str_feed_feed_num}{self.feedConfig.num}') log.log_message(logging.INFO, f'{Constant.str_feed_feed_num}{self.feedConfig.num}')
self.next_position() self.next_position()
@ -486,7 +511,6 @@ class Feeding(QObject):
return return
pos_model = self.reversed_positions[self.reverse_index] pos_model = self.reversed_positions[self.reverse_index]
if pos_model.status == FeedStatus.FTake.value: # 跳过取袋节点 if pos_model.status == FeedStatus.FTake.value: # 跳过取袋节点
print('跳过抓袋点位')
pos_model = self.reversed_positions[self.reverse_index + 1] pos_model = self.reversed_positions[self.reverse_index + 1]
self.reverse_index = 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): 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()): if self.reverse_index!=0 and not real_position.compare(current_position.get_position()):
continue continue
print(f'复位第{self.reverse_index}') #todo 缺少比对 #todo 缺少比对
pos_model = reversed_positions[self.reverse_index] pos_model = reversed_positions[self.reverse_index]
if pos_model.status == FeedStatus.FTake.value: # 跳过取袋节点 if pos_model.status == FeedStatus.FTake.value: # 跳过取袋节点
print('跳过抓袋点位')
pos_model = reversed_positions[self.reverse_index + 1] pos_model = reversed_positions[self.reverse_index + 1]
# TODO take节点判断 # TODO take节点判断
@ -601,6 +625,7 @@ class Feeding(QObject):
position_instruction.m3 = real_position.U position_instruction.m3 = real_position.U
position_instruction.m4 = real_position.V position_instruction.m4 = real_position.V
position_instruction.m5 = real_position.W position_instruction.m5 = real_position.W
position_instruction.smooth = 4
position_instruction.action = move_type.value position_instruction.action = move_type.value
if position_instruction.action == 17: if position_instruction.action == 17:
@ -621,29 +646,28 @@ class Feeding(QObject):
f'U:{position_instruction.m3}-' \ f'U:{position_instruction.m3}-' \
f'V:{position_instruction.m4}-' \ f'V:{position_instruction.m4}-' \
f'W:{position_instruction.m5}' f'W:{position_instruction.m5}'
print(log_str)
try: try:
log.log_message(logging.INFO, log_str) log.log_message(logging.INFO, log_str)
except: except:
print("error") return
self.robotClient.add_sendQuene(request_command) self.robotClient.add_sendQuene(request_command)
pass pass
def get_take_position(self): # def get_take_position(self):
if Constant.Debug: # if Constant.Debug:
return self.robotClient.status_model.getRealPosition() # 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) # _, 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 # self.detection_image = img.copy()
if xyz ==None or uvw==None or points==None: # if xyz ==None or uvw==None or points==None:
return None # return None
target_position,noraml_base = getPosition(*xyz,*uvw,None,points) # target_position,noraml_base = getPosition(*xyz,*uvw,None,points)
#
position = Real_Position().init_position(*target_position[:3],*noraml_base[:3]) # position = Real_Position().init_position(*target_position[:3],*noraml_base[:3])
position.Z = position.Z+40 # position.Z = position.Z+200
return position # return position
def next_start(self,reverse=False): def next_start(self,reverse=False):
print(f'原点到初始位置的第{self.feedConfig.feedLine.origin2start_pos_index}')
start_pos = self.feedConfig.feedLine.get_next_start_position(reverse) start_pos = self.feedConfig.feedLine.get_next_start_position(reverse)
self.feedStatus = FeedStatus(start_pos.status) if self.feedStatus != FeedStatus.FNone else FeedStatus.FNone self.feedStatus = FeedStatus(start_pos.status) if self.feedStatus != FeedStatus.FNone else FeedStatus.FNone
if start_pos.lineType == LineType.CureMid.value: if start_pos.lineType == LineType.CureMid.value:
@ -655,13 +679,13 @@ class Feeding(QObject):
self.feedStatus = None self.feedStatus = None
log.log_message(logging.ERROR, Constant.str_feed_angle_error) log.log_message(logging.ERROR, Constant.str_feed_angle_error)
else: 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: else:
self.sendTargPosition(real_position=start_pos.get_position(),speed=self.robotClient.debug_speed) self.sendTargPosition(real_position=start_pos.get_position(),speed=self.robotClient.debug_speed)
pass pass
def next_take(self,reverse=False): def next_take(self,reverse=False):
print(f'初始位置到拍照点的第{self.feedConfig.feedLine.start2take_pos_index}')
take_pos = self.feedConfig.feedLine.get_next_take_position(reverse) take_pos = self.feedConfig.feedLine.get_next_take_position(reverse)
self.feedStatus = FeedStatus(take_pos.status) if self.feedStatus != FeedStatus.FNone else FeedStatus.FNone self.feedStatus = FeedStatus(take_pos.status) if self.feedStatus != FeedStatus.FNone else FeedStatus.FNone
if take_pos.lineType == LineType.CureMid.value: if take_pos.lineType == LineType.CureMid.value:
@ -673,7 +697,6 @@ class Feeding(QObject):
pass pass
def next_Feed(self,reverse=False): def next_Feed(self,reverse=False):
print(f'拍照到抛料回来的第{self.feedConfig.feedLine.feeding2end_pos_index}')
feed_pos = self.feedConfig.feedLine.get_next_feed_position(reverse) feed_pos = self.feedConfig.feedLine.get_next_feed_position(reverse)
self.feedStatus = FeedStatus(feed_pos.status) if self.feedStatus != FeedStatus.FNone else FeedStatus.FNone self.feedStatus = FeedStatus(feed_pos.status) if self.feedStatus != FeedStatus.FNone else FeedStatus.FNone
if feed_pos.lineType == LineType.CureMid.value: if feed_pos.lineType == LineType.CureMid.value:

View File

@ -2,150 +2,163 @@
id = 1 id = 1
name = 反应釜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] [FeedLine2]
id = 2 id = 2
name = 未定义 name = 反应釜2
[Position3] [Position3]
x = 1.0 x = 1882.882568
y = 2.0 y = 786.492737
z = 0.0 z = 1203.552246
u = 0.0 u = 11.403661
v = 0.0 v = -0.985981
w = 0.0 w = -125.710434
id = 3 id = 3
order = 0 order = 0
lineid = 2 lineid = 2
status = 3 status = 3
linetype = 0 linetype = 0
[Position5] [Position4]
x = 7.0 x = 1868.06311
y = 50.0 y = 872.854065
z = 1.0 z = 1265.651855
u = 12.0 u = 12.479004
v = 0.0 v = 1.611398
w = 1.0 w = -127.729263
id = 5 id = 4
order = 2 order = 2
lineid = 1 lineid = 1
status = 4 status = 4
linetype = 0 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] [Position1]
x = 7.0 x = 348.84654634488436
y = 50.0 y = 1836.958560527403
z = 1.0 z = 223.84778176988266
u = 12.0 u = 2.3775411141593388
v = 0.0 v = -0.7172354339862681
w = 1.0 w = 95.0492701673298
id = 1 id = 1
order = 4 order = 4
lineid = 1 lineid = 1
status = 5 status = 5
linetype = 0 linetype = 0
[Position6] [Position7]
x = 7.0 x = 2218.886475
y = 50.0 y = 483.322144
z = 1.0 z = 1371.784302
u = 12.0 u = 8.190439
v = 0.0 v = 7.692511
w = 1.0 w = -143.628922
id = 6 id = 7
order = 1 order = 0
lineid = 1 lineid = 1
status = 2 status = 3
linetype = 0 linetype = 0
[Position7] [Position8]
x = 7.0 x = 807.391785
y = 50.0 y = 2337.584473
z = 1.0 z = 1852.736816
u = 12.0 u = -0.412497
v = 0.0 v = 9.080836
w = 1.0 w = -110.687553
id = 7 id = 8
order = 5 order = 5
lineid = 1 lineid = 1
status = 6 status = 6
linetype = 0 linetype = 0
[Position8] [Position9]
x = 7.0 x = 1759.061523
y = 50.0 y = 1738.14978
z = 1.0 z = 1852.472412
u = 12.0 u = 0.723375
v = 0.0 v = 9.708878
w = 1.0 w = -126.572548
id = 8 id = 9
order = 6 order = 6
lineid = 1 lineid = 1
status = 7 status = 7
linetype = 0 linetype = 0
[Position9] [Position10]
x = 7.0 x = 1759.061523
y = 50.0 y = 1738.14978
z = 1.0 z = 1852.472412
u = 12.0 u = 0.723375
v = 0.0 v = 9.708878
w = 1.0 w = -126.572548
id = 9 id = 10
order = 7 order = 7
lineid = 1 lineid = 1
status = 8 status = 8
linetype = 0 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] [Position11]
x = 7.0 x = 1960.667847
y = 50.0 y = 837.290405
z = 1.0 z = 1688.202637
u = 12.0 u = -0.347183
v = 0.0 v = 0.356827
w = 1.0 w = -147.846161
id = 11 id = 11
order = 9 order = 8
lineid = 1 lineid = 1
status = 3 status = 3
linetype = 0 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 Debug = True
IO_EmergencyPoint = 3 IO_EmergencyPoint = 3
bag_height = 10 # 一袋的高度 bag_height = 10 # 一袋的高度
position_accuracy = 0.05 position_accuracy = 0.1
manual_adjust_accuracy = 1 manual_adjust_accuracy = 1
# speed = 10 # speed = 10
# shake_speed = 20 # shake_speed = 20
@ -61,6 +61,7 @@ str_feed_start_error = '请先复位到原点'
str_feed_return_original_position_fail = '机械臂未按照实际路线点移动,未能寻找到适配路径点位' str_feed_return_original_position_fail = '机械臂未按照实际路线点移动,未能寻找到适配路径点位'
str_feed_reset_no_line_error = '未定义的线段' str_feed_reset_no_line_error = '未定义的线段'
str_feed_angle_error = '角度差距过大,停止运行' str_feed_angle_error = '角度差距过大,停止运行'
str_feed_reset_start = '开始复位'
str_sys_start = '进入系统' str_sys_start = '进入系统'
str_sys_exit = '退出系统' str_sys_exit = '退出系统'
str_sys_switch_tool = '切换到工具坐标' str_sys_switch_tool = '切换到工具坐标'
@ -78,6 +79,7 @@ str_sys_log_IO_error = 'IO更新失败'
str_sys_log_alarm_error = '发生报警:' str_sys_log_alarm_error = '发生报警:'
str_sys_log_move_error = '请填写全部坐标' str_sys_log_move_error = '请填写全部坐标'
str_sys_set_position_error = '未选中行' str_sys_set_position_error = '未选中行'
str_sys_command = '发送命令'
str_tcp_robot_connect_fail = '连接失败' str_tcp_robot_connect_fail = '连接失败'
str_tcp_robot_connect_success = '连接成功' str_tcp_robot_connect_success = '连接成功'
str_tcp_robot_data_error = '数据解析错误' str_tcp_robot_data_error = '数据解析错误'

View File

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

View File

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

View File

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

View File

@ -1,13 +1,25 @@
import logging
import cv2 import cv2
from PIL.ImageQt import QImage, QPixmap from PIL.ImageQt import QImage, QPixmap
from Util.util_log import log
def cv2_to_qpixmap(cv_img): def cv2_to_qpixmap(cv_img):
"""将OpenCV图像转换为QPixmap""" """将OpenCV图像转换为QPixmap"""
height, width, channel = cv_img.shape # img = cv_img.copy()
bytes_per_line = 3 * width # cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB)
q_img = QImage(cv_img.data, width, height, bytes_per_line, QImage.Format_RGB888) try:
return QPixmap.fromImage(q_img) 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): # def cv2_to_qpixmap(cv_img):
# """将OpenCV图像转换为QPixmap""" # """将OpenCV图像转换为QPixmap"""

3
app.py
View File

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

67
main.py
View File

@ -1,6 +1,7 @@
import configparser import configparser
import json import json
import logging import logging
import os
import queue import queue
import sys import sys
import threading import threading
@ -8,6 +9,7 @@ from multiprocessing import Process
import traceback import traceback
import PySide6 import PySide6
import cv2
from PyQt5.uic.properties import QtWidgets from PyQt5.uic.properties import QtWidgets
from PySide6 import QtCore from PySide6 import QtCore
from PySide6.QtCore import QThread, Signal, Slot, QObject, QEvent, QTimer from PySide6.QtCore import QThread, Signal, Slot, QObject, QEvent, QTimer
@ -46,6 +48,7 @@ from view.ResetView import StopDialog
class MainWindow(QMainWindow, Ui_MainWindow): class MainWindow(QMainWindow, Ui_MainWindow):
updateUI_seting = Signal()
def __init__(self): def __init__(self):
super(MainWindow, self).__init__() super(MainWindow, self).__init__()
self.setupUi(self) self.setupUi(self)
@ -396,8 +399,6 @@ class MainWindow(QMainWindow, Ui_MainWindow):
continue continue
position_model = PositionModel(i) position_model = PositionModel(i)
break break
if position_model.id == 999:
print("d")
if self.tableWidget_line_positions.currentRow()==-1: if self.tableWidget_line_positions.currentRow()==-1:
row_i = self.tableWidget_line_positions.rowCount() row_i = self.tableWidget_line_positions.rowCount()
else: else:
@ -589,6 +590,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.main_threading = None self.main_threading = None
self.detection_person = None # DetectionPerson() self.detection_person = None # DetectionPerson()
self.cton_take_no_photo = CRisOrFall() self.cton_take_no_photo = CRisOrFall()
self.index = 1
self.configReader.read(Constant.set_ini) self.configReader.read(Constant.set_ini)
ip = self.configReader.get('Robot_Feed', 'IPAddress') ip = self.configReader.get('Robot_Feed', 'IPAddress')
@ -642,6 +644,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.last_time = time.time() self.last_time = time.time()
self.remain_lineName = self.configReader.get('Robot_Feed', 'remain_lineName') self.remain_lineName = self.configReader.get('Robot_Feed', 'remain_lineName')
self.remain_Count = int(self.configReader.get('Robot_Feed', 'remain_Count')) self.remain_Count = int(self.configReader.get('Robot_Feed', 'remain_Count'))
self.updateUI_seting.connect(self.update_seting_frame)
try: try:
self.robotClient.CreatConnect() self.robotClient.CreatConnect()
except: except:
@ -812,12 +815,13 @@ class MainWindow(QMainWindow, Ui_MainWindow):
def start_Runing(self): def start_Runing(self):
self.main_threading = Thread(target=self.run) self.main_threading = Thread(target=self.run)
self.robot_connect_threading = Thread(target=self.robotClient.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.main_threading.start()
self.robot_connect_threading.start() self.robot_connect_threading.start()
self.main_UI_threading = Thread(target=self.updateUI)
self.main_UI_threading.start() self.main_UI_threading.start()
self.detect_person_thread = Thread(target=self.run_detect_persion)
self.detect_person_thread.start() self.detect_person_thread.start()
pass pass
def check_continue(self): def check_continue(self):
@ -1035,9 +1039,9 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.robotClient.time_delay_shake = time_delay_shake self.robotClient.time_delay_shake = time_delay_shake
self.configReader = configparser.ConfigParser() self.configReader = configparser.ConfigParser()
self.configReader.read(Constant.set_ini) self.configReader.read(Constant.set_ini)
self.configReader.set('Robot_Feed', 'solenoid_valve1_addr', str(take_addr)) self.configReader.set('Robot_Feed', 'io_take_addr', str(take_addr))
self.configReader.set('Robot_Feed', 'solenoid_valve2_addr', str(press_addr)) self.configReader.set('Robot_Feed', 'io_zip_addr', str(press_addr))
self.configReader.set('Robot_Feed', 'solenoid_valve3_addr', str(shake_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', 'takeDelay', str(time_delay_take))
self.configReader.set('Robot_Feed', 'putDelay', str(time_delay_put)) self.configReader.set('Robot_Feed', 'putDelay', str(time_delay_put))
self.configReader.set('Robot_Feed', 'shakeDelay', str(time_delay_shake)) self.configReader.set('Robot_Feed', 'shakeDelay', str(time_delay_shake))
@ -1177,8 +1181,6 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.send_start_tool_command() self.send_start_tool_command()
def send_reset_button_click(self): def send_reset_button_click(self):
# TODO 清楚痕迹
# TODO 开启自动
# 触发自动运行 # 触发自动运行
if self.robotClient.status_model.curMode != 7: if self.robotClient.status_model.curMode != 7:
self.send_switch_tool_command() self.send_switch_tool_command()
@ -1189,6 +1191,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
line_head = self.comboBox_lineIndex.currentData() line_head = self.comboBox_lineIndex.currentData()
self.send_clear_auto_command() self.send_clear_auto_command()
log.log_message(logging.INFO, Constant.str_feed_reset_start)
#safe_position = self.feedLine_dict[line_head].safe_position #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) # 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 != '': 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) log.log_message(logging.ERROR, Constant.str_feed_reset_no_line_error)
return return
self.feeding.reset_status = ResetStatus.RStart self.feeding.reset_status = ResetStatus.RStart
dialog_reset = StopDialog() # dialog_reset = StopDialog()
dialog_reset.stop_thread_signal.connect(self.stop_reset_thread) # dialog_reset.stop_thread_signal.connect(self.stop_reset_thread)
else: else:
log.log_message(logging.ERROR, Constant.str_feed_reset_no_line_error) log.log_message(logging.ERROR, Constant.str_feed_reset_no_line_error)
return return
@ -1364,13 +1367,14 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.label_date.setText(datetime.now().strftime("%Y-%m-%d")) self.label_date.setText(datetime.now().strftime("%Y-%m-%d"))
self.label_time.setText(datetime.now().strftime("%H:%M:%S")) self.label_time.setText(datetime.now().strftime("%H:%M:%S"))
self.updateUI_Position() self.updateUI_seting.emit()
self.updateUI_label_detection()
self.updateUI_label_status()
self.updateUI_frame_sign(self.feeding.feedStatus)
self.updateUI_IOPanel()
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): def updateRobotSeting(self):
self.lineEdit_origin_x.setText(str(self.robotClient.origin_position.X)) 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_v.setText(str(self.robotClient.origin_position.V))
self.lineEdit_origin_w.setText(str(self.robotClient.origin_position.W)) self.lineEdit_origin_w.setText(str(self.robotClient.origin_position.W))
@Slot()
def show_no_photo_message_box(self): def show_no_photo_message_box(self):
self.feeding.pause = True self.feeding.pause = True
self.send_pause_command(pause=1) self.send_pause_command(pause=1)
@ -1409,6 +1414,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
pass pass
def updateUI_label_detection(self): def updateUI_label_detection(self):
backgroud_img = Util.util_pic.cv2_to_qpixmap(self.feeding.detection_image) 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) 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) self.label_showDetection.setPixmap(backgroud_img)
@ -1560,7 +1567,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
clear_command = CMDInstructRequest() clear_command = CMDInstructRequest()
request_command = clear_command.toString() request_command = clear_command.toString()
log.log_message(logging.INFO, Constant.str_sys_clearAlarm) 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): 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: else:
pause_command.cmdData.append("0") pause_command.cmdData.append("0")
request_command = pause_command.toString() request_command = pause_command.toString()
print(request_command)
self.robotClient.add_sendQuene(request_command) self.robotClient.add_sendQuene(request_command)
def send_emergency_alarm_command(self): def send_emergency_alarm_command(self):
self.feeding.feedStatus = FeedStatus.FNone self.feeding.feedStatus = FeedStatus.FNone
self.feeding.feedConfig.num = 0
stop_command = CMDRequest() stop_command = CMDRequest()
stop_command.cmdData.append("actionStop") stop_command.cmdData.append("actionStop")
stop_command.cmdData.append("1") stop_command.cmdData.append("1")
@ -1607,18 +1614,17 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.send_clear_auto_command() self.send_clear_auto_command()
self.robotClient.add_sendQuene(request_command) self.robotClient.add_sendQuene(request_command)
self.feeding.send_emergency_sound() self.feeding.send_emergency_sound()
self.feeding.feedConfig.num = 0
log.log_message(logging.INFO, Constant.str_sys_emergencyStop) log.log_message(logging.INFO, Constant.str_sys_emergencyStop)
#TODO #TODO
def send_clear_alarm_command(self, pause: bool): def send_clear_alarm_command(self, pause: bool):
self.send_start_tool_command() self.send_clear_auto_command()
pause_command = CMDRequest() pause_command = CMDRequest()
pause_command.cmdData.append("StopButton") pause_command.cmdData.append("StopButton")
pause_command.cmdData.append("1") pause_command.cmdData.append("1")
request_command = pause_command.toString() request_command = pause_command.toString()
print(request_command)
log_str = f'暂停:{pause}'
self.robotClient.add_sendQuene(request_command) self.robotClient.add_sendQuene(request_command)
def send_switch_tool_command(self): def send_switch_tool_command(self):
@ -1626,8 +1632,6 @@ class MainWindow(QMainWindow, Ui_MainWindow):
switch_command.cmdData.append("switchTool") switch_command.cmdData.append("switchTool")
switch_command.cmdData.append("2") switch_command.cmdData.append("2")
request_command = switch_command.toString() request_command = switch_command.toString()
print(request_command)
self.robotClient.add_sendQuene(request_command) self.robotClient.add_sendQuene(request_command)
def send_start_tool_command(self): def send_start_tool_command(self):
@ -1635,8 +1639,6 @@ class MainWindow(QMainWindow, Ui_MainWindow):
switch_command.cmdData.append("startButton") switch_command.cmdData.append("startButton")
switch_command.cmdData.append("1") switch_command.cmdData.append("1")
request_command = switch_command.toString() request_command = switch_command.toString()
print(request_command)
self.robotClient.add_sendQuene(request_command) self.robotClient.add_sendQuene(request_command)
def show_messagebox_of_person(self): 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')) self.configReader.write(open(Constant.set_ini, 'w', encoding='utf-8'))
log.log_message(logging.INFO, f'设置原点:{x},{y},{z}') log.log_message(logging.INFO, f'设置原点:{x},{y},{z}')
except: except:
log.log_message(logging.ERROR, f'设置原点失败')
self.show_infomessage_box("设置原点失败") self.show_infomessage_box("设置原点失败")
@ -1966,14 +1969,16 @@ def handle_exception(exc_type, exc_value, exc_tb):
log.log_message(logging.INFO, "用户主动退出程序") log.log_message(logging.INFO, "用户主动退出程序")
return return
log.log_message(logging.ERROR, exc_value) log.log_message(logging.ERROR, exc_value)
print("未处理的异常:", exc_type, exc_value)
traceback.print_exception(exc_type, exc_value, exc_tb) traceback.print_exception(exc_type, exc_value, exc_tb)
if __name__ == "__main__": if __name__ == "__main__":
app = MyApplication(sys.argv) app = MyApplication(sys.argv)
window = MainWindow() window = MainWindow()
window.show() window.show()
sys.excepthook = handle_exception # 你的 PySide 应用程序代码 pass sys.excepthook = handle_exception
sys.exit(app.exec()) 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 QThread, Signal, Slot
from PySide6.QtCore import QPropertyAnimation, QPoint, QParallelAnimationGroup, QEasingCurve, Property from PySide6.QtWidgets import QApplication, QDialog, QLabel, QVBoxLayout, QPushButton
from PySide6.QtGui import QColor, QPainter, QBrush
from PySide6.QtCore import Qt
import sys 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): class MainWindow(QDialog):
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):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.setWindowTitle("水滴扩散按钮示例") self.setWindowTitle("主窗口")
self.setFixedSize(400, 300) self.setGeometry(100, 100, 300, 200)
self.button = RippleButton("点击我", self) self.button = QPushButton("开始任务", self)
self.button.setGeometry(150, 130, 100, 40) self.button.clicked.connect(self.start_task)
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")
if __name__ == "__main__": layout = QVBoxLayout(self)
app = QApplication(sys.argv) layout.addWidget(self.button)
window = MainWindow()
window.show() @Slot(str)
sys.exit(app.exec()) 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())