using System; using XP.Hardware.MotionControl.Abstractions; using XP.Hardware.MotionControl.Abstractions.Enums; using XP.Hardware.Plc.Abstractions; namespace XP.Hardware.MotionControl.Implementations { /// /// 基于 PLC 的旋转轴实现 | PLC-based Rotary Axis Implementation /// 信号名称硬编码在 MotionSignalNames 中 | Signal names hardcoded in MotionSignalNames /// public class PlcRotaryAxis : RotaryAxisBase { private readonly ISignalDataService _signalService; private readonly string _readSignal; private readonly string _writeSignal; private readonly string _speedSignal; private readonly string _jogPosSignal; private readonly string _jogNegSignal; private readonly string _homeSignal; private readonly string _stopSignal; /// /// 构造函数 | Constructor /// public PlcRotaryAxis( RotaryAxisId axisId, double minAngle, double maxAngle, bool enabled, ISignalDataService signalService, string readSignal, string writeSignal, string speedSignal, string jogPosSignal, string jogNegSignal, string homeSignal, string stopSignal) : base(axisId, minAngle, maxAngle, enabled) { _signalService = signalService ?? throw new ArgumentNullException(nameof(signalService)); _readSignal = readSignal; _writeSignal = writeSignal; _speedSignal = speedSignal; _jogPosSignal = jogPosSignal; _jogNegSignal = jogNegSignal; _homeSignal = homeSignal; _stopSignal = stopSignal; } /// public override MotionResult MoveToTarget(double targetAngle, double? speed = null) { if (!_enabled) return MotionResult.Fail($"旋转轴 {_axisId} 已禁用,拒绝移动命令"); if (!ValidateTarget(targetAngle)) return MotionResult.Fail($"目标角度 {targetAngle} 超出范围 [{_minAngle}, {_maxAngle}]"); if (Status == AxisStatus.Moving) return MotionResult.Fail($"旋转轴 {_axisId} 正在运动中,拒绝重复命令"); if (speed.HasValue) _signalService.EnqueueWrite(_speedSignal, (float)speed.Value); _signalService.EnqueueWrite(_writeSignal, (float)targetAngle); Status = AxisStatus.Moving; return MotionResult.Ok(); } /// public override MotionResult JogStart(bool positive) { if (!_enabled) return MotionResult.Fail($"旋转轴 {_axisId} 已禁用,拒绝 Jog 命令"); if (Status == AxisStatus.Homing) return MotionResult.Fail($"旋转轴 {_axisId} 正在回零,拒绝 Jog 命令"); _signalService.EnqueueWrite(positive ? _jogPosSignal : _jogNegSignal, true); return MotionResult.Ok(); } /// public override MotionResult JogStop() { if (!_enabled) return MotionResult.Fail($"旋转轴 {_axisId} 已禁用,拒绝 Jog 停止命令"); _signalService.EnqueueWrite(_jogPosSignal, false); _signalService.EnqueueWrite(_jogNegSignal, false); return MotionResult.Ok(); } /// public override MotionResult Home() { if (!_enabled) return MotionResult.Fail($"旋转轴 {_axisId} 已禁用,拒绝回零命令"); _signalService.EnqueueWrite(_homeSignal, true); Status = AxisStatus.Homing; return MotionResult.Ok(); } /// public override MotionResult Stop() { if (!_enabled) return MotionResult.Fail($"旋转轴 {_axisId} 已禁用,拒绝停止命令"); _signalService.EnqueueWrite(_stopSignal, true); return MotionResult.Ok(); } /// public override void UpdateStatus() { if (!_enabled) return; ActualAngle = _signalService.GetValueByName(_readSignal); } } }