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

272 lines
6.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}
}