from pickle import FALSE from cv2.gapi import ov from config.settings import app_set_config from hardware.relay import RelayController from hardware.transmitter import TransmitterController import time import threading from datetime import datetime import logging import queue from hardware.upper_plc import OmronFinsPollingService from vision.muju_cls.muju_utils import run_stable_classification_loop from vision.camera_picture import save_camera_picture class FeedingProcess: # 类变量,用于存储实例引用,实现单例检测 _instance = None _lock = threading.Lock() def __new__(cls): """检测实例是否存在,实现单例模式""" with cls._lock: if cls._instance is None: cls._instance = super().__new__(cls) return cls._instance def __init__(self, relay_controller, inverter_controller, transmitter_controller, state): """初始化视觉回调处理器""" # 避免重复初始化 if hasattr(self, '_initialized') and self._initialized: return self.relay_controller = relay_controller self.inverter_controller = inverter_controller self.transmitter_controller = transmitter_controller # 线程安全的参数传递 self._new_data_available = threading.Event() self._is_processing = threading.Lock() #diff参数 self._is_processing_diff = threading.Lock() self._new_data_diff = threading.Event() self._current_diff=0 self._current_diff_area=[] self._is_diff_save=False self._stop_event = threading.Event() # 添加下料斗门控制锁,防止两个线程同时控制 self._door_control_lock = threading.Lock() # 记录当前控制门的线程名称,用于调试 self._current_controlling_thread = None #是否启动后的第一个模具 self._is_first_module=True self.init_val() # self._setup_logging_2() #F块完成重量的70%,控制夹脚,F块多于这个比例就没有记录了(注意) self._max_f_angle_ratio=0.7 #完成多少,调整角度比例 ,多于0.8就没记录了(注意) self._max_angle_radio=0.8 #重量大于95%,停留时间2秒,其他的1秒 self._weight_ratio_955=0.955 #完成多少,忽略未浇筑满 self._max_ignore_radio=0.5 self._mould_accept_aligned=None self._mould_before_aligned=False #模具开始浇筑时间 self._time_mould_begin='' #模具结束浇筑时间 self._time_mould_end='' def run_feed_f(self): """第一阶段下料:下料斗向模具车下料(低速)""" print("--------------------开始下料(F块)--------------------") self._time_mould_begin=datetime.now().strftime("%Y-%m-%d %H:%M:%S") # loc_relay=self.relay_controller loc_mitter=self.transmitter_controller max_weight_none=5 cur_weight_none=0 initial_lower_weight=loc_mitter.read_data(2) if initial_lower_weight is None: print("-----f上料斗重量异常-----") return first_finish_weight=0 self._finish_weight=first_finish_weight self._inital_finish_lweight=initial_lower_weight need_total_weight=0.54*2416 if initial_lower_weight>100: if not self._is_finish: self.is_start_visual=True initial_lower_weight=loc_mitter.read_data(2) if initial_lower_weight is None: print("-----f上料斗重量异常2-----") return self._is_feed_stage=5 while not self._is_finish: current_weight = loc_mitter.read_data(2) if current_weight is None: cur_weight_none+=1 if cur_weight_none>max_weight_none: #如果重量连续5次为None,认为下料斗未就位,跳出循环 print('------------f下到模具车,下料斗重量异常----------------') print('------------f下到模具车,下料斗重量异常----------------') self.close_lower_door_visual() return #视觉处理关闭,异常的话重量没有生效 continue cur_weight_none=0 first_finish_weight=initial_lower_weight-current_weight self._is_finish_ratio=(first_finish_weight)/need_total_weight print(f'------------已下料比例: {self._is_finish_ratio}-------------') if self._is_finish_ratio>self._max_f_angle_ratio: #关5秒 #大于0.7后不再检测了,直接交给视觉控制夹脚 # print(f'------------已下料比例: {self._is_finish_ratio}-------------') break # print(f'------------已下料: {first_finish_weight+second_finish_weight}kg-------------') time.sleep(1) # initial_lower_weight=_current_lower_weight print(f'------------已下料(F): {first_finish_weight}kg-------------') print(f'------------已下料(F): {first_finish_weight}kg-------------') print(f'------------已完成-------------') def run_feed(self): """第一阶段下料:下料斗向模具车下料(低速)""" print("--------------------开始下料(普通块)--------------------") self._time_mould_begin=datetime.now().strftime("%Y-%m-%d %H:%M:%S") loc_relay=self.relay_controller loc_mitter=self.transmitter_controller max_weight_none=5 cur_weight_none=0 initial_lower_weight=loc_mitter.read_data(2) # initial_upper_weight=loc_mitter.read_data(1) if initial_lower_weight is None: print("---------------下料斗重量异常----------------") return first_finish_weight=0 need_total_weight=1.91*2416 # start_time=None self.is_start_visual=True if initial_lower_weight>100: #下料斗的料全部下完 self._is_feed_stage=1 while not self._is_finish: current_weight = loc_mitter.read_data(2) if current_weight is None: cur_weight_none+=1 if cur_weight_none>max_weight_none: print("-----------下料斗重量异常(第一次下到模具车)--------------") self.close_lower_door_visual() return continue cur_weight_none=0 if current_weight<250 and current_weight>0: self.close_lower_door_visual() break time.sleep(1) _current_lower_weight=loc_mitter.read_data(2) if _current_lower_weight is None: print("-------下料斗重量异常---------") return first_finish_weight=initial_lower_weight-_current_lower_weight # initial_lower_weight=_current_lower_weight print(f'------------已下料(第一次): {first_finish_weight}kg-------------') print(f'------------已下料(第一次): {first_finish_weight}kg-------------') self._is_feed_stage=0 while self.plc_data!=5: print('------------上料斗未就位----------------') print('------------上料斗未就位----------------') time.sleep(1) if self.plc_data==5: print(f'------------上料斗向下料斗转移(留3000KG)-------------') #打开上料斗出砼门,开5就,开三分之一下 loc_relay.control_upper_open_sync(6) self._is_feed_stage=2 loc_time_count=1 upper_open_time=time.time() while not self._is_finish: current_upper_weight = loc_mitter.read_data(1) if current_upper_weight is None: cur_weight_none+=1 if cur_weight_none>max_weight_none: #如果重量连续5次为None,认为上料斗未就位,跳出循环 print('------------第一次上到下,上料斗重量异常----------------') print('------------第一次上到下,上料斗重量异常----------------') loc_relay.control_upper_close_sync(5+loc_time_count) return continue cur_weight_none=0 _two_lower_weight=loc_mitter.read_data(2) if _two_lower_weight is None: _two_lower_weight=0 if (current_upper_weight<3000 and current_upper_weight>0) or _two_lower_weight>3200: #关5秒,loc_time_count多关一秒 loc_relay.control_upper_close_sync(5+loc_time_count) break else: if time.time()-upper_open_time>5: if loc_time_count<6: upper_open_time=time.time() loc_relay.control_upper_open_sync(0.8) loc_time_count=loc_time_count+0.8 else: time.sleep(0.5) else: loc_relay.control_upper_close_sync(6+loc_time_count) self.is_start_visual=True initial_lower_weight=loc_mitter.read_data(2) if initial_lower_weight is None: print("-------下料斗重量异常(第二次下料到模具车)---------") return self._is_feed_stage=3 while not self._is_finish: current_weight = loc_mitter.read_data(2) if current_weight is None: cur_weight_none+=1 if cur_weight_none>max_weight_none: print("-------下料斗重量异常(第二次下料到模具车)---------") self.close_lower_door_visual() return continue cur_weight_none=0 # second_finish_weight=initial_lower_weight-current_weight if current_weight<250: self.close_lower_door_visual() break # print(f'------------已下料: {first_finish_weight+second_finish_weight}kg-------------') time.sleep(1) _current_lower_weight=loc_mitter.read_data(2) if _current_lower_weight is None: print("-------下料斗重量异常(第二次下到模)---------") return first_finish_weight=first_finish_weight+initial_lower_weight-_current_lower_weight print(f'------------已下料(第二次): {first_finish_weight}kg-------------') print(f'------------已下料(第二次): {first_finish_weight}kg-------------') self._is_feed_stage=0 if self.plc_data==5: #第二次上料斗向下料斗转移 loc_relay.control_upper_open_sync(12) loc_time_count=1 upper_open_time=time.time() upper_open_time_2=None #第二次到下料斗还需要的量 #loc_left_need_weight=need_total_weight-first_finish_weight # initial_upper_weight=loc_mitter.read_data(1) # start_time=None self._is_feed_stage=4 while not self._is_finish: # print(f'------------上料斗向下料斗转移22222-------------') current_upper_weight = loc_mitter.read_data(1) if current_upper_weight is None: cur_weight_none+=1 if cur_weight_none>max_weight_none: #如果重量连续5次为None,认为上料斗未就位,跳出循环 print('------------第二次上到下,上料斗重量异常----------------') print('------------第二次上到下,上料斗重量异常----------------') loc_relay.control_upper_close_sync(15) break continue cur_weight_none=0 if (current_upper_weight<600 and current_upper_weight>0) or upper_open_time_2 is not None: if upper_open_time_2 is None: upper_open_time_2=time.time() if current_upper_weight<400 or time.time()-upper_open_time_2>5: loc_relay.control_arch_upper_open_async(5) # loc_relay.control_arch_upper_open() loc_relay.control_upper_open_sync(5) # start_time=None #5秒后关闭 loc_relay.control_upper_close_after()#control_upper_close_sync(8+loc_time_count) break time.sleep(1) else: if time.time()-upper_open_time>2: # if loc_time_count<6: upper_open_time=time.time() loc_relay.control_upper_open_sync(1.2) loc_time_count=loc_time_count+1 else: time.sleep(0.5) else: loc_relay.control_upper_close_sync(15) # time.sleep(0.4) #第三次下料斗转移到模具车 if not self._is_finish: self.is_start_visual=True initial_lower_weight=loc_mitter.read_data(2) self._finish_weight=first_finish_weight self._inital_finish_lweight=initial_lower_weight if initial_lower_weight is None: print("-------下料斗重量异常(第三次下到模具车)---------") return self._is_feed_stage=5 while not self._is_finish: current_weight = loc_mitter.read_data(2) if current_weight is None: cur_weight_none+=1 if cur_weight_none>max_weight_none: #重量异常退出 print('------------第三次下到模具车,下料斗重量异常----------------') self.close_lower_door_visual() return continue cur_weight_none=0 second_finish_weight=initial_lower_weight-current_weight self._is_finish_ratio=(second_finish_weight+first_finish_weight)/need_total_weight print(f'------------已下料比例: {self._is_finish_ratio}-------------') if self._is_finish_ratio>=1: #关5秒 # print(f'------------已下料比例: {self._is_finish_ratio}-------------') break # print(f'------------已下料: {first_finish_weight+second_finish_weight}kg-------------') time.sleep(1) # _current_lower_weight=loc_mitter.read_data(2) # first_finish_weight=first_finish_weight+initial_lower_weight-_current_lower_weight # print(f'------------已下料: {first_finish_weight}kg-------------') # print(f'------------已下料: {first_finish_weight}kg-------------') print(f'------------已完成-------------') @classmethod def instance_exists(cls): """检测实例是否存在""" return cls._instance is not None # 创建默认实例 # visual_callback_instance = VisualCallback() # 兼容层,保持原来的函数调用方式可用 # def angle_visual_callback(current_angle, overflow_detected): # """ # 兼容旧版本的函数调用方式 # 将调用转发到默认实例的angle_visual_callback方法 # """ # visual_callback_instance.angle_visual_callback(current_angle, overflow_detected)