using System;
using SimpleCore.Library;
using SimpleLite.RCS.CarTypes;
using StandardScene.Signal.Model;
using StandardScene.Signal.Plc;
namespace StandardScene.Signal.Logic
{
///
/// 销钉 / 牵引棒升降后再放行。对齐反编译 DefaultPlugin.PointControl。
///
///
/// SignalParams:动作;机构名。
/// 动作:UP1 升销钉1,UP2 升销钉1+2,Down1 / Down2 对应下降。
/// 机构名可选:填了则必须等该机构读字节=允许离开才启动;空则只等销钉动作完成。
/// 销钉指令通过 反射调用车体 MethodMember(如 SetPin1Up)。
///
public static class PointControlHandler
{
/// 停稳:先判机构是否允许离开,再下发销钉,全部到位后启动。
public static void OnStopped(Car car, SignalStopSpec spec, Func find)
{
var action = spec.Part(0).Trim();
var jgName = spec.Part(1).Trim();
if (string.IsNullOrEmpty(action))
{
Diagnosis.Log($"AGV{car.id}停在地标{SignalCarAdapter.PositionId(car)},读取配置特殊点名称为空", "SetPin", true);
return;
}
var waitLeave = false;
if (!string.IsNullOrEmpty(jgName))
{
var rt = find(jgName);
if (rt != null)
{
lock (rt.Sync)
waitLeave = rt.ReadSignal != SignalReadValue.允许离开;
}
}
var pos = SignalCarAdapter.PositionId(car);
switch (action)
{
case "UP1":
PinThenGo(car, pos, waitLeave, jgName, "SetPin1Up");
break;
case "UP2":
PinThenGo(car, pos, waitLeave, jgName, "SetPin1Up", "SetPin2Up");
break;
case "Down1":
PinThenGo(car, pos, waitLeave, jgName, "SetPin1Down");
break;
case "Down2":
PinThenGo(car, pos, waitLeave, jgName, "SetPin1Down", "SetPin2Down");
break;
}
}
///
/// 任一销钉未完成则本拍只下发指令、不启动;
/// 全部完成且(无需等离开 或 已允许离开)才 Start。
///
private static void PinThenGo(Car car, int pos, bool waitLeave, string jgName, params string[] actions)
{
var done = true;
foreach (var a in actions)
{
if (!SignalCarAdapter.IsActionFinish(car, a))
done = false;
}
if (!done)
{
foreach (var a in actions)
SignalCarAdapter.Control(car, a);
return;
}
if (waitLeave)
{
Diagnosis.Log($"AGV{car.id}停在地标{pos},需要读取{jgName}工位的允许离开", "SetPin", true);
return;
}
SignalCarAdapter.Start(car);
Diagnosis.Log($"AGV{car.id}停在地标{pos},牵引棒动作到位,已通知AGV启动", "SetPin", true);
}
}
}