2026-02-09 11:36:37 +08:00
|
|
|
|
|
|
|
|
|
|
from pickle import FALSE
|
2026-02-10 10:18:17 +08:00
|
|
|
|
from re import S
|
2026-02-09 11:36:37 +08:00
|
|
|
|
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
|
2026-02-10 10:18:17 +08:00
|
|
|
|
from busisness.blls import ArtifactBll,PDRecordBll
|
|
|
|
|
|
from busisness.models import ArtifactInfoModel,PDRecordModel
|
|
|
|
|
|
from service.mould_service import app_web_service
|
|
|
|
|
|
from core.system_state import SystemState,FeedStatus
|
|
|
|
|
|
from dataclasses import asdict
|
|
|
|
|
|
import json
|
|
|
|
|
|
import math
|
2026-02-09 11:36:37 +08:00
|
|
|
|
|
|
|
|
|
|
class VisualCallback:
|
|
|
|
|
|
# 类变量,用于存储实例引用,实现单例检测
|
|
|
|
|
|
_instance = None
|
|
|
|
|
|
_lock = threading.Lock()
|
|
|
|
|
|
|
2026-02-10 10:18:17 +08:00
|
|
|
|
# def __new__(cls,*args, **kwargs):
|
|
|
|
|
|
# """检测实例是否存在,实现单例模式"""
|
|
|
|
|
|
# with cls._lock:
|
|
|
|
|
|
# if cls._instance is None:
|
|
|
|
|
|
# cls._instance = super().__new__(cls)
|
|
|
|
|
|
# return cls._instance
|
2026-02-09 11:36:37 +08:00
|
|
|
|
|
2026-02-10 10:18:17 +08:00
|
|
|
|
def __init__(self,state:SystemState=None):
|
2026-02-09 11:36:37 +08:00
|
|
|
|
"""初始化视觉回调处理器"""
|
|
|
|
|
|
# 避免重复初始化
|
|
|
|
|
|
if hasattr(self, '_initialized') and self._initialized:
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
self.relay_controller = RelayController()
|
|
|
|
|
|
self.transmitter_controller = TransmitterController(self.relay_controller)
|
2026-02-10 10:18:17 +08:00
|
|
|
|
self.pd_record_bll=PDRecordBll()
|
|
|
|
|
|
self.state=state
|
2026-02-09 11:36:37 +08:00
|
|
|
|
|
|
|
|
|
|
# 线程安全的参数传递
|
|
|
|
|
|
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
|
2026-02-10 10:18:17 +08:00
|
|
|
|
|
2026-02-09 11:36:37 +08:00
|
|
|
|
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
|
|
|
|
|
|
#完成多少,忽略未浇筑满
|
2026-02-10 10:18:17 +08:00
|
|
|
|
self._max_ignore_radio=0.8
|
2026-02-09 11:36:37 +08:00
|
|
|
|
|
|
|
|
|
|
self._mould_accept_aligned=None
|
|
|
|
|
|
self._mould_before_aligned=False
|
|
|
|
|
|
#模具开始浇筑时间
|
|
|
|
|
|
self._time_mould_begin=''
|
|
|
|
|
|
#模具结束浇筑时间
|
|
|
|
|
|
self._time_mould_end=''
|
2026-02-10 10:18:17 +08:00
|
|
|
|
#记录当前模具信息model
|
|
|
|
|
|
self._cur_mould_model=None
|
2026-02-09 11:36:37 +08:00
|
|
|
|
# self.db_queue=queue.Queue()
|
|
|
|
|
|
|
|
|
|
|
|
# self.plc_data=5
|
|
|
|
|
|
self.plc_service = OmronFinsPollingService("192.168.250.233")
|
|
|
|
|
|
self.plc_service.register_data_callback(self.on_plc_update)
|
|
|
|
|
|
# self.plc_service.register_status_callback(self.on_status_change)
|
|
|
|
|
|
self.plc_service.start_polling(interval=2.0)
|
|
|
|
|
|
|
2026-02-10 10:18:17 +08:00
|
|
|
|
# 获取视觉数据线程(angle_visual_callback推送的数据),并进行处理,注意处理视觉进行夹角控制
|
2026-02-09 11:36:37 +08:00
|
|
|
|
self.callback_thread = threading.Thread(
|
|
|
|
|
|
target=self._run_thread_loop,
|
|
|
|
|
|
daemon=True
|
|
|
|
|
|
)
|
|
|
|
|
|
self.callback_thread.start()
|
|
|
|
|
|
|
2026-02-10 10:18:17 +08:00
|
|
|
|
# 启动下料线程检测
|
2026-02-09 11:36:37 +08:00
|
|
|
|
self.feed_thread = threading.Thread(
|
|
|
|
|
|
target=self._run_feed,
|
|
|
|
|
|
daemon=True
|
|
|
|
|
|
)
|
|
|
|
|
|
self.feed_thread.start()
|
|
|
|
|
|
|
2026-02-10 10:18:17 +08:00
|
|
|
|
#启动振动线程
|
2026-02-09 11:36:37 +08:00
|
|
|
|
self.monitor_thread = threading.Thread(
|
|
|
|
|
|
target=self._monitor_loop,
|
|
|
|
|
|
daemon=True,
|
|
|
|
|
|
name='monitor'
|
|
|
|
|
|
)
|
|
|
|
|
|
self.monitor_thread.start()
|
|
|
|
|
|
|
2026-02-10 10:18:17 +08:00
|
|
|
|
#获取diff(diff_visual_callback推送的数据)数据线程
|
2026-02-09 11:36:37 +08:00
|
|
|
|
self.diff_thread = threading.Thread(
|
|
|
|
|
|
target=self._diff_temp,
|
|
|
|
|
|
daemon=True
|
|
|
|
|
|
)
|
|
|
|
|
|
self.diff_thread.start()
|
|
|
|
|
|
|
|
|
|
|
|
"""启动数据库监控"""
|
|
|
|
|
|
# self.db_thread = threading.Thread(
|
|
|
|
|
|
# target=self._monitor_db_loop,
|
|
|
|
|
|
# daemon=True,
|
|
|
|
|
|
# name='db_monitor'
|
|
|
|
|
|
# )
|
|
|
|
|
|
# self.db_thread.start()
|
|
|
|
|
|
|
|
|
|
|
|
def init_val(self):
|
|
|
|
|
|
#初始化值
|
|
|
|
|
|
"""初始化视觉回调处理器"""
|
|
|
|
|
|
self.angle_mode = "normal"
|
|
|
|
|
|
self.overflow = False
|
|
|
|
|
|
self.is_start_visual=False
|
|
|
|
|
|
|
|
|
|
|
|
# 线程安全的参数传递
|
|
|
|
|
|
self._current_angle = None
|
|
|
|
|
|
self._overflow_detected = None
|
|
|
|
|
|
# 新增标志位:指示safe_control_lower_close是否正在执行
|
|
|
|
|
|
self._is_safe_closing = False
|
|
|
|
|
|
|
|
|
|
|
|
self._is_feed_start=True
|
|
|
|
|
|
#未浇筑满时间,用于确定是否进入未浇筑满
|
|
|
|
|
|
self._before_finish_time=None
|
|
|
|
|
|
#进入未浇筑满状态标志位
|
|
|
|
|
|
self._is_before_finish=False
|
|
|
|
|
|
#是否浇筑满标志位
|
|
|
|
|
|
self._is_finish=False
|
|
|
|
|
|
|
|
|
|
|
|
#用于保存diff标志位
|
|
|
|
|
|
# self._is_diff_save=False
|
|
|
|
|
|
#用于判断当前判断是否对齐(diff)
|
|
|
|
|
|
self._is_diff_unaligned=False
|
|
|
|
|
|
|
2026-02-10 10:18:17 +08:00
|
|
|
|
self._diff_f_val=0
|
|
|
|
|
|
self._diff_f_area=[]
|
|
|
|
|
|
|
2026-02-09 11:36:37 +08:00
|
|
|
|
#浇筑完成比例(重量)
|
|
|
|
|
|
self._is_finish_ratio=0
|
|
|
|
|
|
|
|
|
|
|
|
#下料阶段,汇总时用枚举
|
|
|
|
|
|
self._is_feed_stage=0
|
|
|
|
|
|
#振动相关参数
|
|
|
|
|
|
self._last_arch_one_weight=0
|
|
|
|
|
|
self._last_arch_two_weight=0
|
|
|
|
|
|
self._last_arch_three_weight=0
|
|
|
|
|
|
self._last_arch_four_weight=0
|
|
|
|
|
|
self._last_arch_five_weight=0
|
|
|
|
|
|
self._last_arch_time=0
|
|
|
|
|
|
#是否为F块
|
|
|
|
|
|
self._is_small_f=None
|
|
|
|
|
|
#采集数据用,下料重量=之前下的重量+最后一阶段(下-->模具车)重量差
|
|
|
|
|
|
#记录最后一次下料斗到模具车前的重量
|
|
|
|
|
|
self._finish_weight=0
|
|
|
|
|
|
|
|
|
|
|
|
#记录最后一次下料斗到车初始重量
|
|
|
|
|
|
self._inital_finish_lweight=0
|
|
|
|
|
|
#记录视觉停止下料时的重量(计算后面加了多少)
|
|
|
|
|
|
self._last_lower_weight=0
|
2026-02-10 10:18:17 +08:00
|
|
|
|
#每片开始下料斗的重量
|
|
|
|
|
|
self._init_lower_weight=0
|
2026-02-09 11:36:37 +08:00
|
|
|
|
|
|
|
|
|
|
# 初始化控制间隔和堆料状态跟踪属性
|
|
|
|
|
|
self._last_overflow_state = False
|
|
|
|
|
|
self._last_control_time = 0
|
|
|
|
|
|
self._is_running=True
|
2026-02-10 10:18:17 +08:00
|
|
|
|
self._is_stop_one_seconds=False
|
2026-02-09 11:36:37 +08:00
|
|
|
|
self._initialized = True
|
|
|
|
|
|
self.plc_data=None
|
|
|
|
|
|
|
2026-02-10 10:18:17 +08:00
|
|
|
|
self._mould_need_weight=0
|
|
|
|
|
|
#点动等级
|
|
|
|
|
|
self._point_speed_grade=0
|
|
|
|
|
|
self._point_weight=0
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-02-09 11:36:37 +08:00
|
|
|
|
def angle_visual_callback(self, current_angle, overflow_detected, mould_aligned):
|
|
|
|
|
|
"""
|
|
|
|
|
|
视觉控制主逻辑,供外部推送数据
|
|
|
|
|
|
使用单个持续运行的线程,通过参数设置传递数据
|
|
|
|
|
|
如果线程正在处理数据,则丢弃此次推送
|
|
|
|
|
|
"""
|
|
|
|
|
|
#print(f"{datetime.now().strftime('%H:%M:%S.%f')[:-3]} 收到推送数据")
|
|
|
|
|
|
# 尝试获取处理锁,若失败则说明正在处理,丢弃数据
|
|
|
|
|
|
if not self._is_processing.acquire(blocking=False):
|
|
|
|
|
|
print("回调线程仍在执行,丢弃此次推送数据")
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
# 更新参数
|
|
|
|
|
|
|
|
|
|
|
|
if overflow_detected is not None:
|
|
|
|
|
|
# print(f"{datetime.now().strftime('%H:%M:%S.%f')[:-3]} 收到溢料:{overflow_detected}")
|
|
|
|
|
|
self._overflow_detected = overflow_detected
|
|
|
|
|
|
if current_angle is not None:
|
|
|
|
|
|
#print(f"{datetime.now().strftime('%H:%M:%S.%f')[:-3]} 收到角度:{current_angle}")
|
|
|
|
|
|
self._current_angle = current_angle
|
|
|
|
|
|
if mould_aligned is not None:
|
|
|
|
|
|
#print(f"{datetime.now().strftime('%H:%M:%S.%f')[:-3]} 收到对齐:{mould_aligned}")
|
|
|
|
|
|
self._mould_accept_aligned=mould_aligned
|
|
|
|
|
|
# 通知线程有新数据可用
|
|
|
|
|
|
self._new_data_available.set()
|
|
|
|
|
|
finally:
|
|
|
|
|
|
# 释放处理锁
|
|
|
|
|
|
self._is_processing.release()
|
|
|
|
|
|
|
|
|
|
|
|
def diff_visual_callback(self, current_diff,current_area):
|
|
|
|
|
|
"""
|
|
|
|
|
|
视觉模型diff回调
|
|
|
|
|
|
"""
|
|
|
|
|
|
#print(f"{datetime.now().strftime('%H:%M:%S.%f')[:-3]} 收到推送数据")
|
|
|
|
|
|
# 尝试获取处理锁,若失败则说明正在处理,丢弃数据
|
|
|
|
|
|
if not self._is_processing_diff.acquire(blocking=False):
|
|
|
|
|
|
print("222回调线程仍在执行,丢弃此次推送数据")
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
# 更新参数
|
|
|
|
|
|
if current_diff is not None:
|
|
|
|
|
|
# print(f"{datetime.now().strftime('%H:%M:%S.%f')[:-3]} 收到diff:{current_diff}")
|
2026-02-10 10:18:17 +08:00
|
|
|
|
self._current_diff = current_diff
|
|
|
|
|
|
self._diff_f_val=current_diff
|
2026-02-09 11:36:37 +08:00
|
|
|
|
if current_area is not None:
|
|
|
|
|
|
# print(f"{datetime.now().strftime('%H:%M:%S.%f')[:-3]} 收到area:{current_area}")
|
2026-02-10 10:18:17 +08:00
|
|
|
|
self._current_diff_area = current_area
|
|
|
|
|
|
self._diff_f_area = current_area
|
2026-02-09 11:36:37 +08:00
|
|
|
|
# 通知线程有新数据可用
|
|
|
|
|
|
self._new_data_diff.set()
|
|
|
|
|
|
finally:
|
|
|
|
|
|
# 释放处理锁
|
|
|
|
|
|
self._is_processing_diff.release()
|
|
|
|
|
|
|
|
|
|
|
|
def _diff_temp(self):
|
|
|
|
|
|
"""
|
|
|
|
|
|
接受视觉回调数据
|
|
|
|
|
|
线程主循环,持续运行
|
|
|
|
|
|
等待新数据,然后调用处理方法
|
|
|
|
|
|
"""
|
|
|
|
|
|
_temp_diff_count=0
|
|
|
|
|
|
_temp_area_count=0
|
|
|
|
|
|
_temp_diff_str2=''
|
|
|
|
|
|
_temp_area_str2=''
|
|
|
|
|
|
while not self._stop_event.is_set():
|
|
|
|
|
|
# print('-----等待diff 数据------')
|
|
|
|
|
|
# 等待新数据可用
|
|
|
|
|
|
self._new_data_diff.wait()
|
|
|
|
|
|
# 重置事件
|
|
|
|
|
|
self._new_data_diff.clear()
|
|
|
|
|
|
#_is_diff_save是否完成此片
|
|
|
|
|
|
if self._is_diff_save:
|
|
|
|
|
|
# print('-----进入diff 数据------')
|
|
|
|
|
|
#完成了此片,然后是对齐状态
|
|
|
|
|
|
if not self._is_diff_unaligned:
|
|
|
|
|
|
# 处理数据
|
|
|
|
|
|
# print('-----进入对齐数据------')
|
|
|
|
|
|
if self._current_diff is not None and self._current_diff_area is not None:
|
|
|
|
|
|
_timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
|
|
|
|
if _temp_diff_count<=10 and self._current_diff!=0:
|
|
|
|
|
|
_temp_diff_str=f"diff , {_timestamp} , {self._current_diff}\n"
|
|
|
|
|
|
_temp_diff_count+=1
|
|
|
|
|
|
with open('weight.txt', 'a') as f:
|
|
|
|
|
|
f.write(_temp_diff_str+'\n')
|
|
|
|
|
|
# print('-----保存成功(diff 数据)------')
|
|
|
|
|
|
|
|
|
|
|
|
if _temp_area_count<=10 and self._current_diff_area!=[]:
|
|
|
|
|
|
_temp_area_str=f"area , {_timestamp} , {str(self._current_diff_area)}\n"
|
|
|
|
|
|
_temp_area_count+=1
|
|
|
|
|
|
with open('weight.txt', 'a') as f:
|
|
|
|
|
|
f.write(_temp_area_str+'\n')
|
|
|
|
|
|
# print('-----保存成功(area 数据)------')
|
|
|
|
|
|
if _temp_diff_count>=10 and _temp_area_count>=10:
|
|
|
|
|
|
self._is_diff_save=False
|
|
|
|
|
|
time.sleep(1)
|
|
|
|
|
|
continue
|
|
|
|
|
|
# else:
|
|
|
|
|
|
#变成了未对齐,拉起盖板后,重新计数
|
|
|
|
|
|
# if _temp_diff_count>=10 and _temp_area_count>=10:
|
|
|
|
|
|
# _temp_diff_count=0
|
|
|
|
|
|
# _temp_area_count=0
|
|
|
|
|
|
# self._is_diff_save=False
|
|
|
|
|
|
# _temp_diff_str=''
|
|
|
|
|
|
# _temp_area_str=''
|
|
|
|
|
|
|
|
|
|
|
|
self._current_diff=0
|
|
|
|
|
|
self._current_diff_area=[]
|
|
|
|
|
|
_temp_diff_count=0
|
|
|
|
|
|
_temp_area_count=0
|
|
|
|
|
|
_temp_diff_str=''
|
|
|
|
|
|
_temp_area_str=''
|
|
|
|
|
|
time.sleep(1)
|
|
|
|
|
|
|
|
|
|
|
|
def _monitor_loop(self):
|
2026-02-10 10:18:17 +08:00
|
|
|
|
"""破拱线程"""
|
2026-02-09 11:36:37 +08:00
|
|
|
|
while self._is_running:
|
|
|
|
|
|
try:
|
|
|
|
|
|
current_time = time.time()
|
|
|
|
|
|
# 检查下料斗破拱(只有在下料过程中才检查)
|
|
|
|
|
|
if self._is_feed_stage==1: # 下料斗--》模具车
|
|
|
|
|
|
_arch_weight = self.transmitter_controller.read_data(2)
|
|
|
|
|
|
if _arch_weight is not None and _arch_weight>0:
|
|
|
|
|
|
# 检查重量变化是否过慢
|
|
|
|
|
|
_weight_changed=abs(_arch_weight - self._last_arch_one_weight)
|
|
|
|
|
|
#_last_arch_one_weight默认为0,一开始就进入振动
|
|
|
|
|
|
print(f'---------------第一阶段,重量变化:{_weight_changed}------------------')
|
|
|
|
|
|
if (_weight_changed< 200) and \
|
|
|
|
|
|
(current_time - self._last_arch_time) >= 2:
|
|
|
|
|
|
self._last_arch_time = current_time
|
|
|
|
|
|
print('---------------------第一阶段振动5秒(小于200KG)-----------------')
|
|
|
|
|
|
self.relay_controller.control_arch_lower_open_sync(5)
|
|
|
|
|
|
self._last_arch_one_weight = _arch_weight
|
|
|
|
|
|
continue
|
|
|
|
|
|
self._last_arch_one_weight = _arch_weight
|
|
|
|
|
|
|
|
|
|
|
|
elif self._is_feed_stage==2: #上料斗到下料斗,料多,谨慎振动
|
|
|
|
|
|
_arch_weight = self.transmitter_controller.read_data(1)
|
|
|
|
|
|
if _arch_weight is not None and _arch_weight>0:
|
|
|
|
|
|
# 检查重量变化是否过慢
|
|
|
|
|
|
_weight_changed=abs(_arch_weight - self._last_arch_two_weight)
|
|
|
|
|
|
print(f'---------------第二阶段,重量变化:{_weight_changed}------------------')
|
|
|
|
|
|
if (_weight_changed < 100) and \
|
|
|
|
|
|
(current_time - self._last_arch_time) >= 2:
|
|
|
|
|
|
self._last_arch_time = current_time
|
|
|
|
|
|
print('---------------------第二阶段振动3秒-----------------')
|
|
|
|
|
|
self.relay_controller.control_arch_upper_open_sync(3)
|
|
|
|
|
|
self._last_arch_two_weight = _arch_weight
|
|
|
|
|
|
continue
|
|
|
|
|
|
self._last_arch_two_weight = _arch_weight
|
|
|
|
|
|
elif self._is_feed_stage==3: #第二次下料斗-》模具车
|
|
|
|
|
|
_arch_weight = self.transmitter_controller.read_data(2)
|
|
|
|
|
|
if _arch_weight is not None and _arch_weight>0:
|
|
|
|
|
|
#刚开始不需要振动,料太多
|
|
|
|
|
|
if self._last_arch_three_weight>0:
|
|
|
|
|
|
_weight_changed=abs(_arch_weight - self._last_arch_three_weight)
|
|
|
|
|
|
# 检查重量变化是否过慢
|
|
|
|
|
|
print(f'---------------第三阶段,重量变化:{_weight_changed}------------------')
|
|
|
|
|
|
if (_weight_changed < 100) and \
|
|
|
|
|
|
(current_time - self._last_arch_time) >= 2:
|
|
|
|
|
|
self._last_arch_time = current_time
|
|
|
|
|
|
print('---------------------第三阶段振动5秒(小于100KG)-----------------')
|
|
|
|
|
|
self.relay_controller.control_arch_lower_open_sync(5)
|
|
|
|
|
|
self._last_arch_three_weight = _arch_weight
|
|
|
|
|
|
continue
|
|
|
|
|
|
self._last_arch_three_weight = _arch_weight
|
|
|
|
|
|
|
|
|
|
|
|
elif self._is_feed_stage==4: #上料斗--》下料斗
|
|
|
|
|
|
_arch_weight = self.transmitter_controller.read_data(1)
|
|
|
|
|
|
if _arch_weight is not None and _arch_weight>0:
|
|
|
|
|
|
# 检查重量变化是否过慢
|
|
|
|
|
|
_weight_changed=abs(_arch_weight - self._last_arch_four_weight)
|
|
|
|
|
|
print(f'---------------第二阶段,重量变化:{_weight_changed}------------------')
|
|
|
|
|
|
if (_weight_changed < 200) and \
|
|
|
|
|
|
(current_time - self._last_arch_time) > 2:
|
|
|
|
|
|
self._last_arch_time = current_time
|
|
|
|
|
|
print('---------------------第四阶段振动5秒-----------------')
|
2026-02-10 10:18:17 +08:00
|
|
|
|
#重量不准,暂时不振动
|
|
|
|
|
|
# self.relay_controller.control_arch_upper_open_sync(5)
|
2026-02-09 11:36:37 +08:00
|
|
|
|
self._last_arch_four_weight = _arch_weight
|
|
|
|
|
|
continue
|
|
|
|
|
|
self._last_arch_four_weight = _arch_weight
|
|
|
|
|
|
elif self._is_feed_stage==5: #下料斗->模具车
|
|
|
|
|
|
_arch_weight = self.transmitter_controller.read_data(2)
|
|
|
|
|
|
if _arch_weight is not None and _arch_weight>0:
|
|
|
|
|
|
if self._last_arch_five_weight>0:
|
|
|
|
|
|
_weight_changed=abs(_arch_weight - self._last_arch_five_weight)
|
|
|
|
|
|
print(f'---------------第五阶段,重量变化:{_weight_changed}------------------')
|
|
|
|
|
|
_min_arch_weight=20
|
|
|
|
|
|
if self._is_finish_ratio<self._max_angle_radio:
|
|
|
|
|
|
_min_arch_weight=50
|
|
|
|
|
|
if (_weight_changed < _min_arch_weight) and \
|
|
|
|
|
|
(current_time - self._last_arch_time) >= 2:
|
|
|
|
|
|
self._last_arch_time = current_time
|
|
|
|
|
|
print(f'---------------------第五阶段振动3秒(小于{_min_arch_weight}kg))-----------------')
|
|
|
|
|
|
self.relay_controller.control_arch_lower_open_sync(3)
|
|
|
|
|
|
self._last_arch_five_weight = _arch_weight
|
|
|
|
|
|
continue
|
|
|
|
|
|
self._last_arch_five_weight = _arch_weight
|
|
|
|
|
|
|
|
|
|
|
|
# 更新最后读取时间
|
|
|
|
|
|
self._last_arch_time = current_time
|
|
|
|
|
|
time.sleep(2)
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
print(f"监控线程错误: {e}")
|
|
|
|
|
|
|
|
|
|
|
|
def _aligned_get_times(self,flag):
|
|
|
|
|
|
"""
|
|
|
|
|
|
获取对齐,1为对齐,0为未对齐
|
|
|
|
|
|
"""
|
|
|
|
|
|
_current_times=time.time()
|
|
|
|
|
|
_temp_aligned_count=0
|
|
|
|
|
|
if flag==1:
|
|
|
|
|
|
while time.time()-_current_times<=2:
|
2026-02-10 10:18:17 +08:00
|
|
|
|
# print(f'-------------{self._mould_accept_aligned}-----------------')
|
2026-02-09 11:36:37 +08:00
|
|
|
|
if self._mould_accept_aligned=='盖板对齐':
|
|
|
|
|
|
_temp_aligned_count=_temp_aligned_count+1
|
|
|
|
|
|
else:
|
|
|
|
|
|
_temp_aligned_count=0
|
2026-02-10 10:18:17 +08:00
|
|
|
|
if _temp_aligned_count>0:
|
|
|
|
|
|
print(f'-------------{datetime.now().strftime("%H:%M:%S")} 盖板对齐,次数:{_temp_aligned_count}-----------------')
|
2026-02-09 11:36:37 +08:00
|
|
|
|
time.sleep(0.2)
|
|
|
|
|
|
self._mould_accept_aligned=''
|
|
|
|
|
|
if _temp_aligned_count>=8:
|
|
|
|
|
|
return True
|
|
|
|
|
|
else:
|
|
|
|
|
|
return False
|
|
|
|
|
|
elif flag==2:
|
|
|
|
|
|
while time.time()-_current_times<=5:
|
|
|
|
|
|
|
|
|
|
|
|
if self._mould_accept_aligned=='盖板未对齐':
|
|
|
|
|
|
_temp_aligned_count=_temp_aligned_count+1
|
|
|
|
|
|
else:
|
|
|
|
|
|
_temp_aligned_count=0
|
2026-02-10 10:18:17 +08:00
|
|
|
|
if _temp_aligned_count>0:
|
|
|
|
|
|
print(f'-------------{datetime.now().strftime("%H:%M:%S")} 盖板未对齐,次数:{_temp_aligned_count}-----------------')
|
2026-02-09 11:36:37 +08:00
|
|
|
|
time.sleep(0.2)
|
|
|
|
|
|
|
|
|
|
|
|
self._mould_accept_aligned=''
|
|
|
|
|
|
if _temp_aligned_count>=20:
|
|
|
|
|
|
self._is_diff_unaligned=True
|
|
|
|
|
|
return True
|
|
|
|
|
|
else:
|
|
|
|
|
|
self._is_diff_unaligned=False
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
def _no_aligned_diff(self):
|
|
|
|
|
|
"""
|
|
|
|
|
|
diff 未对齐检测
|
|
|
|
|
|
"""
|
|
|
|
|
|
_current_times=time.time()
|
|
|
|
|
|
_temp_aligned_count=0
|
|
|
|
|
|
while time.time()-_current_times<=1:
|
|
|
|
|
|
# print(f'-------------{self._mould_accept_aligned}-----------------')
|
|
|
|
|
|
if self._mould_accept_aligned=='盖板未对齐':
|
|
|
|
|
|
_temp_aligned_count=_temp_aligned_count+1
|
|
|
|
|
|
else:
|
|
|
|
|
|
_temp_aligned_count=0
|
|
|
|
|
|
# print(f'-------------{datetime.now().strftime("%H:%M:%S")} 盖板对齐,次数:{_temp_aligned_count}-----------------')
|
|
|
|
|
|
time.sleep(0.2)
|
|
|
|
|
|
if _temp_aligned_count>=3:
|
|
|
|
|
|
return True
|
|
|
|
|
|
else:
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _run_thread_loop(self):
|
|
|
|
|
|
"""
|
|
|
|
|
|
接受视觉回调数据
|
|
|
|
|
|
线程主循环,持续运行
|
|
|
|
|
|
等待新数据,然后调用处理方法
|
|
|
|
|
|
"""
|
|
|
|
|
|
while not self._stop_event.is_set():
|
|
|
|
|
|
# 等待新数据可用
|
|
|
|
|
|
self._new_data_available.wait()
|
|
|
|
|
|
|
|
|
|
|
|
# 重置事件
|
|
|
|
|
|
self._new_data_available.clear()
|
|
|
|
|
|
|
|
|
|
|
|
# 获取当前参数(使用临时变量避免被其他线程修改)
|
|
|
|
|
|
current_angle = self._current_angle
|
|
|
|
|
|
overflow_detected = self._overflow_detected
|
|
|
|
|
|
self._is_feed_start=True
|
|
|
|
|
|
|
|
|
|
|
|
if self.is_start_visual:
|
|
|
|
|
|
# 处理数据
|
|
|
|
|
|
self._process_angle_callback(current_angle, overflow_detected)
|
|
|
|
|
|
time.sleep(0.1)
|
|
|
|
|
|
|
|
|
|
|
|
def _run_feed(self):
|
2026-02-10 10:18:17 +08:00
|
|
|
|
_is_api_request=True
|
2026-02-09 11:36:37 +08:00
|
|
|
|
while True:
|
|
|
|
|
|
# print("------------已启动----------------")
|
|
|
|
|
|
if self._is_feed_start:
|
|
|
|
|
|
|
|
|
|
|
|
# if self.plc_data==5:
|
|
|
|
|
|
#_is_finish_ratio完成 比例,根据重量过滤一下
|
|
|
|
|
|
|
|
|
|
|
|
if self._is_first_module and self._overflow_detected=='未堆料':
|
|
|
|
|
|
#第一次打开 ,未堆料,检测对齐
|
2026-02-10 10:18:17 +08:00
|
|
|
|
if _is_api_request:
|
|
|
|
|
|
self.get_current_mould()
|
|
|
|
|
|
_is_api_request=False
|
2026-02-09 11:36:37 +08:00
|
|
|
|
_is_aligned=self._aligned_get_times(1)
|
|
|
|
|
|
if _is_aligned:
|
2026-02-10 10:18:17 +08:00
|
|
|
|
_is_api_request=True
|
|
|
|
|
|
print('------------启动程序后,进入第一块-------------')
|
2026-02-09 11:36:37 +08:00
|
|
|
|
self._is_first_module=False
|
|
|
|
|
|
self._mould_before_aligned=True
|
2026-02-10 10:18:17 +08:00
|
|
|
|
_current_weight=self.transmitter_controller.read_data(2)
|
|
|
|
|
|
if _current_weight:
|
|
|
|
|
|
self._init_lower_weight=_current_weight
|
|
|
|
|
|
else:
|
|
|
|
|
|
print('------------获取上料斗重量失败-------------')
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
self.state._feed_status=FeedStatus.FCheckGB
|
2026-02-09 11:36:37 +08:00
|
|
|
|
# self.is_start_visual=True
|
|
|
|
|
|
self.run_feed_all()
|
|
|
|
|
|
elif self._is_finish and self._is_finish_ratio>=0.7:
|
|
|
|
|
|
#后续流程--》检查到未对齐,--》后又对齐+未堆料
|
2026-02-10 10:18:17 +08:00
|
|
|
|
#print('------------------进入连续块检测------------------')
|
2026-02-09 11:36:37 +08:00
|
|
|
|
if self._mould_before_aligned:
|
|
|
|
|
|
#未对齐,检测对齐
|
|
|
|
|
|
_is_not_aligned=self._aligned_get_times(2)
|
|
|
|
|
|
if _is_not_aligned:
|
|
|
|
|
|
#标志位
|
|
|
|
|
|
self._mould_before_aligned=False
|
2026-02-10 10:18:17 +08:00
|
|
|
|
#print('------------连续盖板未对齐-------------')
|
2026-02-09 11:36:37 +08:00
|
|
|
|
else:
|
2026-02-10 10:18:17 +08:00
|
|
|
|
if _is_api_request:
|
|
|
|
|
|
self.get_current_mould()
|
|
|
|
|
|
_is_api_request=False
|
|
|
|
|
|
_is_aligned=self._aligned_get_times(1)
|
|
|
|
|
|
if _is_aligned and self._overflow_detected=='未堆料':
|
|
|
|
|
|
print('------------进入连续生产-------------')
|
|
|
|
|
|
self._mould_before_aligned=True
|
|
|
|
|
|
_is_api_request=True
|
|
|
|
|
|
|
|
|
|
|
|
_current_weight=self.transmitter_controller.read_data(2)
|
|
|
|
|
|
if not _current_weight:
|
|
|
|
|
|
print('------------获取上料斗重量失败-------------')
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# print('-----------进入连续块111111-----------')
|
|
|
|
|
|
# self.is_start_visual=True
|
|
|
|
|
|
if self._last_lower_weight>0:
|
|
|
|
|
|
with open('weight.txt', 'a') as f:
|
|
|
|
|
|
f.write(f"补料:{self._last_lower_weight-_current_weight}\n\n"+"="*32)
|
|
|
|
|
|
|
|
|
|
|
|
self.init_val()
|
|
|
|
|
|
self._init_lower_weight=_current_weight
|
|
|
|
|
|
self.state._feed_status=FeedStatus.FCheckGB
|
|
|
|
|
|
self.run_feed_all()
|
|
|
|
|
|
|
2026-02-09 11:36:37 +08:00
|
|
|
|
# else:
|
|
|
|
|
|
# print("-----------上料斗未就位----------------")
|
|
|
|
|
|
# print("---------3--上料斗未就位----------------")
|
|
|
|
|
|
|
|
|
|
|
|
time.sleep(0.2)
|
|
|
|
|
|
|
|
|
|
|
|
def safe_control_lower_close(self,duration=3):
|
|
|
|
|
|
"""线程安全的下料斗关闭方法"""
|
|
|
|
|
|
thread_name = threading.current_thread().name
|
|
|
|
|
|
# print(f"[{thread_name}] 尝试关闭下料斗...")
|
|
|
|
|
|
# 设置标志位,指示正在执行安全关闭操作
|
|
|
|
|
|
self._is_safe_closing = True
|
|
|
|
|
|
try:
|
|
|
|
|
|
with self._door_control_lock:
|
|
|
|
|
|
self._current_controlling_thread = thread_name
|
2026-02-10 10:18:17 +08:00
|
|
|
|
print(f"关闭下料斗{duration}秒")
|
2026-02-09 11:36:37 +08:00
|
|
|
|
self.relay_controller.control(self.relay_controller.DOOR_LOWER_OPEN, 'close')
|
|
|
|
|
|
self.relay_controller.control(self.relay_controller.DOOR_LOWER_CLOSE, 'open')
|
|
|
|
|
|
time.sleep(duration)
|
|
|
|
|
|
self.relay_controller.control(self.relay_controller.DOOR_LOWER_CLOSE, 'close')
|
|
|
|
|
|
self._current_controlling_thread = None
|
|
|
|
|
|
#print(f"[{thread_name}] 释放下料斗控制权")
|
|
|
|
|
|
finally:
|
|
|
|
|
|
# 无论成功失败,都要重置标志位
|
|
|
|
|
|
self._is_safe_closing = False
|
|
|
|
|
|
|
|
|
|
|
|
def close_lower_door_visual(self):
|
|
|
|
|
|
"""关闭下料斗门"""
|
|
|
|
|
|
self.is_start_visual=False
|
|
|
|
|
|
#休眠让视觉先结束
|
|
|
|
|
|
time.sleep(0.5)
|
|
|
|
|
|
self.safe_control_lower_close()
|
|
|
|
|
|
|
|
|
|
|
|
def _visual_close(self):
|
|
|
|
|
|
self.is_start_visual=False
|
|
|
|
|
|
self._is_finish=True
|
2026-02-10 10:18:17 +08:00
|
|
|
|
self.state.vf_status=3
|
|
|
|
|
|
self.state._feed_status=FeedStatus.FFinished
|
2026-02-09 11:36:37 +08:00
|
|
|
|
self._is_feed_stage=0
|
|
|
|
|
|
print(f'--------进入关闭(浇筑满)-----------')
|
|
|
|
|
|
self.safe_control_lower_close(3)
|
2026-02-10 10:18:17 +08:00
|
|
|
|
print(f'--------浇筑完成-----------')
|
2026-02-09 11:36:37 +08:00
|
|
|
|
# try:
|
|
|
|
|
|
# self.db_queue.put_nowait({
|
|
|
|
|
|
# "f":self._is_small_f,
|
|
|
|
|
|
# "Status": 3
|
|
|
|
|
|
# })
|
|
|
|
|
|
# except queue.Full:
|
|
|
|
|
|
# print("数据库队列已满,无法添加数据")
|
|
|
|
|
|
#记录重量
|
|
|
|
|
|
_current_weight=self.transmitter_controller.read_data(2)
|
|
|
|
|
|
if _current_weight is not None:
|
|
|
|
|
|
self._last_lower_weight=_current_weight
|
|
|
|
|
|
self._finish_weight= self._finish_weight+(self._inital_finish_lweight-_current_weight)
|
|
|
|
|
|
with open('weight.txt', 'a') as f:
|
|
|
|
|
|
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
|
|
|
|
if self._is_small_f:
|
2026-02-10 10:18:17 +08:00
|
|
|
|
if self._cur_mould_model:
|
|
|
|
|
|
f.write(f"{self._time_mould_begin},{timestamp},{self._cur_mould_model.MouldCode},F,{self._finish_weight}\n")
|
|
|
|
|
|
else:
|
|
|
|
|
|
f.write(f"{self._time_mould_begin},{timestamp},F,{self._finish_weight}\n")
|
2026-02-09 11:36:37 +08:00
|
|
|
|
else:
|
2026-02-10 10:18:17 +08:00
|
|
|
|
if self._cur_mould_model:
|
|
|
|
|
|
f.write(f"{self._time_mould_begin},{timestamp},{self._cur_mould_model.MouldCode},B,{self._finish_weight}\n")
|
|
|
|
|
|
else:
|
|
|
|
|
|
f.write(f"{self._time_mould_begin},{timestamp},B,{self._finish_weight}\n")
|
2026-02-09 11:36:37 +08:00
|
|
|
|
#开启保存diff
|
|
|
|
|
|
self._is_diff_save=True
|
|
|
|
|
|
|
|
|
|
|
|
#保存图片
|
|
|
|
|
|
save_camera_picture()
|
|
|
|
|
|
|
|
|
|
|
|
def run_feed_all(self):
|
|
|
|
|
|
"""
|
|
|
|
|
|
全流程下料:包括判断模具类型
|
|
|
|
|
|
"""
|
|
|
|
|
|
_is_f= run_stable_classification_loop()
|
|
|
|
|
|
print(f'------------已判断出模具类型: {_is_f}-------------')
|
|
|
|
|
|
if _is_f is not None:
|
|
|
|
|
|
if _is_f=='模具车1':
|
|
|
|
|
|
self._is_small_f=True
|
|
|
|
|
|
print('-------------F块模具--------------')
|
2026-02-10 10:18:17 +08:00
|
|
|
|
# print('-------------F块模具--------------')
|
|
|
|
|
|
# print('-------------F块模具--------------')
|
|
|
|
|
|
# self.send_pd_data()
|
2026-02-09 11:36:37 +08:00
|
|
|
|
self.run_feed_f()
|
|
|
|
|
|
elif _is_f=='模具车2':
|
|
|
|
|
|
self._is_small_f=False
|
2026-02-10 10:18:17 +08:00
|
|
|
|
print('-------------B-L模具---------------')
|
|
|
|
|
|
# self.send_pd_data()
|
2026-02-09 11:36:37 +08:00
|
|
|
|
self.run_feed()
|
|
|
|
|
|
|
|
|
|
|
|
if self._is_small_f is None:
|
|
|
|
|
|
print('-----------未判断出模具类型--------------')
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
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
|
2026-02-10 10:18:17 +08:00
|
|
|
|
initial_lower_weight=self._init_lower_weight
|
2026-02-09 11:36:37 +08:00
|
|
|
|
first_finish_weight=0
|
|
|
|
|
|
self._finish_weight=first_finish_weight
|
|
|
|
|
|
self._inital_finish_lweight=initial_lower_weight
|
2026-02-10 10:18:17 +08:00
|
|
|
|
self._mould_need_weight=0.54*2416
|
|
|
|
|
|
need_total_weight=self._mould_need_weight
|
2026-02-09 11:36:37 +08:00
|
|
|
|
if initial_lower_weight>100:
|
2026-02-10 10:18:17 +08:00
|
|
|
|
self.state._feed_status=FeedStatus.FFeed5
|
|
|
|
|
|
self.state.vf_status=2
|
2026-02-09 11:36:37 +08:00
|
|
|
|
if not self._is_finish:
|
|
|
|
|
|
self.is_start_visual=True
|
|
|
|
|
|
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}-------------')
|
2026-02-10 10:18:17 +08:00
|
|
|
|
# if self._is_finish_ratio>=1:
|
2026-02-09 11:36:37 +08:00
|
|
|
|
#关5秒
|
|
|
|
|
|
#大于0.7后不再检测了,直接交给视觉控制夹脚
|
|
|
|
|
|
# print(f'------------已下料比例: {self._is_finish_ratio}-------------')
|
2026-02-10 10:18:17 +08:00
|
|
|
|
# break
|
2026-02-09 11:36:37 +08:00
|
|
|
|
|
|
|
|
|
|
# print(f'------------已下料: {first_finish_weight+second_finish_weight}kg-------------')
|
2026-02-10 10:18:17 +08:00
|
|
|
|
time.sleep(0.5)
|
2026-02-09 11:36:37 +08:00
|
|
|
|
# initial_lower_weight=_current_lower_weight
|
|
|
|
|
|
print(f'------------已下料(F): {first_finish_weight}kg-------------')
|
|
|
|
|
|
print(f'------------已下料(F): {first_finish_weight}kg-------------')
|
|
|
|
|
|
|
2026-02-10 10:18:17 +08:00
|
|
|
|
# print(f'------------已完成-------------')
|
2026-02-09 11:36:37 +08:00
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
2026-02-10 10:18:17 +08:00
|
|
|
|
initial_lower_weight=self._init_lower_weight
|
2026-02-09 11:36:37 +08:00
|
|
|
|
# initial_upper_weight=loc_mitter.read_data(1)
|
|
|
|
|
|
first_finish_weight=0
|
2026-02-10 10:18:17 +08:00
|
|
|
|
self._mould_need_weight=1.91*2416
|
|
|
|
|
|
need_total_weight=self._mould_need_weight
|
2026-02-09 11:36:37 +08:00
|
|
|
|
# start_time=None
|
|
|
|
|
|
self.is_start_visual=True
|
2026-02-10 10:18:17 +08:00
|
|
|
|
self.state._feed_status=FeedStatus.FFeed1
|
|
|
|
|
|
self.state.vf_status=1
|
2026-02-09 11:36:37 +08:00
|
|
|
|
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
|
2026-02-10 10:18:17 +08:00
|
|
|
|
self._is_finish_ratio=(initial_lower_weight-current_weight)/need_total_weight
|
|
|
|
|
|
print(f'------------已下料比例: {self._is_finish_ratio}-------------')
|
2026-02-09 11:36:37 +08:00
|
|
|
|
if current_weight<250 and current_weight>0:
|
2026-02-10 10:18:17 +08:00
|
|
|
|
# if current_weight>100:
|
|
|
|
|
|
#100,上面粘贴的,振动一下
|
|
|
|
|
|
# self.relay_controller.control_arch_lower_open_async(5)
|
2026-02-09 11:36:37 +08:00
|
|
|
|
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
|
|
|
|
|
|
|
2026-02-10 10:18:17 +08:00
|
|
|
|
while self.plc_data not in [5,37]:
|
|
|
|
|
|
#print('------------上料斗未就位----------------')
|
|
|
|
|
|
# print('------------上料斗未就位----------------')
|
2026-02-09 11:36:37 +08:00
|
|
|
|
time.sleep(1)
|
|
|
|
|
|
|
2026-02-10 10:18:17 +08:00
|
|
|
|
if self.plc_data==5 or self.plc_data==37:
|
|
|
|
|
|
print(f'------------上料斗就位(上料斗往下料斗阶段)-------------')
|
2026-02-09 11:36:37 +08:00
|
|
|
|
#打开上料斗出砼门,开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
|
2026-02-10 10:18:17 +08:00
|
|
|
|
if (current_upper_weight<3200 and current_upper_weight>0) or _two_lower_weight>3200:
|
2026-02-09 11:36:37 +08:00
|
|
|
|
#关5秒,loc_time_count多关一秒
|
|
|
|
|
|
loc_relay.control_upper_close_sync(5+loc_time_count)
|
|
|
|
|
|
break
|
|
|
|
|
|
else:
|
2026-02-10 10:18:17 +08:00
|
|
|
|
if time.time()-upper_open_time>=4:
|
2026-02-09 11:36:37 +08:00
|
|
|
|
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
|
2026-02-10 10:18:17 +08:00
|
|
|
|
self._is_finish_ratio=(first_finish_weight+initial_lower_weight-current_weight)/need_total_weight
|
2026-02-09 11:36:37 +08:00
|
|
|
|
if current_weight<250:
|
2026-02-10 10:18:17 +08:00
|
|
|
|
# if current_weight>100:
|
|
|
|
|
|
#100,上面粘贴的,振动一下
|
|
|
|
|
|
# self.relay_controller.control_arch_lower_open_async(5)
|
2026-02-09 11:36:37 +08:00
|
|
|
|
self.close_lower_door_visual()
|
|
|
|
|
|
break
|
|
|
|
|
|
# print(f'------------已下料: {first_finish_weight+second_finish_weight}kg-------------')
|
2026-02-10 10:18:17 +08:00
|
|
|
|
time.sleep(0.5)
|
2026-02-09 11:36:37 +08:00
|
|
|
|
_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
|
2026-02-10 10:18:17 +08:00
|
|
|
|
if self.plc_data==5 or self.plc_data==37:
|
2026-02-09 11:36:37 +08:00
|
|
|
|
#第二次上料斗向下料斗转移
|
|
|
|
|
|
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
|
2026-02-10 10:18:17 +08:00
|
|
|
|
#initial_upper_weight=loc_mitter.read_data(1)
|
|
|
|
|
|
#start_time=None
|
2026-02-09 11:36:37 +08:00
|
|
|
|
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
|
2026-02-10 10:18:17 +08:00
|
|
|
|
time.sleep(0.5)
|
2026-02-09 11:36:37 +08:00
|
|
|
|
else:
|
2026-02-10 10:18:17 +08:00
|
|
|
|
if time.time()-upper_open_time>=1:
|
2026-02-09 11:36:37 +08:00
|
|
|
|
# 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}-------------')
|
2026-02-10 10:18:17 +08:00
|
|
|
|
# if self._is_finish_ratio>=1:
|
2026-02-09 11:36:37 +08:00
|
|
|
|
#关5秒
|
|
|
|
|
|
# print(f'------------已下料比例: {self._is_finish_ratio}-------------')
|
2026-02-10 10:18:17 +08:00
|
|
|
|
# break
|
2026-02-09 11:36:37 +08:00
|
|
|
|
|
|
|
|
|
|
# print(f'------------已下料: {first_finish_weight+second_finish_weight}kg-------------')
|
2026-02-10 10:18:17 +08:00
|
|
|
|
time.sleep(0.5)
|
2026-02-09 11:36:37 +08:00
|
|
|
|
|
|
|
|
|
|
# _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-------------')
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-02-10 10:18:17 +08:00
|
|
|
|
# print(f'------------已完成-------------')
|
2026-02-09 11:36:37 +08:00
|
|
|
|
|
|
|
|
|
|
def _process_angle_callback(self, current_angle, overflow_detected):
|
|
|
|
|
|
"""
|
|
|
|
|
|
实时精细控制 - 基于PID思想,无固定间隔
|
|
|
|
|
|
"""
|
|
|
|
|
|
try:
|
|
|
|
|
|
# 记录控制时间戳(用于微分计算,而非限制)
|
|
|
|
|
|
current_time = time.time()
|
|
|
|
|
|
# 确保所有PID相关属性都被正确初始化
|
|
|
|
|
|
if not hasattr(self, '_last_control_time'):
|
|
|
|
|
|
self._last_control_time = current_time
|
|
|
|
|
|
if not hasattr(self, '_last_error'):
|
|
|
|
|
|
self._last_error = 0
|
|
|
|
|
|
if not hasattr(self, '_error_integral'):
|
|
|
|
|
|
self._error_integral = 0
|
|
|
|
|
|
|
|
|
|
|
|
# print(f"{self.angle_mode}")
|
|
|
|
|
|
self.overflow = overflow_detected in ["大堆料", "小堆料"]
|
|
|
|
|
|
|
|
|
|
|
|
if current_angle is None:
|
|
|
|
|
|
return
|
|
|
|
|
|
|
2026-02-10 10:18:17 +08:00
|
|
|
|
print(f"{datetime.now().strftime('%H:%M:%S.%f')[:-3]} 角度11: {current_angle:.2f}°,{overflow_detected},diff_f_val:{self._diff_f_val},diff_f_area:{self._diff_f_area}")
|
2026-02-09 11:36:37 +08:00
|
|
|
|
|
2026-02-10 10:18:17 +08:00
|
|
|
|
if self._is_small_f:
|
|
|
|
|
|
if self._is_finish_ratio>=1.02:
|
|
|
|
|
|
print('重量达到最大比例,浇筑满关闭')
|
|
|
|
|
|
self._visual_close()
|
|
|
|
|
|
return
|
|
|
|
|
|
elif self._is_finish_ratio>=0.9:
|
|
|
|
|
|
if (self._diff_f_val>=427 and self._diff_f_val<=450):
|
|
|
|
|
|
print('------------diff到达浇筑满-------------')
|
|
|
|
|
|
self._visual_close()
|
|
|
|
|
|
return
|
|
|
|
|
|
elif (len(self._diff_f_area)>0 and self._diff_f_area[-1]>=33400 and self._diff_f_area[-1]<=34500):
|
|
|
|
|
|
print('------------area到达浇筑满-------------')
|
|
|
|
|
|
self._visual_close()
|
|
|
|
|
|
return
|
|
|
|
|
|
else:
|
|
|
|
|
|
if self._is_finish_ratio>=1.01:
|
|
|
|
|
|
print('重量达到最大比例,浇筑满关闭')
|
|
|
|
|
|
self._visual_close()
|
|
|
|
|
|
return
|
|
|
|
|
|
elif self._is_finish_ratio>=0.93:
|
|
|
|
|
|
if (self._diff_f_val>=460 and self._diff_f_val<=510):
|
|
|
|
|
|
print('------------diff到达浇筑满-------------')
|
|
|
|
|
|
self._visual_close()
|
|
|
|
|
|
return
|
|
|
|
|
|
if (len(self._diff_f_area)>0 and self._diff_f_area[-1]>=38200 and self._diff_f_area[-1]<=41000):
|
|
|
|
|
|
print('------------area到达浇筑满-------------')
|
|
|
|
|
|
self._visual_close()
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-02-09 11:36:37 +08:00
|
|
|
|
if overflow_detected == "未浇筑满" or self._is_before_finish:
|
|
|
|
|
|
if self._before_finish_time is None:
|
|
|
|
|
|
self._before_finish_time=current_time
|
2026-02-10 10:18:17 +08:00
|
|
|
|
self.safe_control_lower_close(1)
|
2026-02-09 11:36:37 +08:00
|
|
|
|
print('-----------------关闭(未浇筑满)--------------------')
|
|
|
|
|
|
# time.sleep(3)
|
|
|
|
|
|
else:
|
2026-02-10 10:18:17 +08:00
|
|
|
|
if not self._is_stop_one_seconds:
|
|
|
|
|
|
#根据角度来计算还需要多久完全关闭
|
|
|
|
|
|
if current_angle>=20:
|
|
|
|
|
|
self.safe_control_lower_close(2)
|
|
|
|
|
|
elif current_angle>=10 and current_angle<20:
|
|
|
|
|
|
self.safe_control_lower_close(1)
|
|
|
|
|
|
elif current_angle>=6 and current_angle<10:
|
|
|
|
|
|
self.safe_control_lower_close(0.5)
|
|
|
|
|
|
self._is_stop_one_seconds=True
|
|
|
|
|
|
elif current_angle>7:
|
|
|
|
|
|
#点动状态下,如果关闭后角度大于7度,关紧
|
|
|
|
|
|
self.safe_control_lower_close(0.2)
|
|
|
|
|
|
_open_time=0.3
|
|
|
|
|
|
_sleep_time=0.3
|
|
|
|
|
|
_close_time=0.5
|
2026-02-09 11:36:37 +08:00
|
|
|
|
if overflow_detected=='浇筑满':
|
2026-02-10 10:18:17 +08:00
|
|
|
|
if self._is_small_f:
|
|
|
|
|
|
self._visual_close()
|
|
|
|
|
|
return
|
|
|
|
|
|
else:
|
|
|
|
|
|
if self._diff_f_val>=410 and self._diff_f_val<450:
|
|
|
|
|
|
#排除这个范围的关闭
|
|
|
|
|
|
print(f'浇筑满状态,diff_f_val:{self._diff_f_val},不关闭')
|
|
|
|
|
|
_open_time=0.5
|
|
|
|
|
|
_sleep_time=0.3
|
|
|
|
|
|
_close_time=0.7
|
|
|
|
|
|
else:
|
|
|
|
|
|
self._visual_close()
|
|
|
|
|
|
return
|
|
|
|
|
|
|
2026-02-09 11:36:37 +08:00
|
|
|
|
# print(f'--------已关闭已关闭-----------')
|
|
|
|
|
|
elif overflow_detected=="大堆料":
|
|
|
|
|
|
print(f'--------未浇筑满,大堆料-----------')
|
2026-02-10 10:18:17 +08:00
|
|
|
|
elif overflow_detected=="小堆料":
|
|
|
|
|
|
print(f'--------未浇筑满,小堆料-----------')
|
|
|
|
|
|
_open_time=0.5
|
|
|
|
|
|
_sleep_time=0.3
|
|
|
|
|
|
_close_time=0.7
|
2026-02-09 11:36:37 +08:00
|
|
|
|
else:
|
2026-02-10 10:18:17 +08:00
|
|
|
|
if self._is_small_f:
|
|
|
|
|
|
_open_time=0.6
|
|
|
|
|
|
_sleep_time=0.3
|
|
|
|
|
|
_close_time=0.8
|
2026-02-09 11:36:37 +08:00
|
|
|
|
else:
|
2026-02-10 10:18:17 +08:00
|
|
|
|
if self._is_finish_ratio<0.9:
|
|
|
|
|
|
_open_time=1
|
|
|
|
|
|
_sleep_time=0.3
|
|
|
|
|
|
_close_time=1.2
|
|
|
|
|
|
#之前慢的参数
|
|
|
|
|
|
# _open_time=0.8
|
|
|
|
|
|
# _sleep_time=0.3
|
|
|
|
|
|
# _close_time=1
|
|
|
|
|
|
elif self._is_finish_ratio<0.95 and self._is_finish_ratio>=0.9:
|
|
|
|
|
|
if self._point_weight>=10:
|
|
|
|
|
|
_open_time=0.7
|
|
|
|
|
|
_sleep_time=0.3
|
|
|
|
|
|
_close_time=0.9
|
|
|
|
|
|
else:
|
|
|
|
|
|
#之前慢的参数
|
|
|
|
|
|
# _open_time=0.8
|
|
|
|
|
|
# _sleep_time=0.3
|
|
|
|
|
|
# _close_time=1
|
|
|
|
|
|
_open_time=0.9
|
|
|
|
|
|
_sleep_time=0.3
|
|
|
|
|
|
_close_time=1.1
|
|
|
|
|
|
else:
|
|
|
|
|
|
_open_time=0.6
|
|
|
|
|
|
_sleep_time=0.3
|
|
|
|
|
|
_close_time=0.8
|
|
|
|
|
|
|
|
|
|
|
|
if self._point_speed_grade==1:
|
|
|
|
|
|
if _open_time>0.6:
|
|
|
|
|
|
_open_time=0.6
|
|
|
|
|
|
_sleep_time=0.3
|
|
|
|
|
|
_close_time=0.8
|
|
|
|
|
|
elif self._point_speed_grade==2:
|
|
|
|
|
|
if _open_time>0.5:
|
|
|
|
|
|
_open_time=0.5
|
|
|
|
|
|
_sleep_time=0.3
|
|
|
|
|
|
_close_time=0.7
|
|
|
|
|
|
elif self._point_speed_grade==3:
|
|
|
|
|
|
if _open_time>0.4:
|
|
|
|
|
|
_open_time=0.4
|
|
|
|
|
|
_sleep_time=0.3
|
|
|
|
|
|
_close_time=0.6
|
|
|
|
|
|
elif self._point_speed_grade==4:
|
|
|
|
|
|
if _open_time>0.3:
|
|
|
|
|
|
_open_time=0.3
|
|
|
|
|
|
_sleep_time=0.3
|
|
|
|
|
|
_close_time=0.5
|
|
|
|
|
|
_last_finish_ratio=self._is_finish_ratio
|
|
|
|
|
|
print(f'--------比例开始:{_last_finish_ratio}-----------')
|
|
|
|
|
|
self._pulse_control('open',_open_time)
|
|
|
|
|
|
time.sleep(_sleep_time)
|
|
|
|
|
|
self._pulse_control('close',_close_time)
|
|
|
|
|
|
print(f'--------比例结束:{self._is_finish_ratio}-----------')
|
|
|
|
|
|
|
|
|
|
|
|
self._point_weight=(self._is_finish_ratio-_last_finish_ratio)*self._mould_need_weight
|
|
|
|
|
|
print(f'--------流速:{self._point_weight}-----------')
|
|
|
|
|
|
if self._is_small_f:
|
|
|
|
|
|
time.sleep(2.5)
|
|
|
|
|
|
else:
|
|
|
|
|
|
# if self._is_finish_ratio>= 0.93:
|
|
|
|
|
|
# time.sleep(2)
|
|
|
|
|
|
# print('--------重量已到95.5%,需要2秒休息-----------')
|
|
|
|
|
|
# else:
|
2026-02-09 11:36:37 +08:00
|
|
|
|
time.sleep(1)
|
2026-02-10 10:18:17 +08:00
|
|
|
|
#下得过快,需要2秒休息
|
|
|
|
|
|
if self._point_weight>=65:
|
|
|
|
|
|
time.sleep(5)
|
|
|
|
|
|
self._point_speed_grade=4
|
|
|
|
|
|
elif self._point_weight>=50 and self._point_weight<65:
|
|
|
|
|
|
time.sleep(4)
|
|
|
|
|
|
self._point_speed_grade=3
|
|
|
|
|
|
elif self._point_weight>=35 and self._point_weight<50:
|
|
|
|
|
|
time.sleep(3)
|
|
|
|
|
|
self._point_speed_grade=2
|
|
|
|
|
|
elif self._point_weight>=25 and self._point_weight<35:
|
|
|
|
|
|
time.sleep(2)
|
|
|
|
|
|
self._point_speed_grade=1
|
|
|
|
|
|
elif self._point_weight>=15 and self._point_weight<25:
|
|
|
|
|
|
time.sleep(1)
|
|
|
|
|
|
self._point_speed_grade=0
|
|
|
|
|
|
else:
|
|
|
|
|
|
self._point_speed_grade=0
|
|
|
|
|
|
self._is_before_finish=True
|
2026-02-09 11:36:37 +08:00
|
|
|
|
if self._is_finish_ratio<=self._max_ignore_radio:
|
|
|
|
|
|
#如果重量未达到最大忽略角度,需要跳出
|
|
|
|
|
|
self._is_before_finish=False
|
|
|
|
|
|
return
|
|
|
|
|
|
elif overflow_detected == "浇筑满":
|
|
|
|
|
|
self._visual_close()
|
|
|
|
|
|
return
|
|
|
|
|
|
else:
|
|
|
|
|
|
self._before_finish_time=None
|
2026-02-10 10:18:17 +08:00
|
|
|
|
#2160KG
|
|
|
|
|
|
if self._is_finish_ratio>=0.85 and not self._is_small_f:
|
|
|
|
|
|
if overflow_detected == "大堆料":
|
|
|
|
|
|
TARGET_ANGLE = 5.0 # 大堆料时控制在15度左右
|
|
|
|
|
|
elif overflow_detected == "小堆料":
|
|
|
|
|
|
TARGET_ANGLE = 15.0 # 小堆料时控制在35度左右
|
|
|
|
|
|
else:
|
|
|
|
|
|
TARGET_ANGLE = 35.0 # 12.25由25--》35
|
|
|
|
|
|
elif (self._is_finish_ratio>0.7 and self._is_small_f):
|
2026-02-09 11:36:37 +08:00
|
|
|
|
if overflow_detected == "大堆料":
|
|
|
|
|
|
TARGET_ANGLE = 5.0 # 大堆料时控制在15度左右
|
|
|
|
|
|
elif overflow_detected == "小堆料":
|
|
|
|
|
|
TARGET_ANGLE = 15.0 # 小堆料时控制在35度左右
|
|
|
|
|
|
else:
|
|
|
|
|
|
TARGET_ANGLE = 35.0 # 12.25由25--》35
|
|
|
|
|
|
else:
|
|
|
|
|
|
if self._is_feed_stage==1 or self._is_feed_stage==3:
|
|
|
|
|
|
#根据溢料状态动态调整目标角度
|
|
|
|
|
|
if overflow_detected == "大堆料":
|
2026-02-10 10:18:17 +08:00
|
|
|
|
if not self.state.mould_vibrate_status:
|
|
|
|
|
|
TARGET_ANGLE = 15.0 # 临时控制变频器堆料时很小
|
|
|
|
|
|
else:
|
|
|
|
|
|
TARGET_ANGLE = 35.0 # 大堆料时控制在15度左右
|
2026-02-09 11:36:37 +08:00
|
|
|
|
elif overflow_detected == "小堆料":
|
2026-02-10 10:18:17 +08:00
|
|
|
|
TARGET_ANGLE = 55.0 # 小堆料时控制在35度左右
|
2026-02-09 11:36:37 +08:00
|
|
|
|
else:
|
|
|
|
|
|
TARGET_ANGLE = 55.0 # 未溢料时开到最大56度
|
|
|
|
|
|
else:
|
2026-02-10 10:18:17 +08:00
|
|
|
|
if self._is_small_f:
|
2026-02-09 11:36:37 +08:00
|
|
|
|
#根据溢料状态动态调整目标角度
|
2026-02-10 10:18:17 +08:00
|
|
|
|
if overflow_detected == "大堆料":
|
|
|
|
|
|
TARGET_ANGLE = 15.0 # 大堆料时控制在15度左右
|
|
|
|
|
|
elif overflow_detected == "小堆料":
|
|
|
|
|
|
TARGET_ANGLE = 25.0 # 小堆料时控制在35度左右
|
|
|
|
|
|
else:
|
|
|
|
|
|
TARGET_ANGLE = 45.0 # 未溢料时开到最大56度
|
2026-02-09 11:36:37 +08:00
|
|
|
|
else:
|
2026-02-10 10:18:17 +08:00
|
|
|
|
#根据溢料状态动态调整目标角度
|
|
|
|
|
|
if overflow_detected == "大堆料":
|
|
|
|
|
|
TARGET_ANGLE = 15.0 # 大堆料时控制在15度左右
|
|
|
|
|
|
elif overflow_detected == "小堆料":
|
|
|
|
|
|
TARGET_ANGLE = 55.0 # 小堆料时控制在35度左右
|
|
|
|
|
|
else:
|
|
|
|
|
|
TARGET_ANGLE = 55.0 # 未溢料时开到最大56度
|
2026-02-09 11:36:37 +08:00
|
|
|
|
|
|
|
|
|
|
# 确保目标角度在硬件范围内(5-56度)
|
|
|
|
|
|
TARGET_ANGLE = max(5.0, min(56.0, TARGET_ANGLE))
|
|
|
|
|
|
|
|
|
|
|
|
# PID控制参数
|
|
|
|
|
|
KP = 0.2 # 比例系数
|
|
|
|
|
|
KI = 0 # 积分系数
|
|
|
|
|
|
KD = 0 # 微分系数
|
|
|
|
|
|
# KP = 0.15 # 比例系数
|
|
|
|
|
|
# KI = 0.008 # 积分系数
|
|
|
|
|
|
# KD = 0.08 # 微分系数
|
|
|
|
|
|
# if TARGET_ANGLE <= 25.0:
|
|
|
|
|
|
# KP, KI, KD = 0.18, 0.008, 0.08 # 小角度,强控制
|
|
|
|
|
|
# elif TARGET_ANGLE <= 40.0:
|
|
|
|
|
|
# KP, KI, KD = 0.15, 0.01, 0.06 # 中角度
|
|
|
|
|
|
# else:
|
|
|
|
|
|
# KP, KI, KD = 0.12, 0.012, 0.04 # 大角度,温和控制
|
|
|
|
|
|
# 计算误差
|
|
|
|
|
|
error = current_angle - TARGET_ANGLE
|
|
|
|
|
|
dt = current_time - self._last_control_time
|
|
|
|
|
|
|
|
|
|
|
|
# 积分项(抗饱和)
|
|
|
|
|
|
self._error_integral += error * dt
|
|
|
|
|
|
self._error_integral = max(min(self._error_integral, 50), -50) # 积分限幅
|
|
|
|
|
|
|
|
|
|
|
|
# 微分项
|
|
|
|
|
|
error_derivative = (error - self._last_error) / dt if dt > 0 else 0
|
|
|
|
|
|
|
|
|
|
|
|
# PID输出
|
|
|
|
|
|
pid_output = (KP * error + KI * self._error_integral + KD * error_derivative)
|
2026-02-10 10:18:17 +08:00
|
|
|
|
#print(f"📊 PID计算: 误差={error:.2f}°, 积分={self._error_integral:.2f}, "
|
|
|
|
|
|
# f"微分={error_derivative:.2f}, 输出={pid_output:.2f}")
|
2026-02-09 11:36:37 +08:00
|
|
|
|
# 更新历史值
|
|
|
|
|
|
self._last_error = error
|
|
|
|
|
|
self._last_control_time = current_time
|
|
|
|
|
|
|
|
|
|
|
|
# 状态机 + PID控制
|
|
|
|
|
|
|
|
|
|
|
|
if self.angle_mode == "normal":
|
|
|
|
|
|
self._normal_mode_advanced(current_angle, pid_output,TARGET_ANGLE)
|
|
|
|
|
|
|
|
|
|
|
|
elif self.angle_mode == "reducing":
|
|
|
|
|
|
self._reducing_mode_advanced(current_angle, pid_output, TARGET_ANGLE)
|
|
|
|
|
|
|
|
|
|
|
|
elif self.angle_mode == "maintaining":
|
|
|
|
|
|
self._maintaining_mode_advanced(current_angle, pid_output, TARGET_ANGLE)
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
2026-02-10 10:18:17 +08:00
|
|
|
|
print("处理视觉回调时发生异常: ")
|
|
|
|
|
|
print("处理视觉回调时发生异常: ")
|
|
|
|
|
|
print("处理视觉回调时发生异常: ")
|
2026-02-09 11:36:37 +08:00
|
|
|
|
print(f"处理视觉回调时发生异常: {e}")
|
|
|
|
|
|
|
|
|
|
|
|
def _normal_mode_advanced(self, current_angle, pid_output,target_angle):
|
|
|
|
|
|
"""高级正常模式控制"""
|
|
|
|
|
|
if self.overflow:
|
|
|
|
|
|
self.angle_mode = "reducing"
|
|
|
|
|
|
print("检测到溢料,切换到减小模式")
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
# 🎯 修复1: 添加强制控制机制
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 基于PID输出的智能控制
|
|
|
|
|
|
control_threshold = 2 # 从2.0减小到0.5,提高灵敏度
|
|
|
|
|
|
|
|
|
|
|
|
if abs(pid_output) > control_threshold:
|
|
|
|
|
|
if pid_output > 0:
|
|
|
|
|
|
# 需要减小角度(关门)
|
|
|
|
|
|
pulse_time = min(0.3, pid_output * 0.1)
|
|
|
|
|
|
self._pulse_control("close", pulse_time)
|
|
|
|
|
|
print(f"正常模式: 角度偏高{pid_output:.1f},关门{pulse_time:.2f}秒")
|
|
|
|
|
|
else:
|
|
|
|
|
|
# 需要增大角度(开门)
|
|
|
|
|
|
pulse_time = min(0.3, abs(pid_output) * 0.1)
|
|
|
|
|
|
self._pulse_control("open", pulse_time)
|
|
|
|
|
|
print(f"正常模式: 角度偏低{abs(pid_output):.1f},开门{pulse_time:.2f}秒")
|
|
|
|
|
|
else:
|
|
|
|
|
|
# 在死区内,保持静止
|
|
|
|
|
|
error = current_angle - target_angle
|
|
|
|
|
|
abs_error = abs(error)
|
|
|
|
|
|
|
|
|
|
|
|
# 强制控制:如果误差超过5度,强制控制
|
|
|
|
|
|
if abs_error > 5:
|
|
|
|
|
|
if error > 0: # 当前角度 > 目标角度,需要关门
|
|
|
|
|
|
pulse_time=0.1 # 根据误差计算脉冲时间
|
|
|
|
|
|
self._pulse_control("close", pulse_time)
|
2026-02-10 10:18:17 +08:00
|
|
|
|
#print(f"🚨 强制关门: 误差{abs_error:.1f}°过大,脉冲{pulse_time:.3f}s")
|
2026-02-09 11:36:37 +08:00
|
|
|
|
else: # 当前角度 < 目标角度,需要开门
|
|
|
|
|
|
pulse_time =0.1
|
|
|
|
|
|
self._pulse_control("open", pulse_time)
|
2026-02-10 10:18:17 +08:00
|
|
|
|
#print(f"🚨 强制开门: 误差{abs_error:.1f}°过大,脉冲{pulse_time:.3f}s")
|
2026-02-09 11:36:37 +08:00
|
|
|
|
return
|
|
|
|
|
|
else:
|
|
|
|
|
|
self._stop_door()
|
|
|
|
|
|
print(f"正常模式: 角度在目标范围内,保持静止")
|
|
|
|
|
|
|
|
|
|
|
|
def _reducing_mode_advanced(self, current_angle, pid_output, target_angle):
|
|
|
|
|
|
"""高级减小模式控制"""
|
|
|
|
|
|
if not self.overflow:
|
|
|
|
|
|
if current_angle <= target_angle + 5.0:
|
|
|
|
|
|
self.angle_mode = "normal"
|
|
|
|
|
|
print("溢料消除且角度合适,返回正常模式")
|
|
|
|
|
|
else:
|
|
|
|
|
|
# 缓慢恢复
|
|
|
|
|
|
self._pulse_control("close", 0.1)
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
# 有溢料,积极减小角度
|
|
|
|
|
|
if current_angle > target_angle:
|
|
|
|
|
|
# 使用PID输出计算控制量
|
|
|
|
|
|
pulse_time = min(0.5, max(0.1, pid_output * 0.15))
|
|
|
|
|
|
self._pulse_control("close", pulse_time)
|
2026-02-10 10:18:17 +08:00
|
|
|
|
# print(f"减小模式: 积极关门{pulse_time:.2f}秒,PID输出:{pid_output:.1f}")
|
2026-02-09 11:36:37 +08:00
|
|
|
|
else:
|
|
|
|
|
|
self.angle_mode = "maintaining"
|
|
|
|
|
|
print("角度已达标,进入维持模式")
|
|
|
|
|
|
|
|
|
|
|
|
def _maintaining_mode_advanced(self, current_angle, pid_output, target_angle):
|
|
|
|
|
|
"""高级维持模式控制"""
|
|
|
|
|
|
if not self.overflow:
|
|
|
|
|
|
self.angle_mode = "normal"
|
|
|
|
|
|
print("溢料消除,返回正常模式")
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
# 精确维持控制
|
|
|
|
|
|
dead_zone = 1.5 # 更小的死区
|
|
|
|
|
|
|
|
|
|
|
|
if abs(pid_output) > dead_zone:
|
|
|
|
|
|
pulse_time = min(0.2, abs(pid_output) * 0.05) # 更精细的控制
|
|
|
|
|
|
|
|
|
|
|
|
if pid_output > 0:
|
|
|
|
|
|
self._pulse_control("close", pulse_time)
|
|
|
|
|
|
print(f"维持模式: 微调关门{pulse_time:.2f}秒")
|
|
|
|
|
|
else:
|
|
|
|
|
|
self._pulse_control("open", pulse_time)
|
|
|
|
|
|
print(f"维持模式: 微调开门{pulse_time:.2f}秒")
|
|
|
|
|
|
else:
|
|
|
|
|
|
self._stop_door()
|
|
|
|
|
|
print("维持模式: 角度精确控制中")
|
|
|
|
|
|
|
|
|
|
|
|
def _pulse_control(self, action, duration):
|
|
|
|
|
|
"""统一的脉冲控制方法"""
|
|
|
|
|
|
# 检查是否正在执行safe_control_lower_close,如果是则跳过relay操作
|
|
|
|
|
|
if self._is_safe_closing:
|
|
|
|
|
|
thread_name = threading.current_thread().name
|
|
|
|
|
|
print(f"[{thread_name}] safe_control_lower_close正在执行,跳过脉冲控制 {action}")
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
if duration <= 0:
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
thread_name = threading.current_thread().name
|
2026-02-10 10:18:17 +08:00
|
|
|
|
#print(f"[{thread_name}] 尝试脉冲控制 {action},时长 {duration:.2f}秒...")
|
2026-02-09 11:36:37 +08:00
|
|
|
|
|
|
|
|
|
|
with self._door_control_lock:
|
|
|
|
|
|
self._current_controlling_thread = thread_name
|
2026-02-10 10:18:17 +08:00
|
|
|
|
# print(f"[{thread_name}] 获得下料斗控制权,执行脉冲控制")
|
2026-02-09 11:36:37 +08:00
|
|
|
|
|
|
|
|
|
|
if action == "open":
|
|
|
|
|
|
self.relay_controller.control(self.relay_controller.DOOR_LOWER_CLOSE, 'close')
|
|
|
|
|
|
self.relay_controller.control(self.relay_controller.DOOR_LOWER_OPEN, 'open')
|
|
|
|
|
|
time.sleep(duration)
|
|
|
|
|
|
self.relay_controller.control(self.relay_controller.DOOR_LOWER_OPEN, 'close')
|
|
|
|
|
|
print(f"[{thread_name}] 开门脉冲: {duration:.2f}秒")
|
|
|
|
|
|
else: # close
|
|
|
|
|
|
self.relay_controller.control(self.relay_controller.DOOR_LOWER_OPEN, 'close')
|
|
|
|
|
|
self.relay_controller.control(self.relay_controller.DOOR_LOWER_CLOSE, 'open')
|
|
|
|
|
|
time.sleep(duration)
|
|
|
|
|
|
self.relay_controller.control(self.relay_controller.DOOR_LOWER_CLOSE, 'close')
|
|
|
|
|
|
print(f"[{thread_name}] 关门脉冲: {duration:.2f}秒")
|
|
|
|
|
|
|
|
|
|
|
|
self._current_controlling_thread = None
|
2026-02-10 10:18:17 +08:00
|
|
|
|
#print(f"[{thread_name}] 释放下料斗控制权")
|
2026-02-09 11:36:37 +08:00
|
|
|
|
|
|
|
|
|
|
def _stop_door(self):
|
|
|
|
|
|
"""停止门运动"""
|
|
|
|
|
|
# 检查是否正在执行safe_control_lower_close,如果是则跳过relay操作
|
|
|
|
|
|
if self._is_safe_closing:
|
|
|
|
|
|
thread_name = threading.current_thread().name
|
|
|
|
|
|
print(f"[{thread_name}] safe_control_lower_close正在执行,跳过停止门运动操作")
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
thread_name = threading.current_thread().name
|
2026-02-10 10:18:17 +08:00
|
|
|
|
#print(f"[{thread_name}] 尝试停止门运动...")
|
2026-02-09 11:36:37 +08:00
|
|
|
|
|
|
|
|
|
|
with self._door_control_lock:
|
|
|
|
|
|
self._current_controlling_thread = thread_name
|
2026-02-10 10:18:17 +08:00
|
|
|
|
#print(f"[{thread_name}] 获得下料斗控制权,执行停止操作")
|
2026-02-09 11:36:37 +08:00
|
|
|
|
self.relay_controller.control(self.relay_controller.DOOR_LOWER_OPEN, 'close')
|
|
|
|
|
|
self.relay_controller.control(self.relay_controller.DOOR_LOWER_CLOSE, 'close')
|
|
|
|
|
|
self._current_controlling_thread = None
|
2026-02-10 10:18:17 +08:00
|
|
|
|
#print(f"[{thread_name}] 释放下料斗控制权")
|
2026-02-09 11:36:37 +08:00
|
|
|
|
|
|
|
|
|
|
def _open_door(self, duration=0.5):
|
|
|
|
|
|
"""打开门"""
|
|
|
|
|
|
self._pulse_control("open", 0.3)
|
|
|
|
|
|
|
|
|
|
|
|
def _close_door(self, duration=0.5):
|
|
|
|
|
|
"""关闭门"""
|
|
|
|
|
|
self._pulse_control("close", 1)
|
|
|
|
|
|
|
|
|
|
|
|
def on_plc_update(self,data: int, binary: str):
|
|
|
|
|
|
#4即将振捣室5振捣室 64即将搅拌楼 66到达搅拌楼
|
|
|
|
|
|
# print(f"[数据回调] 数值: 0x{data:02X} | 十进制: {data:3d} | 二进制: {binary}")
|
|
|
|
|
|
self.plc_data=data
|
|
|
|
|
|
|
2026-02-10 10:18:17 +08:00
|
|
|
|
# @classmethod
|
|
|
|
|
|
# def instance_exists(cls):
|
2026-02-09 11:36:37 +08:00
|
|
|
|
"""检测实例是否存在"""
|
2026-02-10 10:18:17 +08:00
|
|
|
|
# return cls._instance is not None
|
2026-02-09 11:36:37 +08:00
|
|
|
|
|
|
|
|
|
|
def shutdown(self):
|
|
|
|
|
|
"""关闭线程,清理资源"""
|
|
|
|
|
|
# 设置停止事件
|
|
|
|
|
|
self._stop_event.set()
|
|
|
|
|
|
# 唤醒线程以便它能检测到停止事件
|
|
|
|
|
|
self._new_data_available.set()
|
|
|
|
|
|
|
|
|
|
|
|
self._is_running=False
|
|
|
|
|
|
self._is_finish=True
|
|
|
|
|
|
self.is_start_visual=False
|
|
|
|
|
|
# #关闭下料斗
|
|
|
|
|
|
# self.safe_control_lower_close()
|
|
|
|
|
|
if self.plc_service:
|
|
|
|
|
|
self.plc_service.stop_polling()
|
|
|
|
|
|
# 等待线程结束
|
|
|
|
|
|
if self.callback_thread.is_alive():
|
|
|
|
|
|
self.callback_thread.join(timeout=1.0)
|
|
|
|
|
|
|
|
|
|
|
|
if self.feed_thread.is_alive():
|
|
|
|
|
|
self.feed_thread.join(timeout=1.0)
|
|
|
|
|
|
|
|
|
|
|
|
if self.monitor_thread.is_alive():
|
|
|
|
|
|
self.monitor_thread.join(timeout=1.0)
|
|
|
|
|
|
|
|
|
|
|
|
# self.relay_controller._close_lower_5s
|
|
|
|
|
|
|
2026-02-10 10:18:17 +08:00
|
|
|
|
def send_pd_data(self):
|
|
|
|
|
|
"""
|
|
|
|
|
|
发送PD数据到OPC队列
|
|
|
|
|
|
"""
|
|
|
|
|
|
# 构建PD数据
|
|
|
|
|
|
_cur_mould=self._cur_mould_model
|
|
|
|
|
|
if _cur_mould is not None:
|
|
|
|
|
|
if _cur_mould.MouldCode:
|
|
|
|
|
|
_pdrecords = self.pd_record_bll.get_last_pds(_cur_mould.MouldCode)
|
|
|
|
|
|
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)
|
|
|
|
|
|
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
|
|
|
|
|
|
else:
|
|
|
|
|
|
return None
|
|
|
|
|
|
def get_fact_volumn(self,mould_code:str,block_number:str='') -> float:
|
|
|
|
|
|
"""获取实际派单发量"""
|
|
|
|
|
|
_now_volumn=0
|
|
|
|
|
|
_pd_volumn=0
|
|
|
|
|
|
print(f'get_fact_volumn当前重量:{self._init_lower_weight}')
|
|
|
|
|
|
_now_volumn=self._init_lower_weight/2500
|
|
|
|
|
|
if not block_number and '-' in mould_code:
|
|
|
|
|
|
block_number = mould_code.split('-')[0][-2:]
|
|
|
|
|
|
if block_number in ['B1','B2','B3']:
|
|
|
|
|
|
_pd_volumn=1.9
|
|
|
|
|
|
elif block_number=='L1':
|
|
|
|
|
|
_pd_volumn=2.0
|
|
|
|
|
|
if _now_volumn>0.5:
|
|
|
|
|
|
#保证至少0.5方
|
|
|
|
|
|
_pd_volumn=1.9-_now_volumn+0.5
|
|
|
|
|
|
_pd_volumn=math.ceil(_pd_volumn*10)/10
|
|
|
|
|
|
|
|
|
|
|
|
if _pd_volumn<0.8:
|
|
|
|
|
|
_pd_volumn=0.8
|
|
|
|
|
|
#调整
|
|
|
|
|
|
elif block_number=='L2':
|
|
|
|
|
|
#2.4方,大约L2和F的量
|
|
|
|
|
|
_pd_volumn=2.4
|
|
|
|
|
|
# if _weight>1300:
|
|
|
|
|
|
#留0.15 math.floor(_now_volumn*10)/10 保留一位小数,丢掉其他的
|
|
|
|
|
|
_pd_volumn=_pd_volumn-math.floor(_now_volumn*10)/10+0.1
|
|
|
|
|
|
_pd_volumn=math.ceil(_pd_volumn*10)/10
|
|
|
|
|
|
if _pd_volumn>2.1:
|
|
|
|
|
|
_pd_volumn=2.1
|
|
|
|
|
|
elif _pd_volumn<0.8:
|
|
|
|
|
|
_pd_volumn=0.8
|
|
|
|
|
|
|
|
|
|
|
|
return _pd_volumn
|
|
|
|
|
|
|
|
|
|
|
|
def get_current_mould(self):
|
|
|
|
|
|
"""获取当前要浇筑的管片"""
|
|
|
|
|
|
_not_poured=app_web_service.get_not_pour_artifacts()
|
|
|
|
|
|
if _not_poured is not None and len(_not_poured)>=1:
|
|
|
|
|
|
_cur_poured_model=_not_poured[-1]
|
|
|
|
|
|
if _cur_poured_model.MouldCode:
|
|
|
|
|
|
self._cur_mould_model=_cur_poured_model
|
|
|
|
|
|
print(f'当前要浇筑的管片 {json.dumps(asdict(_cur_poured_model), ensure_ascii=False)}')
|
|
|
|
|
|
else:
|
|
|
|
|
|
print('当前没有未浇筑的管片')
|
|
|
|
|
|
|
2026-02-09 11:36:37 +08:00
|
|
|
|
def __del__(self):
|
|
|
|
|
|
"""析构函数,确保线程安全关闭"""
|
|
|
|
|
|
self.shutdown()
|
|
|
|
|
|
|
|
|
|
|
|
# 创建默认实例
|
|
|
|
|
|
# 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)
|