将Feature/XP.Common和Feature/XP.Hardware分支合并至Develop/XP.forHardwareAndCommon,完善XPapp注册和相关硬件类库通用类库功能。

This commit is contained in:
QI Mingxuan
2026-04-16 17:31:13 +08:00
parent 6ec4c3ddaa
commit 2bd6e566c3
581 changed files with 74600 additions and 222 deletions
@@ -0,0 +1,109 @@
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
{
/// <summary>
/// 基于 PLC 的运动系统实现 | PLC-based Motion System Implementation
/// 使用 MotionSignalNames 硬编码信号名称 | Uses MotionSignalNames for hardcoded signal names
/// </summary>
public class PlcMotionSystem : IMotionSystem
{
private readonly Dictionary<AxisId, ILinearAxis> _linearAxes = new();
private readonly Dictionary<RotaryAxisId, IRotaryAxis> _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);
}
/// <inheritdoc/>
public ISafetyDoor SafetyDoor => _safetyDoor;
/// <inheritdoc/>
public IAxisReset AxisReset => _axisReset;
/// <inheritdoc/>
public IReadOnlyDictionary<AxisId, ILinearAxis> LinearAxes => _linearAxes;
/// <inheritdoc/>
public IReadOnlyDictionary<RotaryAxisId, IRotaryAxis> RotaryAxes => _rotaryAxes;
/// <inheritdoc/>
public ILinearAxis GetLinearAxis(AxisId axisId)
{
if (_linearAxes.TryGetValue(axisId, out var axis)) return axis;
throw new KeyNotFoundException($"未找到直线轴 {axisId} | Linear axis {axisId} not found");
}
/// <inheritdoc/>
public IRotaryAxis GetRotaryAxis(RotaryAxisId axisId)
{
if (_rotaryAxes.TryGetValue(axisId, out var axis)) return axis;
throw new KeyNotFoundException($"未找到旋转轴 {axisId} | Rotary axis {axisId} not found");
}
/// <inheritdoc/>
public void UpdateAllStatus()
{
foreach (var axis in _linearAxes.Values) axis.UpdateStatus();
foreach (var axis in _rotaryAxes.Values) axis.UpdateStatus();
_safetyDoor.UpdateStatus();
_axisReset.UpdateStatus();
}
}
}