87 lines
2.8 KiB
Python
87 lines
2.8 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
|
|
|
|
# 行程与阀门开度反向:行程越大,阀门开度越小。阀门开度减小
|
|
# 时系统压力升高;默认量程下行程 0/1000 分别对应 10/400 kPa。
|
|
travel_ratio = max(0.0, min(1.0, self.position / 1000.0))
|
|
target_pressure = 10.0 + (self.pressure_range - 10.0) * travel_ratio
|
|
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
|
|
|