184 lines
7.4 KiB
C#
184 lines
7.4 KiB
C#
using System;
|
|
using System.Linq;
|
|
using SimpleCore.Library;
|
|
using StandardScene.Signal.Model;
|
|
|
|
namespace StandardScene.Signal.Plc
|
|
{
|
|
/// <summary>读写字节转换与四套自动离站,对齐反编译 PLCManager。</summary>
|
|
public static class PlcStationLogic
|
|
{
|
|
public static SignalReadValue ConvertRead(byte val) => val switch
|
|
{
|
|
1 => SignalReadValue.允许进入,
|
|
2 => SignalReadValue.允许离开,
|
|
_ => SignalReadValue.无状态
|
|
};
|
|
|
|
public static SignalWriteValue ConvertWrite(byte val) => val switch
|
|
{
|
|
1 => SignalWriteValue.进入中,
|
|
2 => SignalWriteValue.到位,
|
|
3 => SignalWriteValue.离开中,
|
|
4 => SignalWriteValue.已离开,
|
|
_ => SignalWriteValue.无状态
|
|
};
|
|
|
|
public static bool ContainsSite(string csv, int siteId)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(csv) || siteId <= 0)
|
|
return false;
|
|
return csv.Split(new[] { ',', ';', ' ' }, StringSplitOptions.RemoveEmptyEntries)
|
|
.Any(s => int.TryParse(s.Trim(), out var n) && n == siteId);
|
|
}
|
|
|
|
public static void AutoLeave(PlcStationRuntime rt)
|
|
{
|
|
if (rt?.Config == null) return;
|
|
switch (rt.Config.LineType)
|
|
{
|
|
case SignalLineType.上线机构:
|
|
AutoLeaveUpLine(rt);
|
|
break;
|
|
case SignalLineType.单牵引下线机构:
|
|
AutoLeaveDownLine(rt, pin2: false);
|
|
break;
|
|
case SignalLineType.双牵引下线机构:
|
|
AutoLeaveDownLine(rt, pin2: true);
|
|
break;
|
|
case SignalLineType.等待通行机构:
|
|
AutoLeaveWaitSit(rt);
|
|
break;
|
|
}
|
|
}
|
|
|
|
private static void ClearLeft(PlcStationRuntime rt, bool fromReadback)
|
|
{
|
|
rt.WriteSignal = SignalWriteValue.无状态;
|
|
rt.InAgvNo = 0;
|
|
if (rt.RequestInAgvNo > 0)
|
|
{
|
|
Diagnosis.Log(
|
|
$"{rt.Config.JgName} {(fromReadback ? "回读已离开" : "写已离开成功")},清空请求进入车 {rt.RequestInAgvNo}",
|
|
"JGControl", true);
|
|
rt.RequestInAgvNo = 0;
|
|
}
|
|
else
|
|
Diagnosis.Log($"{rt.Config.JgName} 已离开,清空信号", "JGControl", true);
|
|
}
|
|
|
|
private static void AutoLeaveUpLine(PlcStationRuntime rt)
|
|
{
|
|
if (rt.WriteSuccess && rt.WriteSignal == SignalWriteValue.已离开)
|
|
ClearLeft(rt, fromReadback: false);
|
|
if (rt.ReadWriteSignal == SignalWriteValue.已离开)
|
|
ClearLeft(rt, fromReadback: true);
|
|
|
|
if (rt.WriteSuccess && rt.WriteSignal == SignalWriteValue.进入中)
|
|
{
|
|
var car = SignalCarAdapter.Find(rt.RequestInAgvNo);
|
|
if (car == null) return;
|
|
if (!ContainsSite(rt.Config.JgInContains, SignalCarAdapter.PositionId(car)))
|
|
{
|
|
rt.WriteSignal = SignalWriteValue.到位;
|
|
rt.InAgvNo = car.id;
|
|
rt.RequestInAgvNo = 0;
|
|
Diagnosis.Log($"AGV{car.id} 已到达机构 {rt.Config.JgName}", "JGControl", true);
|
|
}
|
|
}
|
|
else if (rt.WriteSuccess && rt.WriteSignal == SignalWriteValue.到位)
|
|
{
|
|
var car = SignalCarAdapter.Find(rt.InAgvNo);
|
|
if (car == null || SignalCarAdapter.IsRunning(car))
|
|
rt.WriteSignal = SignalWriteValue.离开中;
|
|
}
|
|
else if (rt.WriteSuccess && rt.WriteSignal == SignalWriteValue.离开中)
|
|
{
|
|
var car = SignalCarAdapter.Find(rt.InAgvNo);
|
|
if (car == null || !ContainsSite(rt.Config.JgContains, SignalCarAdapter.PositionId(car)))
|
|
rt.WriteSignal = SignalWriteValue.已离开;
|
|
}
|
|
}
|
|
|
|
private static void AutoLeaveDownLine(PlcStationRuntime rt, bool pin2)
|
|
{
|
|
if (rt.WriteSuccess && rt.WriteSignal == SignalWriteValue.已离开)
|
|
{
|
|
ClearLeft(rt, fromReadback: false);
|
|
return;
|
|
}
|
|
|
|
if (rt.ReadWriteSignal == SignalWriteValue.已离开)
|
|
ClearLeft(rt, fromReadback: true);
|
|
|
|
if (rt.InAgvNo == 0) return;
|
|
var car = SignalCarAdapter.Find(rt.InAgvNo);
|
|
if (car == null) return;
|
|
|
|
var pos = SignalCarAdapter.PositionId(car);
|
|
if (rt.ReadSignal == SignalReadValue.允许离开 && pos == rt.Config.JgPointId)
|
|
{
|
|
if (rt.WriteSignal == SignalWriteValue.离开中) return;
|
|
var pinOk = SignalCarAdapter.IsActionFinish(car, "SetPin1Up")
|
|
&& (!pin2 || SignalCarAdapter.IsActionFinish(car, "SetPin2Up"))
|
|
&& SignalCarAdapter.IsActionFinish(car, "StopCharge");
|
|
if (pinOk)
|
|
{
|
|
SignalCarAdapter.StopCharge(car);
|
|
SignalCarAdapter.Start(car);
|
|
rt.WriteSignal = SignalWriteValue.离开中;
|
|
Diagnosis.Log($"{rt.Config.JgName} 允许离开,通知 AGV{car.id} 启动,写离开中", "JGControl", true);
|
|
}
|
|
else
|
|
{
|
|
SignalCarAdapter.Control(car, "SetPin1Up");
|
|
if (pin2) SignalCarAdapter.Control(car, "SetPin2Up");
|
|
SignalCarAdapter.Control(car, "StopCharge");
|
|
}
|
|
}
|
|
else if (!string.IsNullOrEmpty(rt.Config.JgContains)
|
|
&& !ContainsSite(rt.Config.JgContains, pos)
|
|
&& rt.ReadWriteSignal != SignalWriteValue.已离开)
|
|
{
|
|
rt.WriteSignal = SignalWriteValue.已离开;
|
|
}
|
|
}
|
|
|
|
private static void AutoLeaveWaitSit(PlcStationRuntime rt)
|
|
{
|
|
if (rt.WriteSuccess && rt.WriteSignal == SignalWriteValue.已离开)
|
|
{
|
|
ClearLeft(rt, fromReadback: false);
|
|
return;
|
|
}
|
|
|
|
if (rt.ReadWriteSignal == SignalWriteValue.已离开)
|
|
ClearLeft(rt, fromReadback: true);
|
|
|
|
if (rt.InAgvNo == 0) return;
|
|
var car = SignalCarAdapter.Find(rt.InAgvNo);
|
|
if (car == null) return;
|
|
|
|
var pos = SignalCarAdapter.PositionId(car);
|
|
if (rt.ReadSignal == SignalReadValue.允许离开 && pos == rt.Config.JgPointId)
|
|
{
|
|
if (rt.WriteSignal == SignalWriteValue.离开中) return;
|
|
if (SignalCarAdapter.IsActionFinish(car, "StopCharge"))
|
|
{
|
|
SignalCarAdapter.Start(car);
|
|
rt.WriteSignal = SignalWriteValue.离开中;
|
|
Diagnosis.Log($"{rt.Config.JgName} 允许离开,通知 AGV{car.id} 启动,写离开中", "JGControl", true);
|
|
}
|
|
else
|
|
SignalCarAdapter.Control(car, "StopCharge");
|
|
}
|
|
else if (!string.IsNullOrEmpty(rt.Config.JgContains)
|
|
&& !ContainsSite(rt.Config.JgContains, pos)
|
|
&& rt.ReadWriteSignal != SignalWriteValue.已离开)
|
|
{
|
|
rt.WriteSignal = SignalWriteValue.已离开;
|
|
}
|
|
}
|
|
}
|
|
}
|