Files
ReinLoopTest/ReinLoop/core/simulated_device.py
T
2026-07-31 11:29:10 +08:00

87 lines
2.7 KiB
Python

"""Deterministic in-memory device used for hardware-free ReinLoop tests.
The public methods intentionally mirror the MT2AM8 client and the small
subset of the legacy PLC/motor clients used by ``tool/gui.py``. No sockets,
serial ports, or Modbus objects are created here.
"""
import time
class SimulatedDevice:
"""A small pressure/flow/valve model for offline control-loop testing."""
def __init__(self, pressure_range=400.0, flow_range=100.0,
initial_pressure=0.0):
self.pressure_range = float(pressure_range)
self.flow_range = float(flow_range)
self.pressure = float(initial_pressure)
self.flow = min(self.flow_range, 50.0)
self.position = 1000.0
self.connected = False
self.last_update = time.monotonic()
self.command_log = []
def connect(self):
self.connected = True
self.last_update = time.monotonic()
print("模拟设备连接成功(未访问真实硬件)")
return True
def disconnect(self):
self.connected = False
print("模拟设备已断开")
def _advance(self):
now = time.monotonic()
dt = max(0.0, min(now - self.last_update, 0.5))
self.last_update = now
if not self.connected or dt == 0:
return
# MT2AM8 的行程控制在当前程序中是反向阀位:较小行程表示更大
# 进气。模型因此让压力向由行程决定的目标值缓慢靠近。
opening = max(0.0, min(1.0, 1.0 - self.position / 1000.0))
target_pressure = self.pressure_range * opening
response = min(1.0, dt / 8.0)
self.pressure += (target_pressure - self.pressure) * response
def get_pressure(self, channel=0):
self._advance()
return max(0.0, self.pressure)
def get_flow(self, channel=0):
self._advance()
opening = max(0.0, min(1.0, 1.0 - self.position / 1000.0))
return self.flow * (0.25 + 0.75 * opening)
def set_motor_position(self, position, channel=0):
self._advance()
position = float(position)
if not 0.0 <= position <= 1000.0:
return False
self.position = position
self.command_log.append({"position": position, "channel": channel,
"time": time.monotonic()})
return True
# Compatibility methods used by the legacy GUI and standalone helpers.
def get_current_p(self):
return self.get_pressure(0)
def read_current_position(self):
return self.position
def set_position(self, position):
return self.set_motor_position(position)
def init(self):
return True
def start_control(self):
return True
def stop_control(self):
return True