using System; using System.Collections.Generic; using XP.Hardware.MotionControl.Abstractions; using XP.Hardware.MotionControl.Abstractions.Enums; using XP.Hardware.MotionControl.Config; using XP.Hardware.Plc.Abstractions; namespace XP.Hardware.MotionControl.Implementations { /// /// 基于 PLC 的运动系统实现 | PLC-based Motion System Implementation /// 使用 MotionSignalNames 硬编码信号名称 | Uses MotionSignalNames for hardcoded signal names /// public class PlcMotionSystem : IMotionSystem { private readonly Dictionary _linearAxes = new(); private readonly Dictionary _rotaryAxes = new(); private readonly ISafetyDoor _safetyDoor; private readonly IAxisReset _axisReset; public PlcMotionSystem(MotionControlConfig config, ISignalDataService signalService) { if (config == null) throw new ArgumentNullException(nameof(config)); if (signalService == null) throw new ArgumentNullException(nameof(signalService)); // 创建直线轴 | Create linear axes if (config.LinearAxes.TryGetValue(AxisId.SourceZ, out var sz)) _linearAxes[AxisId.SourceZ] = new PlcLinearAxis(AxisId.SourceZ, sz.Min, sz.Max, sz.Origin, signalService, MotionSignalNames.SourceZ_Pos, MotionSignalNames.SourceZ_Target, MotionSignalNames.SourceZ_Speed, MotionSignalNames.SourceZ_JogPos, MotionSignalNames.SourceZ_JogNeg, MotionSignalNames.SourceZ_Home, MotionSignalNames.SourceZ_Stop); if (config.LinearAxes.TryGetValue(AxisId.DetectorZ, out var dz)) _linearAxes[AxisId.DetectorZ] = new PlcLinearAxis(AxisId.DetectorZ, dz.Min, dz.Max, dz.Origin, signalService, MotionSignalNames.DetZ_Pos, MotionSignalNames.DetZ_Target, MotionSignalNames.DetZ_Speed, MotionSignalNames.DetZ_JogPos, MotionSignalNames.DetZ_JogNeg, MotionSignalNames.DetZ_Home, MotionSignalNames.DetZ_Stop); if (config.LinearAxes.TryGetValue(AxisId.StageX, out var sx)) _linearAxes[AxisId.StageX] = new PlcLinearAxis(AxisId.StageX, sx.Min, sx.Max, sx.Origin, signalService, MotionSignalNames.StageX_Pos, MotionSignalNames.StageX_Target, MotionSignalNames.StageX_Speed, MotionSignalNames.StageX_JogPos, MotionSignalNames.StageX_JogNeg, MotionSignalNames.StageX_Home, MotionSignalNames.StageX_Stop); if (config.LinearAxes.TryGetValue(AxisId.StageY, out var sy)) _linearAxes[AxisId.StageY] = new PlcLinearAxis(AxisId.StageY, sy.Min, sy.Max, sy.Origin, signalService, MotionSignalNames.StageY_Pos, MotionSignalNames.StageY_Target, MotionSignalNames.StageY_Speed, MotionSignalNames.StageY_JogPos, MotionSignalNames.StageY_JogNeg, MotionSignalNames.StageY_Home, MotionSignalNames.StageY_Stop); // 创建旋转轴 | Create rotary axes if (config.RotaryAxes.TryGetValue(RotaryAxisId.DetectorSwing, out var ds)) _rotaryAxes[RotaryAxisId.DetectorSwing] = new PlcRotaryAxis(RotaryAxisId.DetectorSwing, ds.Min, ds.Max, ds.Enabled, signalService, MotionSignalNames.DetSwing_Angle, MotionSignalNames.DetSwing_Target, MotionSignalNames.DetSwing_Speed, MotionSignalNames.DetSwing_JogPos, MotionSignalNames.DetSwing_JogNeg, MotionSignalNames.DetSwing_Home, MotionSignalNames.DetSwing_Stop); if (config.RotaryAxes.TryGetValue(RotaryAxisId.StageRotation, out var sr)) _rotaryAxes[RotaryAxisId.StageRotation] = new PlcRotaryAxis(RotaryAxisId.StageRotation, sr.Min, sr.Max, sr.Enabled, signalService, MotionSignalNames.StageRot_Angle, MotionSignalNames.StageRot_Target, MotionSignalNames.StageRot_Speed, MotionSignalNames.StageRot_JogPos, MotionSignalNames.StageRot_JogNeg, MotionSignalNames.StageRot_Home, MotionSignalNames.StageRot_Stop); if (config.RotaryAxes.TryGetValue(RotaryAxisId.FixtureRotation, out var fr)) _rotaryAxes[RotaryAxisId.FixtureRotation] = new PlcRotaryAxis(RotaryAxisId.FixtureRotation, fr.Min, fr.Max, fr.Enabled, signalService, MotionSignalNames.FixRot_Angle, MotionSignalNames.FixRot_Target, MotionSignalNames.FixRot_Speed, MotionSignalNames.FixRot_JogPos, MotionSignalNames.FixRot_JogNeg, MotionSignalNames.FixRot_Home, MotionSignalNames.FixRot_Stop); // 创建安全门 | Create safety door _safetyDoor = new PlcSafetyDoor(signalService); // 创建轴复位 | Create axis reset _axisReset = new PlcAxisReset(signalService); } /// public ISafetyDoor SafetyDoor => _safetyDoor; /// public IAxisReset AxisReset => _axisReset; /// public IReadOnlyDictionary LinearAxes => _linearAxes; /// public IReadOnlyDictionary RotaryAxes => _rotaryAxes; /// public ILinearAxis GetLinearAxis(AxisId axisId) { if (_linearAxes.TryGetValue(axisId, out var axis)) return axis; throw new KeyNotFoundException($"未找到直线轴 {axisId} | Linear axis {axisId} not found"); } /// public IRotaryAxis GetRotaryAxis(RotaryAxisId axisId) { if (_rotaryAxes.TryGetValue(axisId, out var axis)) return axis; throw new KeyNotFoundException($"未找到旋转轴 {axisId} | Rotary axis {axisId} not found"); } /// public void UpdateAllStatus() { foreach (var axis in _linearAxes.Values) axis.UpdateStatus(); foreach (var axis in _rotaryAxes.Values) axis.UpdateStatus(); _safetyDoor.UpdateStatus(); _axisReset.UpdateStatus(); } } }