重构目录结构:调整项目布局
This commit is contained in:
9
feeding/__init__.py
Normal file
9
feeding/__init__.py
Normal file
@ -0,0 +1,9 @@
|
||||
# feeding/__init__.py
|
||||
"""
|
||||
下料控制模块
|
||||
包含下料流程控制和管理
|
||||
"""
|
||||
from .process import FeedingProcess
|
||||
from .controller import FeedingController
|
||||
|
||||
__all__ = ['FeedingProcess', 'FeedingController']
|
||||
BIN
feeding/__pycache__/__init__.cpython-39.pyc
Normal file
BIN
feeding/__pycache__/__init__.cpython-39.pyc
Normal file
Binary file not shown.
BIN
feeding/__pycache__/controller.cpython-39.pyc
Normal file
BIN
feeding/__pycache__/controller.cpython-39.pyc
Normal file
Binary file not shown.
BIN
feeding/__pycache__/process.cpython-39.pyc
Normal file
BIN
feeding/__pycache__/process.cpython-39.pyc
Normal file
Binary file not shown.
175
feeding/controller.py
Normal file
175
feeding/controller.py
Normal file
@ -0,0 +1,175 @@
|
||||
# feeding/controller.py
|
||||
import time
|
||||
from feeding.process import FeedingProcess
|
||||
|
||||
|
||||
class FeedingController:
|
||||
def __init__(self, relay_controller, inverter_controller,
|
||||
transmitter_controller, vision_detector,
|
||||
camera_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.state = state
|
||||
self.settings = settings
|
||||
|
||||
# 初始化下料流程
|
||||
self.process = FeedingProcess(
|
||||
relay_controller, inverter_controller,
|
||||
transmitter_controller, vision_detector,
|
||||
camera_controller, state, settings
|
||||
)
|
||||
|
||||
def start_feeding(self):
|
||||
"""启动下料流程"""
|
||||
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
|
||||
|
||||
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.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.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.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.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.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)
|
||||
265
feeding/process.py
Normal file
265
feeding/process.py
Normal file
@ -0,0 +1,265 @@
|
||||
# feeding/process.py
|
||||
class FeedingProcess:
|
||||
def __init__(self, relay_controller, inverter_controller,
|
||||
transmitter_controller, vision_detector,
|
||||
camera_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.state = state
|
||||
self.settings = settings
|
||||
|
||||
def start_feeding(self):
|
||||
"""开始分步下料"""
|
||||
if self.state.lower_feeding_stage != 0:
|
||||
print("下料已在进行中")
|
||||
return
|
||||
|
||||
print("开始分步下料过程")
|
||||
# 重置计数器
|
||||
self.state.lower_feeding_cycle = 0
|
||||
self.state.upper_feeding_count = 0
|
||||
|
||||
# 第一次上料
|
||||
self.transfer_material_from_upper_to_lower()
|
||||
|
||||
# 等待模具车对齐并开始第一轮下料
|
||||
self.state.lower_feeding_stage = 4
|
||||
self.wait_for_vehicle_alignment()
|
||||
|
||||
def transfer_material_from_upper_to_lower(self):
|
||||
"""上料斗向下料斗下料"""
|
||||
print(f"上料斗向下料斗下料 (第 {self.state.upper_feeding_count + 1} 次)")
|
||||
|
||||
# 记录下料前的重量
|
||||
initial_upper_weight = self.transmitter_controller.read_data(1)
|
||||
|
||||
# 如果无法读取重量,直接报错
|
||||
if initial_upper_weight is None:
|
||||
raise Exception("无法读取上料斗重量传感器数据,下料操作终止")
|
||||
|
||||
target_upper_weight = initial_upper_weight - self.settings.single_batch_weight
|
||||
target_upper_weight = max(target_upper_weight, 0) # 确保不低于0
|
||||
|
||||
print(f"上料斗初始重量: {initial_upper_weight:.2f}kg, 目标重量: {target_upper_weight:.2f}kg")
|
||||
|
||||
# 确保下料斗出砼门关闭
|
||||
self.relay_controller.control(self.relay_controller.DOOR_LOWER_2, 'close')
|
||||
# 打开上料斗出砼门
|
||||
self.relay_controller.control(self.relay_controller.DOOR_LOWER_1, 'open')
|
||||
|
||||
# 等待物料流入下料斗,基于上料斗重量变化控制
|
||||
import time
|
||||
start_time = time.time()
|
||||
timeout = 30 # 30秒超时
|
||||
|
||||
while time.time() - start_time < timeout:
|
||||
current_upper_weight = self.transmitter_controller.read_data(1)
|
||||
|
||||
# 如果无法读取重量,继续尝试
|
||||
if current_upper_weight is None:
|
||||
print("无法读取上料斗重量,继续尝试...")
|
||||
time.sleep(1)
|
||||
continue
|
||||
|
||||
print(f"上料斗当前重量: {current_upper_weight:.2f}kg")
|
||||
|
||||
# 如果达到目标重量,则关闭上料斗出砼门
|
||||
if current_upper_weight <= target_upper_weight + 50: # 允许50kg的误差范围
|
||||
print(f"达到目标重量,当前重量: {current_upper_weight:.2f}kg")
|
||||
break
|
||||
elif time.time() - start_time > 25: # 如果25秒后重量变化过小
|
||||
weight_change = initial_upper_weight - current_upper_weight
|
||||
if weight_change < 100: # 如果重量变化小于100kg
|
||||
print("重量变化过小,可能存在堵塞,交由监控系统处理...")
|
||||
break
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
# 关闭上料斗出砼门
|
||||
self.relay_controller.control(self.relay_controller.DOOR_LOWER_1, 'close')
|
||||
|
||||
# 验证下料结果
|
||||
final_upper_weight = self.transmitter_controller.read_data(1)
|
||||
if final_upper_weight is not None:
|
||||
actual_transferred = initial_upper_weight - final_upper_weight
|
||||
print(f"实际下料重量: {actual_transferred:.2f}kg")
|
||||
|
||||
# 增加上料计数
|
||||
self.state.upper_feeding_count += 1
|
||||
print("上料斗下料完成")
|
||||
|
||||
def wait_for_vehicle_alignment(self):
|
||||
"""等待模具车对齐"""
|
||||
print("等待模具车对齐...")
|
||||
self.state.lower_feeding_stage = 4
|
||||
|
||||
import time
|
||||
while self.state.lower_feeding_stage == 4 and self.state.running:
|
||||
if self.state.vehicle_aligned:
|
||||
print("模具车已对齐,开始下料")
|
||||
self.state.lower_feeding_stage = 1
|
||||
self.feeding_stage_one()
|
||||
break
|
||||
time.sleep(self.settings.alignment_check_interval)
|
||||
|
||||
def feeding_stage_one(self):
|
||||
"""第一阶段下料:下料斗向模具车下料(低速)"""
|
||||
print("开始第一阶段下料:下料斗低速下料")
|
||||
self.inverter_controller.set_frequency(self.settings.frequencies[0])
|
||||
self.inverter_controller.control('start')
|
||||
|
||||
# 确保上料斗出砼门关闭
|
||||
self.relay_controller.control(self.relay_controller.DOOR_LOWER_1, 'close')
|
||||
# 打开下料斗出砼门
|
||||
self.relay_controller.control(self.relay_controller.DOOR_LOWER_2, 'open')
|
||||
|
||||
import time
|
||||
start_time = time.time()
|
||||
initial_weight = self.transmitter_controller.read_data(2)
|
||||
if initial_weight is None:
|
||||
print("无法获取初始重量,取消下料")
|
||||
self.finish_feeding_process()
|
||||
return
|
||||
|
||||
target_weight = initial_weight + self.settings.single_batch_weight
|
||||
|
||||
while self.state.lower_feeding_stage == 1:
|
||||
current_weight = self.transmitter_controller.read_data(2)
|
||||
if current_weight is None:
|
||||
self.state.lower_weight_error_count += 1
|
||||
if self.state.lower_weight_error_count >= self.settings.max_error_count:
|
||||
print("下料斗传感器连续读取失败,停止下料")
|
||||
self.finish_feeding_process()
|
||||
return
|
||||
else:
|
||||
self.state.lower_weight_error_count = 0
|
||||
|
||||
if (current_weight is not None and current_weight >= target_weight) or (time.time() - start_time) > 30:
|
||||
self.state.lower_feeding_stage = 2
|
||||
self.feeding_stage_two()
|
||||
break
|
||||
time.sleep(2)
|
||||
|
||||
def feeding_stage_two(self):
|
||||
"""第二阶段下料:下料斗向模具车下料(中速)"""
|
||||
print("开始第二阶段下料:下料斗中速下料")
|
||||
self.inverter_controller.set_frequency(self.settings.frequencies[1])
|
||||
|
||||
# 保持下料斗出砼门打开
|
||||
self.relay_controller.control(self.relay_controller.DOOR_LOWER_2, 'open')
|
||||
# 确保上料斗出砼门关闭
|
||||
self.relay_controller.control(self.relay_controller.DOOR_LOWER_1, 'close')
|
||||
|
||||
import time
|
||||
start_time = time.time()
|
||||
initial_weight = self.transmitter_controller.read_data(2)
|
||||
if initial_weight is None:
|
||||
print("无法获取初始重量,取消下料")
|
||||
self.finish_feeding_process()
|
||||
return
|
||||
|
||||
target_weight = initial_weight + self.settings.single_batch_weight
|
||||
|
||||
while self.state.lower_feeding_stage == 2:
|
||||
current_weight = self.transmitter_controller.read_data(2)
|
||||
if current_weight is None:
|
||||
self.state.lower_weight_error_count += 1
|
||||
if self.state.lower_weight_error_count >= self.settings.max_error_count:
|
||||
print("下料斗传感器连续读取失败,停止下料")
|
||||
self.finish_feeding_process()
|
||||
return
|
||||
else:
|
||||
self.state.lower_weight_error_count = 0
|
||||
|
||||
if (current_weight is not None and current_weight >= target_weight) or (time.time() - start_time) > 30:
|
||||
self.state.lower_feeding_stage = 3
|
||||
self.feeding_stage_three()
|
||||
break
|
||||
time.sleep(2)
|
||||
|
||||
def feeding_stage_three(self):
|
||||
"""第三阶段下料:下料斗向模具车下料(高速)"""
|
||||
print("开始第三阶段下料:下料斗高速下料")
|
||||
self.inverter_controller.set_frequency(self.settings.frequencies[2])
|
||||
|
||||
# 保持下料斗出砼门打开
|
||||
self.relay_controller.control(self.relay_controller.DOOR_LOWER_2, 'open')
|
||||
# 确保上料斗出砼门关闭
|
||||
self.relay_controller.control(self.relay_controller.DOOR_LOWER_1, 'close')
|
||||
|
||||
import time
|
||||
start_time = time.time()
|
||||
initial_weight = self.transmitter_controller.read_data(2)
|
||||
if initial_weight is None:
|
||||
print("无法获取初始重量,取消下料")
|
||||
self.finish_feeding_process()
|
||||
return
|
||||
|
||||
target_weight = initial_weight + self.settings.single_batch_weight
|
||||
|
||||
while self.state.lower_feeding_stage == 3:
|
||||
current_weight = self.transmitter_controller.read_data(2)
|
||||
if current_weight is None:
|
||||
self.state.lower_weight_error_count += 1
|
||||
if self.state.lower_weight_error_count >= self.settings.max_error_count:
|
||||
print("下料斗传感器连续读取失败,停止下料")
|
||||
self.finish_feeding_process()
|
||||
return
|
||||
else:
|
||||
self.state.lower_weight_error_count = 0
|
||||
|
||||
if (current_weight is not None and current_weight >= target_weight) or (time.time() - start_time) > 30:
|
||||
self.state.lower_feeding_stage = 4
|
||||
self.finish_current_batch()
|
||||
break
|
||||
time.sleep(2)
|
||||
|
||||
def finish_current_batch(self):
|
||||
"""完成当前批次下料"""
|
||||
print("当前批次下料完成,关闭出砼门")
|
||||
self.inverter_controller.control('stop')
|
||||
self.relay_controller.control(self.relay_controller.DOOR_LOWER_1, 'close')
|
||||
self.relay_controller.control(self.relay_controller.DOOR_LOWER_2, 'close')
|
||||
|
||||
# 增加三阶段下料轮次计数
|
||||
self.state.lower_feeding_cycle += 1
|
||||
|
||||
# 检查是否完成两轮三阶段下料(总共5吨)
|
||||
if self.state.lower_feeding_cycle >= 2:
|
||||
# 完成整个5吨下料任务
|
||||
print("完成两轮三阶段下料,5吨下料任务完成")
|
||||
self.finish_feeding_process()
|
||||
return
|
||||
|
||||
# 如果只完成一轮三阶段下料,进行第二次上料
|
||||
print("第一轮三阶段下料完成,准备第二次上料")
|
||||
# 上料斗第二次向下料斗下料
|
||||
try:
|
||||
self.transfer_material_from_upper_to_lower()
|
||||
except Exception as e:
|
||||
print(f"第二次上料失败: {e}")
|
||||
print("停止下料流程")
|
||||
self.finish_feeding_process() # 出现严重错误时结束整个流程
|
||||
return
|
||||
|
||||
# 继续等待当前模具车对齐(不需要重新等待对齐,因为是同一辆模具车)
|
||||
print("第二次上料完成,继续三阶段下料")
|
||||
self.state.lower_feeding_stage = 1 # 直接进入第一阶段下料
|
||||
self.feeding_stage_one() # 开始第二轮第一阶段下料
|
||||
|
||||
def finish_feeding_process(self):
|
||||
"""完成整个下料流程"""
|
||||
print("整个下料流程完成")
|
||||
self.state.lower_feeding_stage = 0
|
||||
self.state.lower_feeding_cycle = 0
|
||||
self.state.upper_feeding_count = 0
|
||||
self.return_upper_door_to_default()
|
||||
|
||||
def return_upper_door_to_default(self):
|
||||
"""上料斗回到默认位置(搅拌楼下接料位置)"""
|
||||
print("上料斗回到默认位置")
|
||||
self.relay_controller.control(self.relay_controller.DOOR_UPPER, 'close')
|
||||
self.state.upper_door_position = 'default'
|
||||
Reference in New Issue
Block a user