# feeding/controller.py import time from feeding.process import FeedingProcess from busisness.blls import ArtifactBll class FeedingController: def __init__(self, relay_controller, inverter_controller, transmitter_controller, vision_detector, camera_controller, rfid_controller,state, settings): self.relay_controller = relay_controller self.inverter_controller = inverter_controller self.transmitter_controller = transmitter_controller self.vision_detector = vision_detector self.camera_controller = camera_controller self.rfid_controller = rfid_controller self.state = state self.settings = settings self.artifact_bll = ArtifactBll() # 初始化下料流程 self.process = FeedingProcess( relay_controller, inverter_controller, transmitter_controller, vision_detector, camera_controller, state, settings ) def start_feeding(self): #获取当前的管片任务 #API读取生产任务 --》RFID读取模具配对检测--数据库入库》生产-》同步到数据库 #API读取生产任务--》未读到--》RFID读取模具-数据库入库》生产 --》同步到数据库 #从数据库获取当前的管片任务 """启动下料流程""" self.process.start_feeding() def check_upper_material_request(self): """检查是否需要要料""" current_weight = self.transmitter_controller.read_data(1) if current_weight is None: self.state.upper_weight_error_count += 1 print(f"上料斗重量读取失败,错误计数: {self.state.upper_weight_error_count}") if self.state.upper_weight_error_count >= self.settings.max_error_count: print("警告:上料斗传感器连续读取失败,请检查连接") return False #需要搅拌楼通知下完料后移到上料斗上方 if self.state._upper_door_position != 'over_lower': self.state._upper_door_position = 'over_lower' self.state.upper_weight_error_count = 0 # 判断是否需要要料:当前重量 < 目标重量 + 缓冲重量 if current_weight < (self.settings.single_batch_weight + self.settings.min_required_weight): print("上料斗重量不足,通知搅拌楼要料") self.request_material_from_mixing_building() # 请求搅拌楼下料 return True return False def request_material_from_mixing_building(self): """ 请求搅拌楼下料 """ print("发送要料请求至搅拌楼...") # self.settings. self.process.return_upper_door_to_default() # 这里需要与同事对接具体的通信方式 # 可能是Modbus写寄存器、TCP通信、HTTP请求等 pass def check_arch_blocking(self): """检查是否需要破拱""" current_time = time.time() # 检查下料斗破拱(只有在下料过程中才检查) if self.state._lower_feeding_stage in [1, 2, 3]: # 在所有下料阶段检查 lower_weight = self.transmitter_controller.read_data(2) if lower_weight is not None: # 检查重量变化是否过慢(小于0.1kg变化且时间超过10秒) if (abs(lower_weight - self.state.last_lower_weight) < 0.1) and \ (current_time - self.state.last_weight_time) > 10: print("下料斗可能堵塞,启动破拱") self.state._lower_is_arch_=True self.relay_controller.control(self.relay_controller.BREAK_ARCH_LOWER, 'open') time.sleep(2) self.relay_controller.control(self.relay_controller.BREAK_ARCH_LOWER, 'close') self.state._lower_is_arch_=False self.state.last_lower_weight = lower_weight # 检查上料斗破拱(在上料斗向下料斗下料时检查) if (self.state._upper_door_position == 'over_lower' and self.state._lower_feeding_stage in [0, 1, 2, 3, 4]): # 在任何阶段都可能需要上料斗破拱 upper_weight = self.transmitter_controller.read_data(1) if upper_weight is not None: # 检查重量变化是否过慢(小于0.1kg变化且时间超过10秒) if (abs(upper_weight - self.state.last_upper_weight) < 0.1) and \ (current_time - self.state.last_weight_time) > 10: print("上料斗可能堵塞,启动破拱") self.state._upper_is_arch_=True self.relay_controller.control(self.relay_controller.BREAK_ARCH_UPPER, 'open') time.sleep(2) self.relay_controller.control(self.relay_controller.BREAK_ARCH_UPPER, 'close') self.state._upper_is_arch_=False self.state.last_upper_weight = upper_weight # 更新最后读取时间 if (self.transmitter_controller.read_data(1) is not None or self.transmitter_controller.read_data(2) is not None): self.state.last_weight_time = current_time def visual_control(self, current_frame): """ 视觉控制主逻辑 """ # 检测是否溢料 overflow = self.vision_detector.detect_overflow(current_frame) # 获取当前角度 current_angle = self.vision_detector.detect_angle(image=current_frame) if current_angle is None: print("无法获取当前角度,跳过本次调整") return print(f"当前角度: {current_angle:.2f}°, 溢料状态: {overflow}, 控制模式: {self.state.angle_control_mode}") # 状态机控制逻辑 if self.state.angle_control_mode == "normal": # 正常模式 if overflow and current_angle > self.settings.angle_threshold: # 检测到堆料且角度过大,进入角度减小模式 print("检测到堆料且角度过大,关闭出砼门开始减小角度") self.relay_controller.control(self.relay_controller.DOOR_LOWER_2, 'close') self.state.angle_control_mode = "reducing" else: # 保持正常开门 self.relay_controller.control(self.relay_controller.DOOR_LOWER_2, 'open') elif self.state.angle_control_mode == "reducing": # 角度减小模式 if current_angle <= self.settings.target_angle + self.settings.angle_tolerance: # 角度已达到目标范围 if overflow: # 仍有堆料,进入维持模式 print(f"角度已降至{current_angle:.2f}°,仍有堆料,进入维持模式") self.state.angle_control_mode = "maintaining" self.relay_controller.control(self.relay_controller.DOOR_LOWER_2, 'open') # 先打开门 else: # 无堆料,恢复正常模式 print(f"角度已降至{current_angle:.2f}°,无堆料,恢复正常模式") self.relay_controller.control(self.relay_controller.DOOR_LOWER_2, 'open') self.state.angle_control_mode = "normal" elif self.state.angle_control_mode == "maintaining": # 维持模式 - 使用脉冲控制 if not overflow: # 堆料已消除,恢复正常模式 print("堆料已消除,恢复正常模式") self.relay_controller.control(self.relay_controller.DOOR_LOWER_2, 'open') self.state.angle_control_mode = "normal" else: # 继续维持角度控制 self.pulse_control_door_for_maintaining() elif self.state.angle_control_mode == "recovery": # 恢复模式 - 逐步打开门 if overflow: # 又出现堆料,回到角度减小模式 print("恢复过程中又检测到堆料,回到角度减小模式") self.state.angle_control_mode = "maintaining" else: # 堆料已消除,恢复正常模式 print("堆料已消除,恢复正常模式") self.relay_controller.control(self.relay_controller.DOOR_LOWER_2, 'open') self.state.angle_control_mode = "normal" self.state.last_angle = current_angle def pulse_control_door_for_maintaining(self): """ 用于维持模式的脉冲控制 保持角度在目标范围内 """ print("执行维持脉冲控制") # 关门1秒 self.relay_controller.control(self.relay_controller.DOOR_LOWER_2, 'close') time.sleep(1.0) # 开门1秒 self.relay_controller.control(self.relay_controller.DOOR_LOWER_2, 'open') time.sleep(1.0)