0209整理

This commit is contained in:
2026-02-10 10:18:17 +08:00
parent d6ad01274a
commit 6e74eaf206
62 changed files with 838 additions and 9136 deletions

View File

@ -1,97 +0,0 @@
import sys
import os
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import threading
import time
import queue
from core.system_state import SystemState,FeedStatus
from hardware.relay import RelayController
from hardware.inverter import InverterController
from hardware.transmitter import TransmitterController
from config.ini_manager import ini_manager
from hardware.upper_plc import OmronFinsPollingService
from vision.visual_callback_dq import VisualCallback
from opc.opcua_client_feed import OpcuaClientFeed
from busisness.blls import ArtifactBll,PDRecordBll
from busisness.models import ArtifactInfoModel,PDRecordModel
class FeedingControlSystem:
def __init__(self):
print('FeedingControlSystem初始化')
self.pd_record_bll=PDRecordBll()
def send_pd_data(self):
"""
发送PD数据到OPC队列
"""
# 构建PD数据
_cur_mould='SHR2B1-13'
'F块L1块需要设置重量'
_weight=0
_pdrecords = self.pd_record_bll.get_last_pds(_cur_mould)
if _pdrecords:
_pdrecord=_pdrecords[0]
if _pdrecord.TaskID:
if _pdrecord.BlockNumber=='F':
print(f'{_pdrecord.MouldCode} F块不发送派单数据')
print(f'{_pdrecord.MouldCode} F块不发送派单数据')
print(f'{_pdrecord.MouldCode} F块不发送派单数据')
return True
_fact_volumn=self.get_fact_volumn(_pdrecord.MouldCode,_pdrecord.BlockNumber,_weight)
if _fact_volumn>0:
_pdrecord.FBetonVolume=_fact_volumn
print(f'{_pdrecord.MouldCode}-{_pdrecord.BlockNumber} 实际派单方量:{_fact_volumn},{_fact_volumn},{_fact_volumn}')
print(f'{_pdrecord.MouldCode}-{_pdrecord.BlockNumber} 实际派单方量:{_fact_volumn},{_fact_volumn},{_fact_volumn}')
print(f'{_pdrecord.MouldCode}-{_pdrecord.BlockNumber} 实际派单方量:{_fact_volumn},{_fact_volumn},{_fact_volumn}')
# self.state._pd_data=_pdrecord
return True
else:
return False
else:
print(f'{_pdrecord.MouldCode} 未获取到数据-(等待扫码)')
return False
else:
print(f'接口数据异常')
return False
def get_fact_volumn(self,mould_code:str,block_number:str='',_weight:float=0) -> float:
"""获取实际派单发量"""
_now_volumn=0
_pd_volumn=0
print(f'get_fact_volumn当前重量{_weight}')
_now_volumn=_weight/2500
if not block_number and '-' in mould_code:
block_number = mould_code.split('-')[0][-2:]
if block_number=='B1':
_pd_volumn=1.9
if _weight>750:
#留0.3
_pd_volumn=_pd_volumn-_now_volumn+0.3
if _pd_volumn<1:
_pd_volumn=1
if block_number in ['B2','B3']:
_pd_volumn=1.9
elif block_number=='L1':
_pd_volumn=2.0
elif block_number=='L2':
#多F块后面剩下的大约500那下完F后多的就可以减去
_pd_volumn=2
# if _weight>1300:
_pd_volumn=_pd_volumn-_now_volumn+0.5
if _pd_volumn>2.1:
_pd_volumn=2.1
elif _pd_volumn<0.8:
_pd_volumn=0.8
return round(_pd_volumn,1)
if __name__ == "__main__":
system = FeedingControlSystem()
system.send_pd_data()

View File

@ -1,109 +0,0 @@
from PySide6.QtCore import Signal, QObject
import threading
from enum import IntEnum
class SystemState(QObject):
"""状态中以_开头的属性会发送到OPC通知,不需要的不要加_开头"""
state_updated=Signal(str,object)
def __init__(self):
super().__init__()
#
self._watched_props = []
self.lock = threading.RLock()
# 系统运行状态
self.running = True
# 上料斗控制相关
self._upper_door_position = 'default' # default(在搅拌楼下接料), over_lower(在下料斗上方), returning(返回中)
# 是否破拱
self._upper_is_arch_=False
self._upper_door_closed=True
self._upper_weight=0
self._upper_volume=0.0
#下料斗状态想着
self.lower_feeding_stage = 0 # 0:未下料, 1:第一阶段, 2:第二阶段, 3:第三阶段, 4:等待模具车对齐
self._lower_is_arch_=False
self._lower_weight=0
self._lower_angle=0.0
#模具车状态
self._mould_weight=0
self._mould_frequency=220
self._mould_vibrate_status=0 #1振动中0未振动
#记录模具开始振动的时间
self.mould_vibrate_time=0
self.lower_feeding_cycle = 0 # 下料斗下料循环次数
self.upper_feeding_count = 0 # 上料斗已下料次数
self.upper_feeding_max = 2 #上料斗最大下料次数
# 重量相关
self.last_upper_weight = 0
self.last_lower_weight = 0
self.last_weight_time = 0
#需要下料的总重量
self._mould_need_weight=0
#完成下料的总重量
self._mould_finish_weight=0
self.initial_upper_weight=0
self.initial_lower_weight=0
# 错误计数
self.upper_weight_error_count = 0
self.lower_weight_error_count = 0
# 视觉系统状态
self.angle_control_mode = "normal" # 角度控制模式: normal, reducing, maintaining, recovery
self.overflow_detected = "0" # 堆料检测
self.current_finish_status=False # 当前是否完成浇筑满
self.door_opening_large = False # 夹角
self.vehicle_aligned = False # 模具车是否对齐
self.last_angle = None # 上次检测角度
#当前RFID的内容格式为 模块编号,分块号,尺寸规格,方量
self.rfid_current=None
#当前生产的管片
self.current_artifact=None
#当前生产状态
self._feed_status=FeedStatus.FNone
#每方重量
self.density=2416.4
#
self._watched_props = [k for k in self.__dict__ if k.startswith('_')]
def __setattr__(self, name, value):
super().__setattr__(name, value)
if name in self._watched_props:
with self.lock:
public_name = name.lstrip('_')
self.state_updated.emit(public_name, value)
class FeedStatus(IntEnum):
#初始值
FNone = 0
# 检查模车(模车到位)
FCheckM = 1
#RFID检测或匹配
FRFID=2,
# 开始(管片待生产任务)
FApiCheck = 3
# 检查盖板(盖板到位)
FCheckGB = 4
# 上料到下料(上料斗到下料斗)
FUpperToLower=5
#下料1
FFeed1 = 6
# 下料2
FFeed2 = 7
# 下料3
FFeed3 = 8
#完成(管片生产完成)
FFinished = 11
FFeed=12

View File

@ -1,288 +0,0 @@
# core/system.py
import threading
import time
import cv2
from core.state import SystemState
from hardware.relay import RelayController
from hardware.inverter import InverterController
from hardware.transmitter import TransmitterController
from hardware.RFID.rfid_service import rfid_service
from vision.camera import DualCameraController
from vision.detector import VisionDetector
from feeding.controller import FeedingController
from service.mould_service import app_web_service
from config.settings import app_set_config
class FeedingControlSystem:
def __init__(self):
self.state = SystemState()
# 初始化硬件控制器
self.relay_controller = RelayController(
host=app_set_config.relay_host,
port=app_set_config.relay_port
)
self.inverter_controller = InverterController(self.relay_controller)
self.transmitter_controller = TransmitterController(self.relay_controller)
# 初始化视觉系统
self.camera_controller = DualCameraController(app_set_config.camera_configs)
self.vision_detector = VisionDetector()
# 初始化RFID控制器
self.rfid_controller = rfid_service(
host=app_set_config.rfid_host,
port=app_set_config.rfid_port
)
# 初始化下料控制器
self.feeding_controller = FeedingController(
self.relay_controller,
self.inverter_controller,
self.transmitter_controller,
self.vision_detector,
self.camera_controller,
self.rfid_controller,
self.state
)
# 线程管理
self.monitor_thread = None
self.visual_control_thread = None
self.alignment_check_thread = None
self.lower_feeding_thread = None
self.led_thread = None
def initialize(self):
"""初始化系统"""
print("初始化控制系统...")
# self.check_device_connectivity()
# self.camera_controller.start_cameras()
# if not app_set_config.debug_feeding:
# 启动系统监控(要料,破拱)线程
self.start_monitoring()
# 启动视觉控制(角度、溢出)线程
# self.start_visual_control()
# 启动对齐检查线程
self.start_alignment_check()
# 启动下料线程
self.start_lower_feeding()
#LED屏
# self.start_led()
print("控制系统初始化完成")
def start_monitoring(self):
"""启动系统监控"""
print('振动和要料监控线程启动')
self.monitor_thread = threading.Thread(
target=self._monitor_loop,
daemon=True,
name='monitor'
)
self.monitor_thread.start()
def _monitor_loop(self):
"""监控循环"""
while self.state.running:
try:
# self.feeding_controller.check_upper_material_request()
self.feeding_controller.check_arch_blocking()
time.sleep(1)
except Exception as e:
print(f"监控线程错误: {e}")
def start_visual_control(self):
"""启动视觉控制"""
print('视觉控制线程启动')
self.visual_control_thread = threading.Thread(
target=self._visual_control_loop,
daemon=True,
name='visual_control'
)
self.visual_control_thread.start()
def _visual_control_loop(self):
"""视觉控制循环"""
while self.state.running:
try:
# print('visual_control')
current_frame = self.camera_controller.get_single_latest_frame()
if current_frame is not None:
# 执行视觉控制逻辑
self.feeding_controller.visual_control(current_frame)
time.sleep(app_set_config.visual_check_interval)
except Exception as e:
print(f"视觉控制循环错误: {e}")
time.sleep(app_set_config.visual_check_interval)
def start_alignment_check(self):
"""启动对齐检查"""
print('对齐检查线程启动')
self.alignment_check_thread = threading.Thread(
target=self._alignment_check_loop,
daemon=True,
name='align_check'
)
self.alignment_check_thread.start()
def _alignment_check_loop(self):
"""对齐检查循环"""
loc_align_status=False
loc_before_status=None
while self.state.running:
try:
if self.state.lower_feeding_stage == 4: # 等待对齐阶段
current_frame = self.camera_controller.get_single_latest_frame()
if current_frame is not None:
self.state.vehicle_aligned = self.alignment_check_status()
if self.state.vehicle_aligned:
# loc_count+=1
print("检测到模具车对齐")
else:
print("模具车未对齐")
# time.sleep(app_set_config.alignment_check_interval)
# loc_align_status=self.alignment_check_status()
# if loc_align_status and not loc_before_status:
# print("模具车由未对齐到对齐")
# self.state.vehicle_aligned=True
# elif not loc_align_status and loc_before_status:
# print("模具车由对齐到未对齐")
# self.state.vehicle_aligned=False
# if loc_before_status!=loc_align_status:
# loc_before_status=loc_align_status
except Exception as e:
print(f"对齐检查循环错误: {e}")
finally:
time.sleep(app_set_config.alignment_check_interval)
def alignment_check_status(self)->bool:
"""对齐检查循环"""
loc_aligned=False
loc_count=0
for i in range(4):
try:
current_frame = self.camera_controller.get_single_latest_frame()
if current_frame is not None:
loc_aligned = self.vision_detector.detect_vehicle_alignment(current_frame)
if loc_aligned:
loc_count+=1
print("检测到模具车对齐")
else:
loc_count=0
print("模具车未对齐")
time.sleep(app_set_config.alignment_check_interval)
except Exception as e:
print(f"对齐检查循环错误: {e}")
time.sleep(app_set_config.alignment_check_interval)
if loc_count>=3:
loc_aligned=True
else:
loc_aligned=False
return loc_aligned
def start_lower_feeding(self):
"""启动下料流程"""
self.lower_feeding_thread = threading.Thread(
target=self._start_lower_feeding,
name="Feeding",
daemon=True
)
self.lower_feeding_thread.start()
def _start_lower_feeding(self):
"""启动下料流程"""
while self.state.running:
self.feeding_controller.start_feeding()
time.sleep(app_set_config.lower_feeding_interval)
def start_led(self):
"""启动LED流程"""
self.led_thread = threading.Thread(
target=self._start_led,
name="LED",
daemon=True
)
self.led_thread.start()
def _start_led(self):
"""启动LED流程"""
while self.state.running:
led_info = app_web_service.get_pouring_led()
if led_info:
if self.state.current_artifact.MouldCode==led_info.MouldCode:
led_info.RingTypeCode=self.state.current_artifact.RingTypeCode
led_info.UpperWeight=self.state._upper_weight
led_info.LowerWeight=self.state._lower_weight
led_info.VibrationFrequency=self.state._mould_frequency
#发送到LED屏
time.sleep(app_set_config.led_interval)
def check_device_connectivity(self) -> bool:
"""检查关键设备连接状态"""
try:
# 检查网络继电器连接
test_response = self.relay_controller.send_command(self.relay_controller.read_status_command)
if not test_response:
print("网络继电器连接失败")
return False
# 检查变频器连接
if not self.relay_controller.modbus_client.connect():
print("无法连接到网络继电器Modbus服务")
return False
# 尝试读取变频器一个寄存器(测试连接)
# test_result = self.relay_controller.modbus_client.read_holding_registers(
# address=0x00,
# count=1,
# slave=self.inverter_controller.config['slave_id']
# )
# if isinstance(test_result, Exception):
# print("变频器连接测试失败")
# return False
# 检查下料斗变送器连接
test_weight = self.transmitter_controller.read_data(2)
if test_weight is None:
print("下料斗变送器连接失败")
return False
self.relay_controller.modbus_client.close()
return True
except Exception as e:
print(f"设备连接检查失败: {e}")
return False
def stop(self):
"""停止系统"""
print("停止控制系统...")
self.state.running = False
# 等待线程结束
if self.monitor_thread:
self.monitor_thread.join()
if self.visual_control_thread:
self.visual_control_thread.join()
if self.alignment_check_thread:
self.alignment_check_thread.join()
if self.lower_feeding_thread:
self.lower_feeding_thread.join()
# 释放摄像头资源
self.camera_controller.release()
print("控制系统已停止")

View File

@ -27,62 +27,70 @@ class FeedingControlSystem:
port=ini_manager.relay_port
)
self.inverter_controller = InverterController()
self.transmitter_controller = TransmitterController(self.relay_controller)
self.plc_service = OmronFinsPollingService(ini_manager.upper_plc_ip, ini_manager.upper_plc_port)
# 初始化下料控制器
self.feeding_controller = VisualCallback(
relay_controller=self.relay_controller,
transmitter_controller=self.transmitter_controller,
state=self.state
)
self.plc_service.register_data_callback(self.feeding_controller.on_plc_update)
#小屏修改过屏幕
self.vf_auto_mode=True
# 初始化 OPC UA 客户端
self.opcua_client_feed = OpcuaClientFeed()
# 初始化 RFID 控制器
# self.rfid_controller = rfid_service(
# host=app_set_config.rfid_host,
# port=app_set_config.rfid_port
# )
# self.plc_service = OmronFinsPollingService(ini_manager.upper_plc_ip, ini_manager.upper_plc_port)
# 初始化下料控制器
self.feeding_controller = VisualCallback(self.state)
# 初始化 OPC 队列监听线程
self.opc_queue_thread = None
# 线程管理
self.monitor_thread = None
self.visual_control_thread = None
self.alignment_check_thread = None
self.lower_feeding_thread = None
self.led_thread = None
self.feed_thread = None
self.vf_thread = None
self.arch_thread = None
self.api_thread = None
self.pd_jbl_thread = None
# 初始化 OPC 队列监听线程,用于处理队列中的数据
self.opc_queue_thread = None
def initialize(self):
def initialize(self)->bool:
"""初始化系统"""
print("初始化控制系统...")
# self.check_device_connectivity()
# self.camera_controller.start_cameras()
# self.start_monitoring()
# 启动下料线程
# self.start_lower_feeding()
# 启动OPC队列处理线程
# self.opcua_client_feed.start()
# self.start_opc_queue_thread()
#启用API线程
self.start_api_thread()
#启用上料斗PLC
self.plc_service.start_polling(interval=2.0)
#启用下料线程
self.start_feed_thread()
#启用变频器线程
self.start_vf_thread()
# self.feeding_controller.get_current_mould()
# self.feeding_controller._cur_mould_model.MouldCode='SHR2L1-5'
# self.feeding_controller.send_pd_data()
#启用破拱线程
self.start_arch_thread()
#启用推送模型数据线程
self.feeding_controller.start_visual_thread()
#启用API(对接PD API数据),线程
self.start_api_thread()
#启用派单线程
# self.start_pd_thread()
self.start_pd_thread()
# 启动OPC队列处理线程维护连接的断开重连等
self.opcua_client_feed.start()
self.start_opc_queue_thread()
print("控制系统初始化完成")
return True
def start_feed_thread(self):
"下料线程控制,主要控制下料斗(视觉控制)以及上料斗"
self.feed_thread = threading.Thread(
target=self.feeding_controller._run_feed,
daemon=True
)
self.feed_thread.start()
def start_opc_queue_thread(self):
"""启动OPC队列处理线程"""
"""启动OPC队列处理线程从控制系统中获取数据通过OPC外发"""
print('启动OPC队列处理线程')
self.opc_queue_thread = threading.Thread(
target=self._process_opc_queue,
@ -102,7 +110,7 @@ class FeedingControlSystem:
self.api_thread.start()
def start_vf_thread(self):
"""启动变频器控制线程"""
"""启动变频器控制线程(控制变频器开始启动,以及频率变换)"""
# print('启动API处理线程从API获取未浇筑数据')
self.vf_thread = threading.Thread(
target=self._process_vf,
@ -157,7 +165,6 @@ class FeedingControlSystem:
print(f"处理变频器数据时发生错误: {e}")
time.sleep(2)
def _process_api_db(self):
from service.mould_service import app_web_service
"""处理API队列中的数据"""
@ -296,41 +303,16 @@ class FeedingControlSystem:
self.feeding_controller.shutdown()
self.stop()
def start_monitoring(self):
"""启动系统监控"""
def start_arch_thread(self):
"""启动系统监控和要料"""
print('振动和要料监控线程启动')
self.monitor_thread = threading.Thread(
target=self._monitor_loop,
#启动振动线程
self.arch_thread = threading.Thread(
target=self.feeding_controller._arch_loop,
daemon=True,
name='monitor'
)
self.monitor_thread.start()
def _monitor_loop(self):
"""监控循环"""
while self.state.running:
try:
# self.feeding_controller.check_upper_material_request()
self.feeding_controller.check_arch_blocking()
time.sleep(1)
except Exception as e:
print(f"监控线程错误: {e}")
def start_lower_feeding(self):
"""启动下料流程"""
self.lower_feeding_thread = threading.Thread(
target=self._start_lower_feeding,
name="Feeding",
daemon=True
)
self.lower_feeding_thread.start()
def _start_lower_feeding(self):
"""启动下料流程"""
while self.state.running:
self.feeding_controller.start_feeding()
time.sleep(app_set_config.lower_feeding_interval)
name='arch'
)
self.arch_thread.start()
def check_device_connectivity(self) -> bool:
"""检查关键设备连接状态"""
@ -346,17 +328,6 @@ class FeedingControlSystem:
print("无法连接到网络继电器Modbus服务")
return False
# 尝试读取变频器一个寄存器(测试连接)
# test_result = self.relay_controller.modbus_client.read_holding_registers(
# address=0x00,
# count=1,
# slave=self.inverter_controller.config['slave_id']
# )
# if isinstance(test_result, Exception):
# print("变频器连接测试失败")
# return False
# 检查下料斗变送器连接
test_weight = self.transmitter_controller.read_data(2)
if test_weight is None:
@ -368,8 +339,7 @@ class FeedingControlSystem:
except Exception as e:
print(f"设备连接检查失败: {e}")
return False
def start_pd_thread(self):
"""启动PD线程"""
print('启动派单处理线程从API获取未浇筑数据')
@ -401,7 +371,34 @@ class FeedingControlSystem:
_start_time=None
_isFinish=False
time.sleep(5)
def start_led(self):
"""启动LED流程"""
self.led_thread = threading.Thread(
target=self._start_led,
name="LED",
daemon=True
)
self.led_thread.start()
def _start_led(self):
"""启动LED流程"""
from service.mould_service import app_web_service
while self.state.running:
led_info = app_web_service.get_pouring_led()
if led_info:
if self.state.current_artifact.MouldCode==led_info.MouldCode:
led_info.RingTypeCode=self.state.current_artifact.RingTypeCode
led_info.UpperWeight=self.state._upper_weight
led_info.LowerWeight=self.state._lower_weight
led_info.VibrationFrequency=self.state._mould_frequency
#发送到LED屏
time.sleep(app_set_config.led_interval)
@property
def _is_finish(self):
"""检查系统是否运行"""
@ -428,20 +425,21 @@ class FeedingControlSystem:
self.state.running = False
# 等待线程结束
if self.monitor_thread:
self.monitor_thread.join()
if self.visual_control_thread:
self.visual_control_thread.join()
if self.alignment_check_thread:
self.alignment_check_thread.join()
if self.lower_feeding_thread:
self.lower_feeding_thread.join()
if self.opc_queue_thread:
self.opc_queue_thread.join()
if self.vf_thread:
self.vf_thread.join()
if self.api_thread:
self.api_thread.join()
if self.pd_jbl_thread:
self.pd_jbl_thread.join()
if self.feed_thread:
self.feed_thread.join()
if self.arch_thread:
self.arch_thread.join()
if self.plc_service:
self.plc_service.stop_polling()
self.feeding_controller.shutdown()
# 释放摄像头资源
# self.camera_controller.release()
print("控制系统已停止")

View File

@ -25,6 +25,7 @@ class SystemState:
self._upper_door_closed=True
self._upper_weight=0
self._upper_volume=0.0
#下料比例变频
self.vf_frequencys=[{'radio':0,'fre':230},{'radio':0.3,'fre':230},{'radio':0.6,'fre':230}]
#使用
@ -32,55 +33,26 @@ class SystemState:
self._mould_vibrate_status=False #True振动中False未振动
#记录模具开始振动的时间
self.mould_vibrate_time=0
#下料斗状态想着
self.lower_feeding_stage = 0 # 0:未下料, 1:第一阶段, 2:第二阶段, 3:第三阶段, 4:等待模具车对齐
#下料斗状态
self._lower_is_arch_=False
self._lower_weight=0
self._lower_angle=0.0
#模具车状态
self._mould_weight=0
self.lower_feeding_cycle = 0 # 下料斗下料循环次数
self.upper_feeding_count = 0 # 上料斗已下料次数
self.upper_feeding_max = 2 #上料斗最大下料次数
# 重量相关
self.last_upper_weight = 0
self.last_lower_weight = 0
self.last_weight_time = 0
#需要下料的总重量
self._mould_need_weight=0
#完成下料的总重量
self._mould_finish_weight=0
self.initial_upper_weight=0
self.initial_lower_weight=0
# 错误计数
self.upper_weight_error_count = 0
self.lower_weight_error_count = 0
# 视觉系统状态
self.angle_control_mode = "normal" # 角度控制模式: normal, reducing, maintaining, recovery
self.overflow_detected = "0" # 堆料检测
self.current_finish_status=False # 当前是否完成浇筑满
self.door_opening_large = False # 夹角
self.vehicle_aligned = False # 模具车是否对齐
self.last_angle = None # 上次检测角度
#当前RFID的内容格式为 模块编号,分块号,尺寸规格,方量
self.rfid_current=None
#当前生产的管片
self.current_artifact=None
#当前生产状态
self._feed_status=FeedStatus.FNone
#每方重量
self.density=2416.4
self.bll_artifact=ArtifactBll()
self.bll_pdrecord=PDRecordBll()
#记录正在生产code模具编号,status:2正生产3完成生成,weight:完成重量