Sic.Framework/MECF.Framework.Common/Aitex/Core/RT/Routine/ModuleRoutine.cs

272 lines
6.1 KiB
C#
Raw Normal View History

2023-04-13 11:51:03 +08:00
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Aitex.Core.RT.Event;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.SubstrateTrackings;
namespace Aitex.Core.RT.Routine
{
public class ModuleRoutine : SeqenecRoutine
{
#region Variables
public delegate RoutineState RoutineFunc<T>(T arg);
/// <summary>
/// 用于统计Routine耗时的计时器。
/// </summary>
protected readonly Stopwatch SwStatisticElapse;
protected string _stepName;
protected TimeSpan _stepSpan = new TimeSpan(0, 0, 0, 0);
protected DateTime _stepStartTime;
private static object locker = new object();
#endregion
#region Constuctors
public ModuleRoutine(string module)
{
Module = module;
SwStatisticElapse = new Stopwatch();
}
#endregion
#region Properties
/// <summary>
/// 返回当前Routine所述的模组
/// </summary>
public string Module { get; protected set; }
/// <summary>
/// 返回当前Routine的名称
/// </summary>
public string Name { get; protected set; }
public string StepName => _stepName;
public TimeSpan StepLeftTime
{
get
{
if (_stepSpan.TotalMilliseconds < 1.0)
{
return _stepSpan;
}
return _stepSpan - (DateTime.Now - _stepStartTime);
}
}
#endregion
#region Methods
public virtual Result Monitor()
{
try
{
MonitorBody();
}
catch (RoutineBreakException)
{
return Result.RUN;
}
catch (RoutineFaildException)
{
return Result.FAIL;
}
SwStatisticElapse.Stop();
Notify($"Finished ! Elapsed time: {(int)(SwStatisticElapse.ElapsedMilliseconds / 1000)} s");
return Result.DONE;
}
public virtual Result Start(params object[] args)
{
Reset();
SwStatisticElapse.Restart();
return StartBody(args);
}
public virtual void Abort()
{
}
protected virtual Result StartBody(params object[] args)
{
return Result.RUN;
}
protected virtual void MonitorBody()
{
}
protected void Notify(string message)
{
EV.PostInfoLog(Module, Name + ", " + message);
}
protected void Stop(string failReason)
{
EV.PostAlarmLog(Module, Name + " failed, " + failReason);
}
public void Abort(string failReason)
{
EV.PostAlarmLog(Module, Name + " " + failReason);
}
public void TimeDelay(int id, string stepName, double time)
{
Tuple<bool, Result> tuple = Delay(id, delegate
{
Notify($"Delay {time} seconds");
_stepSpan = new TimeSpan(0, 0, 0, (int)time);
_stepStartTime = DateTime.Now;
_stepName = stepName;
return true;
}, time * 1000.0);
if (tuple.Item1 && tuple.Item2 == Result.RUN)
{
throw new RoutineBreakException();
}
}
public void TimeDelay(int id, double time)
{
Tuple<bool, Result> tuple = Delay(id, delegate
{
Notify($"Delay {time} seconds");
_stepSpan = new TimeSpan(0, 0, 0, (int)time);
_stepStartTime = DateTime.Now;
return true;
}, time * 1000.0);
if (tuple.Item1 && tuple.Item2 == Result.RUN)
{
throw new RoutineBreakException();
}
}
protected void ExecuteRoutine(int id, List<(IRoutine routine, object[] args)> routines)
{
Tuple<bool, Result> tuple = ExecuteAndWait(id, routines);
if (tuple.Item1)
{
if (tuple.Item2 == Result.FAIL)
{
throw new RoutineFaildException();
}
if (tuple.Item2 == Result.RUN)
{
throw new RoutineBreakException();
}
}
}
protected void ExecuteRoutine(int id, List<IRoutine> routines)
{
Tuple<bool, Result> tuple = ExecuteAndWait(id, routines);
if (tuple.Item1)
{
if (tuple.Item2 == Result.FAIL)
{
throw new RoutineFaildException();
}
if (tuple.Item2 == Result.RUN)
{
throw new RoutineBreakException();
}
}
}
protected void ExecuteRoutine(int id, IRoutine routine, params object[] args)
{
Tuple<bool, Result> tuple = ExecuteAndWait(id, routine, args);
if (tuple.Item1)
{
if (tuple.Item2 == Result.FAIL)
{
throw new RoutineFaildException();
}
if (tuple.Item2 == Result.RUN)
{
throw new RoutineBreakException();
}
}
}
protected void PerformStep<T, T1>(T step, RoutineFunc<T1> func, T1 param1)
{
int num = Convert.ToInt32(step);
RoutineState routineState = func(param1);
}
public void Loop(int id, int count)
{
Tuple<bool, Result> tuple = Loop(id, delegate
{
Notify($"Start loop {base.LoopCounter + 1}/{count}");
return true;
}, count);
if (tuple.Item1 && tuple.Item2 == Result.FAIL)
{
throw new RoutineFaildException();
}
}
public void EndLoop(int id)
{
Tuple<bool, Result> tuple = EndLoop(id, delegate
{
Notify("Loop finished");
return true;
});
if (tuple.Item1)
{
throw new RoutineBreakException();
}
}
/// <summary>
/// 转移产品。
/// </summary>
/// <param name="id"></param>
/// <param name="moduleFrom"></param>
/// <param name="slotFrom"></param>
/// <param name="moduleTo"></param>
/// <param name="slotTo"></param>
/// <exception cref="RoutineFaildException"></exception>
protected virtual void Transfer(int id, ModuleName moduleFrom, int slotFrom, ModuleName moduleTo, int slotTo)
{
var ret = Execute(id, () =>
{
Notify($"Transfer {moduleFrom}.{slotFrom} -> {moduleTo}.{slotTo}");
// 产品到达抓取位置后Slot0 转移到 Slot1
WaferManager.Instance.WaferMoved(moduleFrom, slotFrom,
moduleTo, slotTo);
return true;
});
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw new RoutineFaildException();
}
}
}
#endregion
}
}