新增 scene.signal 信号交互插件,落地 PLC 握手与扫车放行。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
ykkokluo
2026-08-14 14:43:11 +08:00
co-authored by Cursor
parent 1e780c2b65
commit 12c7c1d518
29 changed files with 2425 additions and 1 deletions
+183
View File
@@ -0,0 +1,183 @@
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.;
}
}
}
}