108 lines
4.1 KiB
C#
108 lines
4.1 KiB
C#
using System;
|
|
using XP.Hardware.MotionControl.Abstractions;
|
|
using XP.Hardware.MotionControl.Abstractions.Enums;
|
|
using XP.Hardware.Plc.Abstractions;
|
|
|
|
namespace XP.Hardware.MotionControl.Implementations
|
|
{
|
|
/// <summary>
|
|
/// 基于 PLC 的直线轴实现 | PLC-based Linear Axis Implementation
|
|
/// 通过 ISignalDataService 与 PLC 通信,信号名称硬编码在 MotionSignalNames 中
|
|
/// Communicates with PLC via ISignalDataService, signal names hardcoded in MotionSignalNames
|
|
/// </summary>
|
|
public class PlcLinearAxis : LinearAxisBase
|
|
{
|
|
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;
|
|
private readonly string _limitPosSignal;
|
|
private readonly string _limitNegSignal;
|
|
|
|
/// <summary>
|
|
/// 构造函数 | Constructor
|
|
/// </summary>
|
|
public PlcLinearAxis(
|
|
AxisId axisId, double min, double max, double origin,
|
|
ISignalDataService signalService,
|
|
string readSignal, string writeSignal, string speedSignal,
|
|
string jogPosSignal, string jogNegSignal,
|
|
string homeSignal, string stopSignal)
|
|
: base(axisId, min, max, origin)
|
|
{
|
|
_signalService = signalService ?? throw new ArgumentNullException(nameof(signalService));
|
|
_readSignal = readSignal;
|
|
_writeSignal = writeSignal;
|
|
_speedSignal = speedSignal;
|
|
_jogPosSignal = jogPosSignal;
|
|
_jogNegSignal = jogNegSignal;
|
|
_homeSignal = homeSignal;
|
|
_stopSignal = stopSignal;
|
|
_limitPosSignal = $"MC_{axisId}_LimitPos";
|
|
_limitNegSignal = $"MC_{axisId}_LimitNeg";
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
public override MotionResult MoveToTarget(double target, double? speed = null)
|
|
{
|
|
if (!ValidateTarget(target))
|
|
return MotionResult.Fail($"目标位置 {target} 超出范围 [{_min}, {_max}]");
|
|
if (Status == AxisStatus.Moving)
|
|
return MotionResult.Fail($"轴 {_axisId} 正在运动中,拒绝重复命令");
|
|
|
|
if (speed.HasValue)
|
|
_signalService.EnqueueWrite(_speedSignal, (float)speed.Value);
|
|
_signalService.EnqueueWrite(_writeSignal, (float)target);
|
|
Status = AxisStatus.Moving;
|
|
return MotionResult.Ok();
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
public override MotionResult JogStart(bool positive)
|
|
{
|
|
if (Status == AxisStatus.Homing)
|
|
return MotionResult.Fail($"轴 {_axisId} 正在回零,拒绝 Jog 命令");
|
|
|
|
var signal = positive ? _jogPosSignal : _jogNegSignal;
|
|
_signalService.EnqueueWrite(signal, true);
|
|
return MotionResult.Ok();
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
public override MotionResult JogStop()
|
|
{
|
|
_signalService.EnqueueWrite(_jogPosSignal, false);
|
|
_signalService.EnqueueWrite(_jogNegSignal, false);
|
|
return MotionResult.Ok();
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
public override MotionResult Home()
|
|
{
|
|
_signalService.EnqueueWrite(_homeSignal, true);
|
|
Status = AxisStatus.Homing;
|
|
return MotionResult.Ok();
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
public override MotionResult Stop()
|
|
{
|
|
_signalService.EnqueueWrite(_stopSignal, true);
|
|
return MotionResult.Ok();
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
public override void UpdateStatus()
|
|
{
|
|
ActualPosition = _signalService.GetValueByName<float>(_readSignal);
|
|
try { PositiveLimitHit = _signalService.GetValueByName<bool>(_limitPosSignal); } catch { }
|
|
try { NegativeLimitHit = _signalService.GetValueByName<bool>(_limitNegSignal); } catch { }
|
|
if (PositiveLimitHit || NegativeLimitHit) Status = AxisStatus.Alarm;
|
|
}
|
|
}
|
|
}
|