diff --git a/Fedding.py b/Fedding.py index 6671391..625f15a 100644 --- a/Fedding.py +++ b/Fedding.py @@ -12,8 +12,8 @@ import sys sys.path.append(os.path.join(os.path.dirname(__file__), 'src', 'vision')) # 导入视觉处理模块 -from src.vision.anger_caculate import predict_obb_best_angle -from src.vision.resize_tuili_image_main import classify_image_weighted, load_global_rois, crop_and_resize, YOLO +from vision.anger_caculate import predict_obb_best_angle +from vision.resize_tuili_image_main import classify_image_weighted, load_global_rois, crop_and_resize, YOLO class FeedingControlSystem: @@ -124,10 +124,10 @@ class FeedingControlSystem: self.alignment_check_interval = 0.5 # 对齐检查间隔(秒) # 模型路径配置 - self.angle_model_path = "src/vision/angle.pt" - self.overflow_model_path = "src/vision/overflow.pt" - self.alignment_model_path = "src/vision/alig.pt" # 模具车对齐检测模型 - self.roi_file_path = "src/vision/roi_coordinates/1_rois.txt" + self.angle_model_path = "vision/models/angle.pt" + self.overflow_model_path = "vision/models/overflow.pt" + self.alignment_model_path = "vision/models/alig.pt" # 模具车对齐检测模型 + self.roi_file_path = "vision/roi_coordinates/1_rois.txt" # 模型实例 self.angle_model = None # 夹角检测模型实例 @@ -147,7 +147,6 @@ class FeedingControlSystem: def set_camera_config(self, camera_type="ip", ip=None, port=None, username=None, password=None, channel=1): """ 设置摄像头配置 - :param camera_type: 摄像头类型 "usb" 或 "ip" :param ip: 网络摄像头IP地址 :param port: 网络摄像头端口 :param username: 网络摄像头用户名 diff --git a/config/config.yaml b/config/config.yaml deleted file mode 100644 index 55e84ed..0000000 --- a/config/config.yaml +++ /dev/null @@ -1,48 +0,0 @@ -# 网络配置 -network: - relay: - # 网络继电器(所有485设备通过此接口转发) - host: "192.168.0.18" - port: 50000 - -# Modbus设备配置(通过网络继电器访问的RTU设备) -modbus_devices: - inverter: - # 变频器 - slave_id: 1 - address: 1 # 设备地址(用于网络继电器转发识别) - transmitters: - upper: - # 上料斗变送器 - slave_id: 2 - address: 2 - weight_register: 1 - register_count: 2 - lower: - # 下料斗变送器 - slave_id: 3 - address: 3 - weight_register: 1 - register_count: 2 - -# 系统参数 -parameters: - min_required_weight: 50 - max_error_count: 3 - monitoring_interval: 1 - timeout: 30 - -# 下料参数,频率 -feeding: - stage1_frequency: 30.0 - stage2_frequency: 40.0 - stage3_frequency: 50.0 - target_weight_per_stage: 33.3 - -# 继电器DO端口映射 -relay: - door_upper: 0 # DO0 - 上料斗滑动门 - door_lower_1: 1 # DO1 - 出砼门控制1 - door_lower_2: 2 # DO2 - 出砼门控制2 - break_arch_upper: 3 # DO3 - 上料斗破拱 - break_arch_lower: 4 # DO4 - 下料斗破拱 diff --git a/logs/app.log b/logs/app.log index e69de29..e0187ca 100644 --- a/logs/app.log +++ b/logs/app.log @@ -0,0 +1,26 @@ +2025-09-20 15:47:36,993 - FeedingControl.FeedingController - INFO - 豸ʼ +2025-09-20 15:47:37,011 - FeedingControl.MainSystem - INFO - ιϵͳʼ +2025-09-20 15:47:37,011 - FeedingControl.MainSystem - INFO - ϵͳ +2025-09-20 15:47:37,011 - FeedingControl.MainSystem - ERROR - ϵͳд: 'FeedingController' object has no attribute 'start' +2025-09-20 15:47:37,011 - FeedingControl.MainSystem - INFO - ֹͣϵͳ +2025-09-20 15:47:37,012 - FeedingControl - ERROR - ϵͳʧ: 'FeedingController' object has no attribute 'stop' +2025-09-20 15:53:09,420 - FeedingControl.FeedingController - INFO - 豸ʼ +2025-09-20 15:53:09,420 - FeedingControl.MainSystem - INFO - ιϵͳʼ +2025-09-20 15:53:09,420 - FeedingControl.MainSystem - INFO - ϵͳ +2025-09-20 15:53:09,429 - FeedingControl.MainSystem - ERROR - ϵͳд: 'FeedingController' object has no attribute 'start' +2025-09-20 15:53:09,429 - FeedingControl.MainSystem - INFO - ֹͣϵͳ +2025-09-20 15:53:09,429 - FeedingControl - ERROR - ϵͳʧ: 'FeedingController' object has no attribute 'stop' +2025-09-20 15:53:49,321 - FeedingControl.FeedingController - INFO - 豸ʼ +2025-09-20 15:53:49,322 - FeedingControl.MainSystem - INFO - ιϵͳʼ +2025-09-20 15:53:49,322 - FeedingControl.MainSystem - WARNING - ϵͳδ +2025-09-20 15:53:49,322 - FeedingControl.MainSystem - INFO - ϵͳ +2025-09-20 15:53:49,322 - FeedingControl.MainSystem - ERROR - ϵͳд: 'FeedingController' object has no attribute 'start' +2025-09-20 15:53:49,322 - FeedingControl.MainSystem - INFO - ֹͣϵͳ +2025-09-20 15:53:49,322 - FeedingControl - ERROR - ϵͳʧ: 'FeedingController' object has no attribute 'stop' +2025-09-20 16:00:19,400 - FeedingControl.FeedingController - INFO - 豸ʼ +2025-09-20 16:00:19,400 - FeedingControl.MainSystem - INFO - ιϵͳʼ +2025-09-20 16:00:19,400 - FeedingControl.MainSystem - WARNING - ϵͳδ +2025-09-20 16:00:19,400 - FeedingControl.MainSystem - INFO - ϵͳ +2025-09-20 16:00:19,400 - FeedingControl.MainSystem - ERROR - ϵͳд: 'FeedingController' object has no attribute 'start' +2025-09-20 16:00:19,400 - FeedingControl.MainSystem - INFO - ֹͣϵͳ +2025-09-20 16:00:19,400 - FeedingControl - ERROR - ϵͳʧ: 'FeedingController' object has no attribute 'stop' diff --git a/setup.py b/setup.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/__init__.py b/src/__init__.py deleted file mode 100644 index 5da0451..0000000 --- a/src/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -from .control import feeding_controller,state_machine -from .divices import inverter,relay,transmitter -from .utils import config,logger - -__all__ = ['FeedingController', 'FeedingStateMachine', 'FeedingState'] \ No newline at end of file diff --git a/src/control/__init__.py b/src/control/__init__.py deleted file mode 100644 index 2f0d072..0000000 --- a/src/control/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from .feeding_controller import FeedingController -from .state_machine import FeedingStateMachine, FeedingState - -__all__ = ['FeedingController', 'FeedingStateMachine', 'FeedingState'] \ No newline at end of file diff --git a/src/control/feeding_controller.py b/src/control/feeding_controller.py deleted file mode 100644 index c9150c5..0000000 --- a/src/control/feeding_controller.py +++ /dev/null @@ -1,327 +0,0 @@ -import time -from src.utils.config import config -from src.utils.logger import app_logger -from src.divices.relay import RelayController -from src.divices.inverter import InverterController -from src.divices.transmitter import TransmitterController -from .state_machine import FeedingStateMachine, FeedingState - - -class FeedingController: - """下料控制器""" - def __init__(self): - self.logger = app_logger.getChild('FeedingController') - self.state_machine = FeedingStateMachine() - - # 初始化设备 - self._initialize_devices() - - # 系统参数 - self.min_required_weight = config.get('parameters.min_required_weight', 50) - self.max_error_count = config.get('parameters.max_error_count', 3) - self.timeout = config.get('parameters.timeout', 30) - - # 下料参数 - self.stage_frequencies = { - 1: config.get('feeding.stage1_frequency', 30.0),#三阶段的频率 - 2: config.get('feeding.stage2_frequency', 40.0), - 3: config.get('feeding.stage3_frequency', 50.0) - } - self.target_weight_per_stage = config.get('feeding.target_weight_per_stage', 33.3) - - # 状态 - self.error_count = 0 - self.last_upper_weight = 0 - self.last_lower_weight = 0 - self.last_weight_time = time.time() - - def _initialize_devices(self): - """初始化设备""" - try: - # 网络继电器 - relay_config = config.get('network.relay') - self.relay = RelayController( - relay_config['host'], - relay_config['port'] - ) - - # 设置继电器设备映射 - relay_mapping = config.get('relay') - self.relay.set_device_mapping(relay_mapping) - - # 变频器 - 修改为使用新的配置结构 - inverter_config = config.get('modbus_devices.inverter') - self.inverter = InverterController( - relay_config['host'], # 使用网络继电器的host - relay_config['port'], # 使用网络继电器的port - inverter_config['slave_id'], - inverter_config['address'] # 添加设备地址参数 - ) - - # 变送器 - 修改为使用新的配置结构 - transmitters_config = config.get('modbus_devices.transmitters') - - self.upper_transmitter = TransmitterController( - 'upper', - relay_config['host'], # 使用网络继电器的host - relay_config['port'], # 使用网络继电器的port - transmitters_config['upper']['slave_id'], - transmitters_config['upper']['address'] # 添加设备地址参数 - ) - self.upper_transmitter.set_config( - transmitters_config['upper']['weight_register'], - transmitters_config['upper']['register_count'] - ) - - self.lower_transmitter = TransmitterController( - 'lower', - relay_config['host'], # 使用网络继电器的host - relay_config['port'], # 使用网络继电器的port - transmitters_config['lower']['slave_id'], - transmitters_config['lower']['address'] # 添加设备地址参数 - ) - self.lower_transmitter.set_config( - transmitters_config['lower']['weight_register'], - transmitters_config['lower']['register_count'] - ) - - self.logger.info("设备初始化完成") - except Exception as e: - self.logger.error(f"设备初始化失败: {e}") - raise - - def check_material_request(self): - """检查是否需要向上料斗要料""" - current_weight = self.upper_transmitter.read_weight() - - # 如果读取失败,增加错误计数 - if current_weight is None: - self.error_count += 1 - self.logger.warning(f"上料斗重量读取失败,错误计数: {self.error_count}") - - # 如果连续错误次数超过阈值,触发报警 - if self.error_count >= self.max_error_count: - self.logger.error("警告:上料斗重量传感器连续读取失败,请检查设备连接") - return False # 读取失败时不触发要料 - - # 重置错误计数 - self.error_count = 0 - - if current_weight < self.min_required_weight: - self.logger.info("上料斗重量不足,通知搅拌楼要料")#通知搅拌楼要料,调用彭琪的接口 - #一个通讯的函数,内容包括(要料数据) - self.move_upper_door_to_mixer() - return True - return False - - def move_upper_door_to_mixer(self): - """移动上料斗到搅拌楼出砼口""" - self.logger.info("移动上料斗到搅拌楼出砼口") - self.relay.control('door_upper', 'open') - - def return_upper_door(self): - """返回上料斗""" - self.logger.info("上料斗返回原位") - self.relay.control('door_upper', 'close') - - def start_feeding(self): - """开始下料过程""" - if self.state_machine.get_state() != FeedingState.IDLE: - self.logger.warning("下料已在进行中") - return False - - self.logger.info("开始三阶段下料过程") - self.state_machine.set_state(FeedingState.STAGE_ONE) - return True - - def execute_stage_one(self): - """执行第一阶段下料""" - self.logger.info("开始第一阶段下料 (1/3)") - - # 设置变频器频率 - frequency = self.stage_frequencies[1] - if not self.inverter.set_frequency(frequency): - self.logger.error("设置变频器频率失败") - self.finish_feeding() - return - - # 启动变频器 - if not self.inverter.control('start'): - self.logger.error("启动变频器失败") - self.finish_feeding() - return - - # 控制出砼门 - self.relay.control('door_lower_1', 'open') - self.relay.control('door_lower_2', 'open') - - # 监控下料过程 - start_time = time.time() - initial_weight = self.lower_transmitter.read_weight() - - # 如果初始重量读取失败,取消操作 - if initial_weight is None: - self.logger.error("无法获取初始重量,取消下料操作") - self.finish_feeding() - return - - target_weight = initial_weight + self.target_weight_per_stage - - while self.state_machine.get_state() == FeedingState.STAGE_ONE: - current_weight = self.lower_transmitter.read_weight() - - # 检查重量读取是否成功 - if current_weight is None: - self.error_count += 1 - if self.error_count >= self.max_error_count: - self.logger.error("下料斗重量传感器连续读取失败,停止下料") - self.finish_feeding() - return - else: - self.error_count = 0 # 重置错误计数 - - # 检查是否达到目标重量或超时 - if (current_weight is not None and current_weight >= target_weight) or \ - (time.time() - start_time) > self.timeout: - self.state_machine.set_state(FeedingState.STAGE_TWO) - break - time.sleep(2) # 每2秒读取一次 - - def execute_stage_two(self): - """执行第二阶段下料""" - self.logger.info("开始第二阶段下料 (2/3)") - - # 调整变频器频率 - frequency = self.stage_frequencies[2] - if not self.inverter.set_frequency(frequency): - self.logger.error("设置变频器频率失败") - self.finish_feeding() - return - - start_time = time.time() - initial_weight = self.lower_transmitter.read_weight() - - if initial_weight is None: - self.logger.error("无法获取初始重量,取消下料操作") - self.finish_feeding() - return - - target_weight = initial_weight + self.target_weight_per_stage - - while self.state_machine.get_state() == FeedingState.STAGE_TWO: - current_weight = self.lower_transmitter.read_weight() - - if current_weight is None: - self.error_count += 1 - if self.error_count >= self.max_error_count: - self.logger.error("下料斗重量传感器连续读取失败,停止下料") - self.finish_feeding() - return - else: - self.error_count = 0 - - if (current_weight is not None and current_weight >= target_weight) or \ - (time.time() - start_time) > self.timeout: - self.state_machine.set_state(FeedingState.STAGE_THREE) - break - - time.sleep(2) # 每2秒读取一次 - - def execute_stage_three(self): - """执行第三阶段下料""" - self.logger.info("开始第三阶段下料 (3/3)") - - # 调整变频器频率 - frequency = self.stage_frequencies[3] - if not self.inverter.set_frequency(frequency): - self.logger.error("设置变频器频率失败") - self.finish_feeding() - return - - start_time = time.time() - initial_weight = self.lower_transmitter.read_weight() - - if initial_weight is None: - self.logger.error("无法获取初始重量,取消下料操作") - self.finish_feeding() - return - - target_weight = initial_weight + self.target_weight_per_stage - - while self.state_machine.get_state() == FeedingState.STAGE_THREE: - current_weight = self.lower_transmitter.read_weight() - - if current_weight is None: - self.error_count += 1 - if self.error_count >= self.max_error_count: - self.logger.error("下料斗重量传感器连续读取失败,停止下料") - self.finish_feeding() - return - else: - self.error_count = 0 - - if (current_weight is not None and current_weight >= target_weight) or \ - (time.time() - start_time) > self.timeout: - self.state_machine.set_state(FeedingState.COMPLETED) - break - - time.sleep(2) # 每2秒读取一次 - - def finish_feeding(self): - """完成下料""" - self.logger.info("下料完成,关闭出砼门") - self.inverter.control('stop') - self.relay.control('door_lower_1', 'close') - self.relay.control('door_lower_2', 'close') - self.state_machine.set_state(FeedingState.IDLE) - self.error_count = 0 - - def check_arch_blocking(self): - """检查是否需要破拱""" - current_time = time.time() - - # 检查上料斗 - upper_weight = self.upper_transmitter.read_weight() - if upper_weight is not None: - if (abs(upper_weight - self.last_upper_weight) < 0.1) and \ - (current_time - self.last_weight_time) > 10: - self.logger.info("上料斗可能堵塞,启动破拱") - self.relay.control('break_arch_upper', 'open') - time.sleep(2) - self.relay.control('break_arch_upper', 'close') - - # 检查下料斗 - lower_weight = self.lower_transmitter.read_weight() - if lower_weight is not None: - if (abs(lower_weight - self.last_lower_weight) < 0.1) and \ - (current_time - self.last_weight_time) > 10: - self.logger.info("下料斗可能堵塞,启动破拱") - self.relay.control('break_arch_lower', 'open') - time.sleep(2) - self.relay.control('break_arch_lower', 'close') - - # 更新重量记录 - if upper_weight is not None: - self.last_upper_weight = upper_weight - if lower_weight is not None: - self.last_lower_weight = lower_weight - - if upper_weight is not None or lower_weight is not None: - self.last_weight_time = current_time - - def run_cycle(self): - """运行一个控制周期""" - try: - # 检查是否需要要料 - self.check_material_request() - - # 检查破拱 - self.check_arch_blocking() - - # 执行状态机 - self.state_machine.transition(self) - - return True - except Exception as e: - self.logger.error(f"控制周期执行错误: {e}") - return False \ No newline at end of file diff --git a/src/control/state_machine.py b/src/control/state_machine.py deleted file mode 100644 index eb22c58..0000000 --- a/src/control/state_machine.py +++ /dev/null @@ -1,105 +0,0 @@ -from abc import ABC, abstractmethod -from enum import Enum -from src.utils.logger import app_logger - - -class FeedingState(Enum): - """下料状态枚举""" - IDLE = 0 - STAGE_ONE = 1 - STAGE_TWO = 2 - STAGE_THREE = 3 - COMPLETED = 4 - - -class State(ABC): - """状态基类""" - - def __init__(self): - self.logger = app_logger.getChild('StateMachine') - - @abstractmethod - def handle(self, context): - """处理状态逻辑""" - pass - - -class IdleState(State): - """空闲状态""" - - def handle(self, context): - self.logger.info("系统处于空闲状态") - # 等待开始下料命令 - return FeedingState.IDLE - - -class StageOneState(State): - """第一阶段下料状态""" - - def handle(self, context): - self.logger.info("执行第一阶段下料") - # 第一阶段下料逻辑 - context.execute_stage_one() - return FeedingState.STAGE_TWO - - -class StageTwoState(State): - """第二阶段下料状态""" - - def handle(self, context): - self.logger.info("执行第二阶段下料") - # 第二阶段下料逻辑 - context.execute_stage_two() - return FeedingState.STAGE_THREE - - -class StageThreeState(State): - """第三阶段下料状态""" - - def handle(self, context): - self.logger.info("执行第三阶段下料") - # 第三阶段下料逻辑 - context.execute_stage_three() - return FeedingState.COMPLETED - - -class CompletedState(State): - """完成状态""" - - def handle(self, context): - self.logger.info("下料完成") - # 完成逻辑 - context.finish_feeding() - return FeedingState.IDLE - - -class FeedingStateMachine: - """下料状态机""" - - def __init__(self): - self.states = { - FeedingState.IDLE: IdleState(), - FeedingState.STAGE_ONE: StageOneState(), - FeedingState.STAGE_TWO: StageTwoState(), - FeedingState.STAGE_THREE: StageThreeState(), - FeedingState.COMPLETED: CompletedState() - } - self.current_state = FeedingState.IDLE - self.logger = app_logger.getChild('FeedingStateMachine') - - def transition(self, context): - """状态转换""" - if self.current_state in self.states: - next_state = self.states[self.current_state].handle(context) - if next_state != self.current_state: - self.logger.info(f"状态从 {self.current_state} 转换到 {next_state}") - self.current_state = next_state - - def set_state(self, state: FeedingState): - """设置当前状态""" - self.logger.info(f"手动设置状态为 {state}") - self.current_state = state - - def get_state(self): - """获取当前状态""" - return self.current_state \ No newline at end of file diff --git a/src/divices/__init__.py b/src/divices/__init__.py deleted file mode 100644 index 82f5c8e..0000000 --- a/src/divices/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -from .relay import RelayController -from .inverter import InverterController -from .transmitter import TransmitterController - -__all__ = ['RelayController', 'InverterController', 'TransmitterController'] \ No newline at end of file diff --git a/src/divices/inverter.py b/src/divices/inverter.py deleted file mode 100644 index e4f788d..0000000 --- a/src/divices/inverter.py +++ /dev/null @@ -1,102 +0,0 @@ -from pymodbus.client import ModbusTcpClient -from pymodbus.exceptions import ModbusException -from src.utils.logger import app_logger - - -class InverterController: - """变频器控制器""" - - def __init__(self, relay_host: str, relay_port: int, slave_id: int = 1, device_address: int = 1): - self.relay_host = relay_host - self.relay_port = relay_port - self.slave_id = slave_id - self.device_address = device_address # 设备地址,用于网络继电器转发识别 - self.client = None - self.logger = app_logger.getChild('InverterController') - - # 变频器寄存器地址 - self.registers = { - 'frequency': 0x01, # 频率设置寄存器 - 'start': 0x00, # 启动命令寄存器 - 'stop': 0x01 # 停止命令寄存器 - } - - def connect(self): - """连接变频器""" - try: - self.client = ModbusTcpClient(self.relay_host, port=self.relay_port) - connection_result = self.client.connect() - - # 这里可能需要添加设备地址的处理逻辑,具体取决于网络继电器的协议 - # 例如,可能需要发送一个初始化命令告诉继电器要与哪个设备通信 - - return connection_result - except Exception as e: - self.logger.error(f"连接变频器失败: {e}") - return False - - def disconnect(self): - """断开变频器连接""" - if self.client: - try: - self.client.close() - except Exception as e: - self.logger.error(f"断开变频器连接失败: {e}") - - def set_frequency(self, frequency: float): - """设置变频器频率""" - if not self.client: - if not self.connect(): - return False - - try: - # 写入频率值 (假设频率值需要转换为Hz*10) - result = self.client.write_register( - self.registers['frequency'], - int(frequency * 10), - slave=self.slave_id - ) - - if isinstance(result, Exception): - self.logger.error(f"设置变频器频率失败: {result}") - return False - - self.logger.info(f"设置变频器频率为 {frequency}Hz") - return True - except ModbusException as e: - self.logger.error(f"变频器Modbus通信错误: {e}") - return False - - def control(self, action: str): - """控制变频器启停""" - if not self.client: - if not self.connect(): - return False - - try: - if action == 'start': - result = self.client.write_register( - self.registers['start'], - 1, - slave=self.slave_id - ) - self.logger.info("启动变频器") - elif action == 'stop': - result = self.client.write_register( - self.registers['stop'], - 1, - slave=self.slave_id - ) - self.logger.info("停止变频器") - else: - self.logger.error(f"无效的变频器操作: {action}") - return False - - if isinstance(result, Exception): - self.logger.error(f"控制变频器失败: {result}") - return False - - return True - except ModbusException as e: - self.logger.error(f"变频器控制错误: {e}") - return False \ No newline at end of file diff --git a/src/divices/relay.py b/src/divices/relay.py deleted file mode 100644 index 39e736c..0000000 --- a/src/divices/relay.py +++ /dev/null @@ -1,85 +0,0 @@ -import socket -import binascii -import time -from src.utils.logger import app_logger - - -class RelayController: - """网络继电器控制器""" - - def __init__(self, host: str, port: int): - self.host = host - self.port = port - self.logger = app_logger.getChild('RelayController') - - # 设备DO端口映射 (将在初始化时从配置加载) - self.device_mapping = {} - - # 继电器控制命令 - self.relay_commands = { - 0: {'open': '00000000000601050000FF00', 'close': '000000000006010500000000'}, - 1: {'open': '00000000000601050001FF00', 'close': '000000000006010500010000'}, - 2: {'open': '00000000000601050002FF00', 'close': '000000000006010500020000'}, - 3: {'open': '00000000000601050003FF00', 'close': '000000000006010500030000'}, - 4: {'open': '00000000000601050004FF00', 'close': '000000000006010500040000'} - } - - # 读取状态命令 - self.read_status_command = '000000000006010100000008' - - def set_device_mapping(self, mapping: dict): - """设置设备映射""" - self.device_mapping = mapping - - def send_command(self, command_hex: str): - """发送命令到网络继电器""" - try: - byte_data = binascii.unhexlify(command_hex) - with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: - sock.settimeout(5) # 设置超时 - sock.connect((self.host, self.port)) - sock.send(byte_data) - response = sock.recv(1024) - self.logger.debug(f"收到继电器响应: {binascii.hexlify(response)}") - return response - except Exception as e: - self.logger.error(f"继电器通信错误: {e}") - return None - - def get_status(self): - """获取继电器状态""" - response = self.send_command(self.read_status_command) - status_dict = {} - - if response and len(response) >= 10: - status_byte = response[9] - status_bin = f"{status_byte:08b}"[::-1] - - # 根据设备映射返回状态 - for device_name, bit_index in self.device_mapping.items(): - status_dict[device_name] = status_bin[bit_index] == '1' - else: - self.logger.warning("读取继电器状态失败或响应无效") - - return status_dict - - def control(self, device_name: str, action: str): - """控制继电器开关""" - if device_name not in self.device_mapping: - self.logger.error(f"无效的继电器设备: {device_name}") - return False - - bit_index = self.device_mapping[device_name] - - if bit_index not in self.relay_commands: - self.logger.error(f"不支持的DO端口: {bit_index}") - return False - - if action not in self.relay_commands[bit_index]: - self.logger.error(f"无效的继电器动作: {action}") - return False - - self.logger.info(f"控制继电器 {device_name} ({bit_index}) {action}") - result = self.send_command(self.relay_commands[bit_index][action]) - time.sleep(0.1) # 短暂延迟确保命令执行 - return result is not None \ No newline at end of file diff --git a/src/divices/transmitter.py b/src/divices/transmitter.py deleted file mode 100644 index 70991a1..0000000 --- a/src/divices/transmitter.py +++ /dev/null @@ -1,90 +0,0 @@ -from pymodbus.client import ModbusTcpClient -from pymodbus.exceptions import ModbusException -import struct -from src.utils.logger import app_logger - - -class TransmitterController: - """重量变送器控制器""" - - def __init__(self, name: str, relay_host: str, relay_port: int, slave_id: int = 1, device_address: int = 1): - self.name = name - self.relay_host = relay_host - self.relay_port = relay_port - self.slave_id = slave_id - self.device_address = device_address # 设备地址,用于网络继电器转发识别 - self.client = None - self.logger = app_logger.getChild(f'TransmitterController.{name}') - - # 默认配置 - self.weight_register = 0 - self.register_count = 2 - - def connect(self): - """连接变送器""" - try: - self.client = ModbusTcpClient(self.relay_host, port=self.relay_port) - connection_result = self.client.connect() - - # 这里可能需要添加设备地址的处理逻辑,具体取决于网络继电器的协议 - - return connection_result - except Exception as e: - self.logger.error(f"连接变送器 {self.name} 失败: {e}") - return False - - def disconnect(self): - """断开变送器连接""" - if self.client: - try: - self.client.close() - except Exception as e: - self.logger.error(f"断开变送器 {self.name} 连接失败: {e}") - - def read_weight(self): - """读取重量数据""" - if not self.client: - if not self.connect(): - return None - - try: - # 读取保持寄存器 - result = self.client.read_holding_registers( - address=self.weight_register, - count=self.register_count, - slave=self.slave_id - ) - - if isinstance(result, Exception): - self.logger.error(f"读取变送器 {self.name} 数据失败: {result}") - return None - - # 解析重量数据 - if self.register_count == 2: - # 根据协议,重量数据从第三个寄存器开始,需要4个字节 - # 组合两个寄存器为32位整数 (大端序) - # 按照协议描述,应该是4个字节的数据: [reg0_high, reg0_low, reg1_high, reg1_low] - weight_bytes = struct.pack('>HH', result.registers[0], result.registers[1]) - # 按照协议,从第4个字节开始是重量数据,即前4个字节就是重量数据 - weight = struct.unpack('>I', weight_bytes)[0] # 使用大端序无符号整数解析 - elif self.register_count == 1: - # 单个寄存器直接作为整数 - weight = float(result.registers[0]) - else: - self.logger.error(f"不支持的寄存器数量: {self.register_count}") - return None - - self.logger.debug(f"变送器 {self.name} 读取重量: {weight}kg") - return float(weight) - - except ModbusException as e: - self.logger.error(f"变送器 {self.name} Modbus通信错误: {e}") - return None - except Exception as e: - self.logger.error(f"变送器 {self.name} 数据解析错误: {e}") - return None - - def set_config(self, weight_register, register_count): - """设置重量读取相关的寄存器配置""" - self.weight_register = weight_register - self.register_count = register_count \ No newline at end of file diff --git a/src/logs/app.log b/src/logs/app.log deleted file mode 100644 index 29f2558..0000000 --- a/src/logs/app.log +++ /dev/null @@ -1,236 +0,0 @@ -2025-09-12 19:40:44,426 - FeedingControl.FeedingController - INFO - 豸ʼ -2025-09-12 19:40:44,426 - FeedingControl.FeedingController - INFO - 豸ʼ -2025-09-12 19:40:44,426 - FeedingControl.MainSystem - INFO - ʼ -2025-09-12 19:40:44,426 - FeedingControl.MainSystem - INFO - ʼ -2025-09-12 19:40:44,426 - FeedingControl.MainSystem - INFO - ϵͳ -2025-09-12 19:40:44,426 - FeedingControl.MainSystem - INFO - ϵͳ -2025-09-12 19:40:47,438 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 1 -2025-09-12 19:40:47,438 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 1 -2025-09-12 19:40:50,453 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-12 19:40:50,453 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-12 19:40:53,476 - FeedingControl.StateMachine - INFO - ϵͳڿ״̬ -2025-09-12 19:40:53,476 - FeedingControl.StateMachine - INFO - ϵͳڿ״̬ -2025-09-12 19:40:57,499 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-12 19:40:57,499 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-12 19:40:57,499 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 2 -2025-09-12 19:40:57,499 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 2 -2025-09-12 19:41:00,500 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-12 19:41:00,500 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-12 19:41:03,500 - FeedingControl.TransmitterController.lower - ERROR - lower ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.22:502] -2025-09-12 19:41:03,500 - FeedingControl.TransmitterController.lower - ERROR - lower ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.22:502] -2025-09-12 19:41:03,500 - FeedingControl.StateMachine - INFO - ϵͳڿ״̬ -2025-09-12 19:41:03,500 - FeedingControl.StateMachine - INFO - ϵͳڿ״̬ -2025-09-12 19:41:07,507 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-12 19:41:07,507 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-12 19:41:07,507 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 3 -2025-09-12 19:41:07,507 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 3 -2025-09-12 19:41:07,507 - FeedingControl.FeedingController - ERROR - 棺϶ȡʧܣ豸 -2025-09-12 19:41:07,507 - FeedingControl.FeedingController - ERROR - 棺϶ȡʧܣ豸 -2025-09-12 19:41:10,516 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-12 19:41:10,516 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-12 19:41:13,529 - FeedingControl.TransmitterController.lower - ERROR - lower ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.22:502] -2025-09-12 19:41:13,529 - FeedingControl.TransmitterController.lower - ERROR - lower ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.22:502] -2025-09-12 19:41:13,529 - FeedingControl.StateMachine - INFO - ϵͳڿ״̬ -2025-09-12 19:41:13,529 - FeedingControl.StateMachine - INFO - ϵͳڿ״̬ -2025-09-12 19:41:17,535 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-12 19:41:17,535 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-12 19:41:17,535 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 4 -2025-09-12 19:41:17,535 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 4 -2025-09-12 19:41:17,535 - FeedingControl.FeedingController - ERROR - 棺϶ȡʧܣ豸 -2025-09-12 19:41:17,535 - FeedingControl.FeedingController - ERROR - 棺϶ȡʧܣ豸 -2025-09-12 19:42:04,120 - FeedingControl.FeedingController - INFO - 豸ʼ -2025-09-12 19:42:04,120 - FeedingControl.FeedingController - INFO - 豸ʼ -2025-09-12 19:42:04,120 - FeedingControl.MainSystem - INFO - ʼ -2025-09-12 19:42:04,120 - FeedingControl.MainSystem - INFO - ʼ -2025-09-12 19:42:04,120 - FeedingControl.MainSystem - INFO - ϵͳ -2025-09-12 19:42:04,120 - FeedingControl.MainSystem - INFO - ϵͳ -2025-09-12 19:42:07,124 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 1 -2025-09-12 19:42:07,124 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 1 -2025-09-12 19:42:10,125 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-12 19:42:10,125 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-13 10:35:50,544 - FeedingControl.FeedingController - INFO - 豸ʼ -2025-09-13 10:35:50,544 - FeedingControl.FeedingController - INFO - 豸ʼ -2025-09-13 10:35:50,546 - FeedingControl.MainSystem - INFO - ʼ -2025-09-13 10:35:50,546 - FeedingControl.MainSystem - INFO - ʼ -2025-09-13 10:35:50,546 - FeedingControl.MainSystem - INFO - ϵͳ -2025-09-13 10:35:50,546 - FeedingControl.MainSystem - INFO - ϵͳ -2025-09-13 10:35:53,550 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 1 -2025-09-13 10:35:53,550 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 1 -2025-09-13 10:35:56,552 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-13 10:35:56,552 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-13 10:35:59,555 - FeedingControl.StateMachine - INFO - ϵͳڿ״̬ -2025-09-13 10:35:59,555 - FeedingControl.StateMachine - INFO - ϵͳڿ״̬ -2025-09-13 10:36:03,566 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-13 10:36:03,566 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-13 10:36:03,566 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 2 -2025-09-13 10:36:03,566 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 2 -2025-09-13 10:36:06,573 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-13 10:36:06,573 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-13 10:36:09,582 - FeedingControl.TransmitterController.lower - ERROR - lower ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.22:502] -2025-09-13 10:36:09,582 - FeedingControl.TransmitterController.lower - ERROR - lower ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.22:502] -2025-09-13 10:36:09,582 - FeedingControl.StateMachine - INFO - ϵͳڿ״̬ -2025-09-13 10:36:09,582 - FeedingControl.StateMachine - INFO - ϵͳڿ״̬ -2025-09-13 10:36:13,601 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-13 10:36:13,601 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-13 10:36:13,601 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 3 -2025-09-13 10:36:13,601 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 3 -2025-09-13 10:36:13,601 - FeedingControl.FeedingController - ERROR - 棺϶ȡʧܣ豸 -2025-09-13 10:36:13,601 - FeedingControl.FeedingController - ERROR - 棺϶ȡʧܣ豸 -2025-09-13 10:36:16,602 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-13 10:36:16,602 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-13 10:36:19,617 - FeedingControl.TransmitterController.lower - ERROR - lower ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.22:502] -2025-09-13 10:36:19,617 - FeedingControl.TransmitterController.lower - ERROR - lower ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.22:502] -2025-09-13 10:36:19,617 - FeedingControl.StateMachine - INFO - ϵͳڿ״̬ -2025-09-13 10:36:19,617 - FeedingControl.StateMachine - INFO - ϵͳڿ״̬ -2025-09-13 10:36:23,626 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-13 10:36:23,626 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-13 10:36:23,626 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 4 -2025-09-13 10:36:23,626 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 4 -2025-09-13 10:36:23,626 - FeedingControl.FeedingController - ERROR - 棺϶ȡʧܣ豸 -2025-09-13 10:36:23,626 - FeedingControl.FeedingController - ERROR - 棺϶ȡʧܣ豸 -2025-09-13 10:36:26,638 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-13 10:36:26,638 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-13 10:36:29,640 - FeedingControl.TransmitterController.lower - ERROR - lower ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.22:502] -2025-09-13 10:36:29,640 - FeedingControl.TransmitterController.lower - ERROR - lower ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.22:502] -2025-09-13 10:36:29,640 - FeedingControl.StateMachine - INFO - ϵͳڿ״̬ -2025-09-13 10:36:29,640 - FeedingControl.StateMachine - INFO - ϵͳڿ״̬ -2025-09-13 10:36:33,662 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-13 10:36:33,662 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-13 10:36:33,663 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 5 -2025-09-13 10:36:33,663 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 5 -2025-09-13 10:36:33,663 - FeedingControl.FeedingController - ERROR - 棺϶ȡʧܣ豸 -2025-09-13 10:36:33,663 - FeedingControl.FeedingController - ERROR - 棺϶ȡʧܣ豸 -2025-09-13 10:36:36,672 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-13 10:36:36,672 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-13 10:36:39,685 - FeedingControl.TransmitterController.lower - ERROR - lower ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.22:502] -2025-09-13 10:36:39,685 - FeedingControl.TransmitterController.lower - ERROR - lower ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.22:502] -2025-09-13 10:36:39,685 - FeedingControl.StateMachine - INFO - ϵͳڿ״̬ -2025-09-13 10:36:39,685 - FeedingControl.StateMachine - INFO - ϵͳڿ״̬ -2025-09-13 10:36:43,711 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-13 10:36:43,711 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-13 10:36:43,711 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 6 -2025-09-13 10:36:43,711 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 6 -2025-09-13 10:36:43,711 - FeedingControl.FeedingController - ERROR - 棺϶ȡʧܣ豸 -2025-09-13 10:36:43,711 - FeedingControl.FeedingController - ERROR - 棺϶ȡʧܣ豸 -2025-09-13 10:36:46,715 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-13 10:36:46,715 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-13 10:36:49,725 - FeedingControl.TransmitterController.lower - ERROR - lower ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.22:502] -2025-09-13 10:36:49,725 - FeedingControl.TransmitterController.lower - ERROR - lower ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.22:502] -2025-09-13 10:36:49,725 - FeedingControl.StateMachine - INFO - ϵͳڿ״̬ -2025-09-13 10:36:49,725 - FeedingControl.StateMachine - INFO - ϵͳڿ״̬ -2025-09-16 19:45:07,373 - FeedingControl.FeedingController - INFO - 豸ʼ -2025-09-16 19:45:07,373 - FeedingControl.FeedingController - INFO - 豸ʼ -2025-09-16 19:45:11,736 - FeedingControl.MainSystem - INFO - ʼ -2025-09-16 19:45:11,736 - FeedingControl.MainSystem - INFO - ʼ -2025-09-16 19:45:12,696 - FeedingControl.MainSystem - INFO - ϵͳ -2025-09-16 19:45:12,696 - FeedingControl.MainSystem - INFO - ϵͳ -2025-09-16 19:45:15,710 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 1 -2025-09-16 19:45:15,710 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 1 -2025-09-16 19:45:18,711 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-16 19:45:18,711 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-16 19:45:21,725 - FeedingControl.StateMachine - INFO - ϵͳڿ״̬ -2025-09-16 19:45:21,725 - FeedingControl.StateMachine - INFO - ϵͳڿ״̬ -2025-09-16 19:45:25,741 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-16 19:45:25,741 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-16 19:45:25,741 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 2 -2025-09-16 19:45:25,741 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 2 -2025-09-16 19:45:28,752 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-16 19:45:28,752 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-16 19:45:31,765 - FeedingControl.TransmitterController.lower - ERROR - lower ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.22:502] -2025-09-16 19:45:31,765 - FeedingControl.TransmitterController.lower - ERROR - lower ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.22:502] -2025-09-16 19:45:31,765 - FeedingControl.StateMachine - INFO - ϵͳڿ״̬ -2025-09-16 19:45:31,765 - FeedingControl.StateMachine - INFO - ϵͳڿ״̬ -2025-09-16 19:45:35,782 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-16 19:45:35,782 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-16 19:45:35,782 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 3 -2025-09-16 19:45:35,782 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 3 -2025-09-16 19:45:35,782 - FeedingControl.FeedingController - ERROR - 棺϶ȡʧܣ豸 -2025-09-16 19:45:35,782 - FeedingControl.FeedingController - ERROR - 棺϶ȡʧܣ豸 -2025-09-16 19:45:38,797 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-16 19:45:38,797 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-16 19:45:41,810 - FeedingControl.TransmitterController.lower - ERROR - lower ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.22:502] -2025-09-16 19:45:41,810 - FeedingControl.TransmitterController.lower - ERROR - lower ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.22:502] -2025-09-16 19:45:41,810 - FeedingControl.StateMachine - INFO - ϵͳڿ״̬ -2025-09-16 19:45:41,810 - FeedingControl.StateMachine - INFO - ϵͳڿ״̬ -2025-09-16 19:45:45,835 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-16 19:45:45,835 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-16 19:45:45,835 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 4 -2025-09-16 19:45:45,835 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 4 -2025-09-16 19:45:45,835 - FeedingControl.FeedingController - ERROR - 棺϶ȡʧܣ豸 -2025-09-16 19:45:45,835 - FeedingControl.FeedingController - ERROR - 棺϶ȡʧܣ豸 -2025-09-16 19:45:48,845 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-16 19:45:48,845 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-16 19:45:51,859 - FeedingControl.TransmitterController.lower - ERROR - lower ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.22:502] -2025-09-16 19:45:51,859 - FeedingControl.TransmitterController.lower - ERROR - lower ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.22:502] -2025-09-16 19:45:51,859 - FeedingControl.StateMachine - INFO - ϵͳڿ״̬ -2025-09-16 19:45:51,859 - FeedingControl.StateMachine - INFO - ϵͳڿ״̬ -2025-09-16 19:45:55,885 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-16 19:45:55,885 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-16 19:45:55,885 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 5 -2025-09-16 19:45:55,885 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 5 -2025-09-16 19:45:55,885 - FeedingControl.FeedingController - ERROR - 棺϶ȡʧܣ豸 -2025-09-16 19:45:55,885 - FeedingControl.FeedingController - ERROR - 棺϶ȡʧܣ豸 -2025-09-16 19:45:58,890 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-16 19:45:58,890 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-16 19:46:01,900 - FeedingControl.TransmitterController.lower - ERROR - lower ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.22:502] -2025-09-16 19:46:01,900 - FeedingControl.TransmitterController.lower - ERROR - lower ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.22:502] -2025-09-16 19:46:01,900 - FeedingControl.StateMachine - INFO - ϵͳڿ״̬ -2025-09-16 19:46:01,900 - FeedingControl.StateMachine - INFO - ϵͳڿ״̬ -2025-09-16 19:46:05,921 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-16 19:46:05,921 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-16 19:46:05,921 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 6 -2025-09-16 19:46:05,921 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 6 -2025-09-16 19:46:05,921 - FeedingControl.FeedingController - ERROR - 棺϶ȡʧܣ豸 -2025-09-16 19:46:05,921 - FeedingControl.FeedingController - ERROR - 棺϶ȡʧܣ豸 -2025-09-16 19:46:08,926 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-16 19:46:08,926 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-16 19:46:11,936 - FeedingControl.TransmitterController.lower - ERROR - lower ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.22:502] -2025-09-16 19:46:11,936 - FeedingControl.TransmitterController.lower - ERROR - lower ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.22:502] -2025-09-16 19:46:11,936 - FeedingControl.StateMachine - INFO - ϵͳڿ״̬ -2025-09-16 19:46:11,936 - FeedingControl.StateMachine - INFO - ϵͳڿ״̬ -2025-09-16 19:46:15,950 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-16 19:46:15,950 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-16 19:46:15,950 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 7 -2025-09-16 19:46:15,950 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 7 -2025-09-16 19:46:15,950 - FeedingControl.FeedingController - ERROR - 棺϶ȡʧܣ豸 -2025-09-16 19:46:15,950 - FeedingControl.FeedingController - ERROR - 棺϶ȡʧܣ豸 -2025-09-16 19:46:18,958 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-16 19:46:18,958 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-16 19:46:21,965 - FeedingControl.TransmitterController.lower - ERROR - lower ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.22:502] -2025-09-16 19:46:21,965 - FeedingControl.TransmitterController.lower - ERROR - lower ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.22:502] -2025-09-16 19:46:21,965 - FeedingControl.StateMachine - INFO - ϵͳڿ״̬ -2025-09-16 19:46:21,965 - FeedingControl.StateMachine - INFO - ϵͳڿ״̬ -2025-09-16 19:46:25,987 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-16 19:46:25,987 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-16 19:46:25,987 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 8 -2025-09-16 19:46:25,987 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 8 -2025-09-16 19:46:25,987 - FeedingControl.FeedingController - ERROR - 棺϶ȡʧܣ豸 -2025-09-16 19:46:25,987 - FeedingControl.FeedingController - ERROR - 棺϶ȡʧܣ豸 -2025-09-16 19:46:28,989 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-16 19:46:28,989 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-16 19:46:31,993 - FeedingControl.TransmitterController.lower - ERROR - lower ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.22:502] -2025-09-16 19:46:31,993 - FeedingControl.TransmitterController.lower - ERROR - lower ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.22:502] -2025-09-16 19:46:31,993 - FeedingControl.StateMachine - INFO - ϵͳڿ״̬ -2025-09-16 19:46:31,993 - FeedingControl.StateMachine - INFO - ϵͳڿ״̬ -2025-09-16 19:46:32,358 - FeedingControl.MainSystem - INFO - յź 2ֹͣϵͳ... -2025-09-16 19:46:32,358 - FeedingControl.MainSystem - INFO - յź 2ֹͣϵͳ... -2025-09-16 19:46:32,358 - FeedingControl.MainSystem - INFO - ֹͣϵͳ -2025-09-16 19:46:32,358 - FeedingControl.MainSystem - INFO - ֹͣϵͳ -2025-09-16 19:46:32,358 - FeedingControl.MainSystem - INFO - ϵͳֹͣ -2025-09-16 19:46:32,358 - FeedingControl.MainSystem - INFO - ϵͳֹͣ -2025-09-16 19:57:25,205 - FeedingControl.FeedingController - INFO - 豸ʼ -2025-09-16 19:57:25,205 - FeedingControl.FeedingController - INFO - 豸ʼ -2025-09-16 19:57:30,519 - FeedingControl.MainSystem - INFO - ʼ -2025-09-16 19:57:30,519 - FeedingControl.MainSystem - INFO - ʼ -2025-09-16 19:57:32,282 - FeedingControl.MainSystem - INFO - ϵͳ -2025-09-16 19:57:32,282 - FeedingControl.MainSystem - INFO - ϵͳ -2025-09-16 19:57:47,433 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 1 -2025-09-16 19:57:47,433 - FeedingControl.FeedingController - WARNING - ϶ȡʧܣ: 1 -2025-09-16 19:58:06,833 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-16 19:58:06,833 - FeedingControl.TransmitterController.upper - ERROR - upper ModbusͨŴ: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.0.21:502] -2025-09-16 19:58:12,731 - FeedingControl.MainSystem - INFO - յź 2ֹͣϵͳ... -2025-09-16 19:58:12,731 - FeedingControl.MainSystem - INFO - յź 2ֹͣϵͳ... -2025-09-16 19:58:12,731 - FeedingControl.MainSystem - INFO - ֹͣϵͳ -2025-09-16 19:58:12,731 - FeedingControl.MainSystem - INFO - ֹͣϵͳ -2025-09-16 19:58:12,731 - FeedingControl.MainSystem - INFO - ϵͳֹͣ -2025-09-16 19:58:12,731 - FeedingControl.MainSystem - INFO - ϵͳֹͣ diff --git a/src/main.py b/src/main.py deleted file mode 100644 index ebc8f52..0000000 --- a/src/main.py +++ /dev/null @@ -1,84 +0,0 @@ -import time -import signal -import sys -import threading -from utils.config import config -from utils.logger import app_logger -from control.feeding_controller import FeedingController - - -class FeedingControlSystem: - """主控制系统""" - - def __init__(self): - self.logger = app_logger.getChild('MainSystem') - self.running = False - self.controller = None - self._setup_signal_handlers() - self._initialize_controller() - - def _setup_signal_handlers(self): - """设置信号处理器""" - signal.signal(signal.SIGINT, self._signal_handler) - signal.signal(signal.SIGTERM, self._signal_handler) - - def _signal_handler(self, signum, frame): - """信号处理函数""" - self.logger.info(f"收到信号 {signum},正在停止系统...") - self.stop() - sys.exit(0) - - def _initialize_controller(self): - """初始化控制器""" - try: - self.controller = FeedingController() - self.logger.info("控制器初始化完成") - except Exception as e: - self.logger.error(f"控制器初始化失败: {e}") - raise - - def start(self): - """启动系统""" - if self.running: - self.logger.warning("系统已在运行") - return - - self.logger.info("启动控制系统") - self.running = True - - # 主循环 - monitoring_interval = config.get('parameters.monitoring_interval', 1) - - while self.running: - try: - if self.controller: - self.controller.run_cycle() - time.sleep(monitoring_interval) - except Exception as e: - self.logger.error(f"系统运行错误: {e}") - time.sleep(monitoring_interval) - - def stop(self): - """停止系统""" - if not self.running: - self.logger.warning("系统未在运行") - return - - self.logger.info("停止控制系统") - self.running = False - - self.logger.info("控制系统已停止") - - -def main(): - """主函数""" - try: - system = FeedingControlSystem() - system.start() - except Exception as e: - app_logger.error(f"系统启动失败: {e}") - sys.exit(1) - - -if __name__ == "__main__": - main() diff --git a/src/utils/__init__.py b/src/utils/__init__.py deleted file mode 100644 index b1ea832..0000000 --- a/src/utils/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from .config import Config -from .logger import setup_logger - -__all__ = ['Config', 'setup_logger'] \ No newline at end of file diff --git a/src/utils/config.py b/src/utils/config.py deleted file mode 100644 index 0945474..0000000 --- a/src/utils/config.py +++ /dev/null @@ -1,39 +0,0 @@ -import yaml -import os -from typing import Dict, Any - - -class Config: - """配置管理类""" - - def __init__(self, config_path: str = "D:\pycharmproject\Feeding_control_system\config\config.yaml"): - self.config_path = config_path - self._config = self._load_config() - - def _load_config(self) -> Dict[str, Any]: - """加载配置文件""" - if not os.path.exists(self.config_path): - raise FileNotFoundError(f"配置文件不存在: {self.config_path}") - - with open(self.config_path, 'r', encoding='utf-8') as file: - return yaml.safe_load(file) - - def get(self, key_path: str, default=None): - """获取配置值,支持点号分隔的路径""" - keys = key_path.split('.') - value = self._config - - try: - for key in keys: - value = value[key] - return value - except (KeyError, TypeError): - return default - - def reload(self): - """重新加载配置""" - self._config = self._load_config() - - -# 全局配置实例 -config = Config() \ No newline at end of file diff --git a/src/utils/logger.py b/src/utils/logger.py deleted file mode 100644 index 0955c1c..0000000 --- a/src/utils/logger.py +++ /dev/null @@ -1,33 +0,0 @@ -import logging -import os - - -def setup_logger(name, log_file, level=logging.INFO): - """设置日志记录器""" - formatter = logging.Formatter( - '%(asctime)s - %(name)s - %(levelname)s - %(message)s' - ) - - # 确保日志目录存在 - log_dir = os.path.dirname(log_file) - if log_dir and not os.path.exists(log_dir): - os.makedirs(log_dir) - - # 文件处理器 - file_handler = logging.FileHandler(log_file) - file_handler.setFormatter(formatter) - - # 控制台处理器 - console_handler = logging.StreamHandler() - console_handler.setFormatter(formatter) - - logger = logging.getLogger(name) - logger.setLevel(level) - logger.addHandler(file_handler) - logger.addHandler(console_handler) - - return logger - - -# 创建全局日志记录器 -app_logger = setup_logger('FeedingControl', 'logs/app.log') \ No newline at end of file diff --git a/src/vision/alig.pt b/src/vision/alig.pt deleted file mode 100644 index 9e3f2ac..0000000 Binary files a/src/vision/alig.pt and /dev/null differ diff --git a/src/vision/anger_caculate.py b/src/vision/anger_caculate.py deleted file mode 100644 index 2a82dd3..0000000 --- a/src/vision/anger_caculate.py +++ /dev/null @@ -1,88 +0,0 @@ -import cv2 -import os -import numpy as np -from ultralytics import YOLO - -def predict_obb_best_angle(model=None, model_path=None, image=None, image_path=None, save_path=None): - """ - 输入: - model: 预加载的YOLO模型实例(可选) - model_path: YOLO 权重路径(当model为None时使用) - image: 图像数组(numpy array) - image_path: 图片路径(当image为None时使用) - save_path: 可选,保存带标注图像 - 输出: - angle_deg: 置信度最高两个框的主方向夹角(度),如果检测少于两个目标返回 None - annotated_img: 可视化图像 - """ - # 1. 使用预加载的模型或加载新模型 - if model is not None: - loaded_model = model - elif model_path is not None: - loaded_model = YOLO(model_path) - else: - raise ValueError("必须提供model或model_path参数") - - # 2. 读取图像(优先使用传入的图像数组) - if image is not None: - img = image - elif image_path is not None: - img = cv2.imread(image_path) - if img is None: - print(f"无法读取图像: {image_path}") - return None, None - else: - raise ValueError("必须提供image或image_path参数") - - # 3. 推理 OBB - results = loaded_model(img, save=False, imgsz=640, conf=0.5, mode='obb') - result = results[0] - - # 4. 可视化 - annotated_img = result.plot() - if save_path: - os.makedirs(os.path.dirname(save_path), exist_ok=True) - cv2.imwrite(save_path, annotated_img) - print(f"推理结果已保存至: {save_path}") - - # 5. 提取旋转角度和置信度 - boxes = result.obb - if boxes is None or len(boxes) < 2: - print("检测到少于两个目标,无法计算夹角。") - return None, annotated_img - - box_info = [] - for box in boxes: - conf = box.conf.cpu().numpy()[0] - cx, cy, w, h, r_rad = box.xywhr.cpu().numpy()[0] - direction = r_rad if w >= h else r_rad + np.pi/2 - direction = direction % np.pi - box_info.append((conf, direction)) - - # 6. 取置信度最高两个框 - box_info = sorted(box_info, key=lambda x: x[0], reverse=True) - dir1, dir2 = box_info[0][1], box_info[1][1] - - # 7. 计算夹角(最小夹角,0~90°) - diff = abs(dir1 - dir2) - diff = min(diff, np.pi - diff) - angle_deg = np.degrees(diff) - - print(f"置信度最高两个框主方向夹角: {angle_deg:.2f}°") - return angle_deg, annotated_img - - -# ------------------- 测试 ------------------- -# if __name__ == "__main__": -# weight_path = r'angle.pt' -# image_path = r"./test_image/3.jpg" -# save_path = "./inference_results/detected_3.jpg" -# -# #angle_deg, annotated_img = predict_obb_best_angle(weight_path, image_path, save_path) -# angle_deg,_ = predict_obb_best_angle(model_path=weight_path, image_path=image_path, save_path=save_path) -# annotated_img = None -# print(angle_deg) -# if annotated_img is not None: -# cv2.imshow("YOLO OBB Prediction", annotated_img) -# cv2.waitKey(0) -# cv2.destroyAllWindows() \ No newline at end of file diff --git a/src/vision/angle.pt b/src/vision/angle.pt deleted file mode 100644 index 7b5b32d..0000000 Binary files a/src/vision/angle.pt and /dev/null differ diff --git a/src/vision/overflow.pt b/src/vision/overflow.pt deleted file mode 100644 index 3fd6d73..0000000 Binary files a/src/vision/overflow.pt and /dev/null differ diff --git a/src/vision/resize_main.py b/src/vision/resize_main.py deleted file mode 100644 index f14e8e3..0000000 --- a/src/vision/resize_main.py +++ /dev/null @@ -1,106 +0,0 @@ -import os -import shutil -from pathlib import Path -from ultralytics import YOLO -import cv2 - -# --------------------------- -# ROI 裁剪函数 -# --------------------------- -def load_global_rois(txt_path): - """加载全局 ROI 坐标""" - rois = [] - if not os.path.exists(txt_path): - print(f"❌ ROI 文件不存在: {txt_path}") - return rois - with open(txt_path, 'r') as f: - for line in f: - line = line.strip() - if line: - try: - x, y, w, h = map(int, line.split(',')) - rois.append((x, y, w, h)) - print(f"📌 加载 ROI: (x={x}, y={y}, w={w}, h={h})") - except Exception as e: - print(f"⚠️ 无法解析 ROI 行: {line}, 错误: {e}") - return rois - -def crop_and_resize(img, rois, target_size=640): - """根据 ROI 裁剪并 resize""" - crops = [] - for i, (x, y, w, h) in enumerate(rois): - h_img, w_img = img.shape[:2] - if x < 0 or y < 0 or x + w > w_img or y + h > h_img: - print(f"⚠️ ROI 越界,跳过: {x},{y},{w},{h}") - continue - roi_img = img[y:y+h, x:x+w] - roi_resized = cv2.resize(roi_img, (target_size, target_size), interpolation=cv2.INTER_AREA) - crops.append((roi_resized, i)) - return crops - -# --------------------------- -# 分类函数 -# --------------------------- -def classify_and_save_images(model_path, input_folder, output_root, roi_file, target_size=640): - # 加载模型 - model = YOLO(model_path) - - # 确保输出根目录存在 - output_root = Path(output_root) - output_root.mkdir(parents=True, exist_ok=True) - - # 创建类别子文件夹 (class0 到 class4) - class_dirs = [] - for i in range(5): # 假设有5个类别 (0-4) - class_dir = output_root / f"class{i}" - class_dir.mkdir(exist_ok=True) - class_dirs.append(class_dir) - - # 加载 ROI - rois = load_global_rois(roi_file) - if len(rois) == 0: - print("❌ 没有有效 ROI,退出") - return - - # 遍历输入文件夹 - for img_path in Path(input_folder).glob("*.*"): - if img_path.suffix.lower() not in ['.jpg', '.jpeg', '.png', '.bmp', '.tif']: - continue - - try: - # 读取原图 - img = cv2.imread(str(img_path)) - if img is None: - print(f"❌ 无法读取图像: {img_path}") - continue - - # 根据 ROI 裁剪 - crops = crop_and_resize(img, rois, target_size) - - for roi_img, roi_idx in crops: - # YOLO 推理 - results = model(roi_img) - - pred = results[0].probs.data # 获取概率分布 - class_id = int(pred.argmax()) - - # 保存到对应类别文件夹 - suffix = f"_roi{roi_idx}" if len(crops) > 1 else "" - dst_path = class_dirs[class_id] / f"{img_path.stem}{suffix}{img_path.suffix}" - cv2.imwrite(dst_path, roi_img) # 保存裁剪后的 ROI 图像 - print(f"Processed {img_path.name}{suffix} -> Class {class_id}") - - except Exception as e: - print(f"Error processing {img_path.name}: {str(e)}") - -# --------------------------- -# 主程序 -# --------------------------- -if __name__ == "__main__": - model_path = r"overflow.pt" - input_folder = "/media/hx/04e879fa-d697-4b02-ac7e-a4148876ebb0/dataset/f6" - output_root = "/media/hx/04e879fa-d697-4b02-ac7e-a4148876ebb0/dataset/class111" - roi_file = "./roi_coordinates/1_rois.txt" # 训练时使用的 ROI 文件 - target_size = 640 - - classify_and_save_images(model_path, input_folder, output_root, roi_file, target_size) diff --git a/src/vision/resize_tuili_image_main.py b/src/vision/resize_tuili_image_main.py deleted file mode 100644 index f9e95de..0000000 --- a/src/vision/resize_tuili_image_main.py +++ /dev/null @@ -1,184 +0,0 @@ -import os -from pathlib import Path -import cv2 -import numpy as np -from ultralytics import YOLO - -# --------------------------- -# 类别映射 -# --------------------------- -CLASS_NAMES = { - 0: "未堆料", - 1: "小堆料", - 2: "大堆料", - 3: "未浇筑满", - 4: "浇筑满" -} - - -# --------------------------- -# 加载 ROI 列表 -# --------------------------- -def load_global_rois(txt_path): - rois = [] - if not os.path.exists(txt_path): - print(f"ROI 文件不存在: {txt_path}") - return rois - with open(txt_path, 'r') as f: - for line in f: - s = line.strip() - if s: - try: - x, y, w, h = map(int, s.split(',')) - rois.append((x, y, w, h)) - except Exception as e: - print(f"无法解析 ROI 行 '{s}': {e}") - return rois - - -# --------------------------- -# 裁剪并 resize ROI -# --------------------------- -def crop_and_resize(img, rois, target_size=640): - crops = [] - h_img, w_img = img.shape[:2] - for i, (x, y, w, h) in enumerate(rois): - if x < 0 or y < 0 or x + w > w_img or y + h > h_img: - continue - roi = img[y:y + h, x:x + w] - roi_resized = cv2.resize(roi, (target_size, target_size), interpolation=cv2.INTER_AREA) - crops.append((roi_resized, i)) - return crops - - -# --------------------------- -# class1/class2 加权判断 -# --------------------------- -def weighted_small_large(pred_probs, threshold=0.4, w1=0.3, w2=0.7): - p1 = float(pred_probs[1]) - p2 = float(pred_probs[2]) - total = p1 + p2 - if total > 0: - score = (w1 * p1 + w2 * p2) / total - else: - score = 0.0 - final_class = "大堆料" if score >= threshold else "小堆料" - return final_class, score, p1, p2 - - -# --------------------------- -# 单张图片推理函数 -# --------------------------- -def classify_image_weighted(image, model, threshold=0.4): - results = model(image) - pred_probs = results[0].probs.data.cpu().numpy().flatten() - class_id = int(pred_probs.argmax()) - confidence = float(pred_probs[class_id]) - class_name = CLASS_NAMES.get(class_id, f"未知类别({class_id})") - - # class1/class2 使用加权得分 - if class_id in [1, 2]: - final_class, score, p1, p2 = weighted_small_large(pred_probs, threshold=threshold) - else: - final_class = class_name - score = confidence - p1 = float(pred_probs[1]) - p2 = float(pred_probs[2]) - - return final_class, score, p1, p2 - - -# --------------------------- -# 实时视频流推理函数 -# --------------------------- -def real_time_inference(rtsp_url, model_path, roi_file, target_size=640, threshold=0.4): - """ - 从RTSP流实时推理 - :param rtsp_url: RTSP流URL - :param model_path: 模型路径 - :param roi_file: ROI文件路径 - :param target_size: 目标尺寸 - :param threshold: 分类阈值 - """ - # 加载模型 - model = YOLO(model_path) - - # 加载ROI - rois = load_global_rois(roi_file) - if not rois: - print("❌ 没有有效 ROI,退出") - return - - # 打开RTSP流 - cap = cv2.VideoCapture(rtsp_url) - - if not cap.isOpened(): - print(f"❌ 无法打开视频流: {rtsp_url}") - return - - print(f"✅ 成功连接到视频流: {rtsp_url}") - print("按 'q' 键退出,按 's' 键保存当前帧") - - frame_count = 0 - while True: - ret, frame = cap.read() - if not ret: - print("❌ 无法读取帧,可能连接已断开") - break - - frame_count += 1 - print(f"\n处理第 {frame_count} 帧") - - try: - # 裁剪并调整ROI - crops = crop_and_resize(frame, rois, target_size) - - for roi_resized, roi_idx in crops: - final_class, score, p1, p2 = classify_image_weighted(roi_resized, model, threshold=threshold) - - print(f"ROI {roi_idx} -> 类别: {final_class}, 加权分数: {score:.2f}, " - f"class1 置信度: {p1:.2f}, class2 置信度: {p2:.2f}") - - # 判断是否溢料 - if "大堆料" in final_class or "浇筑满" in final_class: - print(f"🚨 检测到溢料: ROI {roi_idx} - {final_class}") - - # 可视化(可选) - cv2.imshow(f'ROI {roi_idx}', roi_resized) - - # 显示原始帧 - cv2.imshow('Original Frame', frame) - - except Exception as e: - print(f"处理帧时出错: {e}") - continue - - # 键盘控制 - key = cv2.waitKey(1) & 0xFF - if key == ord('q'): # 按q退出 - break - elif key == ord('s'): # 按s保存当前帧 - cv2.imwrite(f"frame_{frame_count}.jpg", frame) - print(f"保存帧到 frame_{frame_count}.jpg") - - # 清理资源 - cap.release() - cv2.destroyAllWindows() - print("✅ 视频流处理结束") - - -# --------------------------- -# 主函数 - 实时推理示例 -# --------------------------- -if __name__ == "__main__": - # RTSP流URL - rtsp_url = "rtsp://admin:XJ123456@192.168.1.51:554/streaming/channels/101" - - # 配置参数 - model_path = r"overflow.pt" - roi_file = r"./roi_coordinates/1_rois.txt" - target_size = 640 - threshold = 0.4 - - print("开始实时视频流推理...") - real_time_inference(rtsp_url, model_path, roi_file, target_size, threshold) diff --git a/src/vision/roi_coordinates/1_rois.txt b/src/vision/roi_coordinates/1_rois.txt deleted file mode 100644 index bb8f71d..0000000 --- a/src/vision/roi_coordinates/1_rois.txt +++ /dev/null @@ -1 +0,0 @@ -859,810,696,328 diff --git a/src/vision/test_image/1.jpg b/src/vision/test_image/1.jpg deleted file mode 100644 index 2882cd5..0000000 Binary files a/src/vision/test_image/1.jpg and /dev/null differ diff --git a/src/vision/test_image/2.jpg b/src/vision/test_image/2.jpg deleted file mode 100644 index dcd5369..0000000 Binary files a/src/vision/test_image/2.jpg and /dev/null differ diff --git a/src/vision/test_image/3.jpg b/src/vision/test_image/3.jpg deleted file mode 100644 index 8df7feb..0000000 Binary files a/src/vision/test_image/3.jpg and /dev/null differ diff --git a/tests/test_control/logs/app.log b/tests/test_control/logs/app.log deleted file mode 100644 index 3a185c3..0000000 --- a/tests/test_control/logs/app.log +++ /dev/null @@ -1,4 +0,0 @@ -2025-09-12 19:40:24,636 - FeedingControl.FeedingController - INFO - 豸ʼ -2025-09-12 19:40:27,379 - FeedingControl.FeedingController - INFO - 豸ʼ -2025-09-12 19:40:31,216 - FeedingControl.FeedingController - INFO - 豸ʼ -2025-09-13 11:01:27,838 - FeedingControl.FeedingController - INFO - 豸ʼ diff --git a/tests/test_control/test_feeding.py b/tests/test_control/test_feeding.py deleted file mode 100644 index 81fb8a5..0000000 --- a/tests/test_control/test_feeding.py +++ /dev/null @@ -1,75 +0,0 @@ -import unittest -from unittest.mock import patch, MagicMock -import sys -import os - -from src.control.feeding_controller import FeedingController - -# 添加src目录到Python路径 -sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', 'src')) - - -from src.control.state_machine import FeedingState - - -class TestFeedingController(unittest.TestCase): - - def setUp(self): - # Mock配置 - self.mock_config = { - 'network': { - 'relay': {'host': '192.168.0.18', 'port': 50000}, - 'inverter': {'host': '192.168.0.20', 'port': 502, 'slave_id': 1}, - 'transmitters': { - 'upper': {'host': '192.168.0.21', 'port': 502, 'slave_id': 1, 'weight_register': 0, - 'register_count': 2}, - 'lower': {'host': '192.168.0.22', 'port': 502, 'slave_id': 2, 'weight_register': 0, - 'register_count': 2} - } - }, - 'parameters': { - 'min_required_weight': 50, - 'max_error_count': 3, - 'monitoring_interval': 1, - 'timeout': 30 - }, - 'feeding': { - 'stage1_frequency': 30.0, - 'stage2_frequency': 40.0, - 'stage3_frequency': 50.0, - 'target_weight_per_stage': 33.3 - }, - 'relay': { - 'door_upper': 0, - 'door_lower_1': 1, - 'door_lower_2': 2, - 'break_arch_upper': 3, - 'break_arch_lower': 4 - } - } - - @patch('control.feeding_controller.config') - def test_initialization(self, mock_config): - mock_config.get.side_effect = lambda key, default=None: self._get_nested_config(key, default) - - with patch('control.feeding_controller.RelayController') as mock_relay, \ - patch('control.feeding_controller.InverterController') as mock_inverter, \ - patch('control.feeding_controller.TransmitterController') as mock_transmitter: - controller = FeedingController() - self.assertIsNotNone(controller) - - def _get_nested_config(self, key_path, default=None): - """辅助函数:获取嵌套配置值""" - keys = key_path.split('.') - value = self.mock_config - - try: - for key in keys: - value = value[key] - return value - except (KeyError, TypeError): - return default - - -if __name__ == '__main__': - unittest.main() \ No newline at end of file diff --git a/tests/test_devices/logs/app.log b/tests/test_devices/logs/app.log deleted file mode 100644 index d6adecb..0000000 --- a/tests/test_devices/logs/app.log +++ /dev/null @@ -1,5 +0,0 @@ -2025-09-13 10:37:43,979 - FeedingControl.RelayController - INFO - Ƽ̵ door_upper (0) open -2025-09-13 11:03:31,681 - FeedingControl.RelayController - INFO - Ƽ̵ door_upper (0) open -2025-09-13 11:03:34,120 - FeedingControl.RelayController - ERROR - Чļ̵豸: invalid_device -2025-09-13 11:03:36,864 - FeedingControl.RelayController - ERROR - Чļ̵豸: invalid_device -2025-09-13 11:03:36,864 - FeedingControl.RelayController - INFO - Ƽ̵ door_upper (0) open diff --git a/tests/test_devices/test_relay.py b/tests/test_devices/test_relay.py deleted file mode 100644 index 5ded677..0000000 --- a/tests/test_devices/test_relay.py +++ /dev/null @@ -1,48 +0,0 @@ -import unittest -from unittest.mock import patch, MagicMock -import sys -import os - -# 添加src目录到Python路径 -sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', 'src')) - -from src.divices.relay import RelayController - - -class TestRelayController(unittest.TestCase): - - def setUp(self): - self.relay = RelayController('192.168.0.18', 50000) - self.relay.set_device_mapping({ - 'door_upper': 0, - 'door_lower_1': 1, - 'door_lower_2': 2, - 'break_arch_upper': 3, - 'break_arch_lower': 4 - }) - - @patch('devices.relay.socket.socket') - def test_send_command_success(self, mock_socket): - # 模拟成功的socket通信 - mock_socket_instance = MagicMock() - mock_socket.return_value.__enter__.return_value = mock_socket_instance - mock_socket_instance.recv.return_value = b'\x00\x00\x00\x00\x00\x06\x01\x05\x00\x00\xff\x00' - - result = self.relay.send_command('00000000000601050000FF00') - self.assertIsNotNone(result) - - def test_control_valid_device_and_action(self): - with patch.object(self.relay, 'send_command') as mock_send: - mock_send.return_value = b'some_response' - result = self.relay.control('door_upper', 'open') - self.assertTrue(result) - - def test_control_invalid_device(self): - with patch.object(self.relay, 'send_command') as mock_send: - result = self.relay.control('invalid_device', 'open') - self.assertFalse(result) - mock_send.assert_not_called() - - -if __name__ == '__main__': - unittest.main() \ No newline at end of file