Files
Feeding_control_system/controller/hopper_controller.py

219 lines
9.4 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from PySide6.QtCore import QTimer, Signal, QObject, Slot
import threading
# from hardware.transmitter import TransmitterController
# from hardware.relay import RelayController
from view.widgets.hopper_widget import HopperWidget
from view.widgets.conveyor_system_widget import ConveyorSystemWidget
from enum import Enum
class UpperHopperPosition(Enum):
"""上料斗位置
- MIXING_TOWER: 搅拌楼处,对应数值 1
- VIBRATION_CHAMBER: 振捣室处,对应数值 2
- IN_TRANSIT: 途中,对应数值 3
"""
MIXING_TOWER = 1 # 搅拌楼处
VIBRATION_CHAMBER = 2 # 振捣室处
IN_TRANSIT = 3 # 运输途中
# 信号类:后台线程向主线程传递数据
class HopperSignals(QObject):
upper_weight_updated = Signal(int) # 上料斗重量更新信号
class HopperController:
def __init__(self, hopper_view:HopperWidget, conveyor_view:ConveyorSystemWidget):
self.hopper_view = hopper_view
self.conveyor_view = conveyor_view # 控制传送带中的上料斗
self.signals = HopperSignals() # 信号
# 下料斗夹爪测试用例数据
# 注意:目前只控制 下料斗的夹爪角度变化
self.angle = 10.33 # 夹爪当前角度
self.max_angle = 60.00 # 夹爪最大张开角度
self.min_angle = 10.00 # 夹爪最小张开角度
self.is_add = True # 角度增加/减小 控制
self.timer_angle = QTimer() # 角度更新定时器
self.timer_angle.setInterval(1000) # 1秒更新一次角度
# 重量读取定时器
# self.timer_weight = QTimer() # 重量读取定时器
# self.timer_weight.setInterval(2000) # 每2秒读取一次重量
# 绑定信号
self._connect_signals()
# 开启定时器
# self.timer_angle.start()
# self.timer_weight.start()
def _connect_signals(self):
# 更新上料斗重量
self.signals.upper_weight_updated.connect(self.onUpdateUpperHopperWeight)
# 上料斗重量定时读取
# self.timer_weight.timeout.connect(self.handleReadUpperHopperWeight)
# 下料斗夹爪定时更新
self.timer_angle.timeout.connect(self.handleLowerClampAngleUpdate)
# 上料斗 "开"按钮点击
self.hopper_view.upper_open_btn.clicked.connect(self.onUpperClampOpenBottonClicked)
# 上料斗 "破拱"按钮点击
self.hopper_view.upper_arch_breaking_signal.connect(self.onUpperArchBreakingClicked)
# 下料斗 "开"按钮点击
self.hopper_view.lower_open_btn.clicked.connect(self.onLowerClampOpenBottonClicked)
# 下料斗 "破拱"按钮点击
self.hopper_view.lower_arch_breaking_signal.connect(self.onLowerArchBreakingClicked)
def handleLowerClampAngleUpdate(self):
"""处理下料斗夹爪开合"""
# 角度增减逻辑
if self.is_add:
self.angle += 1.22
else:
self.angle -= 1.33
# 边界控制
if self.angle > self.max_angle:
self.is_add = False
self.angle = self.max_angle
if self.angle <= self.min_angle:
self.is_add = True
self.angle = self.min_angle
# 更新下料斗夹爪角度
self.onUpdateLowerClampAngle(self.angle)
@Slot(int)
def onUpdateUpperHopperWeight(self, weight:int):
"更新上料斗重量"
self.hopper_view.setUpperHopperWeight(weight)
# 注意:此时需要同步更新传送带中的上料斗的重量
self.conveyor_view.setConveyorHopperWeight(weight)
@Slot(int)
def onUpdateLowerHopperWeight(self, weight:int):
"更新下料斗重量"
self.hopper_view.setLowerHopperWeight(weight)
@Slot()
def handleReadUpperHopperWeight(self):
# 后台读取上料斗重量
# def upper_weight_task():
# loc_tra = TransmitterController(RelayController())
# # 上料斗重量 (目前只有上料斗安装变送器, 可以读取到重量)
# upper_weight = loc_tra.read_data(1)
# # 发送信号到主线程更新UI
# if upper_weight is not None:
# self.signals.upper_weight_updated.emit(upper_weight)
# threading.Thread(target=upper_weight_task, daemon=True).start()
pass
@Slot(float)
def onUpdateLowerClampAngle(self, angle:float):
"""更新下料斗夹爪角度"""
self.hopper_view.setLowerHopperOpeningAngle(angle)
@Slot(float)
def onUpdateUpperClampAngle(self, angle:float):
"""更新上料斗夹爪角度"""
self.hopper_view.setUpperHopperClampAngle(angle)
@Slot()
def onUpperClampOpenBottonClicked(self):
# 上料斗 夹爪 "开"按钮点击
print("hopper_controller: onUpperClampOpenBottonClicked")
# 测试上料斗夹爪6秒打开60度
self.hopper_view.upper_clamp_widget.testAnimation(target_angle=60, duration=10)
@Slot(int)
def onUpdateUpperClampStatus(self, status:int):
# 上料斗夹爪状态 1:半开2全开0:关闭)
if status == 1:
# 上料斗门半开
self.hopper_view.upper_clamp_widget.testAnimation(target_angle=30, duration=5)
elif status == 2:
# 上料斗门全开
self.hopper_view.upper_clamp_widget.testAnimation(target_angle=60, duration=10)
elif status == 0:
# 上料斗门关闭
self.hopper_view.upper_clamp_widget.testAnimation(target_angle=0, duration=6)
def onUpdateUpperHopperPosition(self, position:int):
# 上料斗位置
if position == UpperHopperPosition.MIXING_TOWER.value: # 上料斗到达搅拌楼
# 上料斗在搅拌楼下
self.hopper_view.hideUpperHopper() # 隐藏非传送带处的上料斗
self.conveyor_view.moveHopperBelowMixer() # 传送带处的上料斗移动到搅料楼下
self.conveyor_view.showHopper() # 显示传送带处的上料斗
elif position == UpperHopperPosition.VIBRATION_CHAMBER.value: # 上料斗就绪,到达振捣室
# 上料斗在振捣室处
self.conveyor_view.hideHopper() # 隐藏传送带处的上料斗
self.hopper_view.upper_clamp_widget.set_angle(0) # 上料斗夹爪角度设置为0此时上料斗一定是关闭的
self.hopper_view.showUpperHopper() # 显示非传送带处的上料斗
elif position == UpperHopperPosition.IN_TRANSIT.value:
# 上料斗在途中
self.hopper_view.hideUpperHopper() # 隐藏非传送带处的上料斗 (下料斗处对应的上料斗叫非传送带处上料斗)
self.conveyor_view.moveHopperToTransition() # 传送带处上料斗移动到中间过渡位置
self.conveyor_view.showHopper() # 显示传送带处的上料斗
@Slot(bool)
def onUpperArchBreakingStatusChanged(self, status:bool):
"""上料斗破拱状态改变: status 为True表示 破拱状态, 为False表示 不破拱状态"""
if status == True: # 破拱状态
self.hopper_view.upper_arch_breaking_status = True
self.hopper_view.upper_arch_label.setHidden(False)
else: # 不破拱状态
self.hopper_view.upper_arch_breaking_status = False
self.hopper_view.upper_arch_label.setHidden(True)
@Slot(bool)
def onUpperArchBreakingClicked(self, status:bool):
"""上料斗破拱按钮点击: status 为True表示 开启破拱, 为False表示 关闭破拱"""
print("hopper_controller: onUpperArchBreakingClicked ", status)
# 这里需要控制网络继电器开启上料斗破拱可能还需要同步opc的上料斗破拱状态
@Slot(int)
def onUpperHopperStatusChanged(self, status:int):
"""上料斗状态改变: status为 0=绿(正常), 1=黄(警告), 2=红(异常) """
# 料斗中的状态指示器
self.hopper_view.setUpperHopperStatus(status)
@Slot(float)
def onUpdateUpperHopperVolume(self, volume: float):
"""更新上料斗显示的方量,如: 2.0"""
self.hopper_view.setUpperHopperVolume(volume)
@Slot()
def onLowerClampOpenBottonClicked(self):
# 下料斗 夹爪 "开"按钮点击
print("hopper_controller: onLowerClampOpenBottonClicked")
@Slot(bool)
def onLowerArchBreakingStatusChanged(self, status:bool):
"""下料斗破拱状态改变: status 为True表示 破拱状态, 为False表示 不破拱状态"""
if status == True: # 破拱状态
self.hopper_view.lower_arch_breaking_status = True
self.hopper_view.lower_arch_label.setHidden(False)
else: # 不破拱状态
self.hopper_view.lower_arch_breaking_status = False
self.hopper_view.lower_arch_label.setHidden(True)
@Slot(bool)
def onLowerArchBreakingClicked(self, status:bool):
"""下料斗破拱按钮点击: status 为True表示 开启破拱, 为False表示 关闭破拱"""
print("hopper_controller: onLowerArchBreakingClicked ", status)
# 这里需要控制网络继电器开启下料斗破拱可能还需要同步opc的下料斗破拱状态
@Slot(int)
def onLowerHopperStatusChanged(self, status:int):
"""下料斗状态改变: status为 0=绿(正常), 1=黄(警告), 2=红(异常) """
# 料斗中的状态指示器
self.hopper_view.setLowerHopperStatus(status)